OSDN Git Service

* config/sh/sh.md (divsi_inv_m0): Remove unused variable.
[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
157   ;; These are used with unspec_volatile.
158   (UNSPECV_BLOCKAGE     0)
159   (UNSPECV_ALIGN        1)
160   (UNSPECV_CONST2       2)
161   (UNSPECV_CONST4       4)
162   (UNSPECV_CONST8       6)
163   (UNSPECV_WINDOW_END   10)
164   (UNSPECV_CONST_END    11)
165 ])
166
167 ;; -------------------------------------------------------------------------
168 ;; Attributes
169 ;; -------------------------------------------------------------------------
170
171 ;; Target CPU.
172
173 (define_attr "cpu"
174  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175   (const (symbol_ref "sh_cpu_attr")))
176
177 (define_attr "endian" "big,little"
178  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179                       (const_string "little") (const_string "big"))))
180
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184                          (const_string "yes") (const_string "no"))))
185
186 (define_attr "fmovd" "yes,no"
187   (const (if_then_else (symbol_ref "TARGET_FMOVD")
188                        (const_string "yes") (const_string "no"))))
189 ;; pipeline model
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
191   (const
192    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194          (const_string "sh1"))))
195
196 ;; cbranch      conditional branch instructions
197 ;; jump         unconditional jumps
198 ;; arith        ordinary arithmetic
199 ;; arith3       a compound insn that behaves similarly to a sequence of
200 ;;              three insns of type arith
201 ;; arith3b      like above, but might end with a redirected branch
202 ;; load         from memory
203 ;; load_si      Likewise, SImode variant for general register.
204 ;; fload        Likewise, but load to fp register.
205 ;; store        to memory
206 ;; move         general purpose register to register
207 ;; mt_group     other sh4 mt instructions
208 ;; fmove        register to register, floating point
209 ;; smpy         word precision integer multiply
210 ;; dmpy         longword or doublelongword precision integer multiply
211 ;; return       rts
212 ;; pload        load of pr reg, which can't be put into delay slot of rts
213 ;; prset        copy register to pr reg, ditto
214 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
215 ;; prget        copy pr to register, ditto
216 ;; pcload       pc relative load of constant value
217 ;; pcfload      Likewise, but load to fp register.
218 ;; pcload_si    Likewise, SImode variant for general register.
219 ;; rte          return from exception
220 ;; sfunc        special function call with known used registers
221 ;; call         function call
222 ;; fp           floating point
223 ;; fdiv         floating point divide (or square root)
224 ;; gp_fpul      move from general purpose register to fpul
225 ;; fpul_gp      move from fpul to general purpose register
226 ;; mac_gp       move from mac[lh] to general purpose register
227 ;; dfp_arith, dfp_cmp,dfp_conv
228 ;; ftrc_s       fix_truncsfsi2_i4
229 ;; dfdiv        double precision floating point divide (or square root)
230 ;; cwb          ic_invalidate_line_i
231 ;; movua        SH4a unaligned load
232 ;; fsrra        square root reciprocal approximate
233 ;; fsca         sine and cosine approximate
234 ;; tls_load     load TLS related address
235 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
236 ;; cbranch_media SHmedia conditional branch instructions
237 ;; cmp_media    SHmedia compare instructions
238 ;; dfdiv_media  SHmedia double precision divide and square root
239 ;; dfmul_media  SHmedia double precision multiply instruction
240 ;; dfparith_media SHmedia double precision floating point arithmetic
241 ;; dfpconv_media SHmedia double precision floating point conversions
242 ;; dmpy_media   SHmedia longword multiply
243 ;; fcmp_media   SHmedia floating point compare instructions
244 ;; fdiv_media   SHmedia single precision divide and square root
245 ;; fload_media  SHmedia floating point register load instructions
246 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
247 ;; fparith_media SHmedia single precision floating point arithmetic
248 ;; fpconv_media SHmedia single precision floating point conversions
249 ;; fstore_media SHmedia floating point register store instructions
250 ;; gettr_media  SHmedia gettr instruction
251 ;; invalidate_line_media SHmedia invalidate_line sequence
252 ;; jump_media   SHmedia unconditional branch instructions
253 ;; load_media   SHmedia general register load instructions
254 ;; pt_media     SHmedia pt instruction (expanded by assembler)
255 ;; ptabs_media  SHmedia ptabs instruction
256 ;; store_media  SHmedia general register store instructions
257 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
258 ;; mac_media    SHmedia mac-style fixed point operations
259 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
260 ;; atrans_media SHmedia approximate transcendental functions
261 ;; ustore_media SHmedia unaligned stores
262 ;; nil          no-op move, will be deleted.
263
264 (define_attr "type"
265  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
266   (const_string "other"))
267
268 ;; We define a new attribute namely "insn_class".We use
269 ;; this for the DFA based pipeline description.
270 ;;
271 ;; mt_group      SH4 "mt" group instructions.
272 ;;
273 ;; ex_group      SH4 "ex" group instructions.
274 ;;
275 ;; ls_group      SH4 "ls" group instructions.
276 ;;
277
278 (define_attr "insn_class"
279   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
280   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
281          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
282          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
283          (eq_attr "type" "cbranch,jump") (const_string "br_group")
284          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
285            (const_string "fe_group")
286          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
287         (const_string "none")))
288 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
289 ;; so these do not belong in an insn group, although they are modeled
290 ;; with their own define_insn_reservations.
291
292 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293
294 (define_attr "fp_mode" "single,double,none" (const_string "none"))
295
296 ;; Indicate if the fpu mode is set by this instruction
297 ;; "unknown" must have the value as "none" in fp_mode, and means
298 ;; that the instruction/abi has left the processor in an unknown
299 ;; state.
300 ;; "none" means that nothing has changed and no mode is set.
301 ;; This attribute is only used for the Renesas ABI.
302 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
303
304 ; If a conditional branch destination is within -252..258 bytes away
305 ; from the instruction it can be 2 bytes long.  Something in the
306 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
307 ; branches are initially assumed to be 16 bytes long.
308 ; In machine_dependent_reorg, we split all branches that are longer than
309 ; 2 bytes.
310
311 ;; The maximum range used for SImode constant pool entries is 1018.  A final
312 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
313 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
314 ;; instruction around the pool table, 2 bytes of alignment before the table,
315 ;; and 30 bytes of alignment after the table.  That gives a maximum total
316 ;; pool size of 1058 bytes.
317 ;; Worst case code/pool content size ratio is 1:2 (using asms).
318 ;; Thus, in the worst case, there is one instruction in front of a maximum
319 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
320 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
321 ;; If we have a forward branch, the initial table will be put after the
322 ;; unconditional branch.
323 ;;
324 ;; ??? We could do much better by keeping track of the actual pcloads within
325 ;; the branch range and in the pcload range in front of the branch range.
326
327 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
328 ;; inside an le.
329 (define_attr "short_cbranch_p" "no,yes"
330   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
331          (const_string "no")
332          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
333          (const_string "yes")
334          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
337          (const_string "yes")
338          ] (const_string "no")))
339
340 (define_attr "med_branch_p" "no,yes"
341   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
342               (const_int 1988))
343          (const_string "yes")
344          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
345          (const_string "no")
346          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
347               (const_int 8186))
348          (const_string "yes")
349          ] (const_string "no")))
350
351 (define_attr "med_cbranch_p" "no,yes"
352   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
353               (const_int 1986))
354          (const_string "yes")
355          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356          (const_string "no")
357          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
358                (const_int 8184))
359          (const_string "yes")
360          ] (const_string "no")))
361
362 (define_attr "braf_branch_p" "no,yes"
363   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
366               (const_int 20660))
367          (const_string "yes")
368          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369          (const_string "no")
370          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
371               (const_int 65530))
372          (const_string "yes")
373          ] (const_string "no")))
374
375 (define_attr "braf_cbranch_p" "no,yes"
376   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
377          (const_string "no")
378          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
379               (const_int 20658))
380          (const_string "yes")
381          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
382          (const_string "no")
383          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
384               (const_int 65528))
385          (const_string "yes")
386          ] (const_string "no")))
387
388 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
389 ; For wider ranges, we need a combination of a code and a data part.
390 ; If we can get a scratch register for a long range jump, the code
391 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
392 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
393 ; long; otherwise, it must be 6 bytes long.
394
395 ; All other instructions are two bytes long by default.
396
397 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
398 ;; but getattrtab doesn't understand this.
399 (define_attr "length" ""
400   (cond [(eq_attr "type" "cbranch")
401          (cond [(eq_attr "short_cbranch_p" "yes")
402                 (const_int 2)
403                 (eq_attr "med_cbranch_p" "yes")
404                 (const_int 6)
405                 (eq_attr "braf_cbranch_p" "yes")
406                 (const_int 12)
407 ;; ??? using pc is not computed transitively.
408                 (ne (match_dup 0) (match_dup 0))
409                 (const_int 14)
410                 (ne (symbol_ref ("flag_pic")) (const_int 0))
411                 (const_int 24)
412                 ] (const_int 16))
413          (eq_attr "type" "jump")
414          (cond [(eq_attr "med_branch_p" "yes")
415                 (const_int 2)
416                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
417                          (symbol_ref "INSN"))
418                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
419                          (symbol_ref "code_for_indirect_jump_scratch")))
420                 (cond [(eq_attr "braf_branch_p" "yes")
421                        (const_int 6)
422                        (eq (symbol_ref "flag_pic") (const_int 0))
423                        (const_int 10)
424                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
425                        (const_int 10)] (const_int 18))
426                 (eq_attr "braf_branch_p" "yes")
427                 (const_int 10)
428 ;; ??? using pc is not computed transitively.
429                 (ne (match_dup 0) (match_dup 0))
430                 (const_int 12)
431                 (ne (symbol_ref ("flag_pic")) (const_int 0))
432                 (const_int 22)
433                 ] (const_int 14))
434          (eq_attr "type" "pt_media")
435          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
436                        (const_int 20) (const_int 12))
437          (and (eq_attr "type" "jump_media")
438               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
439          (const_int 8)
440          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
441                          (const_int 4)
442                          (const_int 2))))
443
444 ;; DFA descriptions for the pipelines
445
446 (include "sh1.md")
447 (include "shmedia.md")
448 (include "sh4.md")
449
450 (include "predicates.md")
451
452 ;; Definitions for filling delay slots
453
454 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
455
456 ;; ??? This should be (nil) instead of (const_int 0)
457 (define_attr "hit_stack" "yes,no"
458         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
459                    (const_int 0))
460                (const_string "no")]
461               (const_string "yes")))
462
463 (define_attr "interrupt_function" "no,yes"
464   (const (symbol_ref "current_function_interrupt")))
465
466 (define_attr "in_delay_slot" "yes,no"
467   (cond [(eq_attr "type" "cbranch") (const_string "no")
468          (eq_attr "type" "pcload,pcload_si") (const_string "no")
469          (eq_attr "needs_delay_slot" "yes") (const_string "no")
470          (eq_attr "length" "2") (const_string "yes")
471          ] (const_string "no")))
472
473 (define_attr "cond_delay_slot" "yes,no"
474   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
475          ] (const_string "no")))
476
477 (define_attr "is_sfunc" ""
478   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
479
480 (define_attr "is_mac_media" ""
481   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
482
483 (define_attr "branch_zero" "yes,no"
484   (cond [(eq_attr "type" "!cbranch") (const_string "no")
485          (ne (symbol_ref "(next_active_insn (insn)\
486                            == (prev_active_insn\
487                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
488                           && get_attr_length (next_active_insn (insn)) == 2")
489              (const_int 0))
490          (const_string "yes")]
491         (const_string "no")))
492
493 ;; SH4 Double-precision computation with double-precision result -
494 ;; the two halves are ready at different times.
495 (define_attr "dfp_comp" "yes,no"
496   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
497         (const_string "no")))
498
499 ;; Insns for which the latency of a preceding fp insn is decreased by one.
500 (define_attr "late_fp_use" "yes,no" (const_string "no"))
501 ;; And feeding insns for which this relevant.
502 (define_attr "any_fp_comp" "yes,no"
503   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
504          (const_string "yes")]
505         (const_string "no")))
506
507 (define_attr "any_int_load" "yes,no"
508   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
509          (const_string "yes")]
510         (const_string "no")))
511
512 (define_attr "highpart" "user, ignore, extend, depend, must_split"
513   (const_string "user"))
514
515 (define_delay
516   (eq_attr "needs_delay_slot" "yes")
517   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
518
519 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
520 ;; and thus we can't put a pop instruction in its delay slot.
521 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
522 ;; instruction can go in the delay slot.
523
524 ;; Since a normal return (rts) implicitly uses the PR register,
525 ;; we can't allow PR register loads in an rts delay slot.
526
527 (define_delay
528   (eq_attr "type" "return")
529   [(and (eq_attr "in_delay_slot" "yes")
530         (ior (and (eq_attr "interrupt_function" "no")
531                   (eq_attr "type" "!pload,prset"))
532              (and (eq_attr "interrupt_function" "yes")
533                   (ior
534                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
535                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
536
537 ;; Since a call implicitly uses the PR register, we can't allow
538 ;; a PR register store in a jsr delay slot.
539
540 (define_delay
541   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
542   [(and (eq_attr "in_delay_slot" "yes")
543         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
544
545 ;; Say that we have annulled true branches, since this gives smaller and
546 ;; faster code when branches are predicted as not taken.
547
548 ;; ??? The non-annulled condition should really be "in_delay_slot",
549 ;; but insns that can be filled in non-annulled get priority over insns
550 ;; that can only be filled in anulled.
551
552 (define_delay
553   (and (eq_attr "type" "cbranch")
554        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
555   ;; SH2e has a hardware bug that pretty much prohibits the use of
556   ;; annuled delay slots.
557   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
558                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
559 \f
560 ;; -------------------------------------------------------------------------
561 ;; SImode signed integer comparisons
562 ;; -------------------------------------------------------------------------
563
564 (define_insn ""
565   [(set (reg:SI T_REG)
566         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
567                        (match_operand:SI 1 "arith_operand" "K08,r"))
568                (const_int 0)))]
569   "TARGET_SH1"
570   "tst  %1,%0"
571   [(set_attr "type" "mt_group")])
572
573 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
574 ;; That would still allow reload to create cmpi instructions, but would
575 ;; perhaps allow forcing the constant into a register when that is better.
576 ;; Probably should use r0 for mem/imm compares, but force constant into a
577 ;; register for pseudo/imm compares.
578
579 (define_insn "cmpeqsi_t"
580   [(set (reg:SI T_REG)
581         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
582                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
583   "TARGET_SH1"
584   "@
585         tst     %0,%0
586         cmp/eq  %1,%0
587         cmp/eq  %1,%0"
588    [(set_attr "type" "mt_group")])
589
590 (define_insn "cmpgtsi_t"
591   [(set (reg:SI T_REG)
592         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
593                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
594   "TARGET_SH1"
595   "@
596         cmp/gt  %1,%0
597         cmp/pl  %0"
598    [(set_attr "type" "mt_group")])
599
600 (define_insn "cmpgesi_t"
601   [(set (reg:SI T_REG)
602         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
603                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
604   "TARGET_SH1"
605   "@
606         cmp/ge  %1,%0
607         cmp/pz  %0"
608    [(set_attr "type" "mt_group")])
609
610 ;; -------------------------------------------------------------------------
611 ;; SImode unsigned integer comparisons
612 ;; -------------------------------------------------------------------------
613
614 (define_insn "cmpgeusi_t"
615   [(set (reg:SI T_REG)
616         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
617                 (match_operand:SI 1 "arith_reg_operand" "r")))]
618   "TARGET_SH1"
619   "cmp/hs       %1,%0"
620    [(set_attr "type" "mt_group")])
621
622 (define_insn "cmpgtusi_t"
623   [(set (reg:SI T_REG)
624         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
625                 (match_operand:SI 1 "arith_reg_operand" "r")))]
626   "TARGET_SH1"
627   "cmp/hi       %1,%0"
628    [(set_attr "type" "mt_group")])
629
630 ;; We save the compare operands in the cmpxx patterns and use them when
631 ;; we generate the branch.
632
633 (define_expand "cmpsi"
634   [(set (reg:SI T_REG)
635         (compare (match_operand:SI 0 "cmpsi_operand" "")
636                  (match_operand:SI 1 "arith_operand" "")))]
637   "TARGET_SH1 || TARGET_SHMEDIA"
638   "
639 {
640   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
641       && GET_CODE (operands[1]) != CONST_INT)
642     operands[0] = copy_to_mode_reg (SImode, operands[0]);
643   sh_compare_op0 = operands[0];
644   sh_compare_op1 = operands[1];
645   DONE;
646 }")
647 \f
648 ;; -------------------------------------------------------------------------
649 ;; DImode signed integer comparisons
650 ;; -------------------------------------------------------------------------
651
652 ;; ??? Could get better scheduling by splitting the initial test from the
653 ;; rest of the insn after reload.  However, the gain would hardly justify
654 ;; the sh.md size increase necessary to do that.
655
656 (define_insn ""
657   [(set (reg:SI T_REG)
658         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
659                        (match_operand:DI 1 "arith_operand" "r"))
660                (const_int 0)))]
661   "TARGET_SH1"
662   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
663                                  insn, operands);"
664   [(set_attr "length" "6")
665    (set_attr "type" "arith3b")])
666
667 (define_insn "cmpeqdi_t"
668   [(set (reg:SI T_REG)
669         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
670                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
671   "TARGET_SH1"
672   "@
673         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
674         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
675   [(set_attr "length" "6")
676    (set_attr "type" "arith3b")])
677
678 (define_split
679   [(set (reg:SI T_REG)
680         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
681                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
682 ;; If we applied this split when not optimizing, it would only be
683 ;; applied during the machine-dependent reorg, when no new basic blocks
684 ;; may be created.
685   "TARGET_SH1 && reload_completed && optimize"
686   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
687    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
688                            (label_ref (match_dup 6))
689                            (pc)))
690    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
691    (match_dup 6)]
692   "
693 {
694   operands[2]
695     = gen_rtx_REG (SImode,
696                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
697   operands[3]
698     = (operands[1] == const0_rtx
699        ? const0_rtx
700        : gen_rtx_REG (SImode,
701                       true_regnum (operands[1])
702                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
703   operands[4] = gen_lowpart (SImode, operands[0]);
704   operands[5] = gen_lowpart (SImode, operands[1]);
705   operands[6] = gen_label_rtx ();
706 }")
707
708 (define_insn "cmpgtdi_t"
709   [(set (reg:SI T_REG)
710         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
711                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
712   "TARGET_SH2"
713   "@
714         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
715         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
716   [(set_attr "length" "8")
717    (set_attr "type" "arith3")])
718
719 (define_insn "cmpgedi_t"
720   [(set (reg:SI T_REG)
721         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
722                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
723   "TARGET_SH2"
724   "@
725         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
726         cmp/pz\\t%S0"
727   [(set_attr "length" "8,2")
728    (set_attr "type" "arith3,mt_group")])
729 \f
730 ;; -------------------------------------------------------------------------
731 ;; DImode unsigned integer comparisons
732 ;; -------------------------------------------------------------------------
733
734 (define_insn "cmpgeudi_t"
735   [(set (reg:SI T_REG)
736         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
737                 (match_operand:DI 1 "arith_reg_operand" "r")))]
738   "TARGET_SH2"
739   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
740   [(set_attr "length" "8")
741    (set_attr "type" "arith3")])
742
743 (define_insn "cmpgtudi_t"
744   [(set (reg:SI T_REG)
745         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
746                 (match_operand:DI 1 "arith_reg_operand" "r")))]
747   "TARGET_SH2"
748   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
749   [(set_attr "length" "8")
750    (set_attr "type" "arith3")])
751
752 (define_insn "cmpeqsi_media"
753   [(set (match_operand:DI 0 "register_operand" "=r")
754         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
755                (match_operand:SI 2 "cmp_operand" "Nr")))]
756   "TARGET_SHMEDIA"
757   "cmpeq        %1, %N2, %0"
758   [(set_attr "type" "cmp_media")])
759
760 (define_insn "cmpeqdi_media"
761   [(set (match_operand:DI 0 "register_operand" "=r")
762         (eq:DI (match_operand:DI 1 "register_operand" "%r")
763                (match_operand:DI 2 "cmp_operand" "Nr")))]
764   "TARGET_SHMEDIA"
765   "cmpeq        %1, %N2, %0"
766   [(set_attr "type" "cmp_media")])
767
768 (define_insn "cmpgtsi_media"
769   [(set (match_operand:DI 0 "register_operand" "=r")
770         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
771                (match_operand:SI 2 "cmp_operand" "rN")))]
772   "TARGET_SHMEDIA"
773   "cmpgt        %N1, %N2, %0"
774   [(set_attr "type" "cmp_media")])
775
776 (define_insn "cmpgtdi_media"
777   [(set (match_operand:DI 0 "register_operand" "=r")
778         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
779                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
780   "TARGET_SHMEDIA"
781   "cmpgt        %N1, %N2, %0"
782   [(set_attr "type" "cmp_media")])
783
784 (define_insn "cmpgtusi_media"
785   [(set (match_operand:DI 0 "register_operand" "=r")
786         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
787                 (match_operand:SI 2 "cmp_operand" "rN")))]
788   "TARGET_SHMEDIA"
789   "cmpgtu       %N1, %N2, %0"
790   [(set_attr "type" "cmp_media")])
791
792 (define_insn "cmpgtudi_media"
793   [(set (match_operand:DI 0 "register_operand" "=r")
794         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
795                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
796   "TARGET_SHMEDIA"
797   "cmpgtu       %N1, %N2, %0"
798   [(set_attr "type" "cmp_media")])
799
800 (define_insn "cmpsieqsi_media"
801   [(set (match_operand:SI 0 "register_operand" "=r")
802         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
803                (match_operand:SI 2 "cmp_operand" "Nr")))]
804   "TARGET_SHMEDIA"
805   "cmpeq        %1, %N2, %0"
806   [(set_attr "type" "cmp_media")])
807
808 (define_insn "cmpsieqdi_media"
809   [(set (match_operand:SI 0 "register_operand" "=r")
810         (eq:SI (match_operand:DI 1 "register_operand" "%r")
811                (match_operand:DI 2 "cmp_operand" "Nr")))]
812   "TARGET_SHMEDIA"
813   "cmpeq        %1, %N2, %0"
814   [(set_attr "type" "cmp_media")])
815
816 (define_insn "cmpsigtsi_media"
817   [(set (match_operand:SI 0 "register_operand" "=r")
818         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
819                (match_operand:SI 2 "cmp_operand" "rN")))]
820   "TARGET_SHMEDIA"
821   "cmpgt        %N1, %N2, %0"
822   [(set_attr "type" "cmp_media")])
823
824 (define_insn "cmpsigtdi_media"
825   [(set (match_operand:SI 0 "register_operand" "=r")
826         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
827                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
828   "TARGET_SHMEDIA"
829   "cmpgt        %N1, %N2, %0"
830   [(set_attr "type" "cmp_media")])
831
832 (define_insn "cmpsigtusi_media"
833   [(set (match_operand:SI 0 "register_operand" "=r")
834         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
835                 (match_operand:SI 2 "cmp_operand" "rN")))]
836   "TARGET_SHMEDIA"
837   "cmpgtu       %N1, %N2, %0"
838   [(set_attr "type" "cmp_media")])
839
840 (define_insn "cmpsigtudi_media"
841   [(set (match_operand:SI 0 "register_operand" "=r")
842         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
843                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
844   "TARGET_SHMEDIA"
845   "cmpgtu       %N1, %N2, %0"
846   [(set_attr "type" "cmp_media")])
847
848 ; These two patterns are for combine.
849 (define_insn "*cmpne0si_media"
850   [(set (match_operand:DI 0 "register_operand" "=r")
851         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
852   "TARGET_SHMEDIA"
853   "cmpgtu       %1,r63,%0"
854   [(set_attr "type" "cmp_media")])
855
856 (define_insn "*cmpne0sisi_media"
857   [(set (match_operand:SI 0 "register_operand" "=r")
858         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
859   "TARGET_SHMEDIA"
860   "cmpgtu       %1,r63,%0"
861   [(set_attr "type" "cmp_media")])
862
863 ;; We save the compare operands in the cmpxx patterns and use them when
864 ;; we generate the branch.
865
866 (define_expand "cmpdi"
867   [(set (reg:SI T_REG)
868         (compare (match_operand:DI 0 "arith_operand" "")
869                  (match_operand:DI 1 "arith_operand" "")))]
870   "TARGET_SH2 || TARGET_SHMEDIA"
871   "
872 {
873   sh_compare_op0 = operands[0];
874   sh_compare_op1 = operands[1];
875   DONE;
876 }")
877 ;; -------------------------------------------------------------------------
878 ;; Conditional move instructions
879 ;; -------------------------------------------------------------------------
880
881 ;; The insn names may seem reversed, but note that cmveq performs the move
882 ;; if op1 == 0, and cmvne does it if op1 != 0.
883
884 (define_insn "movdicc_false"
885   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
886         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
887                              (const_int 0))
888          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
889          (match_operand:DI 3 "arith_reg_operand" "0")))]
890   "TARGET_SHMEDIA"
891   "cmveq        %1, %N2, %0"
892   [(set_attr "type" "arith_media")])
893
894 (define_insn "movdicc_true"
895   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
896         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
897                              (const_int 0))
898          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
899          (match_operand:DI 3 "arith_reg_operand" "0")))]
900   "TARGET_SHMEDIA"
901   "cmvne        %1, %N2, %0"
902   [(set_attr "type" "arith_media")])
903
904 (define_peephole2
905   [(set (match_operand:DI 0 "arith_reg_dest" "")
906         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
907                            [(match_operand:DI 1 "arith_reg_operand" "")
908                             (const_int 0)])
909          (match_operand:DI 2 "arith_reg_dest" "")
910          (match_dup 0)))
911    (set (match_dup 2) (match_dup 0))]
912   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
913   [(set (match_dup 2)
914         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
915   "
916 {
917   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
918                                 VOIDmode, operands[1], CONST0_RTX (DImode));
919 }")
920
921 (define_peephole2
922   [(set (match_operand:DI 0 "general_movdst_operand" "")
923         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
924    (set (match_operand:DI 2 "arith_reg_dest" "")
925         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
926                            [(match_operand:DI 3 "arith_reg_operand" "")
927                             (const_int 0)])
928          (match_dup 0)
929          (match_dup 2)))]
930   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
931   [(set (match_dup 2)
932         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
933   "")
934
935 (define_expand "movdicc"
936   [(set (match_operand:DI 0 "register_operand" "")
937         (if_then_else:DI (match_operand 1 "comparison_operator" "")
938                          (match_operand:DI 2 "register_operand" "")
939                          (match_operand:DI 3 "register_operand" "")))]
940   "TARGET_SHMEDIA"
941   "
942 {
943   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
944       && GET_MODE (sh_compare_op0) == DImode
945       && sh_compare_op1 == const0_rtx)
946     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
947                                   sh_compare_op0, sh_compare_op1);
948   else
949     {
950       rtx tmp;
951
952       if (no_new_pseudos)
953         FAIL;
954
955       tmp = gen_reg_rtx (DImode);
956
957       switch (GET_CODE (operands[1]))
958         {
959         case EQ:
960           emit_insn (gen_seq (tmp));
961           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
962           break;
963
964         case NE:
965           emit_insn (gen_seq (tmp));
966           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
967           break;
968
969         case GT:
970           emit_insn (gen_sgt (tmp));
971           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
972           break;
973
974         case LT:
975           emit_insn (gen_slt (tmp));
976           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
977           break;
978
979         case GE:
980           emit_insn (gen_slt (tmp));
981           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
982           break;
983
984         case LE:
985           emit_insn (gen_sgt (tmp));
986           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
987           break;
988
989         case GTU:
990           emit_insn (gen_sgtu (tmp));
991           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
992           break;
993
994         case LTU:
995           emit_insn (gen_sltu (tmp));
996           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997           break;
998
999         case GEU:
1000           emit_insn (gen_sltu (tmp));
1001           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002           break;
1003
1004         case LEU:
1005           emit_insn (gen_sgtu (tmp));
1006           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1007           break;
1008
1009         case UNORDERED:
1010           emit_insn (gen_sunordered (tmp));
1011           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012           break;
1013
1014         case ORDERED:
1015           emit_insn (gen_sunordered (tmp));
1016           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1017           break;
1018
1019         case UNEQ:
1020         case UNGE:
1021         case UNGT:
1022         case UNLE:
1023         case UNLT:
1024         case LTGT:
1025           FAIL;
1026
1027         default:
1028           gcc_unreachable ();
1029         }
1030     }
1031 }")
1032
1033 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1034 ;; SImode to DImode.
1035 (define_insn "movsicc_false"
1036   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1037         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1038                           (const_int 0))
1039          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1040          (match_operand:SI 3 "arith_reg_operand" "0")))]
1041   "TARGET_SHMEDIA"
1042   "cmveq        %1, %N2, %0"
1043   [(set_attr "type" "arith_media")])
1044
1045 (define_insn "movsicc_true"
1046   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1047         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1048                           (const_int 0))
1049          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1050          (match_operand:SI 3 "arith_reg_operand" "0")))]
1051   "TARGET_SHMEDIA"
1052   "cmvne        %1, %N2, %0"
1053   [(set_attr "type" "arith_media")])
1054
1055 (define_peephole2
1056   [(set (match_operand:SI 0 "arith_reg_dest" "")
1057         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1058                            [(match_operand:SI 1 "arith_reg_operand" "")
1059                             (const_int 0)])
1060          (match_operand:SI 2 "arith_reg_dest" "")
1061          (match_dup 0)))
1062    (set (match_dup 2) (match_dup 0))]
1063   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1064   [(set (match_dup 2)
1065         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1066   "
1067 {
1068   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1069                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1070 }")
1071
1072 (define_peephole2
1073   [(set (match_operand:SI 0 "general_movdst_operand" "")
1074         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1075    (set (match_operand:SI 2 "arith_reg_dest" "")
1076         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1077                            [(match_operand:SI 3 "arith_reg_operand" "")
1078                             (const_int 0)])
1079          (match_dup 0)
1080          (match_dup 2)))]
1081   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1082    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1083   [(set (match_dup 2)
1084         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1085   "
1086 {
1087   replace_rtx (operands[4], operands[0], operands[1]);
1088 }")
1089
1090 (define_peephole2
1091   [(set (match_operand 0 "any_register_operand" "")
1092         (match_operand 1 "any_register_operand" ""))
1093    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1094    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1095   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1096     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1097    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1098    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1099    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1100    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1101    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1102    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1103    && (REGNO_REG_CLASS (REGNO (operands[0]))
1104        == REGNO_REG_CLASS (REGNO (operands[2])))
1105    && (REGNO_REG_CLASS (REGNO (operands[1]))
1106        == REGNO_REG_CLASS (REGNO (operands[0])))"
1107   [(set (match_dup 0) (match_dup 3))
1108    (set (match_dup 4) (match_dup 5))]
1109   "
1110 {
1111   rtx set1, set2;
1112   rtx replacements[4];
1113
1114   /* We want to replace occurrences of operands[0] with operands[1] and
1115      operands[2] with operands[0] in operands[4]/operands[5].
1116      Doing just two replace_rtx calls naively would result in the second
1117      replacement undoing all that the first did if operands[1] and operands[2]
1118      are identical, so we must do this simultaneously.  */
1119   replacements[0] = operands[0];
1120   replacements[1] = operands[1];
1121   replacements[2] = operands[2];
1122   replacements[3] = operands[0];
1123   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1124       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1125       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1126     FAIL;
1127
1128   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1129   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1130   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1131   /* The operands array is aliased to recog_data.operand, which gets
1132      clobbered by extract_insn, so finish with it now.  */
1133   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1134   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1135   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1136      always uses emit_insn.  */
1137   /* Check that we don't violate matching constraints or earlyclobbers.  */
1138   extract_insn (emit_insn (set1));
1139   if (! constrain_operands (1))
1140     goto failure;
1141   extract_insn (emit (set2));
1142   if (! constrain_operands (1))
1143     {
1144       rtx tmp;
1145     failure:
1146       tmp = replacements[0];
1147       replacements[0] = replacements[1];
1148       replacements[1] = tmp;
1149       tmp = replacements[2];
1150       replacements[2] = replacements[3];
1151       replacements[3] = tmp;
1152       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1153       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1154       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1155       FAIL;
1156     }
1157   DONE;
1158 }")
1159
1160 ;; The register allocator is rather clumsy in handling multi-way conditional
1161 ;; moves, so allow the combiner to make them, and we split them up after
1162 ;; reload.  */
1163 (define_insn_and_split "*movsicc_umin"
1164   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1165         (umin:SI (if_then_else:SI
1166                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1167                        (const_int 0))
1168                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1169                    (match_operand:SI 3 "register_operand" "0"))
1170                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1171    (clobber (match_scratch:SI 5 "=&r"))]
1172   "TARGET_SHMEDIA && no_new_pseudos"
1173   "#"
1174   "TARGET_SHMEDIA && reload_completed"
1175   [(pc)]
1176   "
1177 {
1178   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1179                                 operands[3]));
1180   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1181   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1182                                 operands[0]));
1183   DONE;
1184 }")
1185
1186 (define_insn "*movsicc_t_false"
1187   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1188         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1189                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1190                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1191   "TARGET_PRETEND_CMOVE
1192    && (arith_reg_operand (operands[1], SImode)
1193        || (immediate_operand (operands[1], SImode)
1194            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1195   "bt 0f\;mov %1,%0\\n0:"
1196   [(set_attr "type" "mt_group,arith") ;; poor approximation
1197    (set_attr "length" "4")])
1198
1199 (define_insn "*movsicc_t_true"
1200   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1201         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1202                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1203                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1204   "TARGET_PRETEND_CMOVE
1205    && (arith_reg_operand (operands[1], SImode)
1206        || (immediate_operand (operands[1], SImode)
1207            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1208   "bf 0f\;mov %1,%0\\n0:"
1209   [(set_attr "type" "mt_group,arith") ;; poor approximation
1210    (set_attr "length" "4")])
1211
1212 (define_expand "movsicc"
1213   [(set (match_operand:SI 0 "arith_reg_dest" "")
1214         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1215                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1216                          (match_operand:SI 3 "arith_reg_operand" "")))]
1217   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1218   "
1219 {
1220   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1221       && GET_MODE (sh_compare_op0) == SImode
1222       && (TARGET_SHMEDIA
1223           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1224       && sh_compare_op1 == const0_rtx)
1225     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1226                                   sh_compare_op0, sh_compare_op1);
1227   else if (TARGET_PRETEND_CMOVE)
1228     {
1229       enum rtx_code code = GET_CODE (operands[1]);
1230       enum rtx_code new_code = code;
1231       rtx tmp;
1232
1233       if (! currently_expanding_to_rtl)
1234         FAIL;
1235       switch (code)
1236         {
1237         case LT: case LE: case LEU: case LTU:
1238           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1239             break;
1240         case NE:
1241           new_code = reverse_condition (code);
1242           break;
1243         case EQ: case GT: case GE: case GEU: case GTU:
1244           break;
1245         default:
1246           FAIL;
1247         }
1248       tmp = prepare_scc_operands (new_code);
1249       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1250                                     tmp, const0_rtx);
1251     }
1252   else
1253     {
1254       rtx tmp;
1255
1256       if (no_new_pseudos)
1257         FAIL;
1258
1259       tmp = gen_reg_rtx (SImode);
1260
1261       switch (GET_CODE (operands[1]))
1262         {
1263         case EQ:
1264           emit_insn (gen_seq (tmp));
1265           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1266           break;
1267
1268         case NE:
1269           emit_insn (gen_seq (tmp));
1270           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1271           break;
1272
1273         case GT:
1274           emit_insn (gen_sgt (tmp));
1275           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1276           break;
1277
1278         case LT:
1279           emit_insn (gen_slt (tmp));
1280           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1281           break;
1282
1283         case GE:
1284           emit_insn (gen_slt (tmp));
1285           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1286           break;
1287
1288         case LE:
1289           emit_insn (gen_sgt (tmp));
1290           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1291           break;
1292
1293         case GTU:
1294           emit_insn (gen_sgtu (tmp));
1295           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1296           break;
1297
1298         case LTU:
1299           emit_insn (gen_sltu (tmp));
1300           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1301           break;
1302
1303         case GEU:
1304           emit_insn (gen_sltu (tmp));
1305           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1306           break;
1307
1308         case LEU:
1309           emit_insn (gen_sgtu (tmp));
1310           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1311           break;
1312
1313         case UNORDERED:
1314           emit_insn (gen_sunordered (tmp));
1315           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1316           break;
1317
1318         case ORDERED:
1319           emit_insn (gen_sunordered (tmp));
1320           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1321           break;
1322
1323         case UNEQ:
1324         case UNGE:
1325         case UNGT:
1326         case UNLE:
1327         case UNLT:
1328         case LTGT:
1329           FAIL;
1330
1331         default:
1332           abort ();
1333         }
1334     }
1335 }")
1336
1337 (define_expand "movqicc"
1338   [(set (match_operand:QI 0 "register_operand" "")
1339         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1340                          (match_operand:QI 2 "register_operand" "")
1341                          (match_operand:QI 3 "register_operand" "")))]
1342   "TARGET_SHMEDIA"
1343   "
1344 {
1345   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1346   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1347   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1348   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1349   DONE;
1350 }")
1351 \f
1352 ;; -------------------------------------------------------------------------
1353 ;; Addition instructions
1354 ;; -------------------------------------------------------------------------
1355
1356 (define_expand "adddi3"
1357   [(set (match_operand:DI 0 "arith_reg_operand" "")
1358         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1359                  (match_operand:DI 2 "arith_operand" "")))]
1360   ""
1361   "
1362 {
1363   if (TARGET_SH1)
1364     {
1365       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1366         FAIL;
1367       operands[2] = force_reg (DImode, operands[2]);
1368       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1369       DONE;
1370     }
1371 }")
1372
1373 (define_insn "*adddi3_media"
1374   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1375         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1376                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1377   "TARGET_SHMEDIA"
1378   "@
1379         add     %1, %2, %0
1380         addi    %1, %2, %0"
1381   [(set_attr "type" "arith_media")])
1382
1383 (define_insn "*adddisi3_media"
1384   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1385         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1386                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1387   "TARGET_SHMEDIA"
1388   "@
1389         add.l   %1, %2, %0
1390         addi.l  %1, %2, %0"
1391   [(set_attr "type" "arith_media")
1392    (set_attr "highpart" "ignore")])
1393
1394 (define_insn "adddi3z_media"
1395   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1396         (zero_extend:DI
1397          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1398                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1399   "TARGET_SHMEDIA"
1400   "addz.l       %1, %N2, %0"
1401   [(set_attr "type" "arith_media")
1402    (set_attr "highpart" "ignore")])
1403
1404 (define_insn "adddi3_compact"
1405   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1406         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1407                  (match_operand:DI 2 "arith_reg_operand" "r")))
1408    (clobber (reg:SI T_REG))]
1409   "TARGET_SH1"
1410   "#"
1411   [(set_attr "length" "6")])
1412
1413 (define_split
1414   [(set (match_operand:DI 0 "arith_reg_dest" "")
1415         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1416                  (match_operand:DI 2 "arith_reg_operand" "")))
1417    (clobber (reg:SI T_REG))]
1418   "TARGET_SH1 && reload_completed"
1419   [(const_int 0)]
1420   "
1421 {
1422   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1423   high0 = gen_rtx_REG (SImode,
1424                        true_regnum (operands[0])
1425                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1426   high2 = gen_rtx_REG (SImode,
1427                        true_regnum (operands[2])
1428                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1429   emit_insn (gen_clrt ());
1430   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1431   emit_insn (gen_addc1 (high0, high0, high2));
1432   DONE;
1433 }")
1434
1435 (define_insn "addc"
1436   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1438                           (match_operand:SI 2 "arith_reg_operand" "r"))
1439                  (reg:SI T_REG)))
1440    (set (reg:SI T_REG)
1441         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1442   "TARGET_SH1"
1443   "addc %2,%0"
1444   [(set_attr "type" "arith")])
1445
1446 (define_insn "addc1"
1447   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1448         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1449                           (match_operand:SI 2 "arith_reg_operand" "r"))
1450                  (reg:SI T_REG)))
1451    (clobber (reg:SI T_REG))]
1452   "TARGET_SH1"
1453   "addc %2,%0"
1454   [(set_attr "type" "arith")])
1455
1456 (define_expand "addsi3"
1457   [(set (match_operand:SI 0 "arith_reg_operand" "")
1458         (plus:SI (match_operand:SI 1 "arith_operand" "")
1459                  (match_operand:SI 2 "arith_operand" "")))]
1460   ""
1461   "
1462 {
1463   if (TARGET_SHMEDIA)
1464     operands[1] = force_reg (SImode, operands[1]);
1465 }")
1466
1467 (define_insn "addsi3_media"
1468   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1469         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1470                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1471   "TARGET_SHMEDIA"
1472   "@
1473         add.l   %1, %2, %0
1474         addi.l  %1, %2, %0"
1475   [(set_attr "type" "arith_media")
1476    (set_attr "highpart" "ignore")])
1477
1478 (define_insn "addsidi3_media"
1479   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1480         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1481                                   "%r,r")
1482                                  (match_operand:SI 2 "arith_operand"
1483                                   "r,I10"))))]
1484   "TARGET_SHMEDIA"
1485   "@
1486         add.l   %1, %2, %0
1487         addi.l  %1, %2, %0"
1488   [(set_attr "type" "arith_media")
1489    (set_attr "highpart" "ignore")])
1490
1491 (define_insn "*addsi3_compact"
1492   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1494                  (match_operand:SI 2 "arith_operand" "rI08")))]
1495   "TARGET_SH1"
1496   "add  %2,%0"
1497   [(set_attr "type" "arith")])
1498
1499 ;; -------------------------------------------------------------------------
1500 ;; Subtraction instructions
1501 ;; -------------------------------------------------------------------------
1502
1503 (define_expand "subdi3"
1504   [(set (match_operand:DI 0 "arith_reg_operand" "")
1505         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1506                   (match_operand:DI 2 "arith_reg_operand" "")))]
1507   ""
1508   "
1509 {
1510   if (TARGET_SH1)
1511     {
1512       operands[1] = force_reg (DImode, operands[1]);
1513       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1514       DONE;
1515     }
1516 }")
1517
1518 (define_insn "*subdi3_media"
1519   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1520         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1521                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1522   "TARGET_SHMEDIA"
1523   "sub  %N1, %2, %0"
1524   [(set_attr "type" "arith_media")])
1525   
1526 (define_insn "subdisi3_media"
1527   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1528         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1529                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1530   "TARGET_SHMEDIA"
1531   "sub.l        %N1, %2, %0"
1532   [(set_attr "type" "arith_media")
1533    (set_attr "highpart" "ignore")])
1534
1535 (define_insn "subdi3_compact"
1536   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1537         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1538                  (match_operand:DI 2 "arith_reg_operand" "r")))
1539    (clobber (reg:SI T_REG))]
1540   "TARGET_SH1"
1541   "#"
1542   [(set_attr "length" "6")])
1543
1544 (define_split
1545   [(set (match_operand:DI 0 "arith_reg_dest" "")
1546         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1547                   (match_operand:DI 2 "arith_reg_operand" "")))
1548    (clobber (reg:SI T_REG))]
1549   "TARGET_SH1 && reload_completed"
1550   [(const_int 0)]
1551   "
1552 {
1553   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1554   high0 = gen_rtx_REG (SImode,
1555                        true_regnum (operands[0])
1556                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1557   high2 = gen_rtx_REG (SImode,
1558                        true_regnum (operands[2])
1559                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1560   emit_insn (gen_clrt ());
1561   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1562   emit_insn (gen_subc1 (high0, high0, high2));
1563   DONE;
1564 }")
1565
1566 (define_insn "subc"
1567   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1568         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1569                             (match_operand:SI 2 "arith_reg_operand" "r"))
1570                   (reg:SI T_REG)))
1571    (set (reg:SI T_REG)
1572         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1573                           (reg:SI T_REG))
1574                 (match_dup 1)))]
1575   "TARGET_SH1"
1576   "subc %2,%0"
1577   [(set_attr "type" "arith")])
1578
1579 (define_insn "subc1"
1580   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1581         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1582                             (match_operand:SI 2 "arith_reg_operand" "r"))
1583                   (reg:SI T_REG)))
1584    (clobber (reg:SI T_REG))]
1585   "TARGET_SH1"
1586   "subc %2,%0"
1587   [(set_attr "type" "arith")])
1588
1589 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1590 ;; pattern for this case.  This helps multimedia applications that compute
1591 ;; the sum of absolute differences.
1592 (define_insn "mov_neg_si_t"
1593   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1594   "TARGET_SH1"
1595   "subc %0,%0"
1596   [(set_attr "type" "arith")])
1597
1598 (define_insn "*subsi3_internal"
1599   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1600         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1601                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1602   "TARGET_SH1"
1603   "sub  %2,%0"
1604   [(set_attr "type" "arith")])
1605
1606 (define_insn_and_split "*subsi3_media"
1607   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1608         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1609                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1610   "TARGET_SHMEDIA
1611    && (operands[1] != constm1_rtx
1612        || (GET_CODE (operands[2]) != TRUNCATE
1613            && GET_CODE (operands[2]) != SUBREG))"
1614   "sub.l        %N1, %2, %0"
1615   "operands[1] == constm1_rtx"
1616   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1617   ""
1618   [(set_attr "type" "arith_media")
1619    (set_attr "highpart" "ignore")])
1620
1621 (define_split
1622   [(set (match_operand:SI 0 "arith_reg_dest" "")
1623         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1624                                                        "general_extend_operand"
1625                                                        "") 0)) 0)))]
1626   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1627   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1628    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1629   "")
1630
1631 (define_split
1632   [(set (match_operand:SI 0 "arith_reg_dest" "")
1633         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1634                                                        "general_extend_operand"
1635                                                        "") 0)) 3)))]
1636   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1637   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1638    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1639   "")
1640 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1641 ;; will sometimes save one instruction.  Otherwise we might get
1642 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1643 ;; are the same.
1644
1645 (define_expand "subsi3"
1646   [(set (match_operand:SI 0 "arith_reg_operand" "")
1647         (minus:SI (match_operand:SI 1 "arith_operand" "")
1648                   (match_operand:SI 2 "arith_reg_operand" "")))]
1649   ""
1650   "
1651 {
1652   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1653     {
1654       emit_insn (gen_negsi2 (operands[0], operands[2]));
1655       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1656       DONE;
1657     }
1658   if (TARGET_SHMEDIA)
1659     {
1660       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1661         FAIL;
1662       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1663         operands[1] = force_reg (SImode, operands[1]);
1664     }
1665 }")
1666 \f
1667 ;; -------------------------------------------------------------------------
1668 ;; Division instructions
1669 ;; -------------------------------------------------------------------------
1670
1671 ;; We take advantage of the library routines which don't clobber as many
1672 ;; registers as a normal function call would.
1673
1674 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1675 ;; also has an effect on the register that holds the address of the sfunc.
1676 ;; To make this work, we have an extra dummy insn that shows the use
1677 ;; of this register for reorg.
1678
1679 (define_insn "use_sfunc_addr"
1680   [(set (reg:SI PR_REG)
1681         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1682   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1683   ""
1684   [(set_attr "length" "0")])
1685
1686 (define_insn "udivsi3_sh2a"
1687   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1688         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1689                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1690   "TARGET_SH2A"
1691   "divu %2,%1"
1692   [(set_attr "type" "arith")
1693    (set_attr "in_delay_slot" "no")])
1694
1695 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1696 ;; hard register 0.  If we used hard register 0, then the next instruction
1697 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1698 ;; gets allocated to a stack slot that needs its address reloaded, then
1699 ;; there is nothing to prevent reload from using r0 to reload the address.
1700 ;; This reload would clobber the value in r0 we are trying to store.
1701 ;; If we let reload allocate r0, then this problem can never happen.
1702
1703 (define_insn "udivsi3_i1"
1704   [(set (match_operand:SI 0 "register_operand" "=z")
1705         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1706    (clobber (reg:SI T_REG))
1707    (clobber (reg:SI PR_REG))
1708    (clobber (reg:SI R4_REG))
1709    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1710   "TARGET_SH1 && ! TARGET_SH4"
1711   "jsr  @%1%#"
1712   [(set_attr "type" "sfunc")
1713    (set_attr "needs_delay_slot" "yes")])
1714
1715 ; Since shmedia-nofpu code could be linked against shcompact code, and
1716 ; the udivsi3 libcall has the same name, we must consider all registers
1717 ; clobbered that are in the union of the registers clobbered by the
1718 ; shmedia and the shcompact implementation.  Note, if the shcompact
1719 ; implementation actually used shcompact code, we'd need to clobber
1720 ; also r23 and fr23.
1721 (define_insn "udivsi3_i1_media"
1722   [(set (match_operand:SI 0 "register_operand" "=z")
1723         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1724    (clobber (reg:SI T_MEDIA_REG))
1725    (clobber (reg:SI PR_MEDIA_REG))
1726    (clobber (reg:SI R20_REG))
1727    (clobber (reg:SI R21_REG))
1728    (clobber (reg:SI R22_REG))
1729    (clobber (reg:DI TR0_REG))
1730    (clobber (reg:DI TR1_REG))
1731    (clobber (reg:DI TR2_REG))
1732    (use (match_operand 1 "target_operand" "b"))]
1733   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1734   "blink        %1, r18"
1735   [(set_attr "type" "sfunc")
1736    (set_attr "needs_delay_slot" "yes")])
1737
1738 (define_expand "udivsi3_i4_media"
1739   [(set (match_dup 3)
1740         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1741    (set (match_dup 4)
1742         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1743    (set (match_dup 5) (float:DF (match_dup 3)))
1744    (set (match_dup 6) (float:DF (match_dup 4)))
1745    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1746    (set (match_dup 8) (fix:DI (match_dup 7)))
1747    (set (match_operand:SI 0 "register_operand" "")
1748         (truncate:SI (match_dup 8)))]
1749   "TARGET_SHMEDIA_FPU"
1750   "
1751 {
1752   operands[3] = gen_reg_rtx (DImode);
1753   operands[4] = gen_reg_rtx (DImode);
1754   operands[5] = gen_reg_rtx (DFmode);
1755   operands[6] = gen_reg_rtx (DFmode);
1756   operands[7] = gen_reg_rtx (DFmode);
1757   operands[8] = gen_reg_rtx (DImode);
1758 }")
1759
1760 (define_insn "udivsi3_i4"
1761   [(set (match_operand:SI 0 "register_operand" "=y")
1762         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1763    (clobber (reg:SI T_REG))
1764    (clobber (reg:SI PR_REG))
1765    (clobber (reg:DF DR0_REG))
1766    (clobber (reg:DF DR2_REG))
1767    (clobber (reg:DF DR4_REG))
1768    (clobber (reg:SI R0_REG))
1769    (clobber (reg:SI R1_REG))
1770    (clobber (reg:SI R4_REG))
1771    (clobber (reg:SI R5_REG))
1772    (use (reg:PSI FPSCR_REG))
1773    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1774   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1775   "jsr  @%1%#"
1776   [(set_attr "type" "sfunc")
1777    (set_attr "fp_mode" "double")
1778    (set_attr "needs_delay_slot" "yes")])
1779
1780 (define_insn "udivsi3_i4_single"
1781   [(set (match_operand:SI 0 "register_operand" "=y")
1782         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1783    (clobber (reg:SI T_REG))
1784    (clobber (reg:SI PR_REG))
1785    (clobber (reg:DF DR0_REG))
1786    (clobber (reg:DF DR2_REG))
1787    (clobber (reg:DF DR4_REG))
1788    (clobber (reg:SI R0_REG))
1789    (clobber (reg:SI R1_REG))
1790    (clobber (reg:SI R4_REG))
1791    (clobber (reg:SI R5_REG))
1792    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1793   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1794   "jsr  @%1%#"
1795   [(set_attr "type" "sfunc")
1796    (set_attr "needs_delay_slot" "yes")])
1797
1798 (define_insn "udivsi3_i4_int"
1799   [(set (match_operand:SI 0 "register_operand" "=z")
1800         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1801    (clobber (reg:SI T_REG))
1802    (clobber (reg:SI R1_REG))
1803    (clobber (reg:SI PR_REG))
1804    (clobber (reg:SI MACH_REG))
1805    (clobber (reg:SI MACL_REG))
1806    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1807   "TARGET_SH1"
1808   "jsr  @%1%#"
1809   [(set_attr "type" "sfunc")
1810    (set_attr "needs_delay_slot" "yes")])
1811
1812
1813 (define_expand "udivsi3"
1814   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1815    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1816    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1817    (parallel [(set (match_operand:SI 0 "register_operand" "")
1818                    (udiv:SI (reg:SI R4_REG)
1819                             (reg:SI R5_REG)))
1820               (clobber (reg:SI T_REG))
1821               (clobber (reg:SI PR_REG))
1822               (clobber (reg:SI R4_REG))
1823               (use (match_dup 3))])]
1824   ""
1825   "
1826 {
1827   rtx first, last;
1828
1829   operands[3] = gen_reg_rtx (Pmode);
1830   /* Emit the move of the address to a pseudo outside of the libcall.  */
1831   if (TARGET_DIVIDE_CALL_TABLE)
1832     {
1833       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1834          that causes problems when the divide code is supposed to come from a
1835          separate library.  Division by zero is undefined, so dividing 1 can be
1836          implemented by comparing with the divisor.  */
1837       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1838         {
1839           emit_insn (gen_cmpsi (operands[1], operands[2]));
1840           emit_insn (gen_sgeu (operands[0]));
1841           DONE;
1842         }
1843       else if (operands[2] == const0_rtx)
1844         {
1845           emit_move_insn (operands[0], operands[2]);
1846           DONE;
1847         }
1848       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1849       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1850     }
1851   else if (TARGET_DIVIDE_CALL_FP)
1852     {
1853       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1854       if (TARGET_FPU_SINGLE)
1855         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1856       else
1857         last = gen_udivsi3_i4 (operands[0], operands[3]);
1858     }
1859   else if (TARGET_SHMEDIA_FPU)
1860     {
1861       operands[1] = force_reg (SImode, operands[1]);
1862       operands[2] = force_reg (SImode, operands[2]);
1863       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1864       DONE;
1865     }
1866   else if (TARGET_SH2A)
1867     {
1868       operands[1] = force_reg (SImode, operands[1]);
1869       operands[2] = force_reg (SImode, operands[2]);
1870       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1871       DONE;
1872     }
1873   else if (TARGET_SH5)
1874     {
1875       function_symbol (operands[3],
1876                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1877                        SFUNC_STATIC);
1878
1879       if (TARGET_SHMEDIA)
1880         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1881       else if (TARGET_FPU_ANY)
1882         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1883       else
1884         last = gen_udivsi3_i1 (operands[0], operands[3]);
1885     }
1886   else
1887     {
1888       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1889       last = gen_udivsi3_i1 (operands[0], operands[3]);
1890     }
1891   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1892   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1893   last = emit_insn (last);
1894   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1895      invariant code motion can move it.  */
1896   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1897   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1898   DONE;
1899 }")
1900
1901 (define_insn "divsi3_sh2a"
1902   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1903         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1904                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1905   "TARGET_SH2A"
1906   "divs %2,%1"
1907   [(set_attr "type" "arith")
1908    (set_attr "in_delay_slot" "no")])
1909
1910 (define_insn "divsi3_i1"
1911   [(set (match_operand:SI 0 "register_operand" "=z")
1912         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1913    (clobber (reg:SI T_REG))
1914    (clobber (reg:SI PR_REG))
1915    (clobber (reg:SI R1_REG))
1916    (clobber (reg:SI R2_REG))
1917    (clobber (reg:SI R3_REG))
1918    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1919   "TARGET_SH1 && ! TARGET_SH4"
1920   "jsr  @%1%#"
1921   [(set_attr "type" "sfunc")
1922    (set_attr "needs_delay_slot" "yes")])
1923
1924 (define_insn "divsi3_i1_media"
1925   [(set (match_operand:SI 0 "register_operand" "=z")
1926         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1927    (clobber (reg:SI T_MEDIA_REG))
1928    (clobber (reg:SI PR_MEDIA_REG))
1929    (clobber (reg:SI R1_REG))
1930    (clobber (reg:SI R20_REG))
1931    (clobber (reg:SI R21_REG))
1932    (clobber (reg:SI TR0_REG))
1933    (use (match_operand 1 "target_operand" "b"))]
1934   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1935   "blink        %1, r18"
1936   [(set_attr "type" "sfunc")])
1937
1938 (define_insn "divsi3_media_2"
1939   [(set (match_operand:SI 0 "register_operand" "=z")
1940         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1941    (clobber (reg:SI T_MEDIA_REG))
1942    (clobber (reg:SI PR_MEDIA_REG))
1943    (clobber (reg:SI R1_REG))
1944    (clobber (reg:SI R21_REG))
1945    (clobber (reg:SI TR0_REG))
1946    (use (reg:SI R20_REG))
1947    (use (match_operand 1 "target_operand" "b"))]
1948   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1949   "blink        %1, r18"
1950   [(set_attr "type" "sfunc")])
1951
1952 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1953 ;; hard reg clobbers and data dependencies that we need when we want
1954 ;; to rematerialize the division into a call.
1955 (define_insn_and_split "divsi_inv_call"
1956   [(set (match_operand:SI 0 "register_operand" "=r")
1957         (div:SI (match_operand:SI 1 "register_operand" "r")
1958                 (match_operand:SI 2 "register_operand" "r")))
1959    (clobber (reg:SI R4_REG))
1960    (clobber (reg:SI R5_REG))
1961    (clobber (reg:SI T_MEDIA_REG))
1962    (clobber (reg:SI PR_MEDIA_REG))
1963    (clobber (reg:SI R1_REG))
1964    (clobber (reg:SI R21_REG))
1965    (clobber (reg:SI TR0_REG))
1966    (clobber (reg:SI R20_REG))
1967    (use (match_operand:SI 3 "register_operand" "r"))]
1968   "TARGET_SHMEDIA"
1969   "#"
1970   "&& (high_life_started || reload_completed)"
1971   [(set (match_dup 0) (match_dup 3))]
1972   ""
1973   [(set_attr "highpart" "must_split")])
1974
1975 ;; This is the combiner pattern for -mdiv=inv:call .
1976 (define_insn_and_split "*divsi_inv_call_combine"
1977   [(set (match_operand:SI 0 "register_operand" "=z")
1978         (div:SI (match_operand:SI 1 "register_operand" "r")
1979                 (match_operand:SI 2 "register_operand" "r")))
1980    (clobber (reg:SI R4_REG))
1981    (clobber (reg:SI R5_REG))
1982    (clobber (reg:SI T_MEDIA_REG))
1983    (clobber (reg:SI PR_MEDIA_REG))
1984    (clobber (reg:SI R1_REG))
1985    (clobber (reg:SI R21_REG))
1986    (clobber (reg:SI TR0_REG))
1987    (clobber (reg:SI R20_REG))
1988    (use (unspec:SI [(match_dup 1)
1989                     (match_operand:SI 3 "" "")
1990                     (unspec:SI [(match_operand:SI 4 "" "")
1991                                 (match_dup 3)
1992                                 (match_operand:DI 5 "" "")]
1993                      UNSPEC_DIV_INV_M2)
1994                     (match_operand:DI 6 "" "")
1995                     (const_int 0)
1996                     (const_int 0)]
1997          UNSPEC_DIV_INV_M3))]
1998   "TARGET_SHMEDIA"
1999   "#"
2000   "&& (high_life_started || reload_completed)"
2001   [(pc)]
2002   "
2003 {
2004   const char *name = sh_divsi3_libfunc;
2005   enum sh_function_kind kind = SFUNC_GOT;
2006   rtx sym;
2007
2008   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2009   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2010   while (TARGET_DIVIDE_INV_CALL2)
2011     {
2012       rtx x = operands[3];
2013
2014       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2015         break;
2016       x = XVECEXP (x, 0, 0);
2017       name = \"__sdivsi3_2\";
2018       kind = SFUNC_STATIC;
2019       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2020       break;
2021     }
2022   sym = function_symbol (NULL, name, kind);
2023   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2024   DONE;
2025 }"
2026   [(set_attr "highpart" "must_split")])
2027
2028 (define_expand "divsi3_i4_media"
2029   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2030    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2031    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2032    (set (match_operand:SI 0 "register_operand" "=r")
2033         (fix:SI (match_dup 5)))]
2034   "TARGET_SHMEDIA_FPU"
2035   "
2036 {
2037   operands[3] = gen_reg_rtx (DFmode);
2038   operands[4] = gen_reg_rtx (DFmode);
2039   operands[5] = gen_reg_rtx (DFmode);
2040 }")
2041
2042 (define_insn "divsi3_i4"
2043   [(set (match_operand:SI 0 "register_operand" "=y")
2044         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2045    (clobber (reg:SI PR_REG))
2046    (clobber (reg:DF DR0_REG))
2047    (clobber (reg:DF DR2_REG))
2048    (use (reg:PSI FPSCR_REG))
2049    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2050   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2051   "jsr  @%1%#"
2052   [(set_attr "type" "sfunc")
2053    (set_attr "fp_mode" "double")
2054    (set_attr "needs_delay_slot" "yes")])
2055
2056 (define_insn "divsi3_i4_single"
2057   [(set (match_operand:SI 0 "register_operand" "=y")
2058         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2059    (clobber (reg:SI PR_REG))
2060    (clobber (reg:DF DR0_REG))
2061    (clobber (reg:DF DR2_REG))
2062    (clobber (reg:SI R2_REG))
2063    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2064   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2065   "jsr  @%1%#"
2066   [(set_attr "type" "sfunc")
2067    (set_attr "needs_delay_slot" "yes")])
2068
2069 (define_insn "divsi3_i4_int"
2070   [(set (match_operand:SI 0 "register_operand" "=z")
2071         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2072    (clobber (reg:SI T_REG))
2073    (clobber (reg:SI PR_REG))
2074    (clobber (reg:SI R1_REG))
2075    (clobber (reg:SI MACH_REG))
2076    (clobber (reg:SI MACL_REG))
2077    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2078   "TARGET_SH1"
2079   "jsr  @%1%#"
2080   [(set_attr "type" "sfunc")
2081    (set_attr "needs_delay_slot" "yes")])
2082
2083 (define_expand "divsi3"
2084   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2085    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2086    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2087    (parallel [(set (match_operand:SI 0 "register_operand" "")
2088                    (div:SI (reg:SI R4_REG)
2089                            (reg:SI R5_REG)))
2090               (clobber (reg:SI T_REG))
2091               (clobber (reg:SI PR_REG))
2092               (clobber (reg:SI R1_REG))
2093               (clobber (reg:SI R2_REG))
2094               (clobber (reg:SI R3_REG))
2095               (use (match_dup 3))])]
2096   ""
2097   "
2098 {
2099   rtx first, last;
2100
2101   operands[3] = gen_reg_rtx (Pmode);
2102   /* Emit the move of the address to a pseudo outside of the libcall.  */
2103   if (TARGET_DIVIDE_CALL_TABLE)
2104     {
2105       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2106       last = gen_divsi3_i4_int (operands[0], operands[3]);
2107     }
2108   else if (TARGET_DIVIDE_CALL_FP)
2109     {
2110       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2111       if (TARGET_FPU_SINGLE)
2112         last = gen_divsi3_i4_single (operands[0], operands[3]);
2113       else
2114         last = gen_divsi3_i4 (operands[0], operands[3]);
2115     }
2116   else if (TARGET_SH2A)
2117     {
2118       operands[1] = force_reg (SImode, operands[1]);
2119       operands[2] = force_reg (SImode, operands[2]);
2120       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2121       DONE;
2122     }
2123   else if (TARGET_DIVIDE_INV)
2124     {
2125       rtx dividend = operands[1];
2126       rtx divisor = operands[2];
2127       rtx tab_base;
2128       rtx nsb_res = gen_reg_rtx (DImode);
2129       rtx norm64 = gen_reg_rtx (DImode);
2130       rtx tab_ix = gen_reg_rtx (DImode);
2131       rtx norm32 = gen_reg_rtx (SImode);
2132       rtx i92 = force_reg (DImode, GEN_INT (92));
2133       rtx scratch0a = gen_reg_rtx (DImode);
2134       rtx scratch0b = gen_reg_rtx (DImode);
2135       rtx inv0 = gen_reg_rtx (SImode);
2136       rtx scratch1a = gen_reg_rtx (DImode);
2137       rtx scratch1b = gen_reg_rtx (DImode);
2138       rtx shift = gen_reg_rtx (DImode);
2139       rtx i2p27, i43;
2140       rtx inv1 = gen_reg_rtx (SImode);
2141       rtx scratch2a = gen_reg_rtx (DImode);
2142       rtx scratch2b = gen_reg_rtx (SImode);
2143       rtx inv2 = gen_reg_rtx (SImode);
2144       rtx scratch3a = gen_reg_rtx (DImode);
2145       rtx scratch3b = gen_reg_rtx (DImode);
2146       rtx scratch3c = gen_reg_rtx (DImode);
2147       rtx scratch3d = gen_reg_rtx (SImode);
2148       rtx scratch3e = gen_reg_rtx (DImode);
2149       rtx result = gen_reg_rtx (SImode);
2150
2151       if (! arith_reg_or_0_operand (dividend, SImode))
2152         dividend = force_reg (SImode, dividend);
2153       if (! arith_reg_operand (divisor, SImode))
2154         divisor = force_reg (SImode, divisor);
2155       if (flag_pic && Pmode != DImode)
2156         {
2157           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2158           tab_base = gen_datalabel_ref (tab_base);
2159           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2160         }
2161       else
2162         {
2163           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2164           tab_base = gen_datalabel_ref (tab_base);
2165           tab_base = force_reg (DImode, tab_base);
2166         }
2167       if (TARGET_DIVIDE_INV20U)
2168         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2169       else
2170         i2p27 = GEN_INT (0);
2171       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2172         i43 = force_reg (DImode, GEN_INT (43));
2173       else
2174         i43 = GEN_INT (0);
2175       emit_insn (gen_nsbdi (nsb_res,
2176                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2177       emit_insn (gen_ashldi3_media (norm64,
2178                                     gen_rtx_SUBREG (DImode, divisor, 0),
2179                                     nsb_res));
2180       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2181       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2182       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2183                                    inv0, scratch0a, scratch0b,
2184                                    scratch1a, scratch1b));
2185       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2186       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2187                                    scratch2a));
2188       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2189                                    i2p27, i43,
2190                                    scratch3a, scratch3b, scratch3c,
2191                                    scratch2a, scratch2b, scratch3d, scratch3e));
2192       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2193         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2194       else if (TARGET_DIVIDE_INV_FP)
2195         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2196                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2197                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2198                                      gen_reg_rtx (DFmode)));
2199       else
2200         emit_move_insn (operands[0], result);
2201       DONE;
2202     }
2203   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2204     {
2205       operands[1] = force_reg (SImode, operands[1]);
2206       operands[2] = force_reg (SImode, operands[2]);
2207       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2208       DONE;
2209     }
2210   else if (TARGET_SH5)
2211     {
2212       if (TARGET_DIVIDE_CALL2)
2213         {
2214           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2215           tab_base = gen_datalabel_ref (tab_base);
2216           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2217         }
2218       if (TARGET_FPU_ANY && TARGET_SH1)
2219         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2220       else if (TARGET_DIVIDE_CALL2)
2221         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2222       else
2223         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2224
2225       if (TARGET_SHMEDIA)
2226         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2227                 (operands[0], operands[3]));
2228       else if (TARGET_FPU_ANY)
2229         last = gen_divsi3_i4_single (operands[0], operands[3]);
2230       else
2231         last = gen_divsi3_i1 (operands[0], operands[3]);
2232     }
2233   else
2234     {
2235       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2236       last = gen_divsi3_i1 (operands[0], operands[3]);
2237     }
2238   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2239   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2240   last = emit_insn (last);
2241   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2242      invariant code motion can move it.  */
2243   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2244   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2245   DONE;
2246 }")
2247
2248 ;; operands: scratch, tab_base, tab_ix
2249 ;; These are unspecs because we could generate an indexed addressing mode
2250 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2251 ;; confuse reload.  See PR27117.
2252
2253 (define_insn "divsi_inv_qitable"
2254   [(set (match_operand:DI 0 "register_operand" "=r")
2255         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2256                                     (match_operand:DI 2 "register_operand" "r")]
2257                          UNSPEC_DIV_INV_TABLE)))]
2258   "TARGET_SHMEDIA"
2259   "@
2260         ldx.ub  %1, %2, %0"
2261   [(set_attr "type" "load_media")
2262    (set_attr "highpart" "user")])
2263
2264 ;; operands: scratch, tab_base, tab_ix
2265 (define_insn "divsi_inv_hitable"
2266   [(set (match_operand:DI 0 "register_operand" "=r")
2267         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2268                                     (match_operand:DI 2 "register_operand" "r")]
2269                          UNSPEC_DIV_INV_TABLE)))]
2270   "TARGET_SHMEDIA"
2271   "@
2272         ldx.w   %1, %2, %0"
2273   [(set_attr "type" "load_media")
2274    (set_attr "highpart" "user")])
2275
2276 ;; operands: inv0, tab_base, tab_ix, norm32
2277 ;; scratch equiv in sdivsi3_2: r19, r21
2278 (define_expand "divsi_inv_m0"
2279   [(set (match_operand:SI 0 "register_operand" "=r")
2280         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2281                     (match_operand:DI 2 "register_operand" "r")
2282                     (match_operand:SI 3 "register_operand" "r")]
2283          UNSPEC_DIV_INV_M0))
2284    (clobber (match_operand:DI 4 "register_operand" "=r"))
2285    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2286   "TARGET_SHMEDIA"
2287   "
2288 {
2289 /*
2290 tab_base: r20
2291 tab_ix: r21
2292 norm32: r25
2293  ldx.ub r20, r21, r19 // u0.8
2294  shlli r21, 1, r21
2295  muls.l r25, r19, r19 // s2.38
2296  ldx.w r20, r21, r21  // s2.14
2297  shari r19, 24, r19   // truncate to s2.14
2298  sub r21, r19, r19    // some 11 bit inverse in s1.14
2299 */
2300
2301   rtx inv0 = operands[0];
2302   rtx tab_base = operands[1];
2303   rtx tab_ix = operands[2];
2304   rtx norm32 = operands[3];
2305   rtx scratch0 = operands[4];
2306   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2307   rtx scratch1 = operands[5];
2308
2309   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2310   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2311   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2312   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2313   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2314   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2315   DONE;
2316 }")
2317
2318 ;; operands: inv1, tab_base, tab_ix, norm32
2319 (define_insn_and_split "divsi_inv_m1"
2320   [(set (match_operand:SI 0 "register_operand" "=r")
2321         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2322                     (match_operand:DI 2 "register_operand" "r")
2323                     (match_operand:SI 3 "register_operand" "r")]
2324          UNSPEC_DIV_INV_M1))
2325    (clobber (match_operand:SI 4 "register_operand" "=r"))
2326    (clobber (match_operand:DI 5 "register_operand" "=r"))
2327    (clobber (match_operand:DI 6 "register_operand" "=r"))
2328    (clobber (match_operand:DI 7 "register_operand" "=r"))
2329    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2330   "TARGET_SHMEDIA"
2331   "#"
2332   "&& no_new_pseudos"
2333   [(pc)]
2334   "
2335 {
2336 /* inv0: r19
2337  muls.l r19, r19, r18 // u0.28
2338  muls.l r25, r18, r18 // s2.58
2339  shlli r19, 45, r0    // multiply by two and convert to s2.58
2340  sub r0, r18, r18
2341  shari r18, 28, r18   // some 18 bit inverse in s1.30
2342 */
2343
2344   rtx inv1 = operands[0];
2345   rtx tab_base = operands[1];
2346   rtx tab_ix = operands[2];
2347   rtx norm32 = operands[3];
2348   rtx inv0 = operands[4];
2349   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2350   rtx scratch0a = operands[5];
2351   rtx scratch0b = operands[6];
2352   rtx scratch0 = operands[7];
2353   rtx scratch1 = operands[8];
2354   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2355
2356   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2357                                scratch0a, scratch0b));
2358   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2359   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2360   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2361   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2362   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2363   DONE;
2364 }")
2365
2366 ;; operands: inv2, norm32, inv1, i92
2367 (define_insn_and_split "divsi_inv_m2"
2368   [(set (match_operand:SI 0 "register_operand" "=r")
2369         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2370                     (match_operand:SI 2 "register_operand" "r")
2371                     (match_operand:DI 3 "register_operand" "r")]
2372          UNSPEC_DIV_INV_M2))
2373    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2374   "TARGET_SHMEDIA"
2375   "#"
2376   "&& no_new_pseudos"
2377   [(pc)]
2378   "
2379 {
2380 /*
2381  muls.l r18, r25, r0  // s2.60
2382  shari r0, 16, r0     // s-16.44
2383   sub
2384  muls.l r0, r18, r19  // s-16.74
2385  shari r19, 30, r19   // s-16.44
2386 */
2387   rtx inv2 = operands[0];
2388   rtx norm32 = operands[1];
2389   rtx inv1 = operands[2];
2390   rtx i92 = operands[3];
2391   rtx scratch0 = operands[4];
2392   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2393
2394   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2395   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2396   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2397   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2398   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2399   DONE;
2400 }")
2401
2402 (define_insn_and_split "divsi_inv_m3"
2403   [(set (match_operand:SI 0 "register_operand" "=r")
2404         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2405                     (match_operand:SI 2 "register_operand" "r")
2406                     (match_operand:SI 3 "register_operand" "r")
2407                     (match_operand:DI 4 "register_operand" "r")
2408                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2409                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2410          UNSPEC_DIV_INV_M3))
2411    (clobber (match_operand:DI 7 "register_operand" "=r"))
2412    (clobber (match_operand:DI 8 "register_operand" "=r"))
2413    (clobber (match_operand:DI 9 "register_operand" "=r"))
2414    (clobber (match_operand:DI 10 "register_operand" "=r"))
2415    (clobber (match_operand:SI 11 "register_operand" "=r"))
2416    (clobber (match_operand:SI 12 "register_operand" "=r"))
2417    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2418   "TARGET_SHMEDIA"
2419   "#"
2420   "&& no_new_pseudos"
2421   [(pc)]
2422   "
2423 {
2424 /*
2425   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2426   r0: scratch0  r19: scratch1 r21: scratch2
2427
2428   muls.l r18, r4, r25 // s32.30
2429  muls.l r19, r4, r19  // s15.30
2430  shari r25, 63, r21
2431   shari r19, 14, r19  // s18.-14
2432  sub r25, r19, r0
2433  shard r0, r1, r0
2434  sub r0, r21, r0
2435 */
2436
2437   rtx result = operands[0];
2438   rtx dividend = operands[1];
2439   rtx inv1 = operands[2];
2440   rtx inv2 = operands[3];
2441   rtx shift = operands[4];
2442   rtx scratch0 = operands[7];
2443   rtx scratch1 = operands[8];
2444   rtx scratch2 = operands[9];
2445
2446   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2447   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2448   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2449   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2450   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2451   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2452   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2453   DONE;
2454 }")
2455
2456 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2457 ;; inv1: tab_base, tab_ix, norm32
2458 ;; inv2: norm32, inv1, i92
2459 (define_insn_and_split "divsi_inv_m1_3"
2460   [(set (match_operand:SI 0 "register_operand" "=r")
2461         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2462                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2463                                 (match_operand:DI 3 "register_operand" "r")
2464                                 (match_operand:SI 4 "register_operand" "r")]
2465                      UNSPEC_DIV_INV_M1)
2466                     (unspec:SI [(match_dup 4)
2467                                 (unspec:SI [(match_dup 2)
2468                                             (match_dup 3)
2469                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2470                                 (match_operand:SI 5 "" "")]
2471                      UNSPEC_DIV_INV_M2)
2472                     (match_operand:DI 6 "register_operand" "r")
2473                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2474                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2475          UNSPEC_DIV_INV_M3))
2476    (clobber (match_operand:DI 9 "register_operand" "=r"))
2477    (clobber (match_operand:DI 10 "register_operand" "=r"))
2478    (clobber (match_operand:DI 11 "register_operand" "=r"))
2479    (clobber (match_operand:DI 12 "register_operand" "=r"))
2480    (clobber (match_operand:SI 13 "register_operand" "=r"))
2481    (clobber (match_operand:SI 14 "register_operand" "=r"))
2482    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2483   "TARGET_SHMEDIA
2484    && (TARGET_DIVIDE_INV_MINLAT
2485        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2486   "#"
2487   "&& no_new_pseudos"
2488   [(pc)]
2489   "
2490 {
2491   rtx result = operands[0];
2492   rtx dividend = operands[1];
2493   rtx tab_base = operands[2];
2494   rtx tab_ix = operands[3];
2495   rtx norm32 = operands[4];
2496   /* rtx i92 = operands[5]; */
2497   rtx shift = operands[6];
2498   rtx i2p27 = operands[7];
2499   rtx i43 = operands[8];
2500   rtx scratch0 = operands[9];
2501   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2502   rtx scratch1 = operands[10];
2503   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2504   rtx scratch2 = operands[11];
2505   rtx scratch3 = operands[12];
2506   rtx scratch4 = operands[13];
2507   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2508   rtx scratch5 = operands[14];
2509   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2510   rtx scratch6 = operands[15];
2511
2512   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2513                                scratch0, scratch1));
2514   /* inv0 == scratch4 */
2515   if (! TARGET_DIVIDE_INV20U)
2516     {
2517       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2518       i2p27 = scratch0;
2519       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2520     }
2521   else
2522     {
2523       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2524       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2525     }
2526   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2527   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2528   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2529   /* inv1 == scratch4 */
2530
2531   if (TARGET_DIVIDE_INV_MINLAT)
2532     {
2533       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2534       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2535       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2536       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2537       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2538       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2539       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2540       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2541       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2542       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2543       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2544     }
2545   else
2546     {
2547       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2548       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2549       emit_insn (gen_nsbdi (scratch6,
2550                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2551       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2552       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2553       emit_insn (gen_divsi_inv20 (scratch2,
2554                                   norm32, scratch4, dividend,
2555                                   scratch6, scratch3, i43,
2556                                   /* scratch0 may be shared with i2p27.  */
2557                                   scratch0, scratch1, scratch5,
2558                                   label, label, i2p27));
2559     }
2560   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2561   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2562   DONE;
2563 }")
2564
2565 (define_insn "divsi_inv20"
2566   [(set (match_operand:DI 0 "register_operand" "=&r")
2567         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2568                     (match_operand:SI 2 "register_operand" "r")
2569                     (match_operand:SI 3 "register_operand" "r")
2570                     (match_operand:DI 4 "register_operand" "r")
2571                     (match_operand:DI 5 "register_operand" "r")
2572                     (match_operand:DI 6 "register_operand" "r")
2573                     (match_operand:DI 12 "register_operand" "r")
2574                     (match_operand 10 "target_operand" "b")
2575                     (match_operand 11 "immediate_operand" "i")]
2576          UNSPEC_DIV_INV20))
2577    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2578    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2579    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2580   "TARGET_SHMEDIA
2581    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2582   "*
2583 {
2584 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2585              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2586              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2587              %10 label (tr), %11 label (imm)
2588
2589  muls.l inv1, norm32, scratch0  // s2.60
2590   muls.l inv1, dividend, result // s32.30
2591   xor i2p27, result_sign, round_scratch
2592  bge/u dividend_nsb, i43, tr.. (label)
2593  shari scratch0, 16, scratch0   // s-16.44
2594  muls.l sratch0_si, inv1, scratch0 // s-16.74
2595   sub result, round_scratch, result
2596   shari dividend, 14, scratch1   // s19.-14
2597  shari scratch0, 30, scratch0   // s-16.44
2598  muls.l scratch0, scratch1, round_scratch // s15.30
2599 label:
2600  sub result, round_scratch, result */
2601
2602   int likely = TARGET_DIVIDE_INV20L;
2603
2604   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2605   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2606   output_asm_insn (likely
2607                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2608                    : \"bge/u\t%4, %6, %10\", operands);
2609   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2610   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2611   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2612   return (likely
2613           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2614           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2615 }")
2616
2617 (define_insn_and_split "divsi_inv_fp"
2618   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2619         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2620                 (match_operand:SI 2 "register_operand" "rf")))
2621    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2622    (clobber (match_operand:SI 4 "register_operand" "=r"))
2623    (clobber (match_operand:SI 5 "register_operand" "=r"))
2624    (clobber (match_operand:DF 6 "register_operand" "=r"))
2625    (clobber (match_operand:DF 7 "register_operand" "=r"))
2626    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2627   "TARGET_SHMEDIA_FPU"
2628   "#"
2629   "&& (high_life_started || reload_completed)"
2630   [(set (match_dup 0) (match_dup 3))]
2631   ""
2632   [(set_attr "highpart" "must_split")])
2633
2634 ;; If a matching group of divide-by-inverse instructions is in the same
2635 ;; basic block after gcse & loop optimizations, we want to transform them
2636 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2637 (define_insn_and_split "*divsi_inv_fp_combine"
2638   [(set (match_operand:SI 0 "register_operand" "=f")
2639         (div:SI (match_operand:SI 1 "register_operand" "f")
2640                 (match_operand:SI 2 "register_operand" "f")))
2641    (use (unspec:SI [(match_dup 1)
2642                     (match_operand:SI 3 "" "")
2643                     (unspec:SI [(match_operand:SI 4 "" "")
2644                                 (match_dup 3)
2645                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2646                     (match_operand:DI 6 "" "")
2647                     (const_int 0)
2648                     (const_int 0)] UNSPEC_DIV_INV_M3))
2649    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2650    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2651    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2652    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2653    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2654   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2655   "#"
2656   "&& 1"
2657   [(set (match_dup 9) (float:DF (match_dup 1)))
2658    (set (match_dup 10) (float:DF (match_dup 2)))
2659    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2660    (set (match_dup 8)
2661         (fix:SI (match_dup 11)))
2662    (set (match_dup 0) (match_dup 8))]
2663   "
2664 {
2665   if (! fp_arith_reg_operand (operands[1], SImode))
2666     {
2667       emit_move_insn (operands[7], operands[1]);
2668       operands[1] = operands[7];
2669     }
2670   if (! fp_arith_reg_operand (operands[2], SImode))
2671     {
2672       emit_move_insn (operands[8], operands[2]);
2673       operands[2] = operands[8];
2674     }
2675 }"
2676   [(set_attr "highpart" "must_split")])
2677 \f
2678 ;; -------------------------------------------------------------------------
2679 ;; Multiplication instructions
2680 ;; -------------------------------------------------------------------------
2681
2682 (define_insn "umulhisi3_i"
2683   [(set (reg:SI MACL_REG)
2684         (mult:SI (zero_extend:SI
2685                   (match_operand:HI 0 "arith_reg_operand" "r"))
2686                  (zero_extend:SI
2687                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2688   "TARGET_SH1"
2689   "mulu.w       %1,%0"
2690   [(set_attr "type" "smpy")])
2691
2692 (define_insn "mulhisi3_i"
2693   [(set (reg:SI MACL_REG)
2694         (mult:SI (sign_extend:SI
2695                   (match_operand:HI 0 "arith_reg_operand" "r"))
2696                  (sign_extend:SI
2697                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2698   "TARGET_SH1"
2699   "muls.w       %1,%0"
2700   [(set_attr "type" "smpy")])
2701
2702 (define_expand "mulhisi3"
2703   [(set (reg:SI MACL_REG)
2704         (mult:SI (sign_extend:SI
2705                   (match_operand:HI 1 "arith_reg_operand" ""))
2706                  (sign_extend:SI
2707                   (match_operand:HI 2 "arith_reg_operand" ""))))
2708    (set (match_operand:SI 0 "arith_reg_operand" "")
2709         (reg:SI MACL_REG))]
2710   "TARGET_SH1"
2711   "
2712 {
2713   rtx first, last;
2714
2715   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2716   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2717   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2718      invariant code motion can move it.  */
2719   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2720   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2721   /* expand_binop can't find a suitable code in umul_widen_optab to
2722      make a REG_EQUAL note from, so make one here.
2723      See also smulsi3_highpart.
2724      ??? Alternatively, we could put this at the calling site of expand_binop,
2725      i.e. expand_expr.  */
2726   REG_NOTES (last)
2727     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2728                          REG_NOTES (last));
2729   DONE;
2730 }")
2731
2732 (define_expand "umulhisi3"
2733   [(set (reg:SI MACL_REG)
2734         (mult:SI (zero_extend:SI
2735                   (match_operand:HI 1 "arith_reg_operand" ""))
2736                  (zero_extend:SI
2737                   (match_operand:HI 2 "arith_reg_operand" ""))))
2738    (set (match_operand:SI 0 "arith_reg_operand" "")
2739         (reg:SI MACL_REG))]
2740   "TARGET_SH1"
2741   "
2742 {
2743   rtx first, last;
2744
2745   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2746   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2747   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2748      invariant code motion can move it.  */
2749   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2750   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2751   /* expand_binop can't find a suitable code in umul_widen_optab to
2752      make a REG_EQUAL note from, so make one here.
2753      See also smulsi3_highpart.
2754      ??? Alternatively, we could put this at the calling site of expand_binop,
2755      i.e. expand_expr.  */
2756   REG_NOTES (last)
2757     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2758                          REG_NOTES (last));
2759   DONE;
2760 }")
2761
2762 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2763 ;; a call to a routine which clobbers known registers.
2764
2765 (define_insn ""
2766   [(set (match_operand:SI 1 "register_operand" "=z")
2767         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2768    (clobber (reg:SI MACL_REG))
2769    (clobber (reg:SI T_REG))
2770    (clobber (reg:SI PR_REG))
2771    (clobber (reg:SI R3_REG))
2772    (clobber (reg:SI R2_REG))
2773    (clobber (reg:SI R1_REG))
2774    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2775   "TARGET_SH1"
2776   "jsr  @%0%#"
2777   [(set_attr "type" "sfunc")
2778    (set_attr "needs_delay_slot" "yes")])
2779
2780 (define_expand "mulsi3_call"
2781   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2782    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2783    (parallel[(set (match_operand:SI 0 "register_operand" "")
2784                   (mult:SI (reg:SI R4_REG)
2785                            (reg:SI R5_REG)))
2786              (clobber (reg:SI MACL_REG))
2787              (clobber (reg:SI T_REG))
2788              (clobber (reg:SI PR_REG))
2789              (clobber (reg:SI R3_REG))
2790              (clobber (reg:SI R2_REG))
2791              (clobber (reg:SI R1_REG))
2792              (use (match_operand:SI 3 "register_operand" ""))])]
2793   "TARGET_SH1"
2794   "")
2795
2796 (define_insn "mul_r"
2797   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2798         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2799                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2800   "TARGET_SH2A"
2801   "mulr %2,%0"
2802   [(set_attr "type" "dmpy")])
2803
2804 (define_insn "mul_l"
2805   [(set (reg:SI MACL_REG)
2806         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2807                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2808   "TARGET_SH2"
2809   "mul.l        %1,%0"
2810   [(set_attr "type" "dmpy")])
2811
2812 (define_expand "mulsi3"
2813   [(set (reg:SI MACL_REG)
2814         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2815                   (match_operand:SI 2 "arith_reg_operand" "")))
2816    (set (match_operand:SI 0 "arith_reg_operand" "")
2817         (reg:SI MACL_REG))]
2818   "TARGET_SH1"
2819   "
2820 {
2821   rtx first, last;
2822
2823   if (!TARGET_SH2)
2824     {
2825       /* The address must be set outside the libcall,
2826          since it goes into a pseudo.  */
2827       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2828       rtx addr = force_reg (SImode, sym);
2829       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2830                                    operands[2], addr);
2831       first = insns;
2832       last = emit_insn (insns);
2833     }
2834   else
2835     {
2836       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2837
2838       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2839       /* consec_sets_giv can only recognize the first insn that sets a
2840          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2841          note.  */
2842       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2843     }
2844   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2845      invariant code motion can move it.  */
2846   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2847   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2848   DONE;
2849 }")
2850
2851 (define_insn "mulsidi3_i"
2852   [(set (reg:SI MACH_REG)
2853         (truncate:SI
2854          (lshiftrt:DI
2855           (mult:DI
2856            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2857            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2858           (const_int 32))))
2859    (set (reg:SI MACL_REG)
2860         (mult:SI (match_dup 0)
2861                  (match_dup 1)))]
2862   "TARGET_SH2"
2863   "dmuls.l      %1,%0"
2864   [(set_attr "type" "dmpy")])
2865
2866 (define_expand "mulsidi3"
2867   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2868         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2869                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2870   "TARGET_SH2 || TARGET_SHMEDIA"
2871   "
2872 {
2873   if (TARGET_SH2)
2874     {
2875        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2876                                         operands[2]));
2877        DONE;
2878     }
2879 }")
2880
2881 (define_insn "mulsidi3_media"
2882   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2883         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2884                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2885   "TARGET_SHMEDIA"
2886   "muls.l       %1, %2, %0"
2887   [(set_attr "type" "dmpy_media")
2888    (set_attr "highpart" "ignore")])
2889
2890 (define_insn "mulsidi3_compact"
2891   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2892         (mult:DI
2893          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2894          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2895    (clobber (reg:SI MACH_REG))
2896    (clobber (reg:SI MACL_REG))]
2897   "TARGET_SH2"
2898   "#")
2899
2900 (define_split
2901   [(set (match_operand:DI 0 "arith_reg_dest" "")
2902         (mult:DI
2903          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2904          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2905    (clobber (reg:SI MACH_REG))
2906    (clobber (reg:SI MACL_REG))]
2907   "TARGET_SH2"
2908   [(const_int 0)]
2909   "
2910 {
2911   rtx low_dst = gen_lowpart (SImode, operands[0]);
2912   rtx high_dst = gen_highpart (SImode, operands[0]);
2913
2914   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2915
2916   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2917   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2918   /* We need something to tag the possible REG_EQUAL notes on to.  */
2919   emit_move_insn (operands[0], operands[0]);
2920   DONE;
2921 }")
2922
2923 (define_insn "umulsidi3_i"
2924   [(set (reg:SI MACH_REG)
2925         (truncate:SI
2926          (lshiftrt:DI
2927           (mult:DI
2928            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2929            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2930           (const_int 32))))
2931    (set (reg:SI MACL_REG)
2932         (mult:SI (match_dup 0)
2933                  (match_dup 1)))]
2934   "TARGET_SH2"
2935   "dmulu.l      %1,%0"
2936   [(set_attr "type" "dmpy")])
2937
2938 (define_expand "umulsidi3"
2939   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2940         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2941                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2942   "TARGET_SH2 || TARGET_SHMEDIA"
2943   "
2944 {
2945   if (TARGET_SH2)
2946     {
2947        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2948                                          operands[2]));
2949        DONE;
2950     }
2951 }")
2952
2953 (define_insn "umulsidi3_media"
2954   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2955         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2956                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2957   "TARGET_SHMEDIA"
2958   "mulu.l       %1, %2, %0"
2959   [(set_attr "type" "dmpy_media")
2960    (set_attr "highpart" "ignore")])
2961
2962 (define_insn "umulsidi3_compact"
2963   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2964         (mult:DI
2965          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2966          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2967    (clobber (reg:SI MACH_REG))
2968    (clobber (reg:SI MACL_REG))]
2969   "TARGET_SH2"
2970   "#")
2971
2972 (define_split
2973   [(set (match_operand:DI 0 "arith_reg_dest" "")
2974         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2975                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2976    (clobber (reg:SI MACH_REG))
2977    (clobber (reg:SI MACL_REG))]
2978   "TARGET_SH2"
2979   [(const_int 0)]
2980   "
2981 {
2982   rtx low_dst = gen_lowpart (SImode, operands[0]);
2983   rtx high_dst = gen_highpart (SImode, operands[0]);
2984
2985   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2986
2987   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2988   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2989   /* We need something to tag the possible REG_EQUAL notes on to.  */
2990   emit_move_insn (operands[0], operands[0]);
2991   DONE;
2992 }")
2993
2994 (define_insn "smulsi3_highpart_i"
2995   [(set (reg:SI MACH_REG)
2996         (truncate:SI
2997          (lshiftrt:DI
2998           (mult:DI
2999            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3000            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3001           (const_int 32))))
3002    (clobber (reg:SI MACL_REG))]
3003   "TARGET_SH2"
3004   "dmuls.l      %1,%0"
3005   [(set_attr "type" "dmpy")])
3006
3007 (define_expand "smulsi3_highpart"
3008   [(parallel
3009     [(set (reg:SI MACH_REG)
3010           (truncate:SI
3011            (lshiftrt:DI
3012             (mult:DI
3013              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3014              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3015             (const_int 32))))
3016     (clobber (reg:SI MACL_REG))])
3017    (set (match_operand:SI 0 "arith_reg_operand" "")
3018         (reg:SI MACH_REG))]
3019   "TARGET_SH2"
3020   "
3021 {
3022   rtx first, last;
3023
3024   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3025   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3026   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3027      invariant code motion can move it.  */
3028   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3029   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3030   /* expand_binop can't find a suitable code in mul_highpart_optab to
3031      make a REG_EQUAL note from, so make one here.
3032      See also {,u}mulhisi.
3033      ??? Alternatively, we could put this at the calling site of expand_binop,
3034      i.e. expand_mult_highpart.  */
3035   REG_NOTES (last)
3036     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
3037                          REG_NOTES (last));
3038   DONE;
3039 }")
3040
3041 (define_insn "umulsi3_highpart_i"
3042   [(set (reg:SI MACH_REG)
3043         (truncate:SI
3044          (lshiftrt:DI
3045           (mult:DI
3046            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3047            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3048           (const_int 32))))
3049    (clobber (reg:SI MACL_REG))]
3050   "TARGET_SH2"
3051   "dmulu.l      %1,%0"
3052   [(set_attr "type" "dmpy")])
3053
3054 (define_expand "umulsi3_highpart"
3055   [(parallel
3056     [(set (reg:SI MACH_REG)
3057           (truncate:SI
3058            (lshiftrt:DI
3059             (mult:DI
3060              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3061              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3062             (const_int 32))))
3063     (clobber (reg:SI MACL_REG))])
3064    (set (match_operand:SI 0 "arith_reg_operand" "")
3065         (reg:SI MACH_REG))]
3066   "TARGET_SH2"
3067   "
3068 {
3069   rtx first, last;
3070
3071   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3072   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3073   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3074      invariant code motion can move it.  */
3075   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3076   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3077   DONE;
3078 }")
3079
3080 (define_insn_and_split "muldi3"
3081   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3082         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3083                  (match_operand:DI 2 "arith_reg_operand" "r")))
3084    (clobber (match_scratch:DI 3 "=&r"))
3085    (clobber (match_scratch:DI 4 "=r"))]
3086   "TARGET_SHMEDIA"
3087   "#"
3088   "reload_completed"
3089   [(const_int 0)]
3090   "
3091 {
3092   rtx op3_v2si, op2_v2si;
3093
3094   op3_v2si = operands[3];
3095   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3096     {
3097       op3_v2si = XEXP (op3_v2si, 0);
3098       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3099     }
3100   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3101   op2_v2si = operands[2];
3102   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3103     {
3104       op2_v2si = XEXP (op2_v2si, 0);
3105       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3106     }
3107   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3108   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3109   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3110   emit_insn (gen_umulsidi3_media (operands[4],
3111                                  sh_gen_truncate (SImode, operands[1], 0),
3112                                  sh_gen_truncate (SImode, operands[2], 0)));
3113   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3114   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3115   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3116   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3117   DONE;
3118 }")
3119
3120 \f
3121 ;; -------------------------------------------------------------------------
3122 ;; Logical operations
3123 ;; -------------------------------------------------------------------------
3124
3125 (define_insn "*andsi3_compact"
3126   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3127         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3128                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3129   "TARGET_SH1"
3130   "and  %2,%0"
3131   [(set_attr "type" "arith")])
3132
3133 (define_insn "*andsi3_media"
3134   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3135         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3136                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3137   "TARGET_SHMEDIA"
3138   "@
3139         and     %1, %2, %0
3140         andi    %1, %2, %0"
3141   [(set_attr "type" "arith_media")])
3142
3143 ;; If the constant is 255, then emit an extu.b instruction instead of an
3144 ;; and, since that will give better code.
3145
3146 (define_expand "andsi3"
3147   [(set (match_operand:SI 0 "arith_reg_operand" "")
3148         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3149                 (match_operand:SI 2 "logical_operand" "")))]
3150   ""
3151   "
3152 {
3153   if (TARGET_SH1
3154       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3155     {
3156       emit_insn (gen_zero_extendqisi2 (operands[0],
3157                                        gen_lowpart (QImode, operands[1])));
3158       DONE;
3159     }
3160 }")
3161
3162 (define_insn_and_split "anddi3"
3163   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3164         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3165                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3166   "TARGET_SHMEDIA"
3167   "@
3168         and     %1, %2, %0
3169         andi    %1, %2, %0
3170         #"
3171   "reload_completed
3172    && ! logical_operand (operands[2], DImode)"
3173   [(const_int 0)]
3174   "
3175 {
3176   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3177     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3178   else
3179     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3180   DONE;
3181 }"
3182   [(set_attr "type" "arith_media")])
3183
3184 (define_insn "andcsi3"
3185   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3187                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3188   "TARGET_SHMEDIA"
3189   "andc %1,%2,%0"
3190   [(set_attr "type" "arith_media")])
3191
3192 (define_insn "andcdi3"
3193   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3194         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3195                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3196   "TARGET_SHMEDIA"
3197   "andc %1,%2,%0"
3198   [(set_attr "type" "arith_media")])
3199
3200 (define_expand "iorsi3"
3201   [(set (match_operand:SI 0 "arith_reg_operand" "")
3202         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3203                 (match_operand:SI 2 "logical_operand" "")))]
3204   ""
3205   "")
3206
3207 (define_insn "*iorsi3_compact"
3208   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3209         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3210                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3211   "TARGET_SH1"
3212   "or   %2,%0"
3213   [(set_attr "type" "arith")])
3214
3215 (define_insn "*iorsi3_media"
3216   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3217         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3218                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3219   "TARGET_SHMEDIA"
3220   "@
3221         or      %1, %2, %0
3222         ori     %1, %2, %0"
3223   [(set_attr "type" "arith_media")])
3224
3225 (define_insn "iordi3"
3226   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3227         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3228                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3229   "TARGET_SHMEDIA"
3230   "@
3231         or      %1, %2, %0
3232         ori     %1, %2, %0"
3233   [(set_attr "type" "arith_media")])
3234
3235 (define_insn_and_split "*logical_sidi3"
3236   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3237         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3238                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3239                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3240   "TARGET_SHMEDIA"
3241   "#"
3242   "&& reload_completed"
3243   [(set (match_dup 0) (match_dup 3))]
3244   "
3245 {
3246   operands[3]
3247     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3248                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3249                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3250 }")
3251
3252 (define_insn_and_split "*logical_sidisi3"
3253   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3254         (truncate:SI (sign_extend:DI
3255                         (match_operator:SI 3 "logical_operator"
3256                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3257                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3258   "TARGET_SHMEDIA"
3259   "#"
3260   "&& 1"
3261   [(set (match_dup 0) (match_dup 3))])
3262
3263 (define_insn_and_split "*logical_sidi3_2"
3264   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3265         (sign_extend:DI (truncate:SI (sign_extend:DI
3266                         (match_operator:SI 3 "logical_operator"
3267                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3268                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3269   "TARGET_SHMEDIA"
3270   "#"
3271   "&& 1"
3272   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3273
3274 (define_expand "xorsi3"
3275   [(set (match_operand:SI 0 "arith_reg_operand" "")
3276         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3277                 (match_operand:SI 2 "xor_operand" "")))]
3278   ""
3279   "")
3280
3281 (define_insn "*xorsi3_compact"
3282   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3283         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3284                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3285   "TARGET_SH1"
3286   "xor  %2,%0"
3287   [(set_attr "type" "arith")])
3288
3289 (define_insn "*xorsi3_media"
3290   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3291         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3292                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3293   "TARGET_SHMEDIA"
3294   "@
3295         xor     %1, %2, %0
3296         xori    %1, %2, %0"
3297   [(set_attr "type" "arith_media")])
3298
3299 (define_insn "xordi3"
3300   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3301         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3302                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3303   "TARGET_SHMEDIA"
3304   "@
3305         xor     %1, %2, %0
3306         xori    %1, %2, %0"
3307   [(set_attr "type" "arith_media")])
3308
3309 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3310 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3311 (define_split
3312   [(set (match_operand:DI 0 "arith_reg_dest" "")
3313         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3314                           [(match_operand 1 "any_register_operand" "")
3315                            (match_operand 2 "any_register_operand" "")])))]
3316   "TARGET_SHMEDIA"
3317   [(set (match_dup 5) (match_dup 4))
3318    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3319 "
3320 {
3321   enum machine_mode inmode = GET_MODE (operands[1]);
3322   int offset = 0;
3323
3324   if (GET_CODE (operands[0]) == SUBREG)
3325     {
3326       offset = SUBREG_BYTE (operands[0]);
3327       operands[0] = SUBREG_REG (operands[0]);
3328     }
3329   gcc_assert (GET_CODE (operands[0]) == REG);
3330   if (! TARGET_LITTLE_ENDIAN)
3331     offset += 8 - GET_MODE_SIZE (inmode);
3332   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3333 }")
3334 \f
3335 ;; -------------------------------------------------------------------------
3336 ;; Shifts and rotates
3337 ;; -------------------------------------------------------------------------
3338
3339 (define_expand "rotldi3"
3340   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3341         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3342                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3343   "TARGET_SHMEDIA"
3344   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3345
3346 (define_insn "rotldi3_mextr"
3347   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3348         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3349                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3350   "TARGET_SHMEDIA"
3351   "*
3352 {
3353   static char templ[16];
3354
3355   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3356            8 - (int) (INTVAL (operands[2]) >> 3));
3357   return templ;
3358 }"
3359   [(set_attr "type" "arith_media")])
3360
3361 (define_expand "rotrdi3"
3362   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3363         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3364                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3365   "TARGET_SHMEDIA"
3366   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3367
3368 (define_insn "rotrdi3_mextr"
3369   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3370         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3371                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3372   "TARGET_SHMEDIA"
3373   "*
3374 {
3375   static char templ[16];
3376
3377   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3378   return templ;
3379 }"
3380   [(set_attr "type" "arith_media")])
3381
3382 (define_split
3383   [(set (match_operand:DI 0 "arith_reg_dest" "")
3384         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3385                                          "ua_address_operand" "")))
3386                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3387                            (const_int 8))))
3388    (clobber (match_operand:DI 3 "register_operand" ""))]
3389   "TARGET_SHMEDIA"
3390   [(match_dup 4) (match_dup 5)]
3391   "
3392 {
3393   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3394                  (operands[3], operands[1]));
3395   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3396                               GEN_INT (56), GEN_INT (8));
3397 }")
3398
3399 (define_insn "rotlsi3_1"
3400   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3401         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3402                    (const_int 1)))
3403    (set (reg:SI T_REG)
3404         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3405   "TARGET_SH1"
3406   "rotl %0"
3407   [(set_attr "type" "arith")])
3408
3409 (define_insn "rotlsi3_31"
3410   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3411         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3412                    (const_int 31)))
3413    (clobber (reg:SI T_REG))]
3414   "TARGET_SH1"
3415   "rotr %0"
3416   [(set_attr "type" "arith")])
3417
3418 (define_insn "rotlsi3_16"
3419   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3420         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3421                    (const_int 16)))]
3422   "TARGET_SH1"
3423   "swap.w       %1,%0"
3424   [(set_attr "type" "arith")])
3425
3426 (define_expand "rotlsi3"
3427   [(set (match_operand:SI 0 "arith_reg_dest" "")
3428         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3429                    (match_operand:SI 2 "immediate_operand" "")))]
3430   "TARGET_SH1"
3431   "
3432 {
3433   static const char rot_tab[] = {
3434     000, 000, 000, 000, 000, 000, 010, 001,
3435     001, 001, 011, 013, 003, 003, 003, 003,
3436     003, 003, 003, 003, 003, 013, 012, 002,
3437     002, 002, 010, 000, 000, 000, 000, 000,
3438   };
3439
3440   int count, choice;
3441
3442   if (GET_CODE (operands[2]) != CONST_INT)
3443     FAIL;
3444   count = INTVAL (operands[2]);
3445   choice = rot_tab[count];
3446   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3447     FAIL;
3448   choice &= 7;
3449   switch (choice)
3450     {
3451     case 0:
3452       emit_move_insn (operands[0], operands[1]);
3453       count -= (count & 16) * 2;
3454       break;
3455     case 3:
3456      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3457      count -= 16;
3458      break;
3459     case 1:
3460     case 2:
3461       {
3462         rtx parts[2];
3463         parts[0] = gen_reg_rtx (SImode);
3464         parts[1] = gen_reg_rtx (SImode);
3465         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3466         emit_move_insn (parts[choice-1], operands[1]);
3467         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3468         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3469         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3470         count = (count & ~16) - 8;
3471       }
3472     }
3473
3474   for (; count > 0; count--)
3475     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3476   for (; count < 0; count++)
3477     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3478
3479   DONE;
3480 }")
3481
3482 (define_insn "*rotlhi3_8"
3483   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3485                    (const_int 8)))]
3486   "TARGET_SH1"
3487   "swap.b       %1,%0"
3488   [(set_attr "type" "arith")])
3489
3490 (define_expand "rotlhi3"
3491   [(set (match_operand:HI 0 "arith_reg_operand" "")
3492         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3493                    (match_operand:HI 2 "immediate_operand" "")))]
3494   "TARGET_SH1"
3495   "
3496 {
3497   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3498     FAIL;
3499 }")
3500
3501 ;;
3502 ;; shift left
3503
3504 (define_insn "ashlsi3_sh2a"
3505   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3506         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3507                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3508   "TARGET_SH2A"
3509   "shad %2,%0"
3510   [(set_attr "type" "arith")
3511    (set_attr "length" "4")])
3512
3513 ;; This pattern is used by init_expmed for computing the costs of shift
3514 ;; insns.
3515
3516 (define_insn_and_split "ashlsi3_std"
3517   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3518         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3519                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3520    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3521   "TARGET_SH3
3522    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3523        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3524   "@
3525    shld %2,%0
3526    add  %0,%0
3527    shll%O2      %0
3528    #"
3529   "TARGET_SH3
3530    && reload_completed
3531    && GET_CODE (operands[2]) == CONST_INT
3532    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3533   [(set (match_dup 3) (match_dup 2))
3534    (parallel
3535     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3536      (clobber (match_dup 4))])]
3537   "operands[4] = gen_rtx_SCRATCH (SImode);"
3538   [(set_attr "length" "*,*,*,4")
3539    (set_attr "type" "dyn_shift,arith,arith,arith")])
3540
3541 (define_insn "ashlhi3_k"
3542   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3543         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3544                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3545   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3546   "@
3547         add     %0,%0
3548         shll%O2 %0"
3549   [(set_attr "type" "arith")])
3550
3551 (define_insn "ashlsi3_n"
3552   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3553         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3554                    (match_operand:SI 2 "const_int_operand" "n")))
3555    (clobber (reg:SI T_REG))]
3556   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3557   "#"
3558   [(set (attr "length")
3559         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3560                (const_string "2")
3561                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3562                (const_string "4")
3563                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3564                (const_string "6")]
3565               (const_string "8")))
3566    (set_attr "type" "arith")])
3567
3568 (define_split
3569   [(set (match_operand:SI 0 "arith_reg_dest" "")
3570         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3571                    (match_operand:SI 2 "const_int_operand" "")))
3572    (clobber (reg:SI T_REG))]
3573   "TARGET_SH1 && reload_completed"
3574   [(use (reg:SI R0_REG))]
3575   "
3576 {
3577   gen_shifty_op (ASHIFT, operands);
3578   DONE;
3579 }")
3580
3581 (define_insn "ashlsi3_media"
3582   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3583         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3584                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3585   "TARGET_SHMEDIA"
3586   "@
3587         shlld.l %1, %2, %0
3588         shlli.l %1, %2, %0"
3589   [(set_attr "type" "arith_media")
3590    (set_attr "highpart" "ignore")])
3591
3592 (define_expand "ashlsi3"
3593   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3594                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3595                               (match_operand:SI 2 "nonmemory_operand" "")))
3596               (clobber (reg:SI T_REG))])]
3597   ""
3598   "
3599 {
3600   if (TARGET_SHMEDIA)
3601     {
3602       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3603       DONE;
3604     }
3605   if (GET_CODE (operands[2]) == CONST_INT
3606       && sh_dynamicalize_shift_p (operands[2]))
3607     operands[2] = force_reg (SImode, operands[2]);
3608   if (TARGET_SH3)
3609     {
3610       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3611       DONE;
3612     }
3613   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3614     FAIL;
3615 }")
3616
3617 (define_insn "*ashlhi3_n"
3618   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3619         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3620                    (match_operand:HI 2 "const_int_operand" "n")))
3621    (clobber (reg:SI T_REG))]
3622   "TARGET_SH1"
3623   "#"
3624   [(set (attr "length")
3625         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3626                (const_string "2")
3627                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3628                (const_string "4")]
3629               (const_string "6")))
3630    (set_attr "type" "arith")])
3631
3632 (define_expand "ashlhi3"
3633   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3634                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3635                               (match_operand:SI 2 "nonmemory_operand" "")))
3636               (clobber (reg:SI T_REG))])]
3637   "TARGET_SH1"
3638   "
3639 {
3640   if (GET_CODE (operands[2]) != CONST_INT)
3641     FAIL;
3642   /* It may be possible to call gen_ashlhi3 directly with more generic
3643      operands.  Make sure operands[1] is a HImode register here.  */
3644   if (!arith_reg_operand (operands[1], HImode))
3645     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3646 }")
3647
3648 (define_split
3649   [(set (match_operand:HI 0 "arith_reg_dest" "")
3650         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3651                    (match_operand:HI 2 "const_int_operand" "")))
3652    (clobber (reg:SI T_REG))]
3653   "TARGET_SH1 && reload_completed"
3654   [(use (reg:SI R0_REG))]
3655   "
3656 {
3657   gen_shifty_hi_op (ASHIFT, operands);
3658   DONE;
3659 }")
3660
3661 ;
3662 ; arithmetic shift right
3663 ;
3664
3665 (define_insn "ashrsi3_sh2a"
3666   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3667         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3668                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3669   "TARGET_SH2A"
3670   "shad %2,%0"
3671   [(set_attr "type" "dyn_shift")
3672    (set_attr "length" "4")])
3673
3674 (define_insn "ashrsi3_k"
3675   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3676         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3677                      (match_operand:SI 2 "const_int_operand" "M")))
3678    (clobber (reg:SI T_REG))]
3679   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3680   "shar %0"
3681   [(set_attr "type" "arith")])
3682
3683 ;; We can't do HImode right shifts correctly unless we start out with an
3684 ;; explicit zero / sign extension; doing that would result in worse overall
3685 ;; code, so just let the machine independent code widen the mode.
3686 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3687
3688
3689 ;; ??? This should be a define expand.
3690
3691 (define_insn "ashrsi2_16"
3692   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3693         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3694                      (const_int 16)))]
3695   "TARGET_SH1"
3696   "#"
3697   [(set_attr "length" "4")])
3698
3699 (define_split
3700   [(set (match_operand:SI 0 "arith_reg_dest" "")
3701         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3702                      (const_int 16)))]
3703   "TARGET_SH1"
3704   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3705    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3706   "operands[2] = gen_lowpart (HImode, operands[0]);")
3707
3708 ;; ??? This should be a define expand.
3709
3710 (define_insn "ashrsi2_31"
3711   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3712         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3713                      (const_int 31)))
3714    (clobber (reg:SI T_REG))]
3715   "TARGET_SH1"
3716   "#"
3717   [(set_attr "length" "4")])
3718
3719 (define_split
3720   [(set (match_operand:SI 0 "arith_reg_dest" "")
3721         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3722                      (const_int 31)))
3723    (clobber (reg:SI T_REG))]
3724   "TARGET_SH1"
3725   [(const_int 0)]
3726   "
3727 {
3728   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3729   emit_insn (gen_mov_neg_si_t (operands[0]));
3730   DONE;
3731 }")
3732
3733 (define_peephole2
3734   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3735    (set (reg:SI T_REG)
3736         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3737   "TARGET_SH1
3738    && peep2_reg_dead_p (2, operands[0])
3739    && peep2_reg_dead_p (2, operands[1])"
3740   [(const_int 0)]
3741   "
3742 {
3743   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3744   DONE;
3745 }")
3746
3747 (define_insn "ashlsi_c"
3748   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3749         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3750    (set (reg:SI T_REG)
3751         (lt:SI (match_dup 1) (const_int 0)))]
3752   "TARGET_SH1"
3753   "shll %0"
3754   [(set_attr "type" "arith")])
3755
3756 (define_insn "*ashlsi_c_void"
3757   [(set (reg:SI T_REG)
3758         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3759    (clobber (match_scratch:SI 1 "=0"))]
3760   "TARGET_SH1 && cse_not_expected"
3761   "shll %0"
3762   [(set_attr "type" "arith")])
3763
3764 (define_insn "ashrsi3_d"
3765   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3768   "TARGET_SH3"
3769   "shad %2,%0"
3770   [(set_attr "type" "dyn_shift")])
3771
3772 (define_insn "ashrsi3_n"
3773   [(set (reg:SI R4_REG)
3774         (ashiftrt:SI (reg:SI R4_REG)
3775                      (match_operand:SI 0 "const_int_operand" "i")))
3776    (clobber (reg:SI T_REG))
3777    (clobber (reg:SI PR_REG))
3778    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3779   "TARGET_SH1"
3780   "jsr  @%1%#"
3781   [(set_attr "type" "sfunc")
3782    (set_attr "needs_delay_slot" "yes")])
3783
3784 (define_insn "ashrsi3_media"
3785   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3786         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3787                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3788   "TARGET_SHMEDIA"
3789   "@
3790         shard.l %1, %2, %0
3791         shari.l %1, %2, %0"
3792   [(set_attr "type" "arith_media")
3793    (set_attr "highpart" "ignore")])
3794
3795 (define_expand "ashrsi3"
3796   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3797                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3798                                 (match_operand:SI 2 "nonmemory_operand" "")))
3799               (clobber (reg:SI T_REG))])]
3800   ""
3801   "
3802 {
3803   if (TARGET_SHMEDIA)
3804     {
3805       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3806       DONE;
3807     }
3808   if (expand_ashiftrt (operands))
3809     DONE;
3810   else
3811     FAIL;
3812 }")
3813
3814 ;; logical shift right
3815
3816 (define_insn "lshrsi3_sh2a"
3817   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3818         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3819                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3820   "TARGET_SH2A"
3821   "shld %2,%0"
3822   [(set_attr "type" "dyn_shift")
3823    (set_attr "length" "4")])
3824
3825 (define_insn "lshrsi3_d"
3826   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3827         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3828                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3829   "TARGET_SH3"
3830   "shld %2,%0"
3831   [(set_attr "type" "dyn_shift")])
3832
3833 ;;  Only the single bit shift clobbers the T bit.
3834
3835 (define_insn "lshrsi3_m"
3836   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3837         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3838                      (match_operand:SI 2 "const_int_operand" "M")))
3839    (clobber (reg:SI T_REG))]
3840   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3841   "shlr %0"
3842   [(set_attr "type" "arith")])
3843
3844 (define_insn "lshrsi3_k"
3845   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3846         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3847                      (match_operand:SI 2 "const_int_operand" "P27")))]
3848   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3849    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3850   "shlr%O2      %0"
3851   [(set_attr "type" "arith")])
3852
3853 (define_insn "lshrsi3_n"
3854   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3855         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3856                      (match_operand:SI 2 "const_int_operand" "n")))
3857    (clobber (reg:SI T_REG))]
3858   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3859   "#"
3860   [(set (attr "length")
3861         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3862                (const_string "2")
3863                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3864                (const_string "4")
3865                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3866                (const_string "6")]
3867               (const_string "8")))
3868    (set_attr "type" "arith")])
3869
3870 (define_split
3871   [(set (match_operand:SI 0 "arith_reg_dest" "")
3872         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3873                      (match_operand:SI 2 "const_int_operand" "")))
3874    (clobber (reg:SI T_REG))]
3875   "TARGET_SH1 && reload_completed"
3876   [(use (reg:SI R0_REG))]
3877   "
3878 {
3879   gen_shifty_op (LSHIFTRT, operands);
3880   DONE;
3881 }")
3882
3883 (define_insn "lshrsi3_media"
3884   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3885         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3886                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3887   "TARGET_SHMEDIA"
3888   "@
3889         shlrd.l %1, %2, %0
3890         shlri.l %1, %2, %0"
3891   [(set_attr "type" "arith_media")
3892    (set_attr "highpart" "ignore")])
3893
3894 (define_expand "lshrsi3"
3895   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3896                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3897                                 (match_operand:SI 2 "nonmemory_operand" "")))
3898               (clobber (reg:SI T_REG))])]
3899   ""
3900   "
3901 {
3902   if (TARGET_SHMEDIA)
3903     {
3904       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3905       DONE;
3906     }
3907   if (GET_CODE (operands[2]) == CONST_INT
3908       && sh_dynamicalize_shift_p (operands[2]))
3909     operands[2] = force_reg (SImode, operands[2]);
3910   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3911     {
3912       rtx count = copy_to_mode_reg (SImode, operands[2]);
3913       emit_insn (gen_negsi2 (count, count));
3914       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3915       DONE;
3916     }
3917   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3918     FAIL;
3919 }")
3920
3921 ;; ??? This should be a define expand.
3922
3923 (define_insn "ashldi3_k"
3924   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3925         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3926                    (const_int 1)))
3927    (clobber (reg:SI T_REG))]
3928   "TARGET_SH1"
3929   "shll %R0\;rotcl      %S0"
3930   [(set_attr "length" "4")
3931    (set_attr "type" "arith")])
3932
3933 (define_insn "ashldi3_media"
3934   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3935         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3936                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3937   "TARGET_SHMEDIA"
3938   "@
3939         shlld   %1, %2, %0
3940         shlli   %1, %2, %0"
3941   [(set_attr "type" "arith_media")])
3942
3943 (define_insn "*ashldisi3_media"
3944   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3945         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3946                    (match_operand:DI 2 "const_int_operand" "n")))]
3947   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3948   "shlli.l      %1, %2, %0"
3949   [(set_attr "type" "arith_media")
3950    (set_attr "highpart" "ignore")])
3951
3952 (define_expand "ashldi3"
3953   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3954                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3955                               (match_operand:DI 2 "immediate_operand" "")))
3956               (clobber (reg:SI T_REG))])]
3957   ""
3958   "
3959 {
3960   if (TARGET_SHMEDIA)
3961     {
3962       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3963       DONE;
3964     }
3965   if (GET_CODE (operands[2]) != CONST_INT
3966       || INTVAL (operands[2]) != 1)
3967     FAIL;
3968 }")
3969
3970 ;; ??? This should be a define expand.
3971
3972 (define_insn "lshrdi3_k"
3973   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3974         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3975                      (const_int 1)))
3976    (clobber (reg:SI T_REG))]
3977   "TARGET_SH1"
3978   "shlr %S0\;rotcr      %R0"
3979   [(set_attr "length" "4")
3980    (set_attr "type" "arith")])
3981
3982 (define_insn "lshrdi3_media"
3983   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3984         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3985                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3986   "TARGET_SHMEDIA
3987    && (arith_reg_dest (operands[0], DImode)
3988        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3989   "@
3990         shlrd   %1, %2, %0
3991         shlri   %1, %2, %0"
3992   [(set_attr "type" "arith_media")])
3993
3994 (define_insn "*lshrdisi3_media"
3995   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3996         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3997                      (match_operand:DI 2 "const_int_operand" "n")))]
3998   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3999   "shlri.l      %1, %2, %0"
4000   [(set_attr "type" "arith_media")
4001    (set_attr "highpart" "ignore")])
4002
4003 (define_expand "lshrdi3"
4004   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4005                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4006                                (match_operand:DI 2 "immediate_operand" "")))
4007              (clobber (reg:SI T_REG))])]
4008   ""
4009   "
4010 {
4011   if (TARGET_SHMEDIA)
4012     {
4013       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4014       DONE;
4015     }
4016   if (GET_CODE (operands[2]) != CONST_INT
4017       || INTVAL (operands[2]) != 1)
4018     FAIL;
4019 }")
4020
4021 ;; ??? This should be a define expand.
4022
4023 (define_insn "ashrdi3_k"
4024   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4025         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4026                      (const_int 1)))
4027    (clobber (reg:SI T_REG))]
4028   "TARGET_SH1"
4029   "shar %S0\;rotcr      %R0"
4030   [(set_attr "length" "4")
4031    (set_attr "type" "arith")])
4032
4033 (define_insn "ashrdi3_media"
4034   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4035         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4036                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4037   "TARGET_SHMEDIA
4038    && (arith_reg_dest (operands[0], DImode)
4039        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4040   "@
4041         shard   %1, %2, %0
4042         shari   %1, %2, %0"
4043   [(set_attr "type" "arith_media")])
4044
4045 (define_insn "*ashrdisi3_media"
4046   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4047         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4048                      (match_operand:DI 2 "const_int_operand" "n")))]
4049   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4050   "shari.l      %1, %2, %0"
4051   [(set_attr "type" "arith_media")
4052    (set_attr "highpart" "ignore")])
4053
4054 (define_insn "ashrdisi3_media_high"
4055   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4056         (truncate:SI
4057            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4058                         (match_operand:DI 2 "const_int_operand" "n"))))]
4059   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4060   "shari        %1, %2, %0"
4061   [(set_attr "type" "arith_media")])
4062
4063 (define_insn "ashrdisi3_media_opaque"
4064   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4065         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4066                     (match_operand:DI 2 "const_int_operand" "n")]
4067          UNSPEC_ASHIFTRT))]
4068   "TARGET_SHMEDIA"
4069   "shari        %1, %2, %0"
4070   [(set_attr "type" "arith_media")])
4071
4072 (define_expand "ashrdi3"
4073   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4074                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4075                                 (match_operand:DI 2 "immediate_operand" "")))
4076               (clobber (reg:SI T_REG))])]
4077   ""
4078   "
4079 {
4080   if (TARGET_SHMEDIA)
4081     {
4082       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4083       DONE;
4084     }
4085   if (GET_CODE (operands[2]) != CONST_INT
4086       || INTVAL (operands[2]) != 1)
4087     FAIL;
4088 }")
4089
4090 ;; combined left/right shift
4091
4092 (define_split
4093   [(set (match_operand:SI 0 "register_operand" "")
4094         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4095                            (match_operand:SI 2 "const_int_operand" ""))
4096                 (match_operand:SI 3 "const_int_operand" "")))]
4097   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4098   [(use (reg:SI R0_REG))]
4099   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4100    DONE;")
4101
4102 (define_split
4103   [(set (match_operand:SI 0 "register_operand" "")
4104         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4105                            (match_operand:SI 2 "const_int_operand" ""))
4106                 (match_operand:SI 3 "const_int_operand" "")))
4107    (clobber (reg:SI T_REG))]
4108   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4109   [(use (reg:SI R0_REG))]
4110   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4111    DONE;")
4112
4113 (define_insn ""
4114   [(set (match_operand:SI 0 "register_operand" "=r")
4115         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4116                            (match_operand:SI 2 "const_int_operand" "n"))
4117                 (match_operand:SI 3 "const_int_operand" "n")))
4118    (clobber (reg:SI T_REG))]
4119   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4120  "#"
4121   [(set (attr "length")
4122         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4123                (const_string "4")
4124                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4125                (const_string "6")
4126                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4127                (const_string "8")
4128                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4129                (const_string "10")
4130                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4131                (const_string "12")
4132                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4133                (const_string "14")
4134                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4135                (const_string "16")]
4136               (const_string "18")))
4137    (set_attr "type" "arith")])
4138
4139 (define_insn ""
4140   [(set (match_operand:SI 0 "register_operand" "=z")
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) == 2"
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               (const_string "10")))
4155    (set_attr "type" "arith")])
4156
4157 ;; shift left / and combination with a scratch register: The combine pass
4158 ;; does not accept the individual instructions, even though they are
4159 ;; cheap.  But it needs a precise description so that it is usable after
4160 ;; reload.
4161 (define_insn "and_shl_scratch"
4162   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4163         (lshiftrt:SI
4164          (ashift:SI
4165           (and:SI
4166            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4167                         (match_operand:SI 2 "const_int_operand" "N,n"))
4168            (match_operand:SI 3 "" "0,r"))
4169           (match_operand:SI 4 "const_int_operand" "n,n"))
4170          (match_operand:SI 5 "const_int_operand" "n,n")))
4171    (clobber (reg:SI T_REG))]
4172   "TARGET_SH1"
4173   "#"
4174   [(set (attr "length")
4175         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4176                (const_string "4")
4177                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4178                (const_string "6")
4179                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4180                (const_string "8")
4181                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4182                (const_string "10")]
4183               (const_string "12")))
4184    (set_attr "type" "arith")])
4185
4186 (define_split
4187   [(set (match_operand:SI 0 "register_operand" "")
4188         (lshiftrt:SI
4189          (ashift:SI
4190           (and:SI
4191            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4192                         (match_operand:SI 2 "const_int_operand" ""))
4193            (match_operand:SI 3 "register_operand" ""))
4194           (match_operand:SI 4 "const_int_operand" ""))
4195          (match_operand:SI 5 "const_int_operand" "")))
4196    (clobber (reg:SI T_REG))]
4197   "TARGET_SH1"
4198   [(use (reg:SI R0_REG))]
4199   "
4200 {
4201   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4202
4203   if (INTVAL (operands[2]))
4204     {
4205       gen_shifty_op (LSHIFTRT, operands);
4206     }
4207   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4208   operands[2] = operands[4];
4209   gen_shifty_op (ASHIFT, operands);
4210   if (INTVAL (operands[5]))
4211     {
4212       operands[2] = operands[5];
4213       gen_shifty_op (LSHIFTRT, operands);
4214     }
4215   DONE;
4216 }")
4217
4218 ;; signed left/right shift combination.
4219 (define_split
4220   [(set (match_operand:SI 0 "register_operand" "")
4221         (sign_extract:SI
4222          (ashift:SI (match_operand:SI 1 "register_operand" "")
4223                     (match_operand:SI 2 "const_int_operand" ""))
4224          (match_operand:SI 3 "const_int_operand" "")
4225          (const_int 0)))
4226    (clobber (reg:SI T_REG))]
4227   "TARGET_SH1"
4228   [(use (reg:SI R0_REG))]
4229   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4230    DONE;")
4231
4232 (define_insn "shl_sext_ext"
4233   [(set (match_operand:SI 0 "register_operand" "=r")
4234         (sign_extract:SI
4235          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4236                     (match_operand:SI 2 "const_int_operand" "n"))
4237          (match_operand:SI 3 "const_int_operand" "n")
4238          (const_int 0)))
4239    (clobber (reg:SI T_REG))]
4240   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4241   "#"
4242   [(set (attr "length")
4243         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4244                (const_string "2")
4245                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4246                (const_string "4")
4247                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4248                (const_string "6")
4249                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4250                (const_string "8")
4251                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4252                (const_string "10")
4253                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4254                (const_string "12")
4255                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4256                (const_string "14")
4257                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4258                (const_string "16")]
4259               (const_string "18")))
4260     (set_attr "type" "arith")])
4261
4262 (define_insn "shl_sext_sub"
4263   [(set (match_operand:SI 0 "register_operand" "=z")
4264         (sign_extract:SI
4265          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4266                     (match_operand:SI 2 "const_int_operand" "n"))
4267          (match_operand:SI 3 "const_int_operand" "n")
4268          (const_int 0)))
4269    (clobber (reg:SI T_REG))]
4270   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4271   "#"
4272   [(set (attr "length")
4273         (cond [(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               (const_string "14")))
4282     (set_attr "type" "arith")])
4283
4284 ;; These patterns are found in expansions of DImode shifts by 16, and
4285 ;; allow the xtrct instruction to be generated from C source.
4286
4287 (define_insn "xtrct_left"
4288   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4289         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4290                            (const_int 16))
4291                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4292                              (const_int 16))))]
4293   "TARGET_SH1"
4294   "xtrct        %1,%0"
4295   [(set_attr "type" "arith")])
4296
4297 (define_insn "xtrct_right"
4298   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4299         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4300                              (const_int 16))
4301                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4302                            (const_int 16))))]
4303   "TARGET_SH1"
4304   "xtrct        %2,%0"
4305   [(set_attr "type" "arith")])
4306
4307 ;; -------------------------------------------------------------------------
4308 ;; Unary arithmetic
4309 ;; -------------------------------------------------------------------------
4310
4311 (define_insn "negc"
4312   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4313         (neg:SI (plus:SI (reg:SI T_REG)
4314                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4315    (set (reg:SI T_REG)
4316         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4317                (const_int 0)))]
4318   "TARGET_SH1"
4319   "negc %1,%0"
4320   [(set_attr "type" "arith")])
4321
4322 (define_insn "*negdi_media"
4323   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4324         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4325   "TARGET_SHMEDIA"
4326   "sub  r63, %1, %0"
4327   [(set_attr "type" "arith_media")])
4328
4329 (define_expand "negdi2"
4330   [(set (match_operand:DI 0 "arith_reg_operand" "")
4331         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4332   ""
4333   "
4334 {
4335   if (TARGET_SH1)
4336     {
4337       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4338       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4339
4340       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4341       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4342
4343       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4344       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4345
4346       emit_insn (gen_clrt ());
4347       emit_insn (gen_negc (low_dst, low_src));
4348       emit_insn (gen_negc (high_dst, high_src));
4349       DONE;
4350     }
4351 }")
4352
4353 (define_insn "negsi2"
4354   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4355         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4356   "TARGET_SH1"
4357   "neg  %1,%0"
4358   [(set_attr "type" "arith")])
4359
4360 (define_insn "one_cmplsi2"
4361   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4362         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4363   "TARGET_SH1"
4364   "not  %1,%0"
4365   [(set_attr "type" "arith")])
4366
4367 (define_expand "one_cmpldi2"
4368   [(set (match_operand:DI 0 "arith_reg_dest" "")
4369         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4370                 (const_int -1)))]
4371   "TARGET_SHMEDIA" "")
4372
4373 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4374    This can be used as some kind of conditional execution, which is useful
4375    for abs.  */
4376 (define_split
4377   [(set (match_operand:SI 0 "arith_reg_dest" "")
4378         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4379                          (match_operand:SI 1 "arith_reg_operand" ""))
4380                  (reg:SI T_REG)))]
4381   "TARGET_HARD_SH4"
4382   [(const_int 0)]
4383   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4384    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4385    DONE;")
4386
4387 (define_insn "cneg"
4388   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4389         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4390                       (match_operand:SI 1 "arith_reg_operand" "0")
4391                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4392   "TARGET_HARD_SH4"
4393   "bf 0f\;neg %2,%0\\n0:"
4394   [(set_attr "type" "arith") ;; poor approximation
4395    (set_attr "length" "4")])
4396
4397 \f
4398 ;; -------------------------------------------------------------------------
4399 ;; Zero extension instructions
4400 ;; -------------------------------------------------------------------------
4401
4402 (define_insn "zero_extendsidi2"
4403   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4404         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4405   "TARGET_SHMEDIA"
4406   "addz.l       %1, r63, %0"
4407   [(set_attr "type" "arith_media")
4408    (set_attr "highpart" "extend")])
4409
4410 (define_insn "zero_extendhidi2"
4411   [(set (match_operand:DI 0 "register_operand" "=r,r")
4412         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4413   "TARGET_SHMEDIA"
4414   "@
4415         #
4416         ld%M1.uw        %m1, %0"
4417   [(set_attr "type" "*,load_media")
4418    (set (attr "highpart")
4419         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4420                (const_string "user")]
4421               (const_string "ignore")))])
4422
4423 (define_split
4424   [(set (match_operand:DI 0 "register_operand" "")
4425         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4426   "TARGET_SHMEDIA && reload_completed"
4427   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4428    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4429   "
4430 {
4431   if (GET_CODE (operands[1]) == TRUNCATE)
4432     operands[1] = XEXP (operands[1], 0);
4433 }")
4434
4435 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4436 ;; reload the entire truncate expression.
4437 (define_insn_and_split "*loaddi_trunc"
4438   [(set (match_operand 0 "any_register_operand" "=r")
4439         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4440   "TARGET_SHMEDIA && reload_completed"
4441   "#"
4442   "TARGET_SHMEDIA && reload_completed"
4443   [(set (match_dup 0) (match_dup 1))]
4444   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4445
4446 (define_insn "zero_extendqidi2"
4447   [(set (match_operand:DI 0 "register_operand" "=r,r")
4448         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4449   "TARGET_SHMEDIA"
4450   "@
4451         andi    %1, 255, %0
4452         ld%M1.ub        %m1, %0"
4453   [(set_attr "type" "arith_media,load_media")
4454    (set (attr "highpart")
4455         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4456                (const_string "user")]
4457               (const_string "ignore")))])
4458
4459 (define_expand "zero_extendhisi2"
4460   [(set (match_operand:SI 0 "arith_reg_operand" "")
4461         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4462   ""
4463   "
4464 {
4465   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4466     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4467 }")
4468
4469 (define_insn "*zero_extendhisi2_compact"
4470   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4471         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4472   "TARGET_SH1"
4473   "extu.w       %1,%0"
4474   [(set_attr "type" "arith")])
4475
4476 (define_insn "*zero_extendhisi2_media"
4477   [(set (match_operand:SI 0 "register_operand" "=r,r")
4478         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4479   "TARGET_SHMEDIA"
4480   "@
4481         #
4482         ld%M1.uw        %m1, %0"
4483   [(set_attr "type" "arith_media,load_media")
4484    (set (attr "highpart")
4485         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4486                (const_string "user")]
4487               (const_string "ignore")))])
4488
4489 (define_split
4490   [(set (match_operand:SI 0 "register_operand" "")
4491         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4492   "TARGET_SHMEDIA && reload_completed"
4493   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4494    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4495   "
4496 {
4497   rtx op1 = operands[1];
4498
4499   if (GET_CODE (op1) == TRUNCATE)
4500     op1 = XEXP (op1, 0);
4501   operands[2]
4502     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4503                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4504 }")
4505
4506 (define_expand "zero_extendqisi2"
4507   [(set (match_operand:SI 0 "arith_reg_operand" "")
4508         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4509   ""
4510   "
4511 {
4512   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4513     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4514 }")
4515
4516 (define_insn "*zero_extendqisi2_compact"
4517   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4518         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4519   "TARGET_SH1"
4520   "extu.b       %1,%0"
4521   [(set_attr "type" "arith")])
4522
4523 (define_insn "*zero_extendqisi2_media"
4524   [(set (match_operand:SI 0 "register_operand" "=r,r")
4525         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4526   "TARGET_SHMEDIA"
4527   "@
4528         andi    %1, 255, %0
4529         ld%M1.ub        %m1, %0"
4530   [(set_attr "type" "arith_media,load_media")
4531    (set (attr "highpart")
4532         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4533                (const_string "user")]
4534               (const_string "ignore")))])
4535
4536 (define_insn "zero_extendqihi2"
4537   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4538         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4539   "TARGET_SH1"
4540   "extu.b       %1,%0"
4541   [(set_attr "type" "arith")])
4542
4543 ;; -------------------------------------------------------------------------
4544 ;; Sign extension instructions
4545 ;; -------------------------------------------------------------------------
4546
4547 ;; ??? This should be a define expand.
4548 ;; ??? Or perhaps it should be dropped?
4549
4550 ;; convert_move generates good code for SH[1-4].
4551 (define_insn "extendsidi2"
4552   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4553         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4554   "TARGET_SHMEDIA"
4555   "@
4556         add.l   %1, r63, %0
4557         ld%M1.l %m1, %0
4558         fmov.sl %1, %0"
4559   [(set_attr "type" "arith_media,load_media,fpconv_media")
4560    (set (attr "highpart")
4561         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4562                (const_string "user")]
4563               (const_string "extend")))])
4564
4565 (define_insn "extendhidi2"
4566   [(set (match_operand:DI 0 "register_operand" "=r,r")
4567         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4568   "TARGET_SHMEDIA"
4569   "@
4570         #
4571         ld%M1.w %m1, %0"
4572   [(set_attr "type" "*,load_media")
4573    (set (attr "highpart")
4574         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4575                (const_string "user")]
4576               (const_string "ignore")))])
4577
4578 (define_split
4579   [(set (match_operand:DI 0 "register_operand" "")
4580         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4581   "TARGET_SHMEDIA && reload_completed"
4582   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4583    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4584   "
4585 {
4586   if (GET_CODE (operands[1]) == TRUNCATE)
4587     operands[1] = XEXP (operands[1], 0);
4588 }")
4589
4590 (define_insn "extendqidi2"
4591   [(set (match_operand:DI 0 "register_operand" "=r,r")
4592         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4593   "TARGET_SHMEDIA"
4594   "@
4595         #
4596         ld%M1.b %m1, %0"
4597   [(set_attr "type" "*,load_media")
4598    (set (attr "highpart")
4599         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600                (const_string "user")]
4601               (const_string "ignore")))])
4602
4603 (define_split
4604   [(set (match_operand:DI 0 "register_operand" "")
4605         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4606   "TARGET_SHMEDIA && reload_completed"
4607   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4608    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4609   "
4610 {
4611   if (GET_CODE (operands[1]) == TRUNCATE)
4612     operands[1] = XEXP (operands[1], 0);
4613 }")
4614
4615 (define_expand "extendhisi2"
4616   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4617         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4618   ""
4619   "")
4620
4621 (define_insn "*extendhisi2_compact"
4622   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4623         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4624   "TARGET_SH1"
4625   "@
4626         exts.w  %1,%0
4627         mov.w   %1,%0"
4628   [(set_attr "type" "arith,load")])
4629
4630 (define_insn "*extendhisi2_media"
4631   [(set (match_operand:SI 0 "register_operand" "=r,r")
4632         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4633   "TARGET_SHMEDIA"
4634   "@
4635         #
4636         ld%M1.w %m1, %0"
4637   [(set_attr "type" "arith_media,load_media")
4638    (set (attr "highpart")
4639         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4640                (const_string "user")]
4641               (const_string "ignore")))])
4642
4643 (define_split
4644   [(set (match_operand:SI 0 "register_operand" "")
4645         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4646   "TARGET_SHMEDIA && reload_completed"
4647   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4648    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4649   "
4650 {
4651   rtx op1 = operands[1];
4652   if (GET_CODE (op1) == TRUNCATE)
4653     op1 = XEXP (op1, 0);
4654   operands[2]
4655     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4656                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4657 }")
4658
4659 (define_expand "extendqisi2"
4660   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4661         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4662   ""
4663   "")
4664
4665 (define_insn "*extendqisi2_compact"
4666   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4667         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4668   "TARGET_SH1"
4669   "@
4670         exts.b  %1,%0
4671         mov.b   %1,%0"
4672   [(set_attr "type" "arith,load")])
4673
4674 (define_insn "*extendqisi2_media"
4675   [(set (match_operand:SI 0 "register_operand" "=r,r")
4676         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4677   "TARGET_SHMEDIA"
4678   "@
4679         #
4680         ld%M1.b %m1, %0"
4681   [(set_attr "type" "arith_media,load_media")
4682    (set (attr "highpart")
4683         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4684                (const_string "user")]
4685               (const_string "ignore")))])
4686
4687 (define_split
4688   [(set (match_operand:SI 0 "register_operand" "")
4689         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4690   "TARGET_SHMEDIA && reload_completed"
4691   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4692    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4693    "
4694 {
4695   rtx op1 = operands[1];
4696   if (GET_CODE (op1) == TRUNCATE)
4697     op1 = XEXP (op1, 0);
4698   operands[2]
4699     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4700                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4701 }")
4702
4703 (define_insn "extendqihi2"
4704   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4705         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4706   "TARGET_SH1"
4707   "@
4708         exts.b  %1,%0
4709         mov.b   %1,%0"
4710   [(set_attr "type" "arith,load")])
4711
4712 /* It would seem useful to combine the truncXi patterns into the movXi
4713    patterns, but unary operators are ignored when matching constraints,
4714    so we need separate patterns.  */
4715 (define_insn "truncdisi2"
4716   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4717         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4718   "TARGET_SHMEDIA"
4719   "@
4720         add.l   %1, r63, %0
4721         st%M0.l %m0, %1
4722         fst%M0.s        %m0, %T1
4723         fmov.ls %1, %0
4724         fmov.sl %T1, %0
4725         fmov.s  %T1, %0"
4726   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4727    (set (attr "highpart")
4728         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4729                (const_string "user")]
4730               (const_string "extend")))])
4731
4732 (define_insn "truncdihi2"
4733   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4734         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4735   "TARGET_SHMEDIA"
4736   "@
4737         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4738         st%M0.w %m0, %1"
4739   [(set_attr "type"   "arith_media,store_media")
4740    (set_attr "length" "8,4")
4741    (set (attr "highpart")
4742         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4743                (const_string "user")]
4744               (const_string "extend")))])
4745
4746 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4747 ; Because we use zero extension, we can't provide signed QImode compares
4748 ; using a simple compare or conditional banch insn.
4749 (define_insn "truncdiqi2"
4750   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4751         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4752   "TARGET_SHMEDIA"
4753   "@
4754         andi    %1, 255, %0
4755         st%M0.b %m0, %1"
4756   [(set_attr "type"   "arith_media,store")
4757    (set (attr "highpart")
4758         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4759                (const_string "user")]
4760               (const_string "extend")))])
4761 ;; -------------------------------------------------------------------------
4762 ;; Move instructions
4763 ;; -------------------------------------------------------------------------
4764
4765 ;; define push and pop so it is easy for sh.c
4766 ;; We can't use push and pop on SHcompact because the stack must always
4767 ;; be 8-byte aligned.
4768
4769 (define_expand "push"
4770   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4771         (match_operand:SI 0 "register_operand" "r,l,x"))]
4772   "TARGET_SH1 && ! TARGET_SH5"
4773   "")
4774
4775 (define_expand "pop"
4776   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4777         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4778   "TARGET_SH1 && ! TARGET_SH5"
4779   "")
4780
4781 (define_expand "push_e"
4782   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4783                    (match_operand:SF 0 "" ""))
4784               (use (reg:PSI FPSCR_REG))
4785               (clobber (scratch:SI))])]
4786   "TARGET_SH1 && ! TARGET_SH5"
4787   "")
4788
4789 (define_insn "push_fpul"
4790   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4791   "TARGET_SH2E && ! TARGET_SH5"
4792   "sts.l        fpul,@-r15"
4793   [(set_attr "type" "store")
4794    (set_attr "late_fp_use" "yes")
4795    (set_attr "hit_stack" "yes")])
4796
4797 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4798 ;; so use that.
4799 (define_expand "push_4"
4800   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4801                    (match_operand:DF 0 "" ""))
4802               (use (reg:PSI FPSCR_REG))
4803               (clobber (scratch:SI))])]
4804   "TARGET_SH1 && ! TARGET_SH5"
4805   "")
4806
4807 (define_expand "pop_e"
4808   [(parallel [(set (match_operand:SF 0 "" "")
4809               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4810               (use (reg:PSI FPSCR_REG))
4811               (clobber (scratch:SI))])]
4812   "TARGET_SH1 && ! TARGET_SH5"
4813   "")
4814
4815 (define_insn "pop_fpul"
4816   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4817   "TARGET_SH2E && ! TARGET_SH5"
4818   "lds.l        @r15+,fpul"
4819   [(set_attr "type" "load")
4820    (set_attr "hit_stack" "yes")])
4821
4822 (define_expand "pop_4"
4823   [(parallel [(set (match_operand:DF 0 "" "")
4824                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4825               (use (reg:PSI FPSCR_REG))
4826               (clobber (scratch:SI))])]
4827   "TARGET_SH1 && ! TARGET_SH5"
4828   "")
4829
4830 (define_expand "push_fpscr"
4831   [(const_int 0)]
4832   "TARGET_SH2E"
4833   "
4834 {
4835   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4836                                                  gen_rtx_PRE_DEC (Pmode,
4837                                                           stack_pointer_rtx)),
4838                                         get_fpscr_rtx ()));
4839   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4840   DONE;
4841 }")
4842
4843 (define_expand "pop_fpscr"
4844   [(const_int 0)]
4845   "TARGET_SH2E"
4846   "
4847 {
4848   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4849                                         gen_frame_mem (PSImode,
4850                                                  gen_rtx_POST_INC (Pmode,
4851                                                           stack_pointer_rtx))));
4852   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4853   DONE;
4854 }")
4855
4856 ;; These two patterns can happen as the result of optimization, when
4857 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4858 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4859
4860 (define_insn "clrt"
4861   [(set (reg:SI T_REG) (const_int 0))]
4862   "TARGET_SH1"
4863   "clrt")
4864
4865 (define_insn "sett"
4866   [(set (reg:SI T_REG) (const_int 1))]
4867   "TARGET_SH1"
4868   "sett")
4869
4870 ;; t/r must come after r/r, lest reload will try to reload stuff like
4871 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4872 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4873 (define_insn "movsi_i"
4874   [(set (match_operand:SI 0 "general_movdst_operand"
4875             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4876         (match_operand:SI 1 "general_movsrc_operand"
4877          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4878   "TARGET_SH1
4879    && ! TARGET_SH2E
4880    && ! TARGET_SH2A
4881    && (register_operand (operands[0], SImode)
4882        || register_operand (operands[1], SImode))"
4883   "@
4884         mov.l   %1,%0
4885         mov     %1,%0
4886         cmp/pl  %1
4887         mov.l   %1,%0
4888         sts     %1,%0
4889         sts     %1,%0
4890         movt    %0
4891         mov.l   %1,%0
4892         sts.l   %1,%0
4893         sts.l   %1,%0
4894         lds     %1,%0
4895         lds     %1,%0
4896         lds.l   %1,%0
4897         lds.l   %1,%0
4898         fake    %1,%0"
4899   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4900    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4901
4902 ;; t/r must come after r/r, lest reload will try to reload stuff like
4903 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4904 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4905 ;; will require a reload.
4906 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4907 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4908 (define_insn "movsi_ie"
4909   [(set (match_operand:SI 0 "general_movdst_operand"
4910             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4911         (match_operand:SI 1 "general_movsrc_operand"
4912          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4913   "(TARGET_SH2E || TARGET_SH2A)
4914    && (register_operand (operands[0], SImode)
4915        || register_operand (operands[1], SImode))"
4916   "@
4917         mov.l   %1,%0
4918         mov     %1,%0
4919         movi20  %1,%0
4920         cmp/pl  %1
4921         mov.l   %1,%0
4922         sts     %1,%0
4923         sts     %1,%0
4924         movt    %0
4925         mov.l   %1,%0
4926         sts.l   %1,%0
4927         sts.l   %1,%0
4928         lds     %1,%0
4929         lds     %1,%0
4930         lds.l   %1,%0
4931         lds.l   %1,%0
4932         lds.l   %1,%0
4933         sts.l   %1,%0
4934         fake    %1,%0
4935         lds     %1,%0
4936         sts     %1,%0
4937         fsts    fpul,%0
4938         flds    %1,fpul
4939         fmov    %1,%0
4940         ! move optimized away"
4941   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4942    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4943    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4944
4945 (define_insn "movsi_i_lowpart"
4946   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4947         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4948    "TARGET_SH1
4949     && (register_operand (operands[0], SImode)
4950         || register_operand (operands[1], SImode))"
4951   "@
4952         mov.l   %1,%0
4953         mov     %1,%0
4954         mov.l   %1,%0
4955         sts     %1,%0
4956         sts     %1,%0
4957         movt    %0
4958         mov.l   %1,%0
4959         fake    %1,%0"
4960   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4961
4962 (define_insn_and_split "load_ra"
4963   [(set (match_operand:SI 0 "general_movdst_operand" "")
4964         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4965   "TARGET_SH1"
4966   "#"
4967   "&& ! currently_expanding_to_rtl"
4968   [(set (match_dup 0) (match_dup 1))]
4969   "
4970 {
4971   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4972     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4973 }")
4974
4975 ;; The '?'s in the following constraints may not reflect the time taken
4976 ;; to perform the move. They are there to discourage the use of floating-
4977 ;; point registers for storing integer values.
4978 (define_insn "*movsi_media"
4979   [(set (match_operand:SI 0 "general_movdst_operand"
4980                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4981         (match_operand:SI 1 "general_movsrc_operand"
4982          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4983   "TARGET_SHMEDIA_FPU
4984    && (register_operand (operands[0], SImode)
4985        || sh_register_operand (operands[1], SImode)
4986        || GET_CODE (operands[1]) == TRUNCATE)"
4987   "@
4988         add.l   %1, r63, %0
4989         movi    %1, %0
4990         #
4991         ld%M1.l %m1, %0
4992         st%M0.l %m0, %N1
4993         fld%M1.s        %m1, %0
4994         fst%M0.s        %m0, %1
4995         fmov.ls %N1, %0
4996         fmov.sl %1, %0
4997         fmov.s  %1, %0
4998         ptabs   %1, %0
4999         gettr   %1, %0
5000         pt      %1, %0"
5001   [(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")
5002    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5003    (set (attr "highpart")
5004         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5005                (const_string "user")]
5006               (const_string "ignore")))])
5007
5008 (define_insn "*movsi_media_nofpu"
5009   [(set (match_operand:SI 0 "general_movdst_operand"
5010                 "=r,r,r,r,m,*b,r,*b")
5011         (match_operand:SI 1 "general_movsrc_operand"
5012          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5013   "TARGET_SHMEDIA
5014    && (register_operand (operands[0], SImode)
5015        || sh_register_operand (operands[1], SImode)
5016        || GET_CODE (operands[1]) == TRUNCATE)"
5017   "@
5018         add.l   %1, r63, %0
5019         movi    %1, %0
5020         #
5021         ld%M1.l %m1, %0
5022         st%M0.l %m0, %N1
5023         ptabs   %1, %0
5024         gettr   %1, %0
5025         pt      %1, %0"
5026   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5027    (set_attr "length" "4,4,8,4,4,4,4,12")
5028    (set (attr "highpart")
5029         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5030                (const_string "user")]
5031               (const_string "ignore")))])
5032
5033 (define_expand "movsi_const"
5034   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5035         (const:SI (sign_extend:SI
5036                    (truncate:HI
5037                     (ashiftrt:SI
5038                      (match_operand:DI 1 "immediate_operand" "s")
5039                      (const_int 16))))))
5040    (set (match_dup 0)
5041         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5042                 (const:SI
5043                   (zero_extend:SI
5044                    (truncate:HI (match_dup 1))))))]
5045   "TARGET_SHMEDIA && reload_completed
5046    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5047   "
5048 {
5049   if (GET_CODE (operands[1]) == LABEL_REF
5050       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5051     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5052   else if (GOTOFF_P (operands[1]))
5053     {
5054       rtx unspec = XEXP (operands[1], 0);
5055
5056       if (! UNSPEC_GOTOFF_P (unspec))
5057         {
5058           unspec = XEXP (unspec, 0);
5059           if (! UNSPEC_GOTOFF_P (unspec))
5060             abort ();
5061         }
5062       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5063           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5064         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5065     }
5066 }")
5067
5068 (define_expand "movsi_const_16bit"
5069   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5070         (const:SI (sign_extend:SI
5071                    (truncate:HI
5072                     (match_operand:DI 1 "immediate_operand" "s")))))]
5073   "TARGET_SHMEDIA && flag_pic && reload_completed
5074    && GET_CODE (operands[1]) == SYMBOL_REF"
5075   "")
5076
5077 (define_split
5078   [(set (match_operand:SI 0 "arith_reg_dest" "")
5079         (match_operand:SI 1 "immediate_operand" ""))]
5080   "TARGET_SHMEDIA && reload_completed
5081    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5082   [(const_int 0)]
5083   "
5084 {
5085   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5086
5087   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5088                                         REG_NOTES (insn));
5089
5090   DONE;
5091 }")
5092
5093 (define_split
5094   [(set (match_operand:SI 0 "register_operand" "")
5095         (match_operand:SI 1 "immediate_operand" ""))]
5096   "TARGET_SHMEDIA && reload_completed
5097    && ((GET_CODE (operands[1]) == CONST_INT
5098         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5099        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5100   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5101
5102 (define_expand "movsi"
5103   [(set (match_operand:SI 0 "general_movdst_operand" "")
5104         (match_operand:SI 1 "general_movsrc_operand" ""))]
5105   ""
5106   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5107
5108 (define_expand "ic_invalidate_line"
5109   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5110                                 (match_dup 1)] UNSPEC_ICACHE)
5111               (clobber (scratch:SI))])]
5112   "TARGET_HARD_SH4 || TARGET_SH5"
5113   "
5114 {
5115   if (TARGET_SHMEDIA)
5116     {
5117       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5118       DONE;
5119     }
5120   else if (TARGET_SHCOMPACT)
5121     {
5122       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5123       operands[1] = force_reg (Pmode, operands[1]);
5124       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5125       DONE;
5126     }
5127   else if (TARGET_SH4A_ARCH)
5128     {
5129       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5130       DONE;
5131     }
5132   operands[0] = force_reg (Pmode, operands[0]);
5133   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5134                                                                Pmode)));
5135 }")
5136
5137 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5138 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5139 ;; the requirement *1*00 for associative address writes.  The alignment of
5140 ;; %0 implies that its least significant bit is cleared,
5141 ;; thus we clear the V bit of a matching entry if there is one.
5142 (define_insn "ic_invalidate_line_i"
5143   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5144                      (match_operand:SI 1 "register_operand" "r")]
5145                      UNSPEC_ICACHE)
5146    (clobber (match_scratch:SI 2 "=&r"))]
5147   "TARGET_HARD_SH4"
5148   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5149   [(set_attr "length" "8")
5150    (set_attr "type" "cwb")])
5151
5152 (define_insn "ic_invalidate_line_sh4a"
5153   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5154                     UNSPEC_ICACHE)]
5155   "TARGET_SH4A_ARCH"
5156   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5157   [(set_attr "length" "16")
5158    (set_attr "type" "cwb")])
5159
5160 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5161 ;; an add in the code that calculates the address.
5162 (define_insn "ic_invalidate_line_media"
5163   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5164                     UNSPEC_ICACHE)]
5165   "TARGET_SHMEDIA"
5166   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5167   [(set_attr "length" "16")
5168    (set_attr "type" "invalidate_line_media")])
5169
5170 (define_insn "ic_invalidate_line_compact"
5171   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5172                      (match_operand:SI 1 "register_operand" "r")]
5173                     UNSPEC_ICACHE)
5174    (clobber (reg:SI PR_REG))]
5175   "TARGET_SHCOMPACT"
5176   "jsr @%1%#"
5177   [(set_attr "type" "sfunc")
5178    (set_attr "needs_delay_slot" "yes")])
5179
5180 (define_expand "initialize_trampoline"
5181   [(match_operand:SI 0 "" "")
5182    (match_operand:SI 1 "" "")
5183    (match_operand:SI 2 "" "")]
5184   "TARGET_SHCOMPACT"
5185   "
5186 {
5187   rtx sfun, tramp;
5188
5189   tramp = force_reg (Pmode, operands[0]);
5190   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5191                                             SFUNC_STATIC));
5192   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5193   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5194
5195   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5196   DONE;
5197 }")
5198
5199 (define_insn "initialize_trampoline_compact"
5200   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5201                      (match_operand:SI 1 "register_operand" "r")
5202                      (reg:SI R2_REG) (reg:SI R3_REG)]
5203                     UNSPEC_INIT_TRAMP)
5204
5205    (clobber (reg:SI PR_REG))]
5206   "TARGET_SHCOMPACT"
5207   "jsr @%1%#"
5208   [(set_attr "type" "sfunc")
5209    (set_attr "needs_delay_slot" "yes")])
5210
5211 (define_insn "movqi_i"
5212   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5213         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5214   "TARGET_SH1
5215    && (arith_reg_operand (operands[0], QImode)
5216        || arith_reg_operand (operands[1], QImode))"
5217   "@
5218         mov     %1,%0
5219         mov.b   %1,%0
5220         mov.b   %1,%0
5221         movt    %0
5222         sts     %1,%0
5223         lds     %1,%0"
5224  [(set_attr "type" "move,load,store,move,move,move")])
5225
5226 (define_insn "*movqi_media"
5227   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5228         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5229   "TARGET_SHMEDIA
5230    && (arith_reg_operand (operands[0], QImode)
5231        || extend_reg_or_0_operand (operands[1], QImode))"
5232   "@
5233         add.l   %1, r63, %0
5234         movi    %1, %0
5235         ld%M1.ub        %m1, %0
5236         st%M0.b %m0, %N1"
5237   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5238    (set (attr "highpart")
5239         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5240                (const_string "user")]
5241               (const_string "ignore")))])
5242
5243 (define_expand "movqi"
5244   [(set (match_operand:QI 0 "general_operand" "")
5245         (match_operand:QI 1 "general_operand"  ""))]
5246   ""
5247   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5248
5249 (define_expand "reload_inqi"
5250   [(set (match_operand:SI 2 "" "=&r")
5251         (match_operand:QI 1 "inqhi_operand" ""))
5252    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5253         (truncate:QI (match_dup 3)))]
5254   "TARGET_SHMEDIA"
5255   "
5256 {
5257   rtx inner = XEXP (operands[1], 0);
5258   int regno = REGNO (inner);
5259
5260   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5261   operands[1] = gen_rtx_REG (SImode, regno);
5262   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5263 }")
5264
5265 /* When storing r0, we have to avoid reg+reg addressing.  */
5266 (define_insn "movhi_i"
5267   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5268         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5269   "TARGET_SH1
5270    && (arith_reg_operand (operands[0], HImode)
5271        || arith_reg_operand (operands[1], HImode))
5272    && (GET_CODE (operands[0]) != MEM
5273        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5274        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5275        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5276   "@
5277         mov.w   %1,%0
5278         mov     %1,%0
5279         mov.w   %1,%0
5280         movt    %0
5281         mov.w   %1,%0
5282         sts     %1,%0
5283         lds     %1,%0
5284         fake    %1,%0"
5285   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5286
5287 (define_insn "*movhi_media"
5288   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5289         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5290   "TARGET_SHMEDIA
5291    && (arith_reg_operand (operands[0], HImode)
5292        || arith_reg_or_0_operand (operands[1], HImode))"
5293   "@
5294         add.l   %1, r63, %0
5295         movi    %1, %0
5296         #
5297         ld%M1.w %m1, %0
5298         st%M0.w %m0, %N1"
5299   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5300    (set (attr "highpart")
5301         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5302                (const_string "user")]
5303               (const_string "ignore")))])
5304
5305 (define_split
5306   [(set (match_operand:HI 0 "register_operand" "")
5307         (match_operand:HI 1 "immediate_operand" ""))]
5308   "TARGET_SHMEDIA && reload_completed
5309    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5310   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5311
5312 (define_expand "movhi"
5313   [(set (match_operand:HI 0 "general_movdst_operand" "")
5314         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5315   ""
5316   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5317
5318 (define_expand "reload_inhi"
5319   [(set (match_operand:SI 2 "" "=&r")
5320         (match_operand:HI 1 "inqhi_operand" ""))
5321    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5322         (truncate:HI (match_dup 3)))]
5323   "TARGET_SHMEDIA"
5324   "
5325 {
5326   rtx inner = XEXP (operands[1], 0);
5327   int regno = REGNO (inner);
5328
5329   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5330   operands[1] = gen_rtx_REG (SImode, regno);
5331   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5332 }")
5333
5334 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5335 ;; compiled with -m2 -ml -O3 -funroll-loops
5336 (define_insn "*movdi_i"
5337   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5338         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5339   "TARGET_SH1
5340    && (arith_reg_operand (operands[0], DImode)
5341        || arith_reg_operand (operands[1], DImode))"
5342   "* return output_movedouble (insn, operands, DImode);"
5343   [(set_attr "length" "4")
5344    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5345
5346 ;; If the output is a register and the input is memory or a register, we have
5347 ;; to be careful and see which word needs to be loaded first.
5348
5349 (define_split
5350   [(set (match_operand:DI 0 "general_movdst_operand" "")
5351         (match_operand:DI 1 "general_movsrc_operand" ""))]
5352   "TARGET_SH1 && reload_completed"
5353   [(set (match_dup 2) (match_dup 3))
5354    (set (match_dup 4) (match_dup 5))]
5355   "
5356 {
5357   int regno;
5358
5359   if ((GET_CODE (operands[0]) == MEM
5360        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5361       || (GET_CODE (operands[1]) == MEM
5362           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5363     FAIL;
5364
5365   switch (GET_CODE (operands[0]))
5366     {
5367     case REG:
5368       regno = REGNO (operands[0]);
5369       break;
5370     case SUBREG:
5371       regno = subreg_regno (operands[0]);
5372       break;
5373     case MEM:
5374       regno = -1;
5375       break;
5376     default:
5377       gcc_unreachable ();
5378     }
5379
5380   if (regno == -1
5381       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5382     {
5383       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5384       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5385       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5386       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5387     }
5388   else
5389     {
5390       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5391       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5392       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5393       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5394     }
5395
5396   if (operands[2] == 0 || operands[3] == 0
5397       || operands[4] == 0 || operands[5] == 0)
5398     FAIL;
5399 }")
5400
5401 ;; The '?'s in the following constraints may not reflect the time taken
5402 ;; to perform the move. They are there to discourage the use of floating-
5403 ;; point registers for storing integer values.
5404 (define_insn "*movdi_media"
5405   [(set (match_operand:DI 0 "general_movdst_operand"
5406                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5407         (match_operand:DI 1 "general_movsrc_operand"
5408          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5409   "TARGET_SHMEDIA_FPU
5410    && (register_operand (operands[0], DImode)
5411        || sh_register_operand (operands[1], DImode))"
5412   "@
5413         add     %1, r63, %0
5414         movi    %1, %0
5415         #
5416         ld%M1.q %m1, %0
5417         st%M0.q %m0, %N1
5418         fld%M1.d        %m1, %0
5419         fst%M0.d        %m0, %1
5420         fmov.qd %N1, %0
5421         fmov.dq %1, %0
5422         fmov.d  %1, %0
5423         ptabs   %1, %0
5424         gettr   %1, %0
5425         pt      %1, %0"
5426   [(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")
5427    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5428
5429 (define_insn "*movdi_media_nofpu"
5430   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5431         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5432   "TARGET_SHMEDIA
5433    && (register_operand (operands[0], DImode)
5434        || sh_register_operand (operands[1], DImode))"
5435   "@
5436         add     %1, r63, %0
5437         movi    %1, %0
5438         #
5439         ld%M1.q %m1, %0
5440         st%M0.q %m0, %N1
5441         ptabs   %1, %0
5442         gettr   %1, %0
5443         pt      %1, %0"
5444   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5445    (set_attr "length" "4,4,16,4,4,4,4,*")])
5446
5447 (define_insn "*movdi_media_I16"
5448   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5449         (match_operand:DI 1 "const_int_operand" "I16"))]
5450   "TARGET_SHMEDIA && reload_completed"
5451   "movi %1, %0"
5452   [(set_attr "type" "arith_media")
5453    (set_attr "length" "4")])
5454
5455 (define_split
5456   [(set (match_operand:DI 0 "arith_reg_dest" "")
5457         (match_operand:DI 1 "immediate_operand" ""))]
5458   "TARGET_SHMEDIA && reload_completed
5459    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5460   [(set (match_dup 0) (match_dup 1))]
5461   "
5462 {
5463   rtx insn;
5464
5465   if (TARGET_SHMEDIA64)
5466     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5467   else
5468     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5469
5470   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5471                                         REG_NOTES (insn));
5472
5473   DONE;
5474 }")
5475
5476 (define_expand "movdi_const"
5477   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5478         (const:DI (sign_extend:DI
5479                    (truncate:HI
5480                     (ashiftrt:DI
5481                      (match_operand:DI 1 "immediate_operand" "s")
5482                      (const_int 48))))))
5483    (set (match_dup 0)
5484         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5485                 (const:DI
5486                  (zero_extend:DI
5487                   (truncate:HI
5488                    (ashiftrt:SI
5489                     (match_dup 1)
5490                     (const_int 32)))))))
5491    (set (match_dup 0)
5492         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5493                 (const:DI
5494                  (zero_extend:DI
5495                   (truncate:HI
5496                    (ashiftrt:SI
5497                     (match_dup 1)
5498                     (const_int 16)))))))
5499    (set (match_dup 0)
5500         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5501                 (const:DI
5502                  (zero_extend:DI
5503                   (truncate:HI
5504                    (match_dup 1))))))]
5505   "TARGET_SHMEDIA64 && reload_completed
5506    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5507   "
5508 {
5509   sh_mark_label (operands[1], 4);
5510 }")
5511
5512 (define_expand "movdi_const_32bit"
5513   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5514         (const:DI (sign_extend:DI
5515                    (truncate:HI
5516                     (ashiftrt:DI
5517                      (match_operand:DI 1 "immediate_operand" "s")
5518                      (const_int 16))))))
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                    (match_dup 1))))))]
5525   "TARGET_SHMEDIA32 && reload_completed
5526    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5527   "
5528 {
5529   sh_mark_label (operands[1], 2);
5530 }")
5531
5532 (define_expand "movdi_const_16bit"
5533   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5534         (const:DI (sign_extend:DI
5535                    (truncate:HI
5536                     (match_operand:DI 1 "immediate_operand" "s")))))]
5537   "TARGET_SHMEDIA && flag_pic && reload_completed
5538    && GET_CODE (operands[1]) == SYMBOL_REF"
5539   "")
5540
5541 (define_split
5542   [(set (match_operand:DI 0 "ext_dest_operand" "")
5543         (match_operand:DI 1 "immediate_operand" ""))]
5544   "TARGET_SHMEDIA && reload_completed
5545    && GET_CODE (operands[1]) == CONST_INT
5546    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5547   [(set (match_dup 0) (match_dup 2))
5548    (match_dup 1)]
5549   "
5550 {
5551   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5552   unsigned HOST_WIDE_INT low = val;
5553   unsigned HOST_WIDE_INT high = val;
5554   unsigned HOST_WIDE_INT sign;
5555   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5556
5557   /* Zero-extend the 16 least-significant bits.  */
5558   low &= 0xffff;
5559
5560   /* Arithmetic shift right the word by 16 bits.  */
5561   high >>= 16;
5562   if (GET_CODE (operands[0]) == SUBREG
5563       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5564     {
5565       high &= 0xffff;
5566       high ^= 0x8000;
5567       high -= 0x8000;
5568     }
5569   else
5570     {
5571       sign = 1;
5572       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5573       high ^= sign;
5574       high -= sign;
5575     }
5576   do
5577     {
5578       /* If we can't generate the constant with a two-insn movi / shori
5579          sequence, try some other strategies.  */
5580       if (! CONST_OK_FOR_I16 (high))
5581         {
5582           /* Try constant load / left shift.  We know VAL != 0.  */
5583           val2 = val ^ (val-1);
5584           if (val2 > 0x1ffff)
5585             {
5586               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5587
5588               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5589                   || (! CONST_OK_FOR_I16 (high >> 16)
5590                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5591                 {
5592                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5593                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5594                                                    GEN_INT (trailing_zeroes));
5595                   break;
5596                 }
5597             }
5598           /* Try constant load / right shift.  */
5599           val2 = (val >> 15) + 1;
5600           if (val2 == (val2 & -val2))
5601             {
5602               int shift = 49 - exact_log2 (val2);
5603
5604               val2 = trunc_int_for_mode (val << shift, DImode);
5605               if (CONST_OK_FOR_I16 (val2))
5606                 {
5607                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5608                                                    GEN_INT (shift));
5609                   break;
5610                 }
5611             }
5612           /* Try mperm.w .  */
5613           val2 = val & 0xffff;
5614           if ((val >> 16 & 0xffff) == val2
5615               && (val >> 32 & 0xffff) == val2
5616               && (val >> 48 & 0xffff) == val2)
5617             {
5618               val2 = (HOST_WIDE_INT) val >> 48;
5619               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5620               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5621               break;
5622             }
5623           /* Try movi / mshflo.l  */
5624           val2 = (HOST_WIDE_INT) val >> 32;
5625           if (val2 == ((unsigned HOST_WIDE_INT)
5626                         trunc_int_for_mode (val, SImode)))
5627             {
5628               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5629                                              operands[0]);
5630               break;
5631             }
5632           /* Try movi / mshflo.l w/ r63.  */
5633           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5634           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5635             {
5636               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5637                                              const0_rtx);
5638               break;
5639             }
5640         }
5641       val2 = high;
5642       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5643     }
5644   while (0);
5645   operands[2] = GEN_INT (val2);
5646 }")
5647
5648 (define_split
5649   [(set (match_operand:DI 0 "ext_dest_operand" "")
5650         (match_operand:DI 1 "immediate_operand" ""))]
5651   "TARGET_SHMEDIA && reload_completed
5652    && GET_CODE (operands[1]) == CONST_DOUBLE"
5653   [(set (match_dup 0) (match_dup 2))
5654   (set (match_dup 0)
5655        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5656   "
5657 {
5658   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5659   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5660   unsigned HOST_WIDE_INT val = low;
5661   unsigned HOST_WIDE_INT sign;
5662
5663   /* Zero-extend the 16 least-significant bits.  */
5664   val &= 0xffff;
5665   operands[1] = GEN_INT (val);
5666
5667   /* Arithmetic shift right the double-word by 16 bits.  */
5668   low >>= 16;
5669   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5670   high >>= 16;
5671   sign = 1;
5672   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5673   high ^= sign;
5674   high -= sign;
5675
5676   /* This will only be true if high is a sign-extension of low, i.e.,
5677      it must be either 0 or (unsigned)-1, and be zero iff the
5678      most-significant bit of low is set.  */
5679   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5680     operands[2] = GEN_INT (low);
5681   else
5682     operands[2] = immed_double_const (low, high, DImode);
5683 }")
5684
5685 (define_insn "shori_media"
5686   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5687         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5688                            (const_int 16))
5689                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5690   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5691   "@
5692         shori   %u2, %0
5693         #"
5694   [(set_attr "type" "arith_media,*")])
5695
5696 (define_insn "*shori_media_si"
5697   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5698         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5699                            (const_int 16))
5700                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5701   "TARGET_SHMEDIA"
5702   "shori        %u2, %0")
5703
5704 (define_expand "movdi"
5705   [(set (match_operand:DI 0 "general_movdst_operand" "")
5706         (match_operand:DI 1 "general_movsrc_operand" ""))]
5707   ""
5708   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5709
5710 (define_insn "movdf_media"
5711   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5712         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5713   "TARGET_SHMEDIA_FPU
5714    && (register_operand (operands[0], DFmode)
5715        || sh_register_operand (operands[1], DFmode))"
5716   "@
5717         fmov.d  %1, %0
5718         fmov.qd %N1, %0
5719         fmov.dq %1, %0
5720         add     %1, r63, %0
5721         #
5722         fld%M1.d        %m1, %0
5723         fst%M0.d        %m0, %1
5724         ld%M1.q %m1, %0
5725         st%M0.q %m0, %N1"
5726   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5727
5728 (define_insn "movdf_media_nofpu"
5729   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5730         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5731   "TARGET_SHMEDIA
5732    && (register_operand (operands[0], DFmode)
5733        || sh_register_operand (operands[1], DFmode))"
5734   "@
5735         add     %1, r63, %0
5736         #
5737         ld%M1.q %m1, %0
5738         st%M0.q %m0, %N1"
5739   [(set_attr "type" "arith_media,*,load_media,store_media")])
5740
5741 (define_split
5742   [(set (match_operand:DF 0 "arith_reg_dest" "")
5743         (match_operand:DF 1 "immediate_operand" ""))]
5744   "TARGET_SHMEDIA && reload_completed"
5745   [(set (match_dup 3) (match_dup 2))]
5746   "
5747 {
5748   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5749   long values[2];
5750   REAL_VALUE_TYPE value;
5751
5752   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5753   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5754
5755   if (HOST_BITS_PER_WIDE_INT >= 64)
5756     operands[2] = immed_double_const ((unsigned long) values[endian]
5757                                       | ((HOST_WIDE_INT) values[1 - endian]
5758                                          << 32), 0, DImode);
5759   else
5760     {
5761       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5762       operands[2] = immed_double_const (values[endian], values[1 - endian],
5763                                         DImode);
5764     }
5765
5766   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5767 }")
5768
5769 ;; ??? This should be a define expand.
5770
5771 (define_insn "movdf_k"
5772   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5773         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5774   "TARGET_SH1
5775    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5776        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5777        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5778        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5779    && (arith_reg_operand (operands[0], DFmode)
5780        || arith_reg_operand (operands[1], DFmode))"
5781   "* return output_movedouble (insn, operands, DFmode);"
5782   [(set_attr "length" "4")
5783    (set_attr "type" "move,pcload,load,store")])
5784
5785 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5786 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5787 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5788 ;; the d/m/c/X alternative, which is split later into single-precision
5789 ;; instructions.  And when not optimizing, no splits are done before fixing
5790 ;; up pcloads, so we need usable length information for that.
5791 (define_insn "movdf_i4"
5792   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5793         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5794    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5795    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5796   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5797    && (arith_reg_operand (operands[0], DFmode)
5798        || arith_reg_operand (operands[1], DFmode))"
5799   "@
5800         fmov    %1,%0
5801         #
5802         #
5803         fmov.d  %1,%0
5804         fmov.d  %1,%0
5805         #
5806         #
5807         #
5808         #
5809         #"
5810   [(set_attr_alternative "length"
5811      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5812       (const_int 4)
5813       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5814       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5815       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5816       (const_int 4)
5817       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5818       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5819       ;; increment or decrement r15 explicitly.
5820       (if_then_else
5821        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5822        (const_int 10) (const_int 8))
5823       (if_then_else
5824        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5825        (const_int 10) (const_int 8))])
5826    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5827    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5828    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5829                                            (const_string "double")
5830                                            (const_string "none")))])
5831
5832 ;; Moving DFmode between fp/general registers through memory
5833 ;; (the top of the stack) is faster than moving through fpul even for
5834 ;; little endian.  Because the type of an instruction is important for its
5835 ;; scheduling,  it is beneficial to split these operations, rather than
5836 ;; emitting them in one single chunk, even if this will expose a stack
5837 ;; use that will prevent scheduling of other stack accesses beyond this
5838 ;; instruction.
5839 (define_split
5840   [(set (match_operand:DF 0 "register_operand" "")
5841         (match_operand:DF 1 "register_operand" ""))
5842    (use (match_operand:PSI 2 "fpscr_operand" ""))
5843    (clobber (match_scratch:SI 3 "=X"))]
5844   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5845    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5846   [(const_int 0)]
5847   "
5848 {
5849   rtx insn, tos;
5850
5851   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5852     {
5853       emit_move_insn (stack_pointer_rtx,
5854                       plus_constant (stack_pointer_rtx, -8));
5855       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5856     }
5857   else
5858     tos = gen_tmp_stack_mem (DFmode,
5859                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5860   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5861   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5862     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5863   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5864     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5865   else
5866     tos = gen_tmp_stack_mem (DFmode,
5867                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5868   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5869   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5870     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5871   else
5872     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5873   DONE;
5874 }")
5875
5876 ;; local-alloc sometimes allocates scratch registers even when not required,
5877 ;; so we must be prepared to handle these.
5878
5879 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5880 (define_split
5881   [(set (match_operand:DF 0 "general_movdst_operand" "")
5882         (match_operand:DF 1 "general_movsrc_operand"  ""))
5883    (use (match_operand:PSI 2 "fpscr_operand" ""))
5884    (clobber (match_scratch:SI 3 ""))]
5885   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5886    && reload_completed
5887    && true_regnum (operands[0]) < 16
5888    && true_regnum (operands[1]) < 16"
5889   [(set (match_dup 0) (match_dup 1))]
5890   "
5891 {
5892   /* If this was a reg <-> mem operation with base + index reg addressing,
5893      we have to handle this in a special way.  */
5894   rtx mem = operands[0];
5895   int store_p = 1;
5896   if (! memory_operand (mem, DFmode))
5897     {
5898       mem = operands[1];
5899       store_p = 0;
5900     }
5901   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5902     mem = SUBREG_REG (mem);
5903   if (GET_CODE (mem) == MEM)
5904     {
5905       rtx addr = XEXP (mem, 0);
5906       if (GET_CODE (addr) == PLUS
5907           && GET_CODE (XEXP (addr, 0)) == REG
5908           && GET_CODE (XEXP (addr, 1)) == REG)
5909         {
5910           int offset;
5911           rtx reg0 = gen_rtx_REG (Pmode, 0);
5912           rtx regop = operands[store_p], word0 ,word1;
5913
5914           if (GET_CODE (regop) == SUBREG)
5915             alter_subreg (&regop);
5916           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5917             offset = 2;
5918           else
5919             offset = 4;
5920           mem = copy_rtx (mem);
5921           PUT_MODE (mem, SImode);
5922           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5923           alter_subreg (&word0);
5924           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5925           alter_subreg (&word1);
5926           if (store_p || ! refers_to_regno_p (REGNO (word0),
5927                                               REGNO (word0) + 1, addr, 0))
5928             {
5929               emit_insn (store_p
5930                          ? gen_movsi_ie (mem, word0)
5931                          : gen_movsi_ie (word0, mem));
5932               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5933               mem = copy_rtx (mem);
5934               emit_insn (store_p
5935                          ? gen_movsi_ie (mem, word1)
5936                          : gen_movsi_ie (word1, mem));
5937               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5938             }
5939           else
5940             {
5941               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5942               emit_insn (gen_movsi_ie (word1, mem));
5943               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5944               mem = copy_rtx (mem);
5945               emit_insn (gen_movsi_ie (word0, mem));
5946             }
5947           DONE;
5948         }
5949     }
5950 }")
5951
5952 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5953 (define_split
5954   [(set (match_operand:DF 0 "register_operand" "")
5955         (match_operand:DF 1 "memory_operand"  ""))
5956    (use (match_operand:PSI 2 "fpscr_operand" ""))
5957    (clobber (reg:SI R0_REG))]
5958   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5959   [(parallel [(set (match_dup 0) (match_dup 1))
5960               (use (match_dup 2))
5961               (clobber (scratch:SI))])]
5962   "")
5963
5964 (define_expand "reload_indf__frn"
5965   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5966                    (match_operand:DF 1 "immediate_operand" "FQ"))
5967               (use (reg:PSI FPSCR_REG))
5968               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5969   "TARGET_SH1"
5970   "")
5971
5972 (define_expand "reload_outdf__RnFRm"
5973   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5974                    (match_operand:DF 1 "register_operand" "af,r"))
5975               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5976   "TARGET_SH1"
5977   "")
5978
5979 ;; Simplify no-op moves.
5980 (define_split
5981   [(set (match_operand:SF 0 "register_operand" "")
5982         (match_operand:SF 1 "register_operand" ""))
5983    (use (match_operand:PSI 2 "fpscr_operand" ""))
5984    (clobber (match_scratch:SI 3 ""))]
5985   "TARGET_SH2E && reload_completed
5986    && true_regnum (operands[0]) == true_regnum (operands[1])"
5987   [(set (match_dup 0) (match_dup 0))]
5988   "")
5989
5990 ;; fmovd substitute post-reload splits
5991 (define_split
5992   [(set (match_operand:DF 0 "register_operand" "")
5993         (match_operand:DF 1 "register_operand" ""))
5994    (use (match_operand:PSI 2 "fpscr_operand" ""))
5995    (clobber (match_scratch:SI 3 ""))]
5996   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5997    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5998    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5999   [(const_int 0)]
6000   "
6001 {
6002   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6003   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6004                            gen_rtx_REG (SFmode, src), operands[2]));
6005   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6006                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6007   DONE;
6008 }")
6009
6010 (define_split
6011   [(set (match_operand:DF 0 "register_operand" "")
6012         (mem:DF (match_operand:SI 1 "register_operand" "")))
6013    (use (match_operand:PSI 2 "fpscr_operand" ""))
6014    (clobber (match_scratch:SI 3 ""))]
6015   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6016    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6017    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6018   [(const_int 0)]
6019   "
6020 {
6021   int regno = true_regnum (operands[0]);
6022   rtx insn;
6023   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6024   rtx mem2
6025     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6026   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027                                            regno + !! TARGET_LITTLE_ENDIAN),
6028                                   mem2, operands[2]));
6029   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6030   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6031                                                regno + ! TARGET_LITTLE_ENDIAN),
6032                                   change_address (mem, SFmode, NULL_RTX),
6033                                   operands[2]));
6034   DONE;
6035 }")
6036
6037 (define_split
6038   [(set (match_operand:DF 0 "register_operand" "")
6039         (match_operand:DF 1 "memory_operand" ""))
6040    (use (match_operand:PSI 2 "fpscr_operand" ""))
6041    (clobber (match_scratch:SI 3 ""))]
6042   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6043    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6044   [(const_int 0)]
6045   "
6046 {
6047   int regno = true_regnum (operands[0]);
6048   rtx addr, insn, adjust = NULL_RTX;
6049   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6050   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6051   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6052
6053   operands[1] = copy_rtx (mem2);
6054   addr = XEXP (mem2, 0);
6055   if (GET_CODE (addr) != POST_INC)
6056     {
6057       /* If we have to modify the stack pointer, the value that we have
6058          read with post-increment might be modified by an interrupt,
6059          so write it back.  */
6060       if (REGNO (addr) == STACK_POINTER_REGNUM)
6061         adjust = gen_push_e (reg0);
6062       else
6063         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6064       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6065     }
6066   addr = XEXP (addr, 0);
6067   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6068   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6069   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6070   if (adjust)
6071     emit_insn (adjust);
6072   else
6073     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6074   DONE;
6075 }")
6076
6077 (define_split
6078   [(set (match_operand:DF 0 "memory_operand" "")
6079         (match_operand:DF 1 "register_operand" ""))
6080    (use (match_operand:PSI 2 "fpscr_operand" ""))
6081    (clobber (match_scratch:SI 3 ""))]
6082   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6083    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6084   [(const_int 0)]
6085   "
6086 {
6087   int regno = true_regnum (operands[1]);
6088   rtx insn, addr, adjust = NULL_RTX;
6089
6090   operands[0] = copy_rtx (operands[0]);
6091   PUT_MODE (operands[0], SFmode);
6092   insn = emit_insn (gen_movsf_ie (operands[0],
6093                                   gen_rtx_REG (SFmode,
6094                                            regno + ! TARGET_LITTLE_ENDIAN),
6095                                   operands[2]));
6096   operands[0] = copy_rtx (operands[0]);
6097   addr = XEXP (operands[0], 0);
6098   if (GET_CODE (addr) != PRE_DEC)
6099     {
6100       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6101       emit_insn_before (adjust, insn);
6102       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6103     }
6104   addr = XEXP (addr, 0);
6105   if (! adjust)
6106     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6107   insn = emit_insn (gen_movsf_ie (operands[0],
6108                                   gen_rtx_REG (SFmode,
6109                                            regno + !! TARGET_LITTLE_ENDIAN),
6110                                   operands[2]));
6111   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6112   DONE;
6113 }")
6114
6115 ;; If the output is a register and the input is memory or a register, we have
6116 ;; to be careful and see which word needs to be loaded first.
6117
6118 (define_split
6119   [(set (match_operand:DF 0 "general_movdst_operand" "")
6120         (match_operand:DF 1 "general_movsrc_operand" ""))]
6121   "TARGET_SH1 && reload_completed"
6122   [(set (match_dup 2) (match_dup 3))
6123    (set (match_dup 4) (match_dup 5))]
6124   "
6125 {
6126   int regno;
6127
6128   if ((GET_CODE (operands[0]) == MEM
6129        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6130       || (GET_CODE (operands[1]) == MEM
6131           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6132     FAIL;
6133
6134   switch (GET_CODE (operands[0]))
6135     {
6136     case REG:
6137       regno = REGNO (operands[0]);
6138       break;
6139     case SUBREG:
6140       regno = subreg_regno (operands[0]);
6141       break;
6142     case MEM:
6143       regno = -1;
6144       break;
6145     default:
6146       gcc_unreachable ();
6147     }
6148
6149   if (regno == -1
6150       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6151     {
6152       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6153       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6154       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6155       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6156     }
6157   else
6158     {
6159       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6160       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6161       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6162       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6163     }
6164
6165   if (operands[2] == 0 || operands[3] == 0
6166       || operands[4] == 0 || operands[5] == 0)
6167     FAIL;
6168 }")
6169
6170 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6171 ;; used only once, let combine add in the index again.
6172
6173 (define_split
6174   [(set (match_operand:SI 0 "register_operand" "")
6175         (match_operand:SI 1 "" ""))
6176    (clobber (match_operand 2 "register_operand" ""))]
6177   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6178    && ALLOW_INDEXED_ADDRESS"
6179   [(use (reg:SI R0_REG))]
6180   "
6181 {
6182   rtx addr, reg, const_int;
6183
6184   if (GET_CODE (operands[1]) != MEM)
6185     FAIL;
6186   addr = XEXP (operands[1], 0);
6187   if (GET_CODE (addr) != PLUS)
6188     FAIL;
6189   reg = XEXP (addr, 0);
6190   const_int = XEXP (addr, 1);
6191   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6192          && GET_CODE (const_int) == CONST_INT))
6193     FAIL;
6194   emit_move_insn (operands[2], const_int);
6195   emit_move_insn (operands[0],
6196                   change_address (operands[1], VOIDmode,
6197                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6198   DONE;
6199 }")
6200
6201 (define_split
6202   [(set (match_operand:SI 1 "" "")
6203         (match_operand:SI 0 "register_operand" ""))
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 (change_address (operands[1], VOIDmode,
6224                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6225                   operands[0]);
6226   DONE;
6227 }")
6228
6229 (define_expand "movdf"
6230   [(set (match_operand:DF 0 "general_movdst_operand" "")
6231         (match_operand:DF 1 "general_movsrc_operand" ""))]
6232   ""
6233   "
6234 {
6235   if (prepare_move_operands (operands, DFmode)) DONE;
6236   if (TARGET_SHMEDIA)
6237     {
6238       if (TARGET_SHMEDIA_FPU)
6239         emit_insn (gen_movdf_media (operands[0], operands[1]));
6240       else
6241         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6242       DONE;
6243     }
6244   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6245     {
6246       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6247       DONE;
6248     }
6249 }")
6250
6251 ;;This is incompatible with the way gcc uses subregs.
6252 ;;(define_insn "movv2sf_i"
6253 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6254 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6255 ;;  "TARGET_SHMEDIA_FPU
6256 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6257 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6258 ;;  "@
6259 ;;      #
6260 ;;      fld%M1.p        %m1, %0
6261 ;;      fst%M0.p        %m0, %1"
6262 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6263
6264 (define_insn_and_split "movv2sf_i"
6265   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6266         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6267   "TARGET_SHMEDIA_FPU"
6268   "#"
6269   "TARGET_SHMEDIA_FPU && reload_completed"
6270   [(set (match_dup 0) (match_dup 1))]
6271   "
6272 {
6273   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6274   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6275 }")
6276
6277 (define_expand "movv2sf"
6278   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6279         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6280   "TARGET_SHMEDIA_FPU"
6281   "
6282 {
6283   if (prepare_move_operands (operands, V2SFmode))
6284     DONE;
6285 }")
6286
6287 (define_expand "addv2sf3"
6288   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6289    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6290    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6291   "TARGET_SHMEDIA_FPU"
6292   "
6293 {
6294   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6295   DONE;
6296 }")
6297
6298 (define_expand "subv2sf3"
6299   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6300    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6301    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6302   "TARGET_SHMEDIA_FPU"
6303   "
6304 {
6305   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6306   DONE;
6307 }")
6308
6309 (define_expand "mulv2sf3"
6310   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6311    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6312    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6313   "TARGET_SHMEDIA_FPU"
6314   "
6315 {
6316   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6317   DONE;
6318 }")
6319
6320 (define_expand "divv2sf3"
6321   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6322    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6323    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6324   "TARGET_SHMEDIA_FPU"
6325   "
6326 {
6327   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6328   DONE;
6329 }")
6330
6331 (define_insn_and_split "*movv4sf_i"
6332   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6333         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6334   "TARGET_SHMEDIA_FPU"
6335   "#"
6336   "&& reload_completed"
6337   [(const_int 0)]
6338   "
6339 {
6340   int i;
6341
6342   for (i = 0; i < 4/2; i++)
6343     {
6344       rtx x, y;
6345
6346       if (GET_CODE (operands[0]) == MEM)
6347         x = adjust_address (operands[0], V2SFmode,
6348                             i * GET_MODE_SIZE (V2SFmode));
6349       else
6350         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6351
6352       if (GET_CODE (operands[1]) == MEM)
6353         y = adjust_address (operands[1], V2SFmode,
6354                             i * GET_MODE_SIZE (V2SFmode));
6355       else
6356         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6357
6358       emit_insn (gen_movv2sf_i (x, y));
6359     }
6360
6361   DONE;
6362 }"
6363   [(set_attr "length" "8")])
6364
6365 (define_expand "movv4sf"
6366   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6367         (match_operand:V4SF 1 "general_operand" ""))]
6368   "TARGET_SHMEDIA_FPU"
6369   "
6370 {
6371   if (prepare_move_operands (operands, V4SFmode))
6372     DONE;
6373 }")
6374
6375 (define_insn_and_split "*movv16sf_i"
6376   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6377         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6378   "TARGET_SHMEDIA_FPU"
6379   "#"
6380   "&& reload_completed"
6381   [(const_int 0)]
6382   "
6383 {
6384   int i;
6385
6386   for (i = 0; i < 16/2; i++)
6387     {
6388       rtx x,y;
6389
6390       if (GET_CODE (operands[0]) == MEM)
6391         x = adjust_address (operands[0], V2SFmode,
6392                             i * GET_MODE_SIZE (V2SFmode));
6393       else
6394         {
6395           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6396           alter_subreg (&x);
6397         }
6398
6399       if (GET_CODE (operands[1]) == MEM)
6400         y = adjust_address (operands[1], V2SFmode,
6401                             i * GET_MODE_SIZE (V2SFmode));
6402       else
6403         {
6404           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6405           alter_subreg (&y);
6406         }
6407
6408       emit_insn (gen_movv2sf_i (x, y));
6409     }
6410
6411   DONE;
6412 }"
6413   [(set_attr "length" "32")])
6414
6415 (define_expand "movv16sf"
6416   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6417         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6418   "TARGET_SHMEDIA_FPU"
6419   "
6420 {
6421   if (prepare_move_operands (operands, V16SFmode))
6422     DONE;
6423 }")
6424
6425 (define_insn "movsf_media"
6426   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6427         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6428   "TARGET_SHMEDIA_FPU
6429    && (register_operand (operands[0], SFmode)
6430        || sh_register_operand (operands[1], SFmode))"
6431   "@
6432         fmov.s  %1, %0
6433         fmov.ls %N1, %0
6434         fmov.sl %1, %0
6435         add.l   %1, r63, %0
6436         #
6437         fld%M1.s        %m1, %0
6438         fst%M0.s        %m0, %1
6439         ld%M1.l %m1, %0
6440         st%M0.l %m0, %N1"
6441   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6442    (set (attr "highpart")
6443         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6444                (const_string "user")]
6445               (const_string "ignore")))])
6446
6447 (define_insn "movsf_media_nofpu"
6448   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6449         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6450   "TARGET_SHMEDIA
6451    && (register_operand (operands[0], SFmode)
6452        || sh_register_operand (operands[1], SFmode))"
6453   "@
6454         add.l   %1, r63, %0
6455         #
6456         ld%M1.l %m1, %0
6457         st%M0.l %m0, %N1"
6458   [(set_attr "type" "arith_media,*,load_media,store_media")
6459    (set (attr "highpart")
6460         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6461                (const_string "user")]
6462               (const_string "ignore")))])
6463
6464 (define_split
6465   [(set (match_operand:SF 0 "arith_reg_dest" "")
6466         (match_operand:SF 1 "immediate_operand" ""))]
6467   "TARGET_SHMEDIA && reload_completed
6468    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6469   [(set (match_dup 3) (match_dup 2))]
6470   "
6471 {
6472   long values;
6473   REAL_VALUE_TYPE value;
6474
6475   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6476   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6477   operands[2] = GEN_INT (values);
6478
6479   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6480 }")
6481
6482 (define_insn "movsf_i"
6483   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6484         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6485   "TARGET_SH1
6486    && (! TARGET_SH2E
6487        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6488        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6489        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6490    && (arith_reg_operand (operands[0], SFmode)
6491        || arith_reg_operand (operands[1], SFmode))"
6492   "@
6493         mov     %1,%0
6494         mov     #0,%0
6495         mov.l   %1,%0
6496         mov.l   %1,%0
6497         mov.l   %1,%0
6498         lds     %1,%0
6499         sts     %1,%0"
6500   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6501
6502 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6503 ;; update_flow_info would not know where to put REG_EQUAL notes
6504 ;; when the destination changes mode.
6505 (define_insn "movsf_ie"
6506   [(set (match_operand:SF 0 "general_movdst_operand"
6507          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6508         (match_operand:SF 1 "general_movsrc_operand"
6509           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6510    (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"))
6511    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6512
6513   "TARGET_SH2E
6514    && (arith_reg_operand (operands[0], SFmode)
6515        || arith_reg_operand (operands[1], SFmode)
6516        || arith_reg_operand (operands[3], SImode)
6517        || (fpul_operand (operands[0], SFmode)
6518            && memory_operand (operands[1], SFmode)
6519            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6520        || (fpul_operand (operands[1], SFmode)
6521            && memory_operand (operands[0], SFmode)
6522            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6523   "@
6524         fmov    %1,%0
6525         mov     %1,%0
6526         fldi0   %0
6527         fldi1   %0
6528         #
6529         fmov.s  %1,%0
6530         fmov.s  %1,%0
6531         mov.l   %1,%0
6532         mov.l   %1,%0
6533         mov.l   %1,%0
6534         fsts    fpul,%0
6535         flds    %1,fpul
6536         lds.l   %1,%0
6537         #
6538         sts     %1,%0
6539         lds     %1,%0
6540         sts.l   %1,%0
6541         lds.l   %1,%0
6542         ! move optimized away"
6543   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6544    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6545    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6546    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6547                                            (const_string "single")
6548                                            (const_string "none")))])
6549
6550 (define_split
6551   [(set (match_operand:SF 0 "register_operand" "")
6552         (match_operand:SF 1 "register_operand" ""))
6553    (use (match_operand:PSI 2 "fpscr_operand" ""))
6554    (clobber (reg:SI FPUL_REG))]
6555   "TARGET_SH1"
6556   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6557               (use (match_dup 2))
6558               (clobber (scratch:SI))])
6559    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6560               (use (match_dup 2))
6561               (clobber (scratch:SI))])]
6562   "")
6563
6564 (define_expand "movsf"
6565   [(set (match_operand:SF 0 "general_movdst_operand" "")
6566         (match_operand:SF 1 "general_movsrc_operand" ""))]
6567   ""
6568   "
6569 {
6570   if (prepare_move_operands (operands, SFmode))
6571     DONE;
6572   if (TARGET_SHMEDIA)
6573     {
6574       if (TARGET_SHMEDIA_FPU)
6575         emit_insn (gen_movsf_media (operands[0], operands[1]));
6576       else
6577         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6578       DONE;
6579     }
6580   if (TARGET_SH2E)
6581     {
6582       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6583       DONE;
6584     }
6585 }")
6586
6587 (define_insn "mov_nop"
6588   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6589   "TARGET_SH2E"
6590   ""
6591   [(set_attr "length" "0")
6592    (set_attr "type" "nil")])
6593
6594 (define_expand "reload_insf__frn"
6595   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6596                    (match_operand:SF 1 "immediate_operand" "FQ"))
6597               (use (reg:PSI FPSCR_REG))
6598               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6599   "TARGET_SH1"
6600   "")
6601
6602 (define_expand "reload_insi__i_fpul"
6603   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6604                    (match_operand:SI 1 "immediate_operand" "i"))
6605               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6606   "TARGET_SH1"
6607   "")
6608
6609 (define_expand "ptabs"
6610   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6611   "TARGET_SHMEDIA"
6612   "
6613 {
6614   if (!TARGET_PT_FIXED)
6615     {
6616       rtx eq = operands[1];
6617
6618       /* ??? For canonical RTL we really should remove any CONST from EQ
6619          before wrapping it in the AND, and finally wrap the EQ into a
6620          const if is constant.  However, for reload we must expose the
6621          input register or symbolic constant, and we can't have
6622          different insn structures outside of the operands for different
6623          alternatives of the same pattern.  */
6624       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6625                        GEN_INT (3));
6626       operands[1]
6627         = (gen_rtx_IF_THEN_ELSE
6628             (PDImode,
6629              eq,
6630              gen_rtx_MEM (PDImode, operands[1]),
6631              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6632                             PDImode, operands[1])));
6633     }
6634 }")
6635
6636 ;; expanded by ptabs expander.
6637 (define_insn "*extendsipdi_media"
6638   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6639         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6640                                                           "r,Csy")
6641                                       (const_int 3))
6642                               (const_int 3))
6643                           (mem:PDI (match_dup 1))
6644                           (sign_extend:PDI (match_dup 1))))]
6645   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6646   "@
6647         ptabs   %1, %0
6648         pt      %1, %0"
6649   [(set_attr "type"   "ptabs_media,pt_media")
6650    (set_attr "length" "4,*")])
6651
6652 (define_insn "*truncdipdi_media"
6653   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6654         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6655                                                           "r,Csy")
6656                                       (const_int 3))
6657                               (const_int 3))
6658                           (mem:PDI (match_dup 1))
6659                           (truncate:PDI (match_dup 1))))]
6660   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6661   "@
6662         ptabs   %1, %0
6663         pt      %1, %0"
6664   [(set_attr "type"   "ptabs_media,pt_media")
6665    (set_attr "length" "4,*")])
6666
6667 (define_insn "*movsi_y"
6668   [(set (match_operand:SI 0 "register_operand" "=y,y")
6669         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6670    (clobber (match_scratch:SI 2 "=&z,r"))]
6671   "TARGET_SH2E
6672    && (reload_in_progress || reload_completed)"
6673   "#"
6674   [(set_attr "length" "4")
6675    (set_attr "type" "pcload,move")])
6676
6677 (define_split
6678   [(set (match_operand:SI 0 "register_operand" "")
6679         (match_operand:SI 1 "immediate_operand" ""))
6680    (clobber (match_operand:SI 2 "register_operand" ""))]
6681   "TARGET_SH1"
6682   [(set (match_dup 2) (match_dup 1))
6683    (set (match_dup 0) (match_dup 2))]
6684   "")
6685
6686 (define_split
6687   [(set (match_operand:SI 0 "register_operand" "")
6688         (match_operand:SI 1 "memory_operand" ""))
6689    (clobber (reg:SI R0_REG))]
6690   "TARGET_SH1"
6691   [(set (match_dup 0) (match_dup 1))]
6692   "")
6693 \f
6694 ;; ------------------------------------------------------------------------
6695 ;; Define the real conditional branch instructions.
6696 ;; ------------------------------------------------------------------------
6697
6698 (define_insn "branch_true"
6699   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6700                            (label_ref (match_operand 0 "" ""))
6701                            (pc)))]
6702   "TARGET_SH1"
6703   "* return output_branch (1, insn, operands);"
6704   [(set_attr "type" "cbranch")])
6705
6706 (define_insn "branch_false"
6707   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6708                            (label_ref (match_operand 0 "" ""))
6709                            (pc)))]
6710   "TARGET_SH1"
6711   "* return output_branch (0, insn, operands);"
6712   [(set_attr "type" "cbranch")])
6713
6714 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6715 ;; which destination is too far away.
6716 ;; The const_int_operand is distinct for each branch target; it avoids
6717 ;; unwanted matches with redundant_insn.
6718 (define_insn "block_branch_redirect"
6719   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6720   "TARGET_SH1"
6721   ""
6722   [(set_attr "length" "0")])
6723
6724 ;; This one has the additional purpose to record a possible scratch register
6725 ;; for the following branch.
6726 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6727 ;; because the insn then might be deemed dead and deleted.  And we can't
6728 ;; make the use in the jump insn explicit because that would disable
6729 ;; delay slot scheduling from the target.
6730 (define_insn "indirect_jump_scratch"
6731   [(set (match_operand:SI 0 "register_operand" "=r")
6732         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6733    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6734   "TARGET_SH1"
6735   ""
6736   [(set_attr "length" "0")])
6737
6738 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6739 ;; being pulled into the delay slot of a condbranch that has been made to
6740 ;; jump around the unconditional jump because it was out of range.
6741 (define_insn "stuff_delay_slot"
6742   [(set (pc)
6743         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6744    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6745   "TARGET_SH1"
6746   ""
6747   [(set_attr "length" "0")
6748    (set_attr "cond_delay_slot" "yes")])
6749 \f
6750 ;; Conditional branch insns
6751
6752 (define_expand "beq_media"
6753   [(set (pc)
6754         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6755                           (match_operand:DI 2 "arith_operand" "r,I06"))
6756                       (match_operand 0 "" "")
6757                       (pc)))]
6758   "TARGET_SHMEDIA"
6759   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6760
6761 (define_insn "*beq_media_i"
6762   [(set (pc)
6763         (if_then_else (match_operator 3 "equality_comparison_operator"
6764                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6765                          (match_operand:DI 2 "arith_operand" "r,I06")])
6766                       (match_operand 0 "target_operand" "b,b")
6767                       (pc)))]
6768   "TARGET_SHMEDIA"
6769   "@
6770         b%o3%'  %1, %2, %0%>
6771         b%o3i%' %1, %2, %0%>"
6772   [(set_attr "type" "cbranch_media")])
6773
6774 (define_insn "*beq_media_i32"
6775   [(set (pc)
6776         (if_then_else (match_operator 3 "equality_comparison_operator"
6777                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6778                          (match_operand:SI 2 "arith_operand" "r,I06")])
6779                       (match_operand 0 "target_operand" "b,b")
6780                       (pc)))]
6781   "TARGET_SHMEDIA"
6782   "@
6783         b%o3%'  %1, %2, %0%>
6784         b%o3i%' %1, %2, %0%>"
6785   [(set_attr "type" "cbranch_media")])
6786
6787 (define_expand "bne_media"
6788   [(set (pc)
6789         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6790                           (match_operand:DI 2 "arith_operand" "r,I06"))
6791                       (match_operand 0 "" "")
6792                       (pc)))]
6793   "TARGET_SHMEDIA"
6794   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6795
6796 (define_expand "bgt_media"
6797   [(set (pc)
6798         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6799                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6800                       (match_operand 0 "" "")
6801                       (pc)))]
6802   "TARGET_SHMEDIA"
6803   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6804
6805 (define_expand "bge_media"
6806   [(set (pc)
6807         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6808                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6809                       (match_operand 0 "" "")
6810                       (pc)))]
6811   "TARGET_SHMEDIA"
6812   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6813
6814 (define_expand "bgtu_media"
6815   [(set (pc)
6816         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6817                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6818                       (match_operand 0 "" "")
6819                       (pc)))]
6820   "TARGET_SHMEDIA"
6821   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6822
6823 (define_expand "bgeu_media"
6824   [(set (pc)
6825         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6826                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6827                       (match_operand 0 "" "")
6828                       (pc)))]
6829   "TARGET_SHMEDIA"
6830   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6831
6832 (define_insn "*bgt_media_i"
6833   [(set (pc)
6834         (if_then_else (match_operator 3 "greater_comparison_operator"
6835                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6836                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6837                       (match_operand 0 "target_operand" "b")
6838                       (pc)))]
6839   "TARGET_SHMEDIA"
6840   "b%o3%'       %N1, %N2, %0%>"
6841   [(set_attr "type" "cbranch_media")])
6842
6843 (define_insn "*bgt_media_i32"
6844   [(set (pc)
6845         (if_then_else (match_operator 3 "greater_comparison_operator"
6846                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6847                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6848                       (match_operand 0 "target_operand" "b")
6849                       (pc)))]
6850   "TARGET_SHMEDIA"
6851   "b%o3%'       %N1, %N2, %0%>"
6852   [(set_attr "type" "cbranch_media")])
6853
6854 ;; These are only needed to make invert_jump() happy - otherwise, jump
6855 ;; optimization will be silently disabled.
6856 (define_insn "*blt_media_i"
6857   [(set (pc)
6858         (if_then_else (match_operator 3 "less_comparison_operator"
6859                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6860                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6861                       (match_operand 0 "target_operand" "b")
6862                       (pc)))]
6863   "TARGET_SHMEDIA"
6864   "b%o3%'       %N2, %N1, %0%>"
6865   [(set_attr "type" "cbranch_media")])
6866
6867 (define_insn "*blt_media_i32"
6868   [(set (pc)
6869         (if_then_else (match_operator 3 "less_comparison_operator"
6870                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6871                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6872                       (match_operand 0 "target_operand" "b")
6873                       (pc)))]
6874   "TARGET_SHMEDIA"
6875   "b%o3%'       %N2, %N1, %0%>"
6876   [(set_attr "type" "cbranch_media")])
6877
6878 (define_expand "beq"
6879   [(set (pc)
6880         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6881                       (label_ref (match_operand 0 "" ""))
6882                       (pc)))]
6883   ""
6884   "
6885 {
6886   if (TARGET_SHMEDIA)
6887     {
6888       enum machine_mode mode = GET_MODE (sh_compare_op0);
6889
6890       if (mode != DImode && mode != SImode)
6891         {
6892           rtx tmp = gen_reg_rtx (DImode);
6893
6894           emit_insn (gen_seq (tmp));
6895           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6896           DONE;
6897         }
6898
6899       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6900       if (CONSTANT_P (sh_compare_op1)
6901           && (GET_CODE (sh_compare_op1) != CONST_INT
6902               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6903         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6904       emit_jump_insn (gen_beq_media (operands[0],
6905                                      sh_compare_op0, sh_compare_op1));
6906       DONE;
6907     }
6908
6909   from_compare (operands, EQ);
6910 }")
6911
6912 (define_expand "bne"
6913   [(set (pc)
6914         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6915                       (label_ref (match_operand 0 "" ""))
6916                       (pc)))]
6917   ""
6918   "
6919 {
6920   if (TARGET_SHMEDIA)
6921     {
6922       enum machine_mode mode = GET_MODE (sh_compare_op0);
6923
6924       if (mode != DImode && mode != SImode)
6925         {
6926           rtx tmp = gen_reg_rtx (DImode);
6927
6928           emit_insn (gen_seq (tmp));
6929           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6930           DONE;
6931         }
6932
6933       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6934       if (CONSTANT_P (sh_compare_op1)
6935           && (GET_CODE (sh_compare_op1) != CONST_INT
6936               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6937         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6938       emit_jump_insn (gen_bne_media (operands[0],
6939                                      sh_compare_op0, sh_compare_op1));
6940       DONE;
6941     }
6942
6943   from_compare (operands, EQ);
6944 }")
6945
6946 (define_expand "bgt"
6947   [(set (pc)
6948         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6949                       (label_ref (match_operand 0 "" ""))
6950                       (pc)))]
6951   ""
6952   "
6953 {
6954   if (TARGET_SHMEDIA)
6955     {
6956       enum machine_mode mode = GET_MODE (sh_compare_op0);
6957
6958       if (mode != DImode && mode != SImode)
6959         {
6960           rtx tmp = gen_reg_rtx (DImode);
6961
6962           emit_insn (gen_sgt (tmp));
6963           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6964           DONE;
6965         }
6966
6967       if (sh_compare_op0 != const0_rtx)
6968         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6969       if (sh_compare_op1 != const0_rtx)
6970         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6971       emit_jump_insn (gen_bgt_media (operands[0],
6972                                      sh_compare_op0, sh_compare_op1));
6973       DONE;
6974     }
6975
6976   from_compare (operands, GT);
6977 }")
6978
6979 (define_expand "blt"
6980   [(set (pc)
6981         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6982                       (label_ref (match_operand 0 "" ""))
6983                       (pc)))]
6984   ""
6985   "
6986 {
6987   if (TARGET_SHMEDIA)
6988     {
6989       enum machine_mode mode = GET_MODE (sh_compare_op0);
6990
6991       if (mode != DImode && mode != SImode)
6992         {
6993           rtx tmp = gen_reg_rtx (DImode);
6994
6995           emit_insn (gen_slt (tmp));
6996           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6997           DONE;
6998         }
6999
7000       if (sh_compare_op0 != const0_rtx)
7001         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7002       if (sh_compare_op1 != const0_rtx)
7003         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7004       emit_jump_insn (gen_bgt_media (operands[0],
7005                                      sh_compare_op1, sh_compare_op0));
7006       DONE;
7007     }
7008
7009   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7010     {
7011       rtx tmp = sh_compare_op0;
7012       sh_compare_op0 = sh_compare_op1;
7013       sh_compare_op1 = tmp;
7014       emit_insn (gen_bgt (operands[0]));
7015       DONE;
7016     }
7017   from_compare (operands, GE);
7018 }")
7019
7020 (define_expand "ble"
7021   [(set (pc)
7022         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7023                       (label_ref (match_operand 0 "" ""))
7024                       (pc)))]
7025   ""
7026   "
7027 {
7028   if (TARGET_SHMEDIA)
7029     {
7030       enum machine_mode mode = GET_MODE (sh_compare_op0);
7031
7032       if (mode != DImode && mode != SImode)
7033         {
7034           rtx tmp = gen_reg_rtx (DImode);
7035
7036           emit_insn (gen_sle (tmp));
7037           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7038           DONE;
7039         }
7040
7041       if (sh_compare_op0 != const0_rtx)
7042         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7043       if (sh_compare_op1 != const0_rtx)
7044         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7045       emit_jump_insn (gen_bge_media (operands[0],
7046                                      sh_compare_op1, sh_compare_op0));
7047       DONE;
7048     }
7049
7050   if (TARGET_SH2E
7051       && TARGET_IEEE
7052       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7053     {
7054       rtx tmp = sh_compare_op0;
7055       sh_compare_op0 = sh_compare_op1;
7056       sh_compare_op1 = tmp;
7057       emit_insn (gen_bge (operands[0]));
7058       DONE;
7059     }
7060   from_compare (operands, GT);
7061 }")
7062
7063 (define_expand "bge"
7064   [(set (pc)
7065         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7066                       (label_ref (match_operand 0 "" ""))
7067                       (pc)))]
7068   ""
7069   "
7070 {
7071   if (TARGET_SHMEDIA)
7072     {
7073       enum machine_mode mode = GET_MODE (sh_compare_op0);
7074
7075       if (mode != DImode && mode != SImode)
7076         {
7077           rtx tmp = gen_reg_rtx (DImode);
7078
7079           emit_insn (gen_sge (tmp));
7080           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7081           DONE;
7082         }
7083
7084       if (sh_compare_op0 != const0_rtx)
7085         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7086       if (sh_compare_op1 != const0_rtx)
7087         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7088       emit_jump_insn (gen_bge_media (operands[0],
7089                                      sh_compare_op0, sh_compare_op1));
7090       DONE;
7091     }
7092
7093   if (TARGET_SH2E
7094       && ! TARGET_IEEE
7095       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7096     {
7097       rtx tmp = sh_compare_op0;
7098       sh_compare_op0 = sh_compare_op1;
7099       sh_compare_op1 = tmp;
7100       emit_insn (gen_ble (operands[0]));
7101       DONE;
7102     }
7103   from_compare (operands, GE);
7104 }")
7105
7106 (define_expand "bgtu"
7107   [(set (pc)
7108         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7109                       (label_ref (match_operand 0 "" ""))
7110                       (pc)))]
7111   ""
7112   "
7113 {
7114   if (TARGET_SHMEDIA)
7115     {
7116       enum machine_mode mode = GET_MODE (sh_compare_op0);
7117
7118       if (sh_compare_op0 != const0_rtx)
7119         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7120       if (sh_compare_op1 != const0_rtx)
7121         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7122       emit_jump_insn (gen_bgtu_media (operands[0],
7123                                       sh_compare_op0, sh_compare_op1));
7124       DONE;
7125     }
7126
7127   from_compare (operands, GTU);
7128 }")
7129
7130 (define_expand "bltu"
7131   [(set (pc)
7132         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7133                       (label_ref (match_operand 0 "" ""))
7134                       (pc)))]
7135   ""
7136   "
7137 {
7138   if (TARGET_SHMEDIA)
7139     {
7140       enum machine_mode mode = GET_MODE (sh_compare_op0);
7141
7142       if (sh_compare_op0 != const0_rtx)
7143         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7144       if (sh_compare_op1 != const0_rtx)
7145         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7146       emit_jump_insn (gen_bgtu_media (operands[0],
7147                                       sh_compare_op1, sh_compare_op0));
7148       DONE;
7149     }
7150
7151   from_compare (operands, GEU);
7152 }")
7153
7154 (define_expand "bgeu"
7155   [(set (pc)
7156         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7157                       (label_ref (match_operand 0 "" ""))
7158                       (pc)))]
7159   ""
7160   "
7161 {
7162   if (TARGET_SHMEDIA)
7163     {
7164       enum machine_mode mode = GET_MODE (sh_compare_op0);
7165
7166       if (sh_compare_op0 != const0_rtx)
7167         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7168       if (sh_compare_op1 != const0_rtx)
7169         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7170       emit_jump_insn (gen_bgeu_media (operands[0],
7171                                       sh_compare_op0, sh_compare_op1));
7172       DONE;
7173     }
7174
7175   from_compare (operands, GEU);
7176 }")
7177
7178 (define_expand "bleu"
7179   [(set (pc)
7180         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7181                       (label_ref (match_operand 0 "" ""))
7182                       (pc)))]
7183   ""
7184   "
7185 {
7186   if (TARGET_SHMEDIA)
7187     {
7188       enum machine_mode mode = GET_MODE (sh_compare_op0);
7189
7190       if (sh_compare_op0 != const0_rtx)
7191         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7192       if (sh_compare_op1 != const0_rtx)
7193         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7194       emit_jump_insn (gen_bgeu_media (operands[0],
7195                                       sh_compare_op1, sh_compare_op0));
7196       DONE;
7197     }
7198
7199   from_compare (operands, GTU);
7200 }")
7201
7202 (define_expand "bunordered"
7203   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7204    (set (pc)
7205         (if_then_else (ne (match_dup 1) (const_int 0))
7206                       (match_operand 0 "" "")
7207                       (pc)))]
7208   "TARGET_SHMEDIA"
7209   "
7210 {
7211   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7212   operands[1] = gen_reg_rtx (DImode);
7213   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7214   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7215 }")
7216
7217 ;; combiner splitter for test-and-branch on single bit in register.  This
7218 ;; is endian dependent because the non-paradoxical subreg looks different
7219 ;; on big endian.
7220 (define_split
7221   [(set (pc)
7222         (if_then_else
7223           (match_operator 3 "equality_comparison_operator"
7224             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7225                                                       "extend_reg_operand" "")
7226                                                     0)
7227                                          (const_int 1)
7228                                          (match_operand 2
7229                                           "const_int_operand" "")) 0)
7230              (const_int 0)])
7231           (match_operand 0 "target_operand" "")
7232           (pc)))
7233    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7234   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7235   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7236    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7237
7238   "
7239 {
7240   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7241   operands[6] = (GET_CODE (operands[3]) == EQ
7242                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7243                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7244 }")
7245 \f
7246 ;; ------------------------------------------------------------------------
7247 ;; Jump and linkage insns
7248 ;; ------------------------------------------------------------------------
7249
7250 (define_insn "jump_compact"
7251   [(set (pc)
7252         (label_ref (match_operand 0 "" "")))]
7253   "TARGET_SH1"
7254   "*
7255 {
7256   /* The length is 16 if the delay slot is unfilled.  */
7257   if (get_attr_length(insn) > 4)
7258     return output_far_jump(insn, operands[0]);
7259   else
7260     return   \"bra      %l0%#\";
7261 }"
7262   [(set_attr "type" "jump")
7263    (set_attr "needs_delay_slot" "yes")])
7264
7265 ;; ??? It would be much saner to explicitly use the scratch register
7266 ;; in the jump insn, and have indirect_jump_scratch only set it,
7267 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7268 ;; from the target then, as it uses simplejump_p.
7269 ;;(define_insn "jump_compact_far"
7270 ;;  [(set (pc)
7271 ;;      (label_ref (match_operand 0 "" "")))
7272 ;;   (use (match_operand 1 "register_operand" "r")]
7273 ;;  "TARGET_SH1"
7274 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7275 ;;  [(set_attr "type" "jump")
7276 ;;   (set_attr "needs_delay_slot" "yes")])
7277
7278 (define_insn "jump_media"
7279   [(set (pc)
7280         (match_operand 0 "target_operand" "b"))]
7281   "TARGET_SHMEDIA"
7282   "blink        %0, r63%>"
7283   [(set_attr "type" "jump_media")])
7284
7285 (define_expand "jump"
7286   [(set (pc)
7287         (label_ref (match_operand 0 "" "")))]
7288   ""
7289   "
7290 {
7291   if (TARGET_SH1)
7292     emit_jump_insn (gen_jump_compact (operands[0]));
7293   else if (TARGET_SHMEDIA)
7294     {
7295       if (reload_in_progress || reload_completed)
7296         FAIL;
7297       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7298                                                          operands[0])));
7299     }
7300   DONE;
7301 }")
7302
7303 (define_insn "force_mode_for_call"
7304   [(use (reg:PSI FPSCR_REG))]
7305   "TARGET_SHCOMPACT"
7306   ""
7307   [(set_attr "length" "0")
7308    (set (attr "fp_mode")
7309         (if_then_else (eq_attr "fpu_single" "yes")
7310                       (const_string "single") (const_string "double")))])
7311
7312 (define_insn "calli"
7313   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7314          (match_operand 1 "" ""))
7315    (use (reg:PSI FPSCR_REG))
7316    (clobber (reg:SI PR_REG))]
7317   "TARGET_SH1"
7318   "jsr  @%0%#"
7319   [(set_attr "type" "call")
7320    (set (attr "fp_mode")
7321         (if_then_else (eq_attr "fpu_single" "yes")
7322                       (const_string "single") (const_string "double")))
7323    (set_attr "needs_delay_slot" "yes")
7324    (set_attr "fp_set" "unknown")])
7325
7326 ;; This is a pc-rel call, using bsrf, for use with PIC.
7327
7328 (define_insn "calli_pcrel"
7329   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7330          (match_operand 1 "" ""))
7331    (use (reg:PSI FPSCR_REG))
7332    (use (reg:SI PIC_REG))
7333    (use (match_operand 2 "" ""))
7334    (clobber (reg:SI PR_REG))]
7335   "TARGET_SH2"
7336   "bsrf %0\\n%O2:%#"
7337   [(set_attr "type" "call")
7338    (set (attr "fp_mode")
7339         (if_then_else (eq_attr "fpu_single" "yes")
7340                       (const_string "single") (const_string "double")))
7341    (set_attr "needs_delay_slot" "yes")
7342    (set_attr "fp_set" "unknown")])
7343
7344 (define_insn_and_split "call_pcrel"
7345   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7346          (match_operand 1 "" ""))
7347    (use (reg:PSI FPSCR_REG))
7348    (use (reg:SI PIC_REG))
7349    (clobber (reg:SI PR_REG))
7350    (clobber (match_scratch:SI 2 "=r"))]
7351   "TARGET_SH2"
7352   "#"
7353   "reload_completed"
7354   [(const_int 0)]
7355   "
7356 {
7357   rtx lab = PATTERN (gen_call_site ());
7358
7359   if (SYMBOL_REF_LOCAL_P (operands[0]))
7360     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7361   else
7362     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7363   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7364   DONE;
7365 }"
7366   [(set_attr "type" "call")
7367    (set (attr "fp_mode")
7368         (if_then_else (eq_attr "fpu_single" "yes")
7369                       (const_string "single") (const_string "double")))
7370    (set_attr "needs_delay_slot" "yes")
7371    (set_attr "fp_set" "unknown")])
7372
7373 (define_insn "call_compact"
7374   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7375          (match_operand 1 "" ""))
7376    (match_operand 2 "immediate_operand" "n")
7377    (use (reg:SI R0_REG))
7378    (use (reg:SI R1_REG))
7379    (use (reg:PSI FPSCR_REG))
7380    (clobber (reg:SI PR_REG))]
7381   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7382   "jsr  @%0%#"
7383   [(set_attr "type" "call")
7384    (set (attr "fp_mode")
7385         (if_then_else (eq_attr "fpu_single" "yes")
7386                       (const_string "single") (const_string "double")))
7387    (set_attr "needs_delay_slot" "yes")])
7388
7389 (define_insn "call_compact_rettramp"
7390   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7391          (match_operand 1 "" ""))
7392    (match_operand 2 "immediate_operand" "n")
7393    (use (reg:SI R0_REG))
7394    (use (reg:SI R1_REG))
7395    (use (reg:PSI FPSCR_REG))
7396    (clobber (reg:SI R10_REG))
7397    (clobber (reg:SI PR_REG))]
7398   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7399   "jsr  @%0%#"
7400   [(set_attr "type" "call")
7401    (set (attr "fp_mode")
7402         (if_then_else (eq_attr "fpu_single" "yes")
7403                       (const_string "single") (const_string "double")))
7404    (set_attr "needs_delay_slot" "yes")])
7405
7406 (define_insn "call_media"
7407   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7408          (match_operand 1 "" ""))
7409    (clobber (reg:DI PR_MEDIA_REG))]
7410   "TARGET_SHMEDIA"
7411   "blink        %0, r18"
7412   [(set_attr "type" "jump_media")])
7413
7414 (define_insn "call_valuei"
7415   [(set (match_operand 0 "" "=rf")
7416         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7417               (match_operand 2 "" "")))
7418    (use (reg:PSI FPSCR_REG))
7419    (clobber (reg:SI PR_REG))]
7420   "TARGET_SH1"
7421   "jsr  @%1%#"
7422   [(set_attr "type" "call")
7423    (set (attr "fp_mode")
7424         (if_then_else (eq_attr "fpu_single" "yes")
7425                       (const_string "single") (const_string "double")))
7426    (set_attr "needs_delay_slot" "yes")
7427    (set_attr "fp_set" "unknown")])
7428
7429 (define_insn "call_valuei_pcrel"
7430   [(set (match_operand 0 "" "=rf")
7431         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7432               (match_operand 2 "" "")))
7433    (use (reg:PSI FPSCR_REG))
7434    (use (reg:SI PIC_REG))
7435    (use (match_operand 3 "" ""))
7436    (clobber (reg:SI PR_REG))]
7437   "TARGET_SH2"
7438   "bsrf %1\\n%O3:%#"
7439   [(set_attr "type" "call")
7440    (set (attr "fp_mode")
7441         (if_then_else (eq_attr "fpu_single" "yes")
7442                       (const_string "single") (const_string "double")))
7443    (set_attr "needs_delay_slot" "yes")
7444    (set_attr "fp_set" "unknown")])
7445
7446 (define_insn_and_split "call_value_pcrel"
7447   [(set (match_operand 0 "" "=rf")
7448         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7449               (match_operand 2 "" "")))
7450    (use (reg:PSI FPSCR_REG))
7451    (use (reg:SI PIC_REG))
7452    (clobber (reg:SI PR_REG))
7453    (clobber (match_scratch:SI 3 "=r"))]
7454   "TARGET_SH2"
7455   "#"
7456   "reload_completed"
7457   [(const_int 0)]
7458   "
7459 {
7460   rtx lab = PATTERN (gen_call_site ());
7461
7462   if (SYMBOL_REF_LOCAL_P (operands[1]))
7463     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7464   else
7465     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7466   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7467                                          operands[2], lab));
7468   DONE;
7469 }"
7470   [(set_attr "type" "call")
7471    (set (attr "fp_mode")
7472         (if_then_else (eq_attr "fpu_single" "yes")
7473                       (const_string "single") (const_string "double")))
7474    (set_attr "needs_delay_slot" "yes")
7475    (set_attr "fp_set" "unknown")])
7476
7477 (define_insn "call_value_compact"
7478   [(set (match_operand 0 "" "=rf")
7479         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7480               (match_operand 2 "" "")))
7481    (match_operand 3 "immediate_operand" "n")
7482    (use (reg:SI R0_REG))
7483    (use (reg:SI R1_REG))
7484    (use (reg:PSI FPSCR_REG))
7485    (clobber (reg:SI PR_REG))]
7486   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7487   "jsr  @%1%#"
7488   [(set_attr "type" "call")
7489    (set (attr "fp_mode")
7490         (if_then_else (eq_attr "fpu_single" "yes")
7491                       (const_string "single") (const_string "double")))
7492    (set_attr "needs_delay_slot" "yes")])
7493
7494 (define_insn "call_value_compact_rettramp"
7495   [(set (match_operand 0 "" "=rf")
7496         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7497               (match_operand 2 "" "")))
7498    (match_operand 3 "immediate_operand" "n")
7499    (use (reg:SI R0_REG))
7500    (use (reg:SI R1_REG))
7501    (use (reg:PSI FPSCR_REG))
7502    (clobber (reg:SI R10_REG))
7503    (clobber (reg:SI PR_REG))]
7504   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7505   "jsr  @%1%#"
7506   [(set_attr "type" "call")
7507    (set (attr "fp_mode")
7508         (if_then_else (eq_attr "fpu_single" "yes")
7509                       (const_string "single") (const_string "double")))
7510    (set_attr "needs_delay_slot" "yes")])
7511
7512 (define_insn "call_value_media"
7513   [(set (match_operand 0 "" "=rf")
7514         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7515               (match_operand 2 "" "")))
7516    (clobber (reg:DI PR_MEDIA_REG))]
7517   "TARGET_SHMEDIA"
7518   "blink        %1, r18"
7519   [(set_attr "type" "jump_media")])
7520
7521 (define_expand "call"
7522   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7523                             (match_operand 1 "" ""))
7524               (match_operand 2 "" "")
7525               (use (reg:PSI FPSCR_REG))
7526               (clobber (reg:SI PR_REG))])]
7527   ""
7528   "
7529 {
7530   if (TARGET_SHMEDIA)
7531     {
7532       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7533       emit_call_insn (gen_call_media (operands[0], operands[1]));
7534       DONE;
7535     }
7536   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7537     {
7538       rtx cookie_rtx = operands[2];
7539       long cookie = INTVAL (cookie_rtx);
7540       rtx func = XEXP (operands[0], 0);
7541       rtx r0, r1;
7542
7543       if (flag_pic)
7544         {
7545           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7546             {
7547               rtx reg = gen_reg_rtx (Pmode);
7548
7549               emit_insn (gen_symGOTPLT2reg (reg, func));
7550               func = reg;
7551             }
7552           else
7553             func = legitimize_pic_address (func, Pmode, 0);
7554         }
7555
7556       r0 = gen_rtx_REG (SImode, R0_REG);
7557       r1 = gen_rtx_REG (SImode, R1_REG);
7558
7559       /* Since such a call function may use all call-clobbered
7560          registers, we force a mode switch earlier, so that we don't
7561          run out of registers when adjusting fpscr for the call.  */
7562       emit_insn (gen_force_mode_for_call ());
7563
7564       operands[0]
7565         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7566                            SFUNC_GOT);
7567       operands[0] = force_reg (SImode, operands[0]);
7568
7569       emit_move_insn (r0, func);
7570       emit_move_insn (r1, cookie_rtx);
7571
7572       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7573         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7574                                                    operands[2]));
7575       else
7576         emit_call_insn (gen_call_compact (operands[0], operands[1],
7577                                           operands[2]));
7578
7579       DONE;
7580     }
7581   else if (TARGET_SHCOMPACT && flag_pic
7582            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7583            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7584     {
7585       rtx reg = gen_reg_rtx (Pmode);
7586
7587       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7588       XEXP (operands[0], 0) = reg;
7589     }
7590   if (flag_pic && TARGET_SH2
7591       && GET_CODE (operands[0]) == MEM
7592       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7593     {
7594       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7595       DONE;
7596     }
7597   else
7598   {
7599     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7600     operands[1] = operands[2];
7601   }
7602
7603   emit_call_insn (gen_calli (operands[0], operands[1]));
7604   DONE;
7605 }")
7606
7607 (define_insn "call_pop_compact"
7608   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7609          (match_operand 1 "" ""))
7610    (match_operand 2 "immediate_operand" "n")
7611    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7612                                  (match_operand 3 "immediate_operand" "n")))
7613    (use (reg:SI R0_REG))
7614    (use (reg:SI R1_REG))
7615    (use (reg:PSI FPSCR_REG))
7616    (clobber (reg:SI PR_REG))]
7617   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7618   "jsr  @%0%#"
7619   [(set_attr "type" "call")
7620    (set (attr "fp_mode")
7621         (if_then_else (eq_attr "fpu_single" "yes")
7622                       (const_string "single") (const_string "double")))
7623    (set_attr "needs_delay_slot" "yes")])
7624
7625 (define_insn "call_pop_compact_rettramp"
7626   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7627          (match_operand 1 "" ""))
7628    (match_operand 2 "immediate_operand" "n")
7629    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7630                                  (match_operand 3 "immediate_operand" "n")))
7631    (use (reg:SI R0_REG))
7632    (use (reg:SI R1_REG))
7633    (use (reg:PSI FPSCR_REG))
7634    (clobber (reg:SI R10_REG))
7635    (clobber (reg:SI PR_REG))]
7636   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7637   "jsr  @%0%#"
7638   [(set_attr "type" "call")
7639    (set (attr "fp_mode")
7640         (if_then_else (eq_attr "fpu_single" "yes")
7641                       (const_string "single") (const_string "double")))
7642    (set_attr "needs_delay_slot" "yes")])
7643
7644 (define_expand "call_pop"
7645   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7646                     (match_operand 1 "" ""))
7647              (match_operand 2 "" "")
7648              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7649                                            (match_operand 3 "" "")))])]
7650   "TARGET_SHCOMPACT"
7651   "
7652 {
7653   rtx cookie_rtx;
7654   long cookie;
7655   rtx func;
7656   rtx r0, r1;
7657
7658   gcc_assert (operands[2] && INTVAL (operands[2]));
7659   cookie_rtx = operands[2];
7660   cookie = INTVAL (cookie_rtx);
7661   func = XEXP (operands[0], 0);
7662
7663   if (flag_pic)
7664     {
7665       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7666         {
7667           rtx reg = gen_reg_rtx (Pmode);
7668           emit_insn (gen_symGOTPLT2reg (reg, func));
7669           func = reg;
7670         }
7671       else
7672         func = legitimize_pic_address (func, Pmode, 0);
7673     }
7674
7675   r0 = gen_rtx_REG (SImode, R0_REG);
7676   r1 = gen_rtx_REG (SImode, R1_REG);
7677
7678   /* Since such a call function may use all call-clobbered
7679      registers, we force a mode switch earlier, so that we don't
7680      run out of registers when adjusting fpscr for the call.  */
7681   emit_insn (gen_force_mode_for_call ());
7682
7683   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7684                                  SFUNC_GOT);
7685   operands[0] = force_reg (SImode, operands[0]);
7686
7687   emit_move_insn (r0, func);
7688   emit_move_insn (r1, cookie_rtx);
7689
7690   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7691     emit_call_insn (gen_call_pop_compact_rettramp
7692                      (operands[0], operands[1], operands[2], operands[3]));
7693   else
7694     emit_call_insn (gen_call_pop_compact
7695                      (operands[0], operands[1], operands[2], operands[3]));
7696
7697   DONE;
7698 }")
7699
7700 (define_expand "call_value"
7701   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7702                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7703                                  (match_operand 2 "" "")))
7704               (match_operand 3 "" "")
7705               (use (reg:PSI FPSCR_REG))
7706               (clobber (reg:SI PR_REG))])]
7707   ""
7708   "
7709 {
7710   if (TARGET_SHMEDIA)
7711     {
7712       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7713       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7714                                             operands[2]));
7715       DONE;
7716     }
7717   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7718     {
7719       rtx cookie_rtx = operands[3];
7720       long cookie = INTVAL (cookie_rtx);
7721       rtx func = XEXP (operands[1], 0);
7722       rtx r0, r1;
7723
7724       if (flag_pic)
7725         {
7726           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7727             {
7728               rtx reg = gen_reg_rtx (Pmode);
7729
7730               emit_insn (gen_symGOTPLT2reg (reg, func));
7731               func = reg;
7732             }
7733           else
7734             func = legitimize_pic_address (func, Pmode, 0);
7735         }
7736
7737       r0 = gen_rtx_REG (SImode, R0_REG);
7738       r1 = gen_rtx_REG (SImode, R1_REG);
7739
7740       /* Since such a call function may use all call-clobbered
7741          registers, we force a mode switch earlier, so that we don't
7742          run out of registers when adjusting fpscr for the call.  */
7743       emit_insn (gen_force_mode_for_call ());
7744
7745       operands[1]
7746         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7747                            SFUNC_GOT);
7748       operands[1] = force_reg (SImode, operands[1]);
7749
7750       emit_move_insn (r0, func);
7751       emit_move_insn (r1, cookie_rtx);
7752
7753       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7754         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7755                                                          operands[1],
7756                                                          operands[2],
7757                                                          operands[3]));
7758       else
7759         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7760                                                 operands[2], operands[3]));
7761
7762       DONE;
7763     }
7764   else if (TARGET_SHCOMPACT && flag_pic
7765            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7766            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7767     {
7768       rtx reg = gen_reg_rtx (Pmode);
7769
7770       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7771       XEXP (operands[1], 0) = reg;
7772     }
7773   if (flag_pic && TARGET_SH2
7774       && GET_CODE (operands[1]) == MEM
7775       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7776     {
7777       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7778                                             operands[2]));
7779       DONE;
7780     }
7781   else
7782     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7783
7784   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7785   DONE;
7786 }")
7787
7788 (define_insn "sibcalli"
7789   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7790          (match_operand 1 "" ""))
7791    (use (reg:PSI FPSCR_REG))
7792    (return)]
7793   "TARGET_SH1"
7794   "jmp  @%0%#"
7795   [(set_attr "needs_delay_slot" "yes")
7796    (set (attr "fp_mode")
7797         (if_then_else (eq_attr "fpu_single" "yes")
7798                       (const_string "single") (const_string "double")))
7799    (set_attr "type" "jump_ind")])
7800
7801 (define_insn "sibcalli_pcrel"
7802   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7803          (match_operand 1 "" ""))
7804    (use (match_operand 2 "" ""))
7805    (use (reg:PSI FPSCR_REG))
7806    (return)]
7807   "TARGET_SH2"
7808   "braf %0\\n%O2:%#"
7809   [(set_attr "needs_delay_slot" "yes")
7810    (set (attr "fp_mode")
7811         (if_then_else (eq_attr "fpu_single" "yes")
7812                       (const_string "single") (const_string "double")))
7813    (set_attr "type" "jump_ind")])
7814
7815 ;; This uses an unspec to describe that the symbol_ref is very close.
7816 (define_insn "sibcalli_thunk"
7817   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7818                              UNSPEC_THUNK))
7819          (match_operand 1 "" ""))
7820    (use (reg:PSI FPSCR_REG))
7821    (return)]
7822   "TARGET_SH1"
7823   "bra  %O0"
7824   [(set_attr "needs_delay_slot" "yes")
7825    (set (attr "fp_mode")
7826         (if_then_else (eq_attr "fpu_single" "yes")
7827                       (const_string "single") (const_string "double")))
7828    (set_attr "type" "jump")
7829    (set_attr "length" "2")])
7830
7831 (define_insn_and_split "sibcall_pcrel"
7832   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7833          (match_operand 1 "" ""))
7834    (use (reg:PSI FPSCR_REG))
7835    (clobber (match_scratch:SI 2 "=k"))
7836    (return)]
7837   "TARGET_SH2"
7838   "#"
7839   "reload_completed"
7840   [(const_int 0)]
7841   "
7842 {
7843   rtx lab = PATTERN (gen_call_site ());
7844   rtx call_insn;
7845
7846   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7847   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7848                                                   lab));
7849   SIBLING_CALL_P (call_insn) = 1;
7850   DONE;
7851 }"
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_ind")])
7857
7858 (define_insn "sibcall_compact"
7859   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7860          (match_operand 1 "" ""))
7861    (return)
7862    (use (match_operand:SI 2 "register_operand" "z,x"))
7863    (use (reg:SI R1_REG))
7864    (use (reg:PSI FPSCR_REG))
7865    ;; We want to make sure the `x' above will only match MACH_REG
7866    ;; because sibcall_epilogue may clobber MACL_REG.
7867    (clobber (reg:SI MACL_REG))]
7868   "TARGET_SHCOMPACT"
7869   "@
7870         jmp     @%0%#
7871         jmp     @%0\\n  sts     %2, r0"
7872   [(set_attr "needs_delay_slot" "yes,no")
7873    (set_attr "length" "2,4")
7874    (set (attr "fp_mode") (const_string "single"))
7875    (set_attr "type" "jump_ind")])
7876
7877 (define_insn "sibcall_media"
7878   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7879          (match_operand 1 "" ""))
7880    (use (reg:SI PR_MEDIA_REG))
7881    (return)]
7882   "TARGET_SHMEDIA"
7883   "blink        %0, r63"
7884   [(set_attr "type" "jump_media")])
7885
7886 (define_expand "sibcall"
7887   [(parallel
7888     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7889            (match_operand 1 "" ""))
7890      (match_operand 2 "" "")
7891      (use (reg:PSI FPSCR_REG))
7892      (return)])]
7893   ""
7894   "
7895 {
7896   if (TARGET_SHMEDIA)
7897     {
7898       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7899       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7900       DONE;
7901     }
7902   else if (TARGET_SHCOMPACT && operands[2]
7903            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7904     {
7905       rtx cookie_rtx = operands[2];
7906       long cookie = INTVAL (cookie_rtx);
7907       rtx func = XEXP (operands[0], 0);
7908       rtx mach, r1;
7909
7910       if (flag_pic)
7911         {
7912           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7913             {
7914               rtx reg = gen_reg_rtx (Pmode);
7915
7916               emit_insn (gen_symGOT2reg (reg, func));
7917               func = reg;
7918             }
7919           else
7920             func = legitimize_pic_address (func, Pmode, 0);
7921         }
7922
7923       /* FIXME: if we could tell whether all argument registers are
7924          already taken, we could decide whether to force the use of
7925          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7926          simple way to tell.  We could use the CALL_COOKIE, but we
7927          can't currently tell a register used for regular argument
7928          passing from one that is unused.  If we leave it up to reload
7929          to decide which register to use, it seems to always choose
7930          R0_REG, which leaves no available registers in SIBCALL_REGS
7931          to hold the address of the trampoline.  */
7932       mach = gen_rtx_REG (SImode, MACH_REG);
7933       r1 = gen_rtx_REG (SImode, R1_REG);
7934
7935       /* Since such a call function may use all call-clobbered
7936          registers, we force a mode switch earlier, so that we don't
7937          run out of registers when adjusting fpscr for the call.  */
7938       emit_insn (gen_force_mode_for_call ());
7939
7940       operands[0]
7941         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7942                            SFUNC_GOT);
7943       operands[0] = force_reg (SImode, operands[0]);
7944
7945       /* We don't need a return trampoline, since the callee will
7946          return directly to the upper caller.  */
7947       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7948         {
7949           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7950           cookie_rtx = GEN_INT (cookie);
7951         }
7952
7953       emit_move_insn (mach, func);
7954       emit_move_insn (r1, cookie_rtx);
7955
7956       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7957       DONE;
7958     }
7959   else if (TARGET_SHCOMPACT && flag_pic
7960            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7961            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7962     {
7963       rtx reg = gen_reg_rtx (Pmode);
7964
7965       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7966       XEXP (operands[0], 0) = reg;
7967     }
7968   if (flag_pic && TARGET_SH2
7969       && GET_CODE (operands[0]) == MEM
7970       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7971       /* The PLT needs the PIC register, but the epilogue would have
7972          to restore it, so we can only use PC-relative PIC calls for
7973          static functions.  */
7974       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7975     {
7976       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7977       DONE;
7978     }
7979   else
7980     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7981
7982   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7983   DONE;
7984 }")
7985
7986 (define_expand "sibcall_value"
7987   [(set (match_operand 0 "" "")
7988         (call (match_operand 1 "" "")
7989               (match_operand 2 "" "")))
7990    (match_operand 3 "" "")]
7991   ""
7992   "
7993 {
7994   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7995   DONE;
7996 }")
7997
7998 (define_insn "call_value_pop_compact"
7999   [(set (match_operand 0 "" "=rf")
8000         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8001               (match_operand 2 "" "")))
8002    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8003                                  (match_operand 4 "immediate_operand" "n")))
8004    (match_operand 3 "immediate_operand" "n")
8005    (use (reg:SI R0_REG))
8006    (use (reg:SI R1_REG))
8007    (use (reg:PSI FPSCR_REG))
8008    (clobber (reg:SI PR_REG))]
8009   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8010   "jsr  @%1%#"
8011   [(set_attr "type" "call")
8012    (set (attr "fp_mode")
8013         (if_then_else (eq_attr "fpu_single" "yes")
8014                       (const_string "single") (const_string "double")))
8015    (set_attr "needs_delay_slot" "yes")])
8016
8017 (define_insn "call_value_pop_compact_rettramp"
8018   [(set (match_operand 0 "" "=rf")
8019         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8020               (match_operand 2 "" "")))
8021    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8022                                  (match_operand 4 "immediate_operand" "n")))
8023    (match_operand 3 "immediate_operand" "n")
8024    (use (reg:SI R0_REG))
8025    (use (reg:SI R1_REG))
8026    (use (reg:PSI FPSCR_REG))
8027    (clobber (reg:SI R10_REG))
8028    (clobber (reg:SI PR_REG))]
8029   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8030   "jsr  @%1%#"
8031   [(set_attr "type" "call")
8032    (set (attr "fp_mode")
8033         (if_then_else (eq_attr "fpu_single" "yes")
8034                       (const_string "single") (const_string "double")))
8035    (set_attr "needs_delay_slot" "yes")])
8036
8037 (define_expand "call_value_pop"
8038   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8039                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8040                                  (match_operand 2 "" "")))
8041               (match_operand 3 "" "")
8042               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8043                                             (match_operand 4 "" "")))])]
8044   "TARGET_SHCOMPACT"
8045   "
8046 {
8047   rtx cookie_rtx;
8048   long cookie;
8049   rtx func;
8050   rtx r0, r1;
8051
8052   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8053   cookie_rtx = operands[3];
8054   cookie = INTVAL (cookie_rtx);
8055   func = XEXP (operands[1], 0);
8056
8057   if (flag_pic)
8058     {
8059       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8060         {
8061           rtx reg = gen_reg_rtx (Pmode);
8062
8063           emit_insn (gen_symGOTPLT2reg (reg, func));
8064           func = reg;
8065         }
8066       else
8067         func = legitimize_pic_address (func, Pmode, 0);
8068     }
8069
8070   r0 = gen_rtx_REG (SImode, R0_REG);
8071   r1 = gen_rtx_REG (SImode, R1_REG);
8072
8073   /* Since such a call function may use all call-clobbered
8074      registers, we force a mode switch earlier, so that we don't
8075      run out of registers when adjusting fpscr for the call.  */
8076   emit_insn (gen_force_mode_for_call ());
8077
8078   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8079                                  SFUNC_GOT);
8080   operands[1] = force_reg (SImode, operands[1]);
8081
8082   emit_move_insn (r0, func);
8083   emit_move_insn (r1, cookie_rtx);
8084
8085   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8086     emit_call_insn (gen_call_value_pop_compact_rettramp
8087                         (operands[0], operands[1], operands[2],
8088                          operands[3], operands[4]));
8089   else
8090     emit_call_insn (gen_call_value_pop_compact
8091                         (operands[0], operands[1], operands[2],
8092                          operands[3], operands[4]));
8093
8094   DONE;
8095 }")
8096
8097 (define_expand "sibcall_epilogue"
8098   [(return)]
8099   ""
8100   "
8101 {
8102   sh_expand_epilogue (1);
8103   if (TARGET_SHCOMPACT)
8104     {
8105       rtx insn, set;
8106
8107       /* If epilogue clobbers r0, preserve it in macl.  */
8108       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8109         if ((set = single_set (insn))
8110             && GET_CODE (SET_DEST (set)) == REG
8111             && REGNO (SET_DEST (set)) == R0_REG)
8112           {
8113             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8114             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8115             rtx i;
8116
8117             /* We can't tell at this point whether the sibcall is a
8118                sibcall_compact and, if it is, whether it uses r0 or
8119                mach as operand 2, so let the instructions that
8120                preserve r0 be optimized away if r0 turns out to be
8121                dead.  */
8122             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8123             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8124                                                REG_NOTES (i));
8125             i = emit_move_insn (r0, tmp);
8126             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8127                                                REG_NOTES (i));
8128             break;
8129           }
8130     }
8131   DONE;
8132 }")
8133
8134 (define_insn "indirect_jump_compact"
8135   [(set (pc)
8136         (match_operand:SI 0 "arith_reg_operand" "r"))]
8137   "TARGET_SH1"
8138   "jmp  @%0%#"
8139   [(set_attr "needs_delay_slot" "yes")
8140    (set_attr "type" "jump_ind")])
8141
8142 (define_expand "indirect_jump"
8143   [(set (pc)
8144         (match_operand 0 "register_operand" ""))]
8145   ""
8146   "
8147 {
8148   if (GET_MODE (operands[0]) != Pmode)
8149     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8150 }")
8151
8152 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8153 ;; which can be present in structured code from indirect jumps which can not
8154 ;; be present in structured code.  This allows -fprofile-arcs to work.
8155
8156 ;; For SH1 processors.
8157 (define_insn "casesi_jump_1"
8158   [(set (pc)
8159         (match_operand:SI 0 "register_operand" "r"))
8160    (use (label_ref (match_operand 1 "" "")))]
8161   "TARGET_SH1"
8162   "jmp  @%0%#"
8163   [(set_attr "needs_delay_slot" "yes")
8164    (set_attr "type" "jump_ind")])
8165
8166 ;; For all later processors.
8167 (define_insn "casesi_jump_2"
8168   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8169                       (label_ref (match_operand 1 "" ""))))
8170    (use (label_ref (match_operand 2 "" "")))]
8171   "TARGET_SH2
8172    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8173   "braf %0%#"
8174   [(set_attr "needs_delay_slot" "yes")
8175    (set_attr "type" "jump_ind")])
8176
8177 (define_insn "casesi_jump_media"
8178   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8179    (use (label_ref (match_operand 1 "" "")))]
8180   "TARGET_SHMEDIA"
8181   "blink        %0, r63"
8182   [(set_attr "type" "jump_media")])
8183
8184 ;; Call subroutine returning any type.
8185 ;; ??? This probably doesn't work.
8186
8187 (define_expand "untyped_call"
8188   [(parallel [(call (match_operand 0 "" "")
8189                     (const_int 0))
8190               (match_operand 1 "" "")
8191               (match_operand 2 "" "")])]
8192   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8193   "
8194 {
8195   int i;
8196
8197   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8198
8199   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8200     {
8201       rtx set = XVECEXP (operands[2], 0, i);
8202       emit_move_insn (SET_DEST (set), SET_SRC (set));
8203     }
8204
8205   /* The optimizer does not know that the call sets the function value
8206      registers we stored in the result block.  We avoid problems by
8207      claiming that all hard registers are used and clobbered at this
8208      point.  */
8209   emit_insn (gen_blockage ());
8210
8211   DONE;
8212 }")
8213 \f
8214 ;; ------------------------------------------------------------------------
8215 ;; Misc insns
8216 ;; ------------------------------------------------------------------------
8217
8218 (define_insn "dect"
8219   [(set (reg:SI T_REG)
8220         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8221    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8222   "TARGET_SH2"
8223   "dt   %0"
8224   [(set_attr "type" "arith")])
8225
8226 (define_insn "nop"
8227   [(const_int 0)]
8228   ""
8229   "nop")
8230
8231 ;; Load address of a label. This is only generated by the casesi expand,
8232 ;; and by machine_dependent_reorg (fixing up fp moves).
8233 ;; This must use unspec, because this only works for labels that are
8234 ;; within range,
8235
8236 (define_insn "mova"
8237   [(set (reg:SI R0_REG)
8238         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8239   "TARGET_SH1"
8240   "mova %O0,r0"
8241   [(set_attr "in_delay_slot" "no")
8242    (set_attr "type" "arith")])
8243
8244 ;; machine_dependent_reorg will make this a `mova'.
8245 (define_insn "mova_const"
8246   [(set (reg:SI R0_REG)
8247         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8248   "TARGET_SH1"
8249   "#"
8250   [(set_attr "in_delay_slot" "no")
8251    (set_attr "type" "arith")])
8252
8253 (define_expand "GOTaddr2picreg"
8254   [(set (reg:SI R0_REG)
8255         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8256                    UNSPEC_MOVA))
8257    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8258    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8259   "" "
8260 {
8261   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8262   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8263
8264   if (TARGET_SHMEDIA)
8265     {
8266       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8267       rtx pic = operands[0];
8268       rtx lab = PATTERN (gen_call_site ());
8269       rtx insn, equiv;
8270
8271       equiv = operands[1];
8272       operands[1] = gen_rtx_MINUS (Pmode,
8273                                    operands[1],
8274                                    gen_rtx_CONST
8275                                    (Pmode,
8276                                     gen_rtx_MINUS (Pmode,
8277                                                    gen_rtx_CONST (Pmode,
8278                                                                   lab),
8279                                                    pc_rtx)));
8280       operands[1] = gen_sym2PIC (operands[1]);
8281       PUT_MODE (operands[1], Pmode);
8282
8283       if (Pmode == SImode)
8284         {
8285           emit_insn (gen_movsi_const (pic, operands[1]));
8286           emit_insn (gen_ptrel_si (tr, pic, lab));
8287         }
8288       else
8289         {
8290           emit_insn (gen_movdi_const (pic, operands[1]));
8291           emit_insn (gen_ptrel_di (tr, pic, lab));
8292         }
8293
8294       insn = emit_move_insn (operands[0], tr);
8295
8296       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8297                                             REG_NOTES (insn));
8298
8299       DONE;
8300     }
8301 }
8302 ")
8303
8304 (define_insn "*ptb"
8305   [(set (match_operand 0 "target_reg_operand" "=b")
8306         (const (unspec [(match_operand 1 "" "Csy")]
8307                              UNSPEC_DATALABEL)))]
8308   "TARGET_SHMEDIA && flag_pic
8309    && EXTRA_CONSTRAINT_Csy (operands[1])"
8310   "ptb/u        datalabel %1, %0"
8311   [(set_attr "type" "ptabs_media")
8312    (set_attr "length" "*")])
8313
8314 (define_insn "ptrel_si"
8315   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8316         (plus:SI (match_operand:SI 1 "register_operand" "r")
8317               (pc)))
8318    (match_operand:SI 2 "" "")]
8319   "TARGET_SHMEDIA"
8320   "%O2: ptrel/u %1, %0"
8321   [(set_attr "type" "ptabs_media")])
8322
8323 (define_insn "ptrel_di"
8324   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8325         (plus:DI (match_operand:DI 1 "register_operand" "r")
8326               (pc)))
8327    (match_operand:DI 2 "" "")]
8328   "TARGET_SHMEDIA"
8329   "%O2: ptrel/u %1, %0"
8330   [(set_attr "type" "ptabs_media")])
8331
8332 (define_expand "builtin_setjmp_receiver"
8333   [(match_operand 0 "" "")]
8334   "flag_pic"
8335   "
8336 {
8337   emit_insn (gen_GOTaddr2picreg ());
8338   DONE;
8339 }")
8340
8341 (define_expand "call_site"
8342   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8343   "TARGET_SH1"
8344   "
8345 {
8346   static HOST_WIDE_INT i = 0;
8347   operands[0] = GEN_INT (i);
8348   i++;
8349 }")
8350
8351 (define_expand "sym_label2reg"
8352   [(set (match_operand:SI 0 "" "")
8353         (const:SI (minus:SI
8354                    (const:SI
8355                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8356                    (const:SI
8357                     (plus:SI
8358                      (match_operand:SI 2 "" "")
8359                      (const_int 2))))))]
8360   "TARGET_SH1" "")
8361
8362 (define_expand "symGOT_load"
8363   [(set (match_dup 2) (match_operand 1 "" ""))
8364    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8365    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8366   ""
8367   "
8368 {
8369   rtx insn, mem;
8370
8371   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8372   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8373
8374   if (TARGET_SHMEDIA)
8375     {
8376       rtx reg = operands[2];
8377
8378       if (Pmode == DImode)
8379         {      
8380           if (flag_pic > 1)
8381             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8382           else
8383             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8384         }
8385       else
8386         {
8387           if (flag_pic > 1)
8388             emit_insn (gen_movsi_const (reg, operands[1]));
8389           else
8390             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8391         }
8392     }
8393   else
8394     emit_move_insn (operands[2], operands[1]);
8395
8396   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8397                                              operands[2],
8398                                              gen_rtx_REG (Pmode, PIC_REG)));
8399
8400   /* N.B. This is not constant for a GOTPLT relocation.  */
8401   mem = gen_rtx_MEM (Pmode, operands[3]);
8402   MEM_NOTRAP_P (mem) = 1;
8403   /* ??? Should we have a special alias set for the GOT?  */
8404   insn = emit_move_insn (operands[0], mem);
8405
8406   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8407                                                                   0), 0, 0),
8408                                         REG_NOTES (insn));
8409
8410   DONE;
8411 }")
8412
8413 (define_expand "sym2GOT"
8414   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8415   ""
8416   "")
8417
8418 (define_expand "symGOT2reg"
8419   [(match_operand 0 "" "") (match_operand 1 "" "")]
8420   ""
8421   "
8422 {
8423   rtx gotsym, insn;
8424
8425   gotsym = gen_sym2GOT (operands[1]);
8426   PUT_MODE (gotsym, Pmode);
8427   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8428
8429   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8430
8431   DONE;
8432 }")
8433
8434 (define_expand "symGOTPLT2reg"
8435   [(match_operand 0 "" "") (match_operand 1 "" "")]
8436   ""
8437   "
8438 {
8439   rtx pltsym = gen_rtx_CONST (Pmode,
8440                               gen_rtx_UNSPEC (Pmode,
8441                                               gen_rtvec (1, operands[1]),
8442                                               UNSPEC_GOTPLT));
8443   emit_insn (gen_symGOT_load (operands[0], pltsym));
8444   DONE;
8445 }")
8446
8447 (define_expand "sym2GOTOFF"
8448   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8449   ""
8450   "")
8451
8452 (define_expand "symGOTOFF2reg"
8453   [(match_operand 0 "" "") (match_operand 1 "" "")]
8454   ""
8455   "
8456 {
8457   rtx gotoffsym, insn;
8458   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8459
8460   gotoffsym = gen_sym2GOTOFF (operands[1]);
8461   PUT_MODE (gotoffsym, Pmode);
8462   emit_move_insn (t, gotoffsym);
8463   insn = emit_move_insn (operands[0],
8464                          gen_rtx_PLUS (Pmode, t,
8465                                        gen_rtx_REG (Pmode, PIC_REG)));
8466
8467   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8468                                         REG_NOTES (insn));
8469
8470   DONE;
8471 }")
8472
8473 (define_expand "symPLT_label2reg"
8474   [(set (match_operand:SI 0 "" "")
8475         (const:SI (minus:SI
8476                    (const:SI
8477                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8478                    (const:SI
8479                     (minus:SI
8480                      (const:SI (plus:SI
8481                                 (match_operand:SI 2 "" "")
8482                                 (const_int 2)))
8483                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8484    ;; Even though the PIC register is not really used by the call
8485    ;; sequence in which this is expanded, the PLT code assumes the PIC
8486    ;; register is set, so we must not skip its initialization.  Since
8487    ;; we only use this expand as part of calling sequences, and never
8488    ;; to take the address of a function, this is the best point to
8489    ;; insert the (use).  Using the PLT to take the address of a
8490    ;; function would be wrong, not only because the PLT entry could
8491    ;; then be called from a function that doesn't initialize the PIC
8492    ;; register to the proper GOT, but also because pointers to the
8493    ;; same function might not compare equal, should they be set by
8494    ;; different shared libraries.
8495    (use (reg:SI PIC_REG))]
8496   "TARGET_SH1"
8497   "")
8498
8499 (define_expand "sym2PIC"
8500   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8501   ""
8502   "")
8503
8504 ;; TLS code generation.
8505 ;; ??? this should be a define_insn_and_split
8506 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8507 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8508 ;; for details.
8509
8510 (define_insn "tls_global_dynamic"
8511   [(set (match_operand:SI 0 "register_operand" "=&z")
8512         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8513                                   UNSPEC_TLSGD))
8514               (const_int 0)))
8515    (use (reg:PSI FPSCR_REG))
8516    (use (reg:SI PIC_REG))
8517    (clobber (reg:SI PR_REG))
8518    (clobber (scratch:SI))]
8519   "TARGET_SH1"
8520   "*
8521 {
8522   return \"\\
8523 mov.l\\t1f,r4\\n\\
8524 \\tmova\\t2f,r0\\n\\
8525 \\tmov.l\\t2f,r1\\n\\
8526 \\tadd\\tr0,r1\\n\\
8527 \\tjsr\\t@r1\\n\\
8528 \\tadd\\tr12,r4\\n\\
8529 \\tbra\\t3f\\n\\
8530 \\tnop\\n\\
8531 \\t.align\\t2\\n\\
8532 1:\\t.long\\t%a1@TLSGD\\n\\
8533 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8534 3:\";
8535 }"
8536   [(set_attr "type" "tls_load")
8537    (set_attr "length" "26")])
8538
8539 (define_insn "tls_local_dynamic"
8540   [(set (match_operand:SI 0 "register_operand" "=&z")
8541         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8542                                   UNSPEC_TLSLDM))
8543               (const_int 0)))
8544    (use (reg:PSI FPSCR_REG))
8545    (use (reg:SI PIC_REG))
8546    (clobber (reg:SI PR_REG))
8547    (clobber (scratch:SI))]
8548   "TARGET_SH1"
8549   "*
8550 {
8551   return \"\\
8552 mov.l\\t1f,r4\\n\\
8553 \\tmova\\t2f,r0\\n\\
8554 \\tmov.l\\t2f,r1\\n\\
8555 \\tadd\\tr0,r1\\n\\
8556 \\tjsr\\t@r1\\n\\
8557 \\tadd\\tr12,r4\\n\\
8558 \\tbra\\t3f\\n\\
8559 \\tnop\\n\\
8560 \\t.align\\t2\\n\\
8561 1:\\t.long\\t%a1@TLSLDM\\n\\
8562 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8563 3:\";
8564 }"
8565   [(set_attr "type" "tls_load")
8566    (set_attr "length" "26")])
8567
8568 (define_expand "sym2DTPOFF"
8569   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8570   ""
8571   "")
8572
8573 (define_expand "symDTPOFF2reg"
8574   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8575   ""
8576   "
8577 {
8578   rtx dtpoffsym, insn;
8579   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8580
8581   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8582   PUT_MODE (dtpoffsym, Pmode);
8583   emit_move_insn (t, dtpoffsym);
8584   insn = emit_move_insn (operands[0],
8585                          gen_rtx_PLUS (Pmode, t, operands[2]));
8586   DONE;
8587 }")
8588
8589 (define_expand "sym2GOTTPOFF"
8590   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8591   ""
8592   "")
8593
8594 (define_insn "tls_initial_exec"
8595   [(set (match_operand:SI 0 "register_operand" "=&r")
8596         (unspec:SI [(match_operand:SI 1 "" "")]
8597                     UNSPEC_TLSIE))
8598    (use (reg:SI GBR_REG))
8599    (use (reg:SI PIC_REG))
8600    (clobber (reg:SI R0_REG))]
8601   ""
8602   "*
8603 {
8604   return \"\\
8605 mov.l\\t1f,r0\\n\\
8606 \\tstc\\tgbr,%0\\n\\
8607 \\tmov.l\\t@(r0,r12),r0\\n\\
8608 \\tbra\\t2f\\n\\
8609 \\tadd\\tr0,%0\\n\\
8610 \\t.align\\t2\\n\\
8611 1:\\t.long\\t%a1\\n\\
8612 2:\";
8613 }"
8614   [(set_attr "type" "tls_load")
8615    (set_attr "length" "16")])
8616
8617 (define_expand "sym2TPOFF"
8618   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8619   ""
8620   "")
8621
8622 (define_expand "symTPOFF2reg"
8623   [(match_operand 0 "" "") (match_operand 1 "" "")]
8624   ""
8625   "
8626 {
8627   rtx tpoffsym, insn;
8628
8629   tpoffsym = gen_sym2TPOFF (operands[1]);
8630   PUT_MODE (tpoffsym, Pmode);
8631   insn = emit_move_insn (operands[0], tpoffsym);
8632   DONE;
8633 }")
8634
8635 (define_insn "load_gbr"
8636   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8637    (use (reg:SI GBR_REG))]
8638   ""
8639   "stc  gbr,%0"
8640   [(set_attr "type" "tls_load")])
8641
8642 ;; case instruction for switch statements.
8643
8644 ;; Operand 0 is index
8645 ;; operand 1 is the minimum bound
8646 ;; operand 2 is the maximum bound - minimum bound + 1
8647 ;; operand 3 is CODE_LABEL for the table;
8648 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8649
8650 (define_expand "casesi"
8651   [(match_operand:SI 0 "arith_reg_operand" "")
8652    (match_operand:SI 1 "arith_reg_operand" "")
8653    (match_operand:SI 2 "arith_reg_operand" "")
8654    (match_operand 3 "" "") (match_operand 4 "" "")]
8655   ""
8656   "
8657 {
8658   rtx reg = gen_reg_rtx (SImode);
8659   rtx reg2 = gen_reg_rtx (SImode);
8660   if (TARGET_SHMEDIA)
8661     {
8662       rtx reg = gen_reg_rtx (DImode);
8663       rtx reg2 = gen_reg_rtx (DImode);
8664       rtx reg3 = gen_reg_rtx (Pmode);
8665       rtx reg4 = gen_reg_rtx (Pmode);
8666       rtx reg5 = gen_reg_rtx (Pmode);
8667       rtx load;
8668
8669       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8670       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8671       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8672
8673       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8674       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8675       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8676       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8677       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8678                                                (Pmode, operands[3])));
8679       /* Messy: can we subreg to clean this up? */
8680       if (Pmode == DImode)
8681         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8682       else
8683         load = gen_casesi_load_media (reg4,
8684                                       gen_rtx_SUBREG (DImode, reg3, 0),
8685                                       reg2, operands[3]);
8686       PUT_MODE (SET_SRC (load), Pmode);
8687       emit_insn (load);
8688       /* ??? The following add could be eliminated if we used ptrel.  */
8689       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8690       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8691       emit_barrier ();
8692       DONE;
8693     }
8694   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8695   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8696   /* If optimizing, casesi_worker depends on the mode of the instruction
8697      before label it 'uses' - operands[3].  */
8698   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8699                            reg));
8700   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8701   if (TARGET_SH2)
8702     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8703   else
8704     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8705   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8706      operands[3], but to lab.  We will fix this up in
8707      machine_dependent_reorg.  */
8708   emit_barrier ();
8709   DONE;
8710 }")
8711
8712 (define_expand "casesi_0"
8713   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8714    (set (match_dup 4) (minus:SI (match_dup 4)
8715                                 (match_operand:SI 1 "arith_operand" "")))
8716    (set (reg:SI T_REG)
8717         (gtu:SI (match_dup 4)
8718                 (match_operand:SI 2 "arith_reg_operand" "")))
8719    (set (pc)
8720         (if_then_else (ne (reg:SI T_REG)
8721                           (const_int 0))
8722                       (label_ref (match_operand 3 "" ""))
8723                       (pc)))]
8724   "TARGET_SH1"
8725   "")
8726
8727 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8728 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8729 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8730
8731 (define_insn "casesi_worker_0"
8732   [(set (match_operand:SI 0 "register_operand" "=r,r")
8733         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8734                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8735    (clobber (match_scratch:SI 3 "=X,1"))
8736    (clobber (match_scratch:SI 4 "=&z,z"))]
8737   "TARGET_SH1"
8738   "#")
8739
8740 (define_split
8741   [(set (match_operand:SI 0 "register_operand" "")
8742         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8743                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8744    (clobber (match_scratch:SI 3 ""))
8745    (clobber (match_scratch:SI 4 ""))]
8746   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8747   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8748    (parallel [(set (match_dup 0)
8749               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8750                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8751               (clobber (match_dup 3))])
8752    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8753   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8754
8755 (define_split
8756   [(set (match_operand:SI 0 "register_operand" "")
8757         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8758                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8759    (clobber (match_scratch:SI 3 ""))
8760    (clobber (match_scratch:SI 4 ""))]
8761   "TARGET_SH2 && reload_completed"
8762   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8763    (parallel [(set (match_dup 0)
8764               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8765                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8766               (clobber (match_dup 3))])]
8767   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8768
8769 (define_insn "casesi_worker_1"
8770   [(set (match_operand:SI 0 "register_operand" "=r,r")
8771         (unspec:SI [(reg:SI R0_REG)
8772                     (match_operand:SI 1 "register_operand" "0,r")
8773                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8774    (clobber (match_scratch:SI 3 "=X,1"))]
8775   "TARGET_SH1"
8776   "*
8777 {
8778   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8779
8780   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8781
8782   switch (GET_MODE (diff_vec))
8783     {
8784     case SImode:
8785       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8786     case HImode:
8787       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8788     case QImode:
8789       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8790         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8791       return \"mov.b    @(r0,%1),%0\";
8792     default:
8793       gcc_unreachable ();
8794     }
8795 }"
8796   [(set_attr "length" "4")])
8797
8798 (define_insn "casesi_worker_2"
8799   [(set (match_operand:SI 0 "register_operand" "=r,r")
8800         (unspec:SI [(reg:SI R0_REG)
8801                     (match_operand:SI 1 "register_operand" "0,r")
8802                     (label_ref (match_operand 2 "" ""))
8803                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8804    (clobber (match_operand:SI 4 "" "=X,1"))]
8805   "TARGET_SH2 && reload_completed && flag_pic"
8806   "*
8807 {
8808   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8809   const char *load;
8810
8811   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8812
8813   switch (GET_MODE (diff_vec))
8814     {
8815     case SImode:
8816       output_asm_insn (\"shll2    %1\", operands);
8817       load = \"mov.l    @(r0,%1),%0\"; break;
8818     case HImode:
8819       output_asm_insn (\"add    %1,%1\", operands);
8820       load = \"mov.w    @(r0,%1),%0\"; break;
8821     case QImode:
8822       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8823         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8824       else
8825         load = \"mov.b  @(r0,%1),%0\";
8826       break;
8827     default:
8828       gcc_unreachable ();
8829     }
8830   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8831   return load;
8832 }"
8833   [(set_attr "length" "8")])
8834
8835 (define_insn "casesi_shift_media"
8836   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8837         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8838                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8839                     UNSPEC_CASESI)))]
8840   "TARGET_SHMEDIA"
8841   "*
8842 {
8843   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8844
8845   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8846
8847   switch (GET_MODE (diff_vec))
8848     {
8849     case SImode:
8850       return \"shlli    %1, 2, %0\";
8851     case HImode:
8852       return \"shlli    %1, 1, %0\";
8853     case QImode:
8854       if (rtx_equal_p (operands[0], operands[1]))
8855         return \"\";
8856       return \"add      %1, r63, %0\";
8857     default:
8858       gcc_unreachable ();
8859     }
8860 }"
8861   [(set_attr "type" "arith_media")])
8862
8863 (define_insn "casesi_load_media"
8864   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8865         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8866                          (match_operand:DI 2 "arith_reg_operand" "r")
8867                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8868   "TARGET_SHMEDIA"
8869   "*
8870 {
8871   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8872
8873   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8874
8875   switch (GET_MODE (diff_vec))
8876     {
8877     case SImode:
8878       return \"ldx.l    %1, %2, %0\";
8879     case HImode:
8880 #if 0
8881       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8882         return \"ldx.uw %1, %2, %0\";
8883 #endif
8884       return \"ldx.w    %1, %2, %0\";
8885     case QImode:
8886       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8887         return \"ldx.ub %1, %2, %0\";
8888       return \"ldx.b    %1, %2, %0\";
8889     default:
8890       gcc_unreachable ();
8891     }
8892 }"
8893   [(set_attr "type" "load_media")])
8894
8895 (define_expand "return"
8896   [(return)]
8897   "reload_completed && ! sh_need_epilogue ()"
8898   "
8899 {
8900   if (TARGET_SHMEDIA)
8901     {
8902       emit_jump_insn (gen_return_media ());
8903       DONE;
8904     }
8905
8906   if (TARGET_SHCOMPACT
8907       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8908     {
8909       emit_jump_insn (gen_shcompact_return_tramp ());
8910       DONE;
8911     }
8912 }")
8913
8914 (define_insn "*return_i"
8915   [(return)]
8916   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8917                     && (current_function_args_info.call_cookie
8918                         & CALL_COOKIE_RET_TRAMP (1)))
8919    && reload_completed
8920    && lookup_attribute (\"trap_exit\",
8921                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8922   "%@   %#"
8923   [(set_attr "type" "return")
8924    (set_attr "needs_delay_slot" "yes")])
8925
8926 ;; trapa has no delay slot.
8927 (define_insn "*return_trapa"
8928   [(return)]
8929   "TARGET_SH1 && !TARGET_SHCOMPACT
8930    && reload_completed"
8931   "%@"
8932   [(set_attr "type" "return")])
8933
8934 (define_expand "shcompact_return_tramp"
8935   [(return)]
8936   "TARGET_SHCOMPACT
8937    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8938   "
8939 {
8940   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8941
8942   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8943   emit_jump_insn (gen_shcompact_return_tramp_i ());
8944   DONE;
8945 }")
8946
8947 (define_insn "shcompact_return_tramp_i"
8948   [(parallel [(return) (use (reg:SI R0_REG))])]
8949   "TARGET_SHCOMPACT
8950    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8951   "jmp  @r0%#"
8952   [(set_attr "type" "jump_ind")
8953    (set_attr "needs_delay_slot" "yes")])
8954
8955 (define_insn "return_media_i"
8956   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8957   "TARGET_SHMEDIA && reload_completed"
8958   "blink        %0, r63"
8959   [(set_attr "type" "jump_media")])
8960
8961 (define_insn "return_media_rte"
8962   [(return)]
8963   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8964   "rte"
8965   [(set_attr "type" "jump_media")])
8966
8967 (define_expand "return_media"
8968   [(return)]
8969   "TARGET_SHMEDIA && reload_completed"
8970   "
8971 {
8972   int tr_regno = sh_media_register_for_return ();
8973   rtx tr;
8974
8975   if (current_function_interrupt)
8976     {
8977       emit_jump_insn (gen_return_media_rte ());
8978       DONE;
8979     }
8980   if (tr_regno < 0)
8981     {
8982       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8983
8984       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8985       tr_regno = TR0_REG;
8986       tr = gen_rtx_REG (Pmode, tr_regno);
8987       emit_move_insn (tr, r18);
8988     }
8989   else
8990     tr = gen_rtx_REG (Pmode, tr_regno);
8991
8992   emit_jump_insn (gen_return_media_i (tr));
8993   DONE;
8994 }")
8995
8996 (define_insn "shcompact_preserve_incoming_args"
8997   [(set (match_operand:SI 0 "register_operand" "+r")
8998         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8999   "TARGET_SHCOMPACT"
9000   ""
9001   [(set_attr "length" "0")])
9002
9003 (define_insn "shcompact_incoming_args"
9004   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9005    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9006    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9007    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9008    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9009    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9010    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9011    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9012    (set (mem:BLK (reg:SI MACL_REG))
9013         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9014    (use (reg:SI R0_REG))
9015    (clobber (reg:SI R0_REG))
9016    (clobber (reg:SI MACL_REG))
9017    (clobber (reg:SI MACH_REG))
9018    (clobber (reg:SI PR_REG))]
9019   "TARGET_SHCOMPACT"
9020   "jsr  @r0%#"
9021   [(set_attr "needs_delay_slot" "yes")])
9022
9023 (define_insn "shmedia_save_restore_regs_compact"
9024   [(set (reg:SI SP_REG)
9025         (plus:SI (reg:SI SP_REG)
9026                  (match_operand:SI 0 "immediate_operand" "i")))
9027    (use (reg:SI R0_REG))
9028    (clobber (reg:SI PR_REG))]
9029   "TARGET_SHCOMPACT
9030    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9031        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9032   "jsr @r0%#"
9033   [(set_attr "needs_delay_slot" "yes")])
9034
9035 (define_expand "prologue"
9036   [(const_int 0)]
9037   ""
9038   "sh_expand_prologue (); DONE;")
9039
9040 (define_expand "epilogue"
9041   [(return)]
9042   ""
9043   "
9044 {
9045   sh_expand_epilogue (0);
9046   emit_jump_insn (gen_return ());
9047   DONE;
9048 }")
9049
9050 (define_expand "eh_return"
9051   [(use (match_operand 0 "register_operand" ""))]
9052   ""
9053 {
9054   rtx ra = operands[0];
9055
9056   if (TARGET_SHMEDIA64)
9057     emit_insn (gen_eh_set_ra_di (ra));
9058   else
9059     emit_insn (gen_eh_set_ra_si (ra));
9060
9061   DONE;
9062 })
9063
9064 ;; Clobber the return address on the stack.  We can't expand this
9065 ;; until we know where it will be put in the stack frame.
9066
9067 (define_insn "eh_set_ra_si"
9068   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9069    (clobber (match_scratch:SI 1 "=&r"))]
9070   "! TARGET_SHMEDIA64"
9071   "#")
9072
9073 (define_insn "eh_set_ra_di"
9074   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9075    (clobber (match_scratch:DI 1 "=&r"))]
9076   "TARGET_SHMEDIA64"
9077   "#")
9078
9079 (define_split
9080   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9081    (clobber (match_scratch 1 ""))]
9082   "reload_completed"
9083   [(const_int 0)]
9084   "
9085 {
9086   sh_set_return_address (operands[0], operands[1]);
9087   DONE;
9088 }")
9089
9090 (define_insn "blockage"
9091   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9092   ""
9093   ""
9094   [(set_attr "length" "0")])
9095 \f
9096 ;; ------------------------------------------------------------------------
9097 ;; Scc instructions
9098 ;; ------------------------------------------------------------------------
9099
9100 (define_insn "movt"
9101   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9102         (eq:SI (reg:SI T_REG) (const_int 1)))]
9103   "TARGET_SH1"
9104   "movt %0"
9105   [(set_attr "type" "arith")])
9106
9107 (define_expand "seq"
9108   [(set (match_operand:SI 0 "arith_reg_dest" "")
9109         (match_dup 1))]
9110   ""
9111   "
9112 {
9113   if (TARGET_SHMEDIA)
9114     {
9115       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9116       if (sh_compare_op1 != const0_rtx)
9117         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9118                                     ? GET_MODE (sh_compare_op0)
9119                                     : GET_MODE (sh_compare_op1),
9120                                     sh_compare_op1);
9121       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9122         {
9123           if (GET_MODE (operands[0]) != SImode)
9124             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9125
9126           switch (GET_MODE (sh_compare_op0))
9127             {
9128             case SImode:
9129               emit_insn (gen_cmpsieqsi_media (operands[0],
9130                                               sh_compare_op0, sh_compare_op1));
9131               break;
9132
9133             case DImode:
9134               emit_insn (gen_cmpsieqdi_media (operands[0],
9135                                               sh_compare_op0, sh_compare_op1));
9136               break;
9137
9138             case SFmode:
9139               if (! TARGET_SHMEDIA_FPU)
9140                 FAIL;
9141               emit_insn (gen_cmpsieqsf_media (operands[0],
9142                                               sh_compare_op0, sh_compare_op1));
9143               break;
9144
9145             case DFmode:
9146               if (! TARGET_SHMEDIA_FPU)
9147                 FAIL;
9148               emit_insn (gen_cmpsieqdf_media (operands[0],
9149                                               sh_compare_op0, sh_compare_op1));
9150               break;
9151
9152             default:
9153               FAIL;
9154             }
9155           DONE;
9156         }
9157
9158       if (GET_MODE (operands[0]) != DImode)
9159         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9160
9161       switch (GET_MODE (sh_compare_op0))
9162         {
9163         case SImode:
9164           emit_insn (gen_cmpeqsi_media (operands[0],
9165                                         sh_compare_op0, sh_compare_op1));
9166           break;
9167
9168         case DImode:
9169           emit_insn (gen_cmpeqdi_media (operands[0],
9170                                         sh_compare_op0, sh_compare_op1));
9171           break;
9172
9173         case SFmode:
9174           if (! TARGET_SHMEDIA_FPU)
9175             FAIL;
9176           emit_insn (gen_cmpeqsf_media (operands[0],
9177                                         sh_compare_op0, sh_compare_op1));
9178           break;
9179
9180         case DFmode:
9181           if (! TARGET_SHMEDIA_FPU)
9182             FAIL;
9183           emit_insn (gen_cmpeqdf_media (operands[0],
9184                                         sh_compare_op0, sh_compare_op1));
9185           break;
9186
9187         default:
9188           FAIL;
9189         }
9190       DONE;
9191     }
9192   if (sh_expand_t_scc (EQ, operands[0]))
9193     DONE;
9194   if (! currently_expanding_to_rtl)
9195     FAIL;
9196   operands[1] = prepare_scc_operands (EQ);
9197 }")
9198
9199 (define_expand "slt"
9200   [(set (match_operand:SI 0 "arith_reg_operand" "")
9201         (match_dup 1))]
9202   ""
9203   "
9204 {
9205   if (TARGET_SHMEDIA)
9206     {
9207       if (GET_MODE (operands[0]) != DImode)
9208         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9209       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9210       if (sh_compare_op1 != const0_rtx)
9211         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9212                                     ? GET_MODE (sh_compare_op0)
9213                                     : GET_MODE (sh_compare_op1),
9214                                     sh_compare_op1);
9215
9216       switch (GET_MODE (sh_compare_op0))
9217         {
9218         case SImode:
9219           emit_insn (gen_cmpgtsi_media (operands[0],
9220                                         sh_compare_op1, sh_compare_op0));
9221           break;
9222
9223         case DImode:
9224           emit_insn (gen_cmpgtdi_media (operands[0],
9225                                         sh_compare_op1, sh_compare_op0));
9226           break;
9227
9228         case SFmode:
9229           if (! TARGET_SHMEDIA_FPU)
9230             FAIL;
9231           emit_insn (gen_cmpgtsf_media (operands[0],
9232                                         sh_compare_op1, sh_compare_op0));
9233           break;
9234
9235         case DFmode:
9236           if (! TARGET_SHMEDIA_FPU)
9237             FAIL;
9238           emit_insn (gen_cmpgtdf_media (operands[0],
9239                                         sh_compare_op1, sh_compare_op0));
9240           break;
9241
9242         default:
9243           FAIL;
9244         }
9245       DONE;
9246     }
9247   if (! currently_expanding_to_rtl)
9248     FAIL;
9249   operands[1] = prepare_scc_operands (LT);
9250 }")
9251
9252 (define_expand "sle"
9253   [(match_operand:SI 0 "arith_reg_operand" "")]
9254   ""
9255   "
9256 {
9257   rtx tmp = sh_compare_op0;
9258
9259   if (TARGET_SHMEDIA)
9260     {
9261       if (GET_MODE (operands[0]) != DImode)
9262         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9263       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9264       if (sh_compare_op1 != const0_rtx)
9265         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9266                                     ? GET_MODE (sh_compare_op0)
9267                                     : GET_MODE (sh_compare_op1),
9268                                     sh_compare_op1);
9269
9270       switch (GET_MODE (sh_compare_op0))
9271         {
9272         case SImode:
9273           {
9274             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9275
9276             emit_insn (gen_cmpgtsi_media (tmp,
9277                                           sh_compare_op0, sh_compare_op1));
9278             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9279             break;
9280           }
9281
9282         case DImode:
9283           {
9284             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9285
9286             emit_insn (gen_cmpgtdi_media (tmp,
9287                                           sh_compare_op0, sh_compare_op1));
9288             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9289             break;
9290           }
9291
9292         case SFmode:
9293           if (! TARGET_SHMEDIA_FPU)
9294             FAIL;
9295           emit_insn (gen_cmpgesf_media (operands[0],
9296                                         sh_compare_op1, sh_compare_op0));
9297           break;
9298
9299         case DFmode:
9300           if (! TARGET_SHMEDIA_FPU)
9301             FAIL;
9302           emit_insn (gen_cmpgedf_media (operands[0],
9303                                         sh_compare_op1, sh_compare_op0));
9304           break;
9305
9306         default:
9307           FAIL;
9308         }
9309       DONE;
9310     }
9311
9312   sh_compare_op0 = sh_compare_op1;
9313   sh_compare_op1 = tmp;
9314   emit_insn (gen_sge (operands[0]));
9315   DONE;
9316 }")
9317
9318 (define_expand "sgt"
9319   [(set (match_operand:SI 0 "arith_reg_operand" "")
9320         (match_dup 1))]
9321   ""
9322   "
9323 {
9324   if (TARGET_SHMEDIA)
9325     {
9326       if (GET_MODE (operands[0]) != DImode)
9327         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9328       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9329       if (sh_compare_op1 != const0_rtx)
9330         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9331                                     ? GET_MODE (sh_compare_op0)
9332                                     : GET_MODE (sh_compare_op1),
9333                                     sh_compare_op1);
9334
9335       switch (GET_MODE (sh_compare_op0))
9336         {
9337         case SImode:
9338           emit_insn (gen_cmpgtsi_media (operands[0],
9339                                         sh_compare_op0, sh_compare_op1));
9340           break;
9341
9342         case DImode:
9343           emit_insn (gen_cmpgtdi_media (operands[0],
9344                                         sh_compare_op0, sh_compare_op1));
9345           break;
9346
9347         case SFmode:
9348           if (! TARGET_SHMEDIA_FPU)
9349             FAIL;
9350           emit_insn (gen_cmpgtsf_media (operands[0],
9351                                         sh_compare_op0, sh_compare_op1));
9352           break;
9353
9354         case DFmode:
9355           if (! TARGET_SHMEDIA_FPU)
9356             FAIL;
9357           emit_insn (gen_cmpgtdf_media (operands[0],
9358                                         sh_compare_op0, sh_compare_op1));
9359           break;
9360
9361         default:
9362           FAIL;
9363         }
9364       DONE;
9365     }
9366   if (! currently_expanding_to_rtl)
9367     FAIL;
9368   operands[1] = prepare_scc_operands (GT);
9369 }")
9370
9371 (define_expand "sge"
9372   [(set (match_operand:SI 0 "arith_reg_operand" "")
9373         (match_dup 1))]
9374   ""
9375   "
9376 {
9377   if (TARGET_SHMEDIA)
9378     {
9379       enum machine_mode mode = GET_MODE (sh_compare_op0);
9380
9381       if ((mode) == VOIDmode)
9382         mode = GET_MODE (sh_compare_op1);
9383       if (GET_MODE (operands[0]) != DImode)
9384         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9385       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9386       if (sh_compare_op1 != const0_rtx)
9387         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9388
9389       switch (mode)
9390         {
9391         case SImode:
9392           {
9393             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9394
9395             emit_insn (gen_cmpgtsi_media (tmp,
9396                                           sh_compare_op1, sh_compare_op0));
9397             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9398             break;
9399           }
9400
9401         case DImode:
9402           {
9403             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9404
9405             emit_insn (gen_cmpgtdi_media (tmp,
9406                                           sh_compare_op1, sh_compare_op0));
9407             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9408             break;
9409           }
9410
9411         case SFmode:
9412           if (! TARGET_SHMEDIA_FPU)
9413             FAIL;
9414           emit_insn (gen_cmpgesf_media (operands[0],
9415                                         sh_compare_op0, sh_compare_op1));
9416           break;
9417
9418         case DFmode:
9419           if (! TARGET_SHMEDIA_FPU)
9420             FAIL;
9421           emit_insn (gen_cmpgedf_media (operands[0],
9422                                         sh_compare_op0, sh_compare_op1));
9423           break;
9424
9425         default:
9426           FAIL;
9427         }
9428       DONE;
9429     }
9430
9431   if (! currently_expanding_to_rtl)
9432     FAIL;
9433   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9434     {
9435       if (TARGET_IEEE)
9436         {
9437           rtx lab = gen_label_rtx ();
9438           prepare_scc_operands (EQ);
9439           emit_jump_insn (gen_branch_true (lab));
9440           prepare_scc_operands (GT);
9441           emit_label (lab);
9442           emit_insn (gen_movt (operands[0]));
9443         }
9444       else
9445         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9446       DONE;
9447     }
9448   operands[1] = prepare_scc_operands (GE);
9449 }")
9450
9451 (define_expand "sgtu"
9452   [(set (match_operand:SI 0 "arith_reg_operand" "")
9453         (match_dup 1))]
9454   ""
9455   "
9456 {
9457   if (TARGET_SHMEDIA)
9458     {
9459       if (GET_MODE (operands[0]) != DImode)
9460         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9461       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9462       if (sh_compare_op1 != const0_rtx)
9463         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9464                                     ? GET_MODE (sh_compare_op0)
9465                                     : GET_MODE (sh_compare_op1),
9466                                     sh_compare_op1);
9467
9468       emit_insn (gen_cmpgtudi_media (operands[0],
9469                                      sh_compare_op0, sh_compare_op1));
9470       DONE;
9471     }
9472   if (! currently_expanding_to_rtl)
9473     FAIL;
9474   operands[1] = prepare_scc_operands (GTU);
9475 }")
9476
9477 (define_expand "sltu"
9478   [(set (match_operand:SI 0 "arith_reg_operand" "")
9479         (match_dup 1))]
9480   ""
9481   "
9482 {
9483   if (TARGET_SHMEDIA)
9484     {
9485       if (GET_MODE (operands[0]) != DImode)
9486         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9487       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9488       if (sh_compare_op1 != const0_rtx)
9489         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9490                                     ? GET_MODE (sh_compare_op0)
9491                                     : GET_MODE (sh_compare_op1),
9492                                     sh_compare_op1);
9493
9494       emit_insn (gen_cmpgtudi_media (operands[0],
9495                                      sh_compare_op1, sh_compare_op0));
9496       DONE;
9497     }
9498   if (! currently_expanding_to_rtl)
9499     FAIL;
9500   operands[1] = prepare_scc_operands (LTU);
9501 }")
9502
9503 (define_expand "sleu"
9504   [(set (match_operand:SI 0 "arith_reg_operand" "")
9505         (match_dup 1))]
9506   ""
9507   "
9508 {
9509   if (TARGET_SHMEDIA)
9510     {
9511       rtx tmp;
9512
9513       if (GET_MODE (operands[0]) != DImode)
9514         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9515       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9516       if (sh_compare_op1 != const0_rtx)
9517         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9518                                     ? GET_MODE (sh_compare_op0)
9519                                     : GET_MODE (sh_compare_op1),
9520                                     sh_compare_op1);
9521
9522       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9523
9524       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9525       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9526
9527       DONE;
9528     }
9529   if (! currently_expanding_to_rtl)
9530     FAIL;
9531   operands[1] = prepare_scc_operands (LEU);
9532 }")
9533
9534 (define_expand "sgeu"
9535   [(set (match_operand:SI 0 "arith_reg_operand" "")
9536         (match_dup 1))]
9537   ""
9538   "
9539 {
9540   if (TARGET_SHMEDIA)
9541     {
9542       rtx tmp;
9543
9544       if (GET_MODE (operands[0]) != DImode)
9545         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9546       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9547       if (sh_compare_op1 != const0_rtx)
9548         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9549                                     ? GET_MODE (sh_compare_op0)
9550                                     : GET_MODE (sh_compare_op1),
9551                                     sh_compare_op1);
9552
9553       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9554
9555       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9556       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9557
9558       DONE;
9559     }
9560
9561   if (! currently_expanding_to_rtl)
9562     FAIL;
9563   operands[1] = prepare_scc_operands (GEU);
9564 }")
9565
9566 ;; sne moves the complement of the T reg to DEST like this:
9567 ;;      cmp/eq ...
9568 ;;      mov    #-1,temp
9569 ;;      negc   temp,dest
9570 ;;   This is better than xoring compare result with 1 because it does
9571 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9572 ;;   loop.
9573
9574 (define_expand "sne"
9575   [(set (match_dup 2) (const_int -1))
9576    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9577                    (neg:SI (plus:SI (match_dup 1)
9578                                     (match_dup 2))))
9579               (set (reg:SI T_REG)
9580                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9581                           (const_int 0)))])]
9582   ""
9583   "
9584 {
9585   if (TARGET_SHMEDIA)
9586     {
9587       rtx tmp;
9588
9589       if (GET_MODE (operands[0]) != DImode)
9590         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9591
9592       if (! TARGET_SHMEDIA_FPU
9593           && GET_MODE (sh_compare_op0) != DImode
9594           && GET_MODE (sh_compare_op0) != SImode)
9595         FAIL;
9596
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 ? operands[0] : gen_reg_rtx (DImode);
9605
9606       emit_insn (gen_seq (tmp));
9607       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9608
9609       DONE;
9610     }
9611
9612   if (sh_expand_t_scc (NE, operands[0]))
9613     DONE;
9614   if (! currently_expanding_to_rtl)
9615     FAIL;
9616   operands[1] = prepare_scc_operands (EQ);
9617   operands[2] = gen_reg_rtx (SImode);
9618 }")
9619
9620 (define_expand "sunordered"
9621   [(set (match_operand:DI 0 "arith_reg_operand" "")
9622         (unordered:DI (match_dup 1) (match_dup 2)))]
9623   "TARGET_SHMEDIA_FPU"
9624   "
9625 {
9626   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9627   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9628 }")
9629
9630 ;; Use the same trick for FP sle / sge
9631
9632 ;; Apart from the constant use and the T setting, this is like movt,
9633 ;; except that it uses the logically negated value of T, i.e.
9634 ;; operand[0] := T ? 0 : 1.
9635 (define_expand "movnegt"
9636   [(set (match_dup 2) (const_int -1))
9637    (parallel [(set (match_operand 0 "" "")
9638                    (neg:SI (plus:SI (match_dup 1)
9639                                     (match_dup 2))))
9640               (set (reg:SI T_REG)
9641                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9642                           (const_int 0)))])]
9643   "TARGET_SH1"
9644   "operands[2] = gen_reg_rtx (SImode);")
9645
9646 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9647 ;; This prevents a regression that occurred when we switched from xor to
9648 ;; mov/neg for sne.
9649
9650 (define_split
9651   [(set (match_operand:SI 0 "arith_reg_dest" "")
9652         (plus:SI (reg:SI T_REG)
9653                  (const_int -1)))]
9654   "TARGET_SH1"
9655   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9656    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9657   "")
9658
9659 ;; -------------------------------------------------------------------------
9660 ;; Instructions to cope with inline literal tables
9661 ;; -------------------------------------------------------------------------
9662
9663 ; 2 byte integer in line
9664
9665 (define_insn "consttable_2"
9666  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9667                     (match_operand 1 "" "")]
9668                    UNSPECV_CONST2)]
9669  ""
9670  "*
9671 {
9672   if (operands[1] != const0_rtx)
9673     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9674   return \"\";
9675 }"
9676  [(set_attr "length" "2")
9677  (set_attr "in_delay_slot" "no")])
9678
9679 ; 4 byte integer in line
9680
9681 (define_insn "consttable_4"
9682  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9683                     (match_operand 1 "" "")]
9684                    UNSPECV_CONST4)]
9685  ""
9686  "*
9687 {
9688   if (operands[1] != const0_rtx)
9689     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9690   return \"\";
9691 }"
9692  [(set_attr "length" "4")
9693   (set_attr "in_delay_slot" "no")])
9694
9695 ; 8 byte integer in line
9696
9697 (define_insn "consttable_8"
9698  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9699                     (match_operand 1 "" "")]
9700                    UNSPECV_CONST8)]
9701  ""
9702  "*
9703 {
9704   if (operands[1] != const0_rtx)
9705     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9706   return \"\";
9707 }"
9708  [(set_attr "length" "8")
9709   (set_attr "in_delay_slot" "no")])
9710
9711 ; 4 byte floating point
9712
9713 (define_insn "consttable_sf"
9714  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9715                     (match_operand 1 "" "")]
9716                    UNSPECV_CONST4)]
9717  ""
9718  "*
9719 {
9720   if (operands[1] != const0_rtx)
9721     {
9722       REAL_VALUE_TYPE d;
9723       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9724       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9725     }
9726   return \"\";
9727 }"
9728  [(set_attr "length" "4")
9729   (set_attr "in_delay_slot" "no")])
9730
9731 ; 8 byte floating point
9732
9733 (define_insn "consttable_df"
9734  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9735                     (match_operand 1 "" "")]
9736                    UNSPECV_CONST8)]
9737  ""
9738  "*
9739 {
9740   if (operands[1] != const0_rtx)
9741     {
9742       REAL_VALUE_TYPE d;
9743       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9744       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9745     }
9746   return \"\";
9747 }"
9748  [(set_attr "length" "8")
9749   (set_attr "in_delay_slot" "no")])
9750
9751 ;; Alignment is needed for some constant tables; it may also be added for
9752 ;; Instructions at the start of loops, or after unconditional branches.
9753 ;; ??? We would get more accurate lengths if we did instruction
9754 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9755 ;; here is too conservative.
9756
9757 ; align to a two byte boundary
9758
9759 (define_expand "align_2"
9760  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9761  ""
9762  "")
9763
9764 ; align to a four byte boundary
9765 ;; align_4 and align_log are instructions for the starts of loops, or
9766 ;; after unconditional branches, which may take up extra room.
9767
9768 (define_expand "align_4"
9769  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9770  ""
9771  "")
9772
9773 ; align to a cache line boundary
9774
9775 (define_insn "align_log"
9776  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9777  ""
9778  ""
9779  [(set_attr "length" "0")
9780   (set_attr "in_delay_slot" "no")])
9781
9782 ; emitted at the end of the literal table, used to emit the
9783 ; 32bit branch labels if needed.
9784
9785 (define_insn "consttable_end"
9786   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9787   ""
9788   "* return output_jump_label_table ();"
9789   [(set_attr "in_delay_slot" "no")])
9790
9791 ; emitted at the end of the window in the literal table.
9792
9793 (define_insn "consttable_window_end"
9794   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9795   ""
9796   ""
9797   [(set_attr "length" "0")
9798    (set_attr "in_delay_slot" "no")])
9799
9800 ;; -------------------------------------------------------------------------
9801 ;; Misc
9802 ;; -------------------------------------------------------------------------
9803
9804 ;; String/block move insn.
9805
9806 (define_expand "movmemsi"
9807   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9808                    (mem:BLK (match_operand:BLK 1 "" "")))
9809               (use (match_operand:SI 2 "nonmemory_operand" ""))
9810               (use (match_operand:SI 3 "immediate_operand" ""))
9811               (clobber (reg:SI PR_REG))
9812               (clobber (reg:SI R4_REG))
9813               (clobber (reg:SI R5_REG))
9814               (clobber (reg:SI R0_REG))])]
9815   "TARGET_SH1 && ! TARGET_SH5"
9816   "
9817 {
9818   if(expand_block_move (operands))
9819      DONE;
9820   else FAIL;
9821 }")
9822
9823 (define_insn "block_move_real"
9824   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9825                    (mem:BLK (reg:SI R5_REG)))
9826               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9827               (clobber (reg:SI PR_REG))
9828               (clobber (reg:SI R0_REG))])]
9829   "TARGET_SH1 && ! TARGET_HARD_SH4"
9830   "jsr  @%0%#"
9831   [(set_attr "type" "sfunc")
9832    (set_attr "needs_delay_slot" "yes")])
9833
9834 (define_insn "block_lump_real"
9835   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9836                    (mem:BLK (reg:SI R5_REG)))
9837               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9838               (use (reg:SI R6_REG))
9839               (clobber (reg:SI PR_REG))
9840               (clobber (reg:SI T_REG))
9841               (clobber (reg:SI R4_REG))
9842               (clobber (reg:SI R5_REG))
9843               (clobber (reg:SI R6_REG))
9844               (clobber (reg:SI R0_REG))])]
9845   "TARGET_SH1 && ! TARGET_HARD_SH4"
9846   "jsr  @%0%#"
9847   [(set_attr "type" "sfunc")
9848    (set_attr "needs_delay_slot" "yes")])
9849
9850 (define_insn "block_move_real_i4"
9851   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9852                    (mem:BLK (reg:SI R5_REG)))
9853               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9854               (clobber (reg:SI PR_REG))
9855               (clobber (reg:SI R0_REG))
9856               (clobber (reg:SI R1_REG))
9857               (clobber (reg:SI R2_REG))])]
9858   "TARGET_HARD_SH4"
9859   "jsr  @%0%#"
9860   [(set_attr "type" "sfunc")
9861    (set_attr "needs_delay_slot" "yes")])
9862
9863 (define_insn "block_lump_real_i4"
9864   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9865                    (mem:BLK (reg:SI R5_REG)))
9866               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9867               (use (reg:SI R6_REG))
9868               (clobber (reg:SI PR_REG))
9869               (clobber (reg:SI T_REG))
9870               (clobber (reg:SI R4_REG))
9871               (clobber (reg:SI R5_REG))
9872               (clobber (reg:SI R6_REG))
9873               (clobber (reg:SI R0_REG))
9874               (clobber (reg:SI R1_REG))
9875               (clobber (reg:SI R2_REG))
9876               (clobber (reg:SI R3_REG))])]
9877   "TARGET_HARD_SH4"
9878   "jsr  @%0%#"
9879   [(set_attr "type" "sfunc")
9880    (set_attr "needs_delay_slot" "yes")])
9881 \f
9882 ;; -------------------------------------------------------------------------
9883 ;; Floating point instructions.
9884 ;; -------------------------------------------------------------------------
9885
9886 ;; ??? All patterns should have a type attribute.
9887
9888 (define_expand "movpsi"
9889   [(set (match_operand:PSI 0 "register_operand" "")
9890         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9891   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9892   "")
9893
9894 ;; The c / m alternative is a fake to guide reload to load directly into
9895 ;; fpscr, since reload doesn't know how to use post-increment.
9896 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9897 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9898 ;; predicate after reload.
9899 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9900 ;; like a mac -> gpr move.
9901 (define_insn "fpu_switch"
9902   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9903         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9904   "TARGET_SH2E
9905    && (! reload_completed
9906        || true_regnum (operands[0]) != FPSCR_REG
9907        || GET_CODE (operands[1]) != MEM
9908        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9909   "@
9910         ! precision stays the same
9911         lds.l   %1,fpscr
9912         mov.l   %1,%0
9913         #
9914         lds     %1,fpscr
9915         mov     %1,%0
9916         mov.l   %1,%0
9917         sts     fpscr,%0
9918         sts.l   fpscr,%0"
9919   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9920    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9921
9922 (define_peephole2
9923   [(set (reg:PSI FPSCR_REG)
9924         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9925   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9926   [(const_int 0)]
9927 {
9928   rtx fpscr, mem, new_insn;
9929
9930   fpscr = SET_DEST (PATTERN (curr_insn));
9931   mem = SET_SRC (PATTERN (curr_insn));
9932   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9933
9934   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9935   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9936   DONE;
9937 })
9938
9939 (define_split
9940   [(set (reg:PSI FPSCR_REG)
9941         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9942   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9943    && (flag_peephole2 ? flow2_completed : reload_completed)"
9944   [(const_int 0)]
9945 {
9946   rtx fpscr, mem, new_insn;
9947
9948   fpscr = SET_DEST (PATTERN (curr_insn));
9949   mem = SET_SRC (PATTERN (curr_insn));
9950   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9951
9952   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9953   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9954
9955   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9956     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9957   DONE;
9958 })
9959
9960 ;; ??? This uses the fp unit, but has no type indicating that.
9961 ;; If we did that, this would either give a bogus latency or introduce
9962 ;; a bogus FIFO constraint.
9963 ;; Since this insn is currently only used for prologues/epilogues,
9964 ;; it is probably best to claim no function unit, which matches the
9965 ;; current setting.
9966 (define_insn "toggle_sz"
9967   [(set (reg:PSI FPSCR_REG)
9968         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9969   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9970   "fschg"
9971   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9972
9973 ;; There's no way we can use it today, since optimize mode switching
9974 ;; doesn't enable us to know from which mode we're switching to the
9975 ;; mode it requests, to tell whether we can use a relative mode switch
9976 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9977 ;; memory).
9978 (define_insn "toggle_pr"
9979   [(set (reg:PSI FPSCR_REG)
9980         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9981   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9982   "fpchg"
9983   [(set_attr "type" "fp")])
9984
9985 (define_expand "addsf3"
9986   [(set (match_operand:SF 0 "arith_reg_operand" "")
9987         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9988                  (match_operand:SF 2 "arith_reg_operand" "")))]
9989   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9990   "
9991 {
9992   if (TARGET_SH2E)
9993     {
9994       expand_sf_binop (&gen_addsf3_i, operands);
9995       DONE;
9996     }
9997 }")
9998
9999 (define_insn "*addsf3_media"
10000   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10001         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10002                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10003   "TARGET_SHMEDIA_FPU"
10004   "fadd.s       %1, %2, %0"
10005   [(set_attr "type" "fparith_media")])
10006
10007 (define_insn_and_split "unary_sf_op"
10008   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10009         (vec_select:V2SF
10010          (vec_concat:V2SF
10011           (vec_select:SF
10012            (match_dup 0)
10013            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10014           (match_operator:SF 2 "unary_float_operator"
10015             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10016                             (parallel [(match_operand 4
10017                                         "const_int_operand" "n")]))]))
10018          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10019   "TARGET_SHMEDIA_FPU"
10020   "#"
10021   "TARGET_SHMEDIA_FPU && reload_completed"
10022   [(set (match_dup 5) (match_dup 6))]
10023   "
10024 {
10025   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10026   rtx op1 = gen_rtx_REG (SFmode,
10027                          (true_regnum (operands[1])
10028                           + (INTVAL (operands[4]) ^ endian)));
10029
10030   operands[7] = gen_rtx_REG (SFmode,
10031                              (true_regnum (operands[0])
10032                               + (INTVAL (operands[3]) ^ endian)));
10033   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10034 }"
10035   [(set_attr "type" "fparith_media")])
10036
10037 (define_insn_and_split "binary_sf_op"
10038   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10039         (vec_select:V2SF
10040          (vec_concat:V2SF
10041           (vec_select:SF
10042            (match_dup 0)
10043            (parallel [(match_operand 7 "const_int_operand" "n")]))
10044           (match_operator:SF 3 "binary_float_operator"
10045             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10046                             (parallel [(match_operand 5
10047                                         "const_int_operand" "n")]))
10048              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10049                             (parallel [(match_operand 6
10050                                         "const_int_operand" "n")]))]))
10051          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10052   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10053   "#"
10054   "&& reload_completed"
10055   [(set (match_dup 8) (match_dup 9))]
10056   "
10057 {
10058   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10059   rtx op1 = gen_rtx_REG (SFmode,
10060                          (true_regnum (operands[1])
10061                           + (INTVAL (operands[5]) ^ endian)));
10062   rtx op2 = gen_rtx_REG (SFmode,
10063                          (true_regnum (operands[2])
10064                           + (INTVAL (operands[6]) ^ endian)));
10065
10066   operands[8] = gen_rtx_REG (SFmode,
10067                              (true_regnum (operands[0])
10068                               + (INTVAL (operands[4]) ^ endian)));
10069   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10070 }"
10071   [(set_attr "type" "fparith_media")])
10072
10073 (define_insn "addsf3_i"
10074   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10075         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10076                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10077    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10078   "TARGET_SH2E"
10079   "fadd %2,%0"
10080   [(set_attr "type" "fp")
10081    (set_attr "fp_mode" "single")])
10082
10083 (define_expand "subsf3"
10084   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10085         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10086                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10087   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10088   "
10089 {
10090   if (TARGET_SH2E)
10091     {
10092       expand_sf_binop (&gen_subsf3_i, operands);
10093       DONE;
10094     }
10095 }")
10096
10097 (define_insn "*subsf3_media"
10098   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10099         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10100                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10101   "TARGET_SHMEDIA_FPU"
10102   "fsub.s       %1, %2, %0"
10103   [(set_attr "type" "fparith_media")])
10104
10105 (define_insn "subsf3_i"
10106   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10107         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10108                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10109    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10110   "TARGET_SH2E"
10111   "fsub %2,%0"
10112   [(set_attr "type" "fp")
10113    (set_attr "fp_mode" "single")])
10114
10115 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10116 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10117 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10118 ;; SH3E, we use a separate insn for SH3E mulsf3.
10119
10120 (define_expand "mulsf3"
10121   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10122         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10123                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10124   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10125   "
10126 {
10127   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10128     expand_sf_binop (&gen_mulsf3_i4, operands);
10129   else if (TARGET_SH2E)
10130     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10131   if (! TARGET_SHMEDIA)
10132     DONE;
10133 }")
10134
10135 (define_insn "*mulsf3_media"
10136   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10137         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10138                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10139   "TARGET_SHMEDIA_FPU"
10140   "fmul.s       %1, %2, %0"
10141   [(set_attr "type" "fparith_media")])
10142
10143 (define_insn "mulsf3_i4"
10144   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10145         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10146                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10147    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10148   "TARGET_SH2E"
10149   "fmul %2,%0"
10150   [(set_attr "type" "fp")
10151    (set_attr "fp_mode" "single")])
10152
10153 (define_insn "mulsf3_ie"
10154   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10155         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10156                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10157   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10158   "fmul %2,%0"
10159   [(set_attr "type" "fp")])
10160
10161 (define_insn "mac_media"
10162   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10163         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10164                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10165                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10166   "TARGET_SHMEDIA_FPU"
10167   "fmac.s %1, %2, %0"
10168   [(set_attr "type" "fparith_media")])
10169
10170 (define_insn "*macsf3"
10171   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10172         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10173                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10174                  (match_operand:SF 3 "arith_reg_operand" "0")))
10175    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10176   "TARGET_SH2E && ! TARGET_SH4"
10177   "fmac fr0,%2,%0"
10178   [(set_attr "type" "fp")
10179    (set_attr "fp_mode" "single")])
10180
10181 (define_expand "divsf3"
10182   [(set (match_operand:SF 0 "arith_reg_operand" "")
10183         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10184                 (match_operand:SF 2 "arith_reg_operand" "")))]
10185   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10186   "
10187 {
10188   if (TARGET_SH2E)
10189     {
10190       expand_sf_binop (&gen_divsf3_i, operands);
10191       DONE;
10192     }
10193 }")
10194
10195 (define_insn "*divsf3_media"
10196   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10197         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10198                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10199   "TARGET_SHMEDIA_FPU"
10200   "fdiv.s       %1, %2, %0"
10201   [(set_attr "type" "fdiv_media")])
10202
10203 (define_insn "divsf3_i"
10204   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10205         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10206                  (match_operand:SF 2 "arith_reg_operand" "f")))
10207    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10208   "TARGET_SH2E"
10209   "fdiv %2,%0"
10210   [(set_attr "type" "fdiv")
10211    (set_attr "fp_mode" "single")])
10212
10213 (define_insn "floatdisf2"
10214   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10215         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10216   "TARGET_SHMEDIA_FPU"
10217   "float.qs %1, %0"
10218   [(set_attr "type" "fpconv_media")])
10219
10220 (define_expand "floatsisf2"
10221   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10222         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10223   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10224   "
10225 {
10226   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10227     {
10228       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10229       DONE;
10230     }
10231 }")
10232
10233 (define_insn "*floatsisf2_media"
10234   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10235         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10236   "TARGET_SHMEDIA_FPU"
10237   "float.ls     %1, %0"
10238   [(set_attr "type" "fpconv_media")])
10239
10240 (define_insn "floatsisf2_i4"
10241   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10242         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10243    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10244   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10245   "float        %1,%0"
10246   [(set_attr "type" "fp")
10247    (set_attr "fp_mode" "single")])
10248
10249 (define_insn "*floatsisf2_ie"
10250   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10251         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10252   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10253   "float        %1,%0"
10254   [(set_attr "type" "fp")])
10255
10256 (define_insn "fix_truncsfdi2"
10257   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10258         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10259   "TARGET_SHMEDIA_FPU"
10260   "ftrc.sq %1, %0"
10261   [(set_attr "type" "fpconv_media")])
10262
10263 (define_expand "fix_truncsfsi2"
10264   [(set (match_operand:SI 0 "fpul_operand" "=y")
10265         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10266   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10267   "
10268 {
10269   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10270     {
10271       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10272       DONE;
10273     }
10274 }")
10275
10276 (define_insn "*fix_truncsfsi2_media"
10277   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10278         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10279   "TARGET_SHMEDIA_FPU"
10280   "ftrc.sl      %1, %0"
10281   [(set_attr "type" "fpconv_media")])
10282
10283 (define_insn "fix_truncsfsi2_i4"
10284   [(set (match_operand:SI 0 "fpul_operand" "=y")
10285         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10286    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10287   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10288   "ftrc %1,%0"
10289   [(set_attr "type" "ftrc_s")
10290    (set_attr "fp_mode" "single")])
10291
10292 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10293 ;; fix_truncsfsi2_i4.
10294 ;; (define_insn "fix_truncsfsi2_i4_2"
10295 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10296 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10297 ;;   (use (reg:PSI FPSCR_REG))
10298 ;;   (clobber (reg:SI FPUL_REG))]
10299 ;;  "TARGET_SH4"
10300 ;;  "#"
10301 ;;  [(set_attr "length" "4")
10302 ;;   (set_attr "fp_mode" "single")])
10303
10304 ;;(define_split
10305 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10306 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10307 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10308 ;;   (clobber (reg:SI FPUL_REG))]
10309 ;;  "TARGET_SH4"
10310 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10311 ;;            (use (match_dup 2))])
10312 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10313
10314 (define_insn "*fixsfsi"
10315   [(set (match_operand:SI 0 "fpul_operand" "=y")
10316         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10317   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10318   "ftrc %1,%0"
10319   [(set_attr "type" "fp")])
10320
10321 (define_insn "cmpgtsf_t"
10322   [(set (reg:SI T_REG)
10323         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10324                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10325   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10326   "fcmp/gt      %1,%0"
10327   [(set_attr "type" "fp")
10328    (set_attr "fp_mode" "single")])
10329
10330 (define_insn "cmpeqsf_t"
10331   [(set (reg:SI T_REG)
10332         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10333                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10334   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10335   "fcmp/eq      %1,%0"
10336   [(set_attr "type" "fp")
10337    (set_attr "fp_mode" "single")])
10338
10339 (define_insn "ieee_ccmpeqsf_t"
10340   [(set (reg:SI T_REG)
10341         (ior:SI (reg:SI T_REG)
10342                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10343                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10344   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10345   "* return output_ieee_ccmpeq (insn, operands);"
10346   [(set_attr "length" "4")])
10347
10348
10349 (define_insn "cmpgtsf_t_i4"
10350   [(set (reg:SI T_REG)
10351         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10352                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10353    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10354   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10355   "fcmp/gt      %1,%0"
10356   [(set_attr "type" "fp")
10357    (set_attr "fp_mode" "single")])
10358
10359 (define_insn "cmpeqsf_t_i4"
10360   [(set (reg:SI T_REG)
10361         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10362                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10363    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10364   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10365   "fcmp/eq      %1,%0"
10366   [(set_attr "type" "fp")
10367    (set_attr "fp_mode" "single")])
10368
10369 (define_insn "*ieee_ccmpeqsf_t_4"
10370   [(set (reg:SI T_REG)
10371         (ior:SI (reg:SI T_REG)
10372                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10373                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10374    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10375   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10376   "* return output_ieee_ccmpeq (insn, operands);"
10377   [(set_attr "length" "4")
10378    (set_attr "fp_mode" "single")])
10379
10380 (define_insn "cmpeqsf_media"
10381   [(set (match_operand:DI 0 "register_operand" "=r")
10382         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10383                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10384   "TARGET_SHMEDIA_FPU"
10385   "fcmpeq.s     %1, %2, %0"
10386   [(set_attr "type" "fcmp_media")])
10387
10388 (define_insn "cmpsieqsf_media"
10389   [(set (match_operand:SI 0 "register_operand" "=r")
10390         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10391                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10392   "TARGET_SHMEDIA_FPU"
10393   "fcmpeq.s     %1, %2, %0"
10394   [(set_attr "type" "fcmp_media")])
10395
10396 (define_insn "cmpgtsf_media"
10397   [(set (match_operand:DI 0 "register_operand" "=r")
10398         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10399                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10400   "TARGET_SHMEDIA_FPU"
10401   "fcmpgt.s     %1, %2, %0"
10402   [(set_attr "type" "fcmp_media")])
10403
10404 (define_insn "cmpgesf_media"
10405   [(set (match_operand:DI 0 "register_operand" "=r")
10406         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10407                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10408   "TARGET_SHMEDIA_FPU"
10409   "fcmpge.s     %1, %2, %0"
10410   [(set_attr "type" "fcmp_media")])
10411
10412 (define_insn "cmpunsf_media"
10413   [(set (match_operand:DI 0 "register_operand" "=r")
10414         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10415                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10416   "TARGET_SHMEDIA_FPU"
10417   "fcmpun.s     %1, %2, %0"
10418   [(set_attr "type" "fcmp_media")])
10419
10420 (define_expand "cmpsf"
10421   [(set (reg:SI T_REG)
10422         (compare (match_operand:SF 0 "arith_operand" "")
10423                  (match_operand:SF 1 "arith_operand" "")))]
10424   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10425   "
10426 {
10427   sh_compare_op0 = operands[0];
10428   sh_compare_op1 = operands[1];
10429   DONE;
10430 }")
10431
10432 (define_expand "negsf2"
10433   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10434         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10435   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10436   "
10437 {
10438   if (TARGET_SH2E)
10439     {
10440       expand_sf_unop (&gen_negsf2_i, operands);
10441       DONE;
10442     }
10443 }")
10444
10445 (define_insn "*negsf2_media"
10446   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10447         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10448   "TARGET_SHMEDIA_FPU"
10449   "fneg.s       %1, %0"
10450   [(set_attr "type" "fmove_media")])
10451
10452 (define_insn "negsf2_i"
10453   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10454         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10455    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10456   "TARGET_SH2E"
10457   "fneg %0"
10458   [(set_attr "type" "fmove")
10459    (set_attr "fp_mode" "single")])
10460
10461 (define_expand "sqrtsf2"
10462   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10463         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10464   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10465   "
10466 {
10467   if (TARGET_SH3E)
10468     {
10469       expand_sf_unop (&gen_sqrtsf2_i, operands);
10470       DONE;
10471     }
10472 }")
10473
10474 (define_insn "*sqrtsf2_media"
10475   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10476         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10477   "TARGET_SHMEDIA_FPU"
10478   "fsqrt.s      %1, %0"
10479   [(set_attr "type" "fdiv_media")])
10480
10481 (define_insn "sqrtsf2_i"
10482   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10483         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10484    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10485   "TARGET_SH3E"
10486   "fsqrt        %0"
10487   [(set_attr "type" "fdiv")
10488    (set_attr "fp_mode" "single")])
10489
10490 (define_insn "rsqrtsf2"
10491   [(set (match_operand:SF 0 "register_operand" "=f")
10492         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10493                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10494    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10495   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10496    && operands[1] == CONST1_RTX (SFmode)"
10497   "fsrra        %0"
10498   [(set_attr "type" "fsrra")
10499    (set_attr "fp_mode" "single")])
10500
10501 (define_insn "fsca"
10502   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10503         (vec_concat:V2SF
10504          (unspec:SF [(mult:SF
10505                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10506                       (match_operand:SF 2 "immediate_operand" "i"))
10507                     ] UNSPEC_FSINA)
10508          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10509                     ] UNSPEC_FCOSA)))
10510    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10511   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10512    && operands[2] == sh_fsca_int2sf ()"
10513   "fsca fpul,%d0"
10514   [(set_attr "type" "fsca")
10515    (set_attr "fp_mode" "single")])
10516
10517 (define_expand "sinsf2"
10518   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10519         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10520                    UNSPEC_FSINA))]
10521   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10522   "
10523 {
10524   rtx scaled = gen_reg_rtx (SFmode);
10525   rtx truncated = gen_reg_rtx (SImode);
10526   rtx fsca = gen_reg_rtx (V2SFmode);
10527   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10528
10529   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10530   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10531   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10532                           get_fpscr_rtx ()));
10533   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10534   DONE;
10535 }")
10536
10537 (define_expand "cossf2"
10538   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10539         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10540                    UNSPEC_FCOSA))]
10541   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10542   "
10543 {
10544   rtx scaled = gen_reg_rtx (SFmode);
10545   rtx truncated = gen_reg_rtx (SImode);
10546   rtx fsca = gen_reg_rtx (V2SFmode);
10547   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10548
10549   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10550   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10551   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10552                           get_fpscr_rtx ()));
10553   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10554   DONE;
10555 }")
10556
10557 (define_expand "sindf2"
10558   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10559         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10560                    UNSPEC_FSINA))]
10561   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10562   "
10563 {
10564   rtx scaled = gen_reg_rtx (DFmode);
10565   rtx truncated = gen_reg_rtx (SImode);
10566   rtx fsca = gen_reg_rtx (V2SFmode);
10567   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10568   rtx sfresult = gen_reg_rtx (SFmode);
10569
10570   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10571   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10572   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10573                           get_fpscr_rtx ()));
10574   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10575   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10576   DONE;
10577 }")
10578
10579 (define_expand "cosdf2"
10580   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10581         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10582                    UNSPEC_FCOSA))]
10583   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10584   "
10585 {
10586   rtx scaled = gen_reg_rtx (DFmode);
10587   rtx truncated = gen_reg_rtx (SImode);
10588   rtx fsca = gen_reg_rtx (V2SFmode);
10589   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10590   rtx sfresult = gen_reg_rtx (SFmode);
10591
10592   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10593   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10594   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10595                           get_fpscr_rtx ()));
10596   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10597   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10598   DONE;
10599 }")
10600
10601 (define_expand "abssf2"
10602   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10603         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10604   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10605   "
10606 {
10607   if (TARGET_SH2E)
10608     {
10609       expand_sf_unop (&gen_abssf2_i, operands);
10610       DONE;
10611     }
10612 }")
10613
10614 (define_insn "*abssf2_media"
10615   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10616         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10617   "TARGET_SHMEDIA_FPU"
10618   "fabs.s       %1, %0"
10619   [(set_attr "type" "fmove_media")])
10620
10621 (define_insn "abssf2_i"
10622   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10623         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10624    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10625   "TARGET_SH2E"
10626   "fabs %0"
10627   [(set_attr "type" "fmove")
10628    (set_attr "fp_mode" "single")])
10629
10630 (define_expand "adddf3"
10631   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10632         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10633                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10634   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10635   "
10636 {
10637   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10638     {
10639       expand_df_binop (&gen_adddf3_i, operands);
10640       DONE;
10641     }
10642 }")
10643
10644 (define_insn "*adddf3_media"
10645   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10646         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10647                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10648   "TARGET_SHMEDIA_FPU"
10649   "fadd.d       %1, %2, %0"
10650   [(set_attr "type" "dfparith_media")])
10651
10652 (define_insn "adddf3_i"
10653   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10654         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10655                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10656    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10657   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10658   "fadd %2,%0"
10659   [(set_attr "type" "dfp_arith")
10660    (set_attr "fp_mode" "double")])
10661
10662 (define_expand "subdf3"
10663   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10664         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10665                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10666   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10667   "
10668 {
10669   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10670     {
10671       expand_df_binop (&gen_subdf3_i, operands);
10672       DONE;
10673     }
10674 }")
10675
10676 (define_insn "*subdf3_media"
10677   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10678         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10679                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10680   "TARGET_SHMEDIA_FPU"
10681   "fsub.d       %1, %2, %0"
10682   [(set_attr "type" "dfparith_media")])
10683
10684 (define_insn "subdf3_i"
10685   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10686         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10687                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10688    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10689   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10690   "fsub %2,%0"
10691   [(set_attr "type" "dfp_arith")
10692    (set_attr "fp_mode" "double")])
10693
10694 (define_expand "muldf3"
10695   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10696         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10697                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10698   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10699   "
10700 {
10701   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10702     {
10703       expand_df_binop (&gen_muldf3_i, operands);
10704       DONE;
10705     }
10706 }")
10707
10708 (define_insn "*muldf3_media"
10709   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10710         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10711                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10712   "TARGET_SHMEDIA_FPU"
10713   "fmul.d       %1, %2, %0"
10714   [(set_attr "type" "dfmul_media")])
10715
10716 (define_insn "muldf3_i"
10717   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10718         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10719                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10720    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10721   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10722   "fmul %2,%0"
10723   [(set_attr "type" "dfp_arith")
10724    (set_attr "fp_mode" "double")])
10725
10726 (define_expand "divdf3"
10727   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10728         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10729                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10730   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10731   "
10732 {
10733   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10734     {
10735       expand_df_binop (&gen_divdf3_i, operands);
10736       DONE;
10737     }
10738 }")
10739
10740 (define_insn "*divdf3_media"
10741   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10742         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10743                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10744   "TARGET_SHMEDIA_FPU"
10745   "fdiv.d       %1, %2, %0"
10746   [(set_attr "type" "dfdiv_media")])
10747
10748 (define_insn "divdf3_i"
10749   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10750         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10751                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10752    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10753   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10754   "fdiv %2,%0"
10755   [(set_attr "type" "dfdiv")
10756    (set_attr "fp_mode" "double")])
10757
10758 (define_insn "floatdidf2"
10759   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10760         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10761   "TARGET_SHMEDIA_FPU"
10762   "float.qd     %1, %0"
10763   [(set_attr "type" "dfpconv_media")])
10764
10765 (define_expand "floatsidf2"
10766   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10767         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10768   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10769   "
10770 {
10771   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10772     {
10773       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10774                                       get_fpscr_rtx ()));
10775       DONE;
10776     }
10777 }")
10778
10779 (define_insn "*floatsidf2_media"
10780   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10781         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10782   "TARGET_SHMEDIA_FPU"
10783   "float.ld     %1, %0"
10784   [(set_attr "type" "dfpconv_media")])
10785
10786 (define_insn "floatsidf2_i"
10787   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10788         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10789    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10791   "float        %1,%0"
10792   [(set_attr "type" "dfp_conv")
10793    (set_attr "fp_mode" "double")])
10794
10795 (define_insn "fix_truncdfdi2"
10796   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10797         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10798   "TARGET_SHMEDIA_FPU"
10799   "ftrc.dq      %1, %0"
10800   [(set_attr "type" "dfpconv_media")])
10801
10802 (define_expand "fix_truncdfsi2"
10803   [(set (match_operand:SI 0 "fpul_operand" "")
10804         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10805   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10806   "
10807 {
10808   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10809     {
10810       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10811                                           get_fpscr_rtx ()));
10812       DONE;
10813     }
10814 }")
10815
10816 (define_insn "*fix_truncdfsi2_media"
10817   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10818         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10819   "TARGET_SHMEDIA_FPU"
10820   "ftrc.dl      %1, %0"
10821   [(set_attr "type" "dfpconv_media")])
10822
10823 (define_insn "fix_truncdfsi2_i"
10824   [(set (match_operand:SI 0 "fpul_operand" "=y")
10825         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10826    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10827   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10828   "ftrc %1,%0"
10829   [(set_attr "type" "dfp_conv")
10830    (set_attr "dfp_comp" "no")
10831    (set_attr "fp_mode" "double")])
10832
10833 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10834 ;; fix_truncdfsi2_i.
10835 ;; (define_insn "fix_truncdfsi2_i4"
10836 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10837 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10838 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10839 ;;    (clobber (reg:SI FPUL_REG))]
10840 ;;   "TARGET_SH4"
10841 ;;   "#"
10842 ;;   [(set_attr "length" "4")
10843 ;;    (set_attr "fp_mode" "double")])
10844 ;;
10845 ;; (define_split
10846 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10847 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10848 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10849 ;;    (clobber (reg:SI FPUL_REG))]
10850 ;;   "TARGET_SH4"
10851 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10852 ;;            (use (match_dup 2))])
10853 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10854
10855 (define_insn "cmpgtdf_t"
10856   [(set (reg:SI T_REG)
10857         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10858                (match_operand:DF 1 "arith_reg_operand" "f")))
10859    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10860   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10861   "fcmp/gt      %1,%0"
10862   [(set_attr "type" "dfp_cmp")
10863    (set_attr "fp_mode" "double")])
10864
10865 (define_insn "cmpeqdf_t"
10866   [(set (reg:SI T_REG)
10867         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10868                (match_operand:DF 1 "arith_reg_operand" "f")))
10869    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10870   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10871   "fcmp/eq      %1,%0"
10872   [(set_attr "type" "dfp_cmp")
10873    (set_attr "fp_mode" "double")])
10874
10875 (define_insn "*ieee_ccmpeqdf_t"
10876   [(set (reg:SI T_REG)
10877         (ior:SI (reg:SI T_REG)
10878                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10879                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10880    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10881   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882   "* return output_ieee_ccmpeq (insn, operands);"
10883   [(set_attr "length" "4")
10884    (set_attr "fp_mode" "double")])
10885
10886 (define_insn "cmpeqdf_media"
10887   [(set (match_operand:DI 0 "register_operand" "=r")
10888         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10889                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10890   "TARGET_SHMEDIA_FPU"
10891   "fcmpeq.d     %1,%2,%0"
10892   [(set_attr "type" "fcmp_media")])
10893
10894 (define_insn "cmpsieqdf_media"
10895   [(set (match_operand:SI 0 "register_operand" "=r")
10896         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10897                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10898   "TARGET_SHMEDIA_FPU"
10899   "fcmpeq.d     %1,%2,%0"
10900   [(set_attr "type" "fcmp_media")])
10901
10902 (define_insn "cmpgtdf_media"
10903   [(set (match_operand:DI 0 "register_operand" "=r")
10904         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10905                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10906   "TARGET_SHMEDIA_FPU"
10907   "fcmpgt.d     %1,%2,%0"
10908   [(set_attr "type" "fcmp_media")])
10909
10910 (define_insn "cmpgedf_media"
10911   [(set (match_operand:DI 0 "register_operand" "=r")
10912         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10913                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10914   "TARGET_SHMEDIA_FPU"
10915   "fcmpge.d     %1,%2,%0"
10916   [(set_attr "type" "fcmp_media")])
10917
10918 (define_insn "cmpundf_media"
10919   [(set (match_operand:DI 0 "register_operand" "=r")
10920         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10921                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10922   "TARGET_SHMEDIA_FPU"
10923   "fcmpun.d     %1,%2,%0"
10924   [(set_attr "type" "fcmp_media")])
10925
10926 (define_expand "cmpdf"
10927   [(set (reg:SI T_REG)
10928         (compare (match_operand:DF 0 "arith_operand" "")
10929                  (match_operand:DF 1 "arith_operand" "")))]
10930   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10931   "
10932 {
10933   sh_compare_op0 = operands[0];
10934   sh_compare_op1 = operands[1];
10935   DONE;
10936 }")
10937
10938 (define_expand "negdf2"
10939   [(set (match_operand:DF 0 "arith_reg_operand" "")
10940         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10941   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10942   "
10943 {
10944   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10945     {
10946       expand_df_unop (&gen_negdf2_i, operands);
10947       DONE;
10948     }
10949 }")
10950
10951 (define_insn "*negdf2_media"
10952   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10953         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10954   "TARGET_SHMEDIA_FPU"
10955   "fneg.d       %1, %0"
10956   [(set_attr "type" "fmove_media")])
10957
10958 (define_insn "negdf2_i"
10959   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10960         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10961    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10962   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10963   "fneg %0"
10964   [(set_attr "type" "fmove")
10965    (set_attr "fp_mode" "double")])
10966
10967 (define_expand "sqrtdf2"
10968   [(set (match_operand:DF 0 "arith_reg_operand" "")
10969         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10970   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10971   "
10972 {
10973   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10974     {
10975       expand_df_unop (&gen_sqrtdf2_i, operands);
10976       DONE;
10977     }
10978 }")
10979
10980 (define_insn "*sqrtdf2_media"
10981   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10982         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10983   "TARGET_SHMEDIA_FPU"
10984   "fsqrt.d      %1, %0"
10985   [(set_attr "type" "dfdiv_media")])
10986
10987 (define_insn "sqrtdf2_i"
10988   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10989         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10990    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10991   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10992   "fsqrt        %0"
10993   [(set_attr "type" "dfdiv")
10994    (set_attr "fp_mode" "double")])
10995
10996 (define_expand "absdf2"
10997   [(set (match_operand:DF 0 "arith_reg_operand" "")
10998         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10999   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11000   "
11001 {
11002   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11003     {
11004       expand_df_unop (&gen_absdf2_i, operands);
11005       DONE;
11006     }
11007 }")
11008
11009 (define_insn "*absdf2_media"
11010   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11011         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11012   "TARGET_SHMEDIA_FPU"
11013   "fabs.d       %1, %0"
11014   [(set_attr "type" "fmove_media")])
11015
11016 (define_insn "absdf2_i"
11017   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11018         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11019    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11020   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11021   "fabs %0"
11022   [(set_attr "type" "fmove")
11023    (set_attr "fp_mode" "double")])
11024
11025 (define_expand "extendsfdf2"
11026   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11027         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11028   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11029   "
11030 {
11031   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11032     {
11033       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11034                                         get_fpscr_rtx ()));
11035       DONE;
11036     }
11037 }")
11038
11039 (define_insn "*extendsfdf2_media"
11040   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11041         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11042   "TARGET_SHMEDIA_FPU"
11043   "fcnv.sd      %1, %0"
11044   [(set_attr "type" "dfpconv_media")])
11045
11046 (define_insn "extendsfdf2_i4"
11047   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11048         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11049    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11050   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11051   "fcnvsd  %1,%0"
11052   [(set_attr "type" "fp")
11053    (set_attr "fp_mode" "double")])
11054
11055 (define_expand "truncdfsf2"
11056   [(set (match_operand:SF 0 "fpul_operand" "")
11057         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11058   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11059   "
11060 {
11061   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11062     {
11063       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11064                                        get_fpscr_rtx ()));
11065       DONE;
11066     }
11067 }")
11068
11069 (define_insn "*truncdfsf2_media"
11070   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11071         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11072   "TARGET_SHMEDIA_FPU"
11073   "fcnv.ds      %1, %0"
11074   [(set_attr "type" "dfpconv_media")])
11075
11076 (define_insn "truncdfsf2_i4"
11077   [(set (match_operand:SF 0 "fpul_operand" "=y")
11078         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11079    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11080   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11081   "fcnvds  %1,%0"
11082   [(set_attr "type" "fp")
11083    (set_attr "fp_mode" "double")])
11084 \f
11085 ;; Bit field extract patterns.  These give better code for packed bitfields,
11086 ;; because they allow auto-increment addresses to be generated.
11087
11088 (define_expand "insv"
11089   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11090                          (match_operand:SI 1 "immediate_operand" "")
11091                          (match_operand:SI 2 "immediate_operand" ""))
11092         (match_operand:SI 3 "general_operand" ""))]
11093   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11094   "
11095 {
11096   rtx addr_target, orig_address, shift_reg, qi_val;
11097   HOST_WIDE_INT bitsize, size, v = 0;
11098   rtx x = operands[3];
11099
11100   /* ??? expmed doesn't care for non-register predicates.  */
11101   if (! memory_operand (operands[0], VOIDmode)
11102       || ! immediate_operand (operands[1], VOIDmode)
11103       || ! immediate_operand (operands[2], VOIDmode)
11104       || ! general_operand (x, VOIDmode))
11105     FAIL;
11106   /* If this isn't a 16 / 24 / 32 bit field, or if
11107      it doesn't start on a byte boundary, then fail.  */
11108   bitsize = INTVAL (operands[1]);
11109   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11110       || (INTVAL (operands[2]) % 8) != 0)
11111     FAIL;
11112
11113   size = bitsize / 8;
11114   orig_address = XEXP (operands[0], 0);
11115   shift_reg = gen_reg_rtx (SImode);
11116   if (GET_CODE (x) == CONST_INT)
11117     {
11118       v = INTVAL (x);
11119       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11120     }
11121   else
11122     {
11123       emit_insn (gen_movsi (shift_reg, operands[3]));
11124       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11125     }
11126   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11127
11128   operands[0] = replace_equiv_address (operands[0], addr_target);
11129   emit_insn (gen_movqi (operands[0], qi_val));
11130
11131   while (size -= 1)
11132     {
11133       if (GET_CODE (x) == CONST_INT)
11134         qi_val
11135           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11136       else
11137         {
11138           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11139           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11140         }
11141       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11142       emit_insn (gen_movqi (operands[0], qi_val));
11143     }
11144
11145   DONE;
11146 }")
11147
11148 (define_insn "movua"
11149   [(set (match_operand:SI 0 "register_operand" "=z")
11150         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11151                          (const_int 32) (const_int 0)))]
11152   "TARGET_SH4A_ARCH"
11153   "movua.l      %1,%0"
11154   [(set_attr "type" "movua")])
11155
11156 ;; We shouldn't need this, but cse replaces increments with references
11157 ;; to other regs before flow has a chance to create post_inc
11158 ;; addressing modes, and only postreload's cse_move2add brings the
11159 ;; increments back to a usable form.
11160 (define_peephole2
11161   [(set (match_operand:SI 0 "register_operand" "")
11162         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11163                          (const_int 32) (const_int 0)))
11164    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11165   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11166   [(set (match_operand:SI 0 "register_operand" "")
11167         (sign_extract:SI (mem:SI (post_inc:SI
11168                                   (match_operand:SI 1 "register_operand" "")))
11169                          (const_int 32) (const_int 0)))]
11170   "")
11171
11172 (define_expand "extv"
11173   [(set (match_operand:SI 0 "register_operand" "")
11174         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11175                          (match_operand 2 "const_int_operand" "")
11176                          (match_operand 3 "const_int_operand" "")))]
11177   "TARGET_SH4A_ARCH"
11178 {
11179   if (TARGET_SH4A_ARCH
11180       && INTVAL (operands[2]) == 32
11181       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11182       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11183     {
11184       emit_insn (gen_movua (operands[0],
11185                             adjust_address (operands[1], SImode, 0)));
11186       DONE;
11187     }
11188
11189   FAIL;
11190 })
11191
11192 (define_expand "extzv"
11193   [(set (match_operand:SI 0 "register_operand" "")
11194         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11195                          (match_operand 2 "const_int_operand" "")
11196                          (match_operand 3 "const_int_operand" "")))]
11197   "TARGET_SH4A_ARCH"
11198 {
11199   if (TARGET_SH4A_ARCH
11200       && INTVAL (operands[2]) == 32
11201       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11202       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11203     {
11204       emit_insn (gen_movua (operands[0],
11205                             adjust_address (operands[1], SImode, 0)));
11206       DONE;
11207     }
11208
11209   FAIL;
11210 })
11211
11212 \f
11213 ;; -------------------------------------------------------------------------
11214 ;; Peepholes
11215 ;; -------------------------------------------------------------------------
11216
11217 ;; This matches cases where a stack pointer increment at the start of the
11218 ;; epilogue combines with a stack slot read loading the return value.
11219
11220 (define_peephole
11221   [(set (match_operand:SI 0 "arith_reg_operand" "")
11222         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11223    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11224   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11225   "mov.l        @%1+,%0")
11226
11227 ;; See the comment on the dt combiner pattern above.
11228
11229 (define_peephole
11230   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11231         (plus:SI (match_dup 0)
11232                  (const_int -1)))
11233    (set (reg:SI T_REG)
11234         (eq:SI (match_dup 0)
11235                (const_int 0)))]
11236   "TARGET_SH2"
11237   "dt   %0")
11238
11239 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11240 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11241 ;; reload when the constant is too large for a reg+offset address.
11242
11243 ;; ??? We would get much better code if this was done in reload.  This would
11244 ;; require modifying find_reloads_address to recognize that if the constant
11245 ;; is out-of-range for an immediate add, then we get better code by reloading
11246 ;; the constant into a register than by reloading the sum into a register,
11247 ;; since the former is one instruction shorter if the address does not need
11248 ;; to be offsettable.  Unfortunately this does not work, because there is
11249 ;; only one register, r0, that can be used as an index register.  This register
11250 ;; is also the function return value register.  So, if we try to force reload
11251 ;; to use double-reg addresses, then we end up with some instructions that
11252 ;; need to use r0 twice.  The only way to fix this is to change the calling
11253 ;; convention so that r0 is not used to return values.
11254
11255 (define_peephole
11256   [(set (match_operand:SI 0 "register_operand" "=r")
11257         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11258    (set (mem:SI (match_dup 0))
11259         (match_operand:SI 2 "general_movsrc_operand" ""))]
11260   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11261   "mov.l        %2,@(%0,%1)")
11262
11263 (define_peephole
11264   [(set (match_operand:SI 0 "register_operand" "=r")
11265         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11266    (set (match_operand:SI 2 "general_movdst_operand" "")
11267         (mem:SI (match_dup 0)))]
11268   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11269   "mov.l        @(%0,%1),%2")
11270
11271 (define_peephole
11272   [(set (match_operand:SI 0 "register_operand" "=r")
11273         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11274    (set (mem:HI (match_dup 0))
11275         (match_operand:HI 2 "general_movsrc_operand" ""))]
11276   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11277   "mov.w        %2,@(%0,%1)")
11278
11279 (define_peephole
11280   [(set (match_operand:SI 0 "register_operand" "=r")
11281         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11282    (set (match_operand:HI 2 "general_movdst_operand" "")
11283         (mem:HI (match_dup 0)))]
11284   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11285   "mov.w        @(%0,%1),%2")
11286
11287 (define_peephole
11288   [(set (match_operand:SI 0 "register_operand" "=r")
11289         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11290    (set (mem:QI (match_dup 0))
11291         (match_operand:QI 2 "general_movsrc_operand" ""))]
11292   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11293   "mov.b        %2,@(%0,%1)")
11294
11295 (define_peephole
11296   [(set (match_operand:SI 0 "register_operand" "=r")
11297         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11298    (set (match_operand:QI 2 "general_movdst_operand" "")
11299         (mem:QI (match_dup 0)))]
11300   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11301   "mov.b        @(%0,%1),%2")
11302
11303 (define_peephole
11304   [(set (match_operand:SI 0 "register_operand" "=r")
11305         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11306    (set (mem:SF (match_dup 0))
11307         (match_operand:SF 2 "general_movsrc_operand" ""))]
11308   "TARGET_SH1 && REGNO (operands[0]) == 0
11309    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11310        || (GET_CODE (operands[2]) == SUBREG
11311            && REGNO (SUBREG_REG (operands[2])) < 16))
11312    && reg_unused_after (operands[0], insn)"
11313   "mov.l        %2,@(%0,%1)")
11314
11315 (define_peephole
11316   [(set (match_operand:SI 0 "register_operand" "=r")
11317         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11318    (set (match_operand:SF 2 "general_movdst_operand" "")
11319
11320         (mem:SF (match_dup 0)))]
11321   "TARGET_SH1 && REGNO (operands[0]) == 0
11322    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11323        || (GET_CODE (operands[2]) == SUBREG
11324            && REGNO (SUBREG_REG (operands[2])) < 16))
11325    && reg_unused_after (operands[0], insn)"
11326   "mov.l        @(%0,%1),%2")
11327
11328 (define_peephole
11329   [(set (match_operand:SI 0 "register_operand" "=r")
11330         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11331    (set (mem:SF (match_dup 0))
11332         (match_operand:SF 2 "general_movsrc_operand" ""))]
11333   "TARGET_SH2E && REGNO (operands[0]) == 0
11334    && ((GET_CODE (operands[2]) == REG
11335         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11336        || (GET_CODE (operands[2]) == SUBREG
11337            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11338    && reg_unused_after (operands[0], insn)"
11339   "fmov{.s|}    %2,@(%0,%1)")
11340
11341 (define_peephole
11342   [(set (match_operand:SI 0 "register_operand" "=r")
11343         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344    (set (match_operand:SF 2 "general_movdst_operand" "")
11345
11346         (mem:SF (match_dup 0)))]
11347   "TARGET_SH2E && REGNO (operands[0]) == 0
11348    && ((GET_CODE (operands[2]) == REG
11349         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11350        || (GET_CODE (operands[2]) == SUBREG
11351            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11352    && reg_unused_after (operands[0], insn)"
11353   "fmov{.s|}    @(%0,%1),%2")
11354
11355 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11356 (define_insn "sp_switch_1"
11357   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11358   "TARGET_SH1"
11359   "*
11360 {
11361   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11362   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11363   return \"mov r0,r15\";
11364 }"
11365   [(set_attr "length" "10")])
11366
11367 ;; Switch back to the original stack for interrupt functions with the
11368 ;; sp_switch attribute.  */
11369 (define_insn "sp_switch_2"
11370   [(const_int 2)]
11371   "TARGET_SH1"
11372   "mov.l @r15+,r15\;mov.l @r15+,r0"
11373   [(set_attr "length" "4")])
11374
11375 ;; Integer vector moves
11376
11377 (define_expand "movv8qi"
11378   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11379         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11380   "TARGET_SHMEDIA"
11381   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11382
11383 (define_insn "movv8qi_i"
11384   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11385         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11386   "TARGET_SHMEDIA
11387    && (register_operand (operands[0], V8QImode)
11388        || sh_register_operand (operands[1], V8QImode))"
11389   "@
11390         add     %1, r63, %0
11391         movi    %1, %0
11392         #
11393         ld%M1.q %m1, %0
11394         st%M0.q %m0, %N1"
11395   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11396    (set_attr "length" "4,4,16,4,4")])
11397
11398 (define_split
11399   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11400         (subreg:V8QI (const_int 0) 0))]
11401   "TARGET_SHMEDIA"
11402   [(set (match_dup 0)
11403         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11404                             (const_int 0) (const_int 0) (const_int 0)
11405                             (const_int 0) (const_int 0)]))])
11406
11407 (define_split
11408   [(set (match_operand 0 "arith_reg_dest" "")
11409         (match_operand 1 "sh_rep_vec" ""))]
11410   "TARGET_SHMEDIA && reload_completed
11411    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11412    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11413    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11414    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11415        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11416    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11417        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11418   [(set (match_dup 0) (match_dup 1))
11419    (match_dup 2)]
11420   "
11421 {
11422   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11423   rtx elt1 = XVECEXP (operands[1], 0, 1);
11424
11425   if (unit_size > 2)
11426     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11427   else
11428     {
11429       if (unit_size < 2)
11430         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11431       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11432     }
11433   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11434   operands[1] = XVECEXP (operands[1], 0, 0);
11435   if (unit_size < 2)
11436     {
11437       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11438         operands[1]
11439           = GEN_INT (TARGET_LITTLE_ENDIAN
11440                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11441                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11442       else
11443         {
11444           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11445           operands[1]
11446             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11447         }
11448     }
11449 }")
11450
11451 (define_split
11452   [(set (match_operand 0 "arith_reg_dest" "")
11453         (match_operand 1 "sh_const_vec" ""))]
11454   "TARGET_SHMEDIA && reload_completed
11455    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11456    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11457   [(set (match_dup 0) (match_dup 1))]
11458   "
11459 {
11460   rtx v = operands[1];
11461   enum machine_mode new_mode
11462     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11463
11464   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11465   operands[1]
11466     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11467 }")
11468
11469 (define_expand "movv2hi"
11470   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11471         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11472   "TARGET_SHMEDIA"
11473   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11474
11475 (define_insn "movv2hi_i"
11476   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11477         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11478   "TARGET_SHMEDIA
11479    && (register_operand (operands[0], V2HImode)
11480        || sh_register_operand (operands[1], V2HImode))"
11481   "@
11482         add.l   %1, r63, %0
11483         movi    %1, %0
11484         #
11485         ld%M1.l %m1, %0
11486         st%M0.l %m0, %N1"
11487   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11488    (set_attr "length" "4,4,16,4,4")
11489    (set (attr "highpart")
11490         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11491                (const_string "user")]
11492               (const_string "ignore")))])
11493
11494 (define_expand "movv4hi"
11495   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11496         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11497   "TARGET_SHMEDIA"
11498   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11499
11500 (define_insn "movv4hi_i"
11501   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11502         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11503   "TARGET_SHMEDIA
11504    && (register_operand (operands[0], V4HImode)
11505        || sh_register_operand (operands[1], V4HImode))"
11506   "@
11507         add     %1, r63, %0
11508         movi    %1, %0
11509         #
11510         ld%M1.q %m1, %0
11511         st%M0.q %m0, %N1"
11512   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11513    (set_attr "length" "4,4,16,4,4")
11514    (set_attr "highpart" "depend")])
11515
11516 (define_expand "movv2si"
11517   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11518         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11519   "TARGET_SHMEDIA"
11520   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11521
11522 (define_insn "movv2si_i"
11523   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11524         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11525   "TARGET_SHMEDIA
11526    && (register_operand (operands[0], V2SImode)
11527        || sh_register_operand (operands[1], V2SImode))"
11528   "@
11529         add     %1, r63, %0
11530         #
11531         #
11532         ld%M1.q %m1, %0
11533         st%M0.q %m0, %N1"
11534   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11535    (set_attr "length" "4,4,16,4,4")
11536    (set_attr "highpart" "depend")])
11537
11538 ;; Multimedia Intrinsics
11539
11540 (define_insn "absv2si2"
11541   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11542         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11543   "TARGET_SHMEDIA"
11544   "mabs.l       %1, %0"
11545   [(set_attr "type" "mcmp_media")
11546    (set_attr "highpart" "depend")])
11547
11548 (define_insn "absv4hi2"
11549   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11550         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11551   "TARGET_SHMEDIA"
11552   "mabs.w       %1, %0"
11553   [(set_attr "type" "mcmp_media")
11554    (set_attr "highpart" "depend")])
11555
11556 (define_insn "addv2si3"
11557   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11558         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11559                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11560   "TARGET_SHMEDIA"
11561   "madd.l       %1, %2, %0"
11562   [(set_attr "type" "arith_media")
11563    (set_attr "highpart" "depend")])
11564
11565 (define_insn "addv4hi3"
11566   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11567         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11568                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11569   "TARGET_SHMEDIA"
11570   "madd.w       %1, %2, %0"
11571   [(set_attr "type" "arith_media")
11572    (set_attr "highpart" "depend")])
11573
11574 (define_insn_and_split "addv2hi3"
11575   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11576         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11577                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11578   "TARGET_SHMEDIA"
11579   "#"
11580   "TARGET_SHMEDIA"
11581   [(const_int 0)]
11582   "
11583 {
11584   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11585   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11586   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11587   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11588   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11589
11590   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11591   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11592   DONE;
11593 }"
11594   [(set_attr "highpart" "must_split")])
11595
11596 (define_insn "ssaddv2si3"
11597   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11598         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11599                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11600   "TARGET_SHMEDIA"
11601   "madds.l      %1, %2, %0"
11602   [(set_attr "type" "mcmp_media")
11603    (set_attr "highpart" "depend")])
11604
11605 (define_insn "usaddv8qi3"
11606   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11607         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11608                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11609   "TARGET_SHMEDIA"
11610   "madds.ub     %1, %2, %0"
11611   [(set_attr "type" "mcmp_media")
11612    (set_attr "highpart" "depend")])
11613
11614 (define_insn "ssaddv4hi3"
11615   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11616         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11617                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11618   "TARGET_SHMEDIA"
11619   "madds.w      %1, %2, %0"
11620   [(set_attr "type" "mcmp_media")
11621    (set_attr "highpart" "depend")])
11622
11623 (define_insn "negcmpeqv8qi"
11624   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11625         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11626                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11627   "TARGET_SHMEDIA"
11628   "mcmpeq.b     %N1, %N2, %0"
11629   [(set_attr "type" "mcmp_media")
11630    (set_attr "highpart" "depend")])
11631
11632 (define_insn "negcmpeqv2si"
11633   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11634         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11635                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11636   "TARGET_SHMEDIA"
11637   "mcmpeq.l     %N1, %N2, %0"
11638   [(set_attr "type" "mcmp_media")
11639    (set_attr "highpart" "depend")])
11640
11641 (define_insn "negcmpeqv4hi"
11642   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11643         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11644                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11645   "TARGET_SHMEDIA"
11646   "mcmpeq.w     %N1, %N2, %0"
11647   [(set_attr "type" "mcmp_media")
11648    (set_attr "highpart" "depend")])
11649
11650 (define_insn "negcmpgtuv8qi"
11651   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11652         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11653                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11654   "TARGET_SHMEDIA"
11655   "mcmpgt.ub    %N1, %N2, %0"
11656   [(set_attr "type" "mcmp_media")
11657    (set_attr "highpart" "depend")])
11658
11659 (define_insn "negcmpgtv2si"
11660   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11661         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11662                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11663   "TARGET_SHMEDIA"
11664   "mcmpgt.l     %N1, %N2, %0"
11665   [(set_attr "type" "mcmp_media")
11666    (set_attr "highpart" "depend")])
11667
11668 (define_insn "negcmpgtv4hi"
11669   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11670         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11671                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11672   "TARGET_SHMEDIA"
11673   "mcmpgt.w     %N1, %N2, %0"
11674   [(set_attr "type" "mcmp_media")
11675    (set_attr "highpart" "depend")])
11676
11677 (define_insn "mcmv"
11678   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11679         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11680                         (match_operand:DI 2 "arith_reg_operand" "r"))
11681                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11682                         (not:DI (match_dup 2)))))]
11683   "TARGET_SHMEDIA"
11684   "mcmv %N1, %2, %0"
11685   [(set_attr "type" "arith_media")
11686    (set_attr "highpart" "depend")])
11687
11688 (define_insn "mcnvs_lw"
11689   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11690         (vec_concat:V4HI
11691          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11692          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11693   "TARGET_SHMEDIA"
11694   "mcnvs.lw     %N1, %N2, %0"
11695   [(set_attr "type" "mcmp_media")])
11696
11697 (define_insn "mcnvs_wb"
11698   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11699         (vec_concat:V8QI
11700          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11701          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11702   "TARGET_SHMEDIA"
11703   "mcnvs.wb     %N1, %N2, %0"
11704   [(set_attr "type" "mcmp_media")])
11705
11706 (define_insn "mcnvs_wub"
11707   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11708         (vec_concat:V8QI
11709          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11710          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11711   "TARGET_SHMEDIA"
11712   "mcnvs.wub    %N1, %N2, %0"
11713   [(set_attr "type" "mcmp_media")])
11714
11715 (define_insn "mextr_rl"
11716   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11717         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11719                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11720                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11721   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11722   "*
11723 {
11724   static char templ[21];
11725
11726   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11727            (int) INTVAL (operands[3]) >> 3);
11728   return templ;
11729 }"
11730   [(set_attr "type" "arith_media")])
11731
11732 (define_insn "*mextr_lr"
11733   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11734         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11735                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11736                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11737                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11738   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11739   "*
11740 {
11741   static char templ[21];
11742
11743   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11744            (int) INTVAL (operands[4]) >> 3);
11745   return templ;
11746 }"
11747   [(set_attr "type" "arith_media")])
11748
11749 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11750 ; vector then varies depending on endianness.
11751 (define_expand "mextr1"
11752   [(match_operand:DI 0 "arith_reg_dest" "")
11753    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11754    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11755   "TARGET_SHMEDIA"
11756   "
11757 {
11758   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11759                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11760   DONE;
11761 }")
11762
11763 (define_expand "mextr2"
11764   [(match_operand:DI 0 "arith_reg_dest" "")
11765    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11766    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11767   "TARGET_SHMEDIA"
11768   "
11769 {
11770   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11771                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11772   DONE;
11773 }")
11774
11775 (define_expand "mextr3"
11776   [(match_operand:DI 0 "arith_reg_dest" "")
11777    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11778    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11779   "TARGET_SHMEDIA"
11780   "
11781 {
11782   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11783                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11784   DONE;
11785 }")
11786
11787 (define_expand "mextr4"
11788   [(match_operand:DI 0 "arith_reg_dest" "")
11789    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11790    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11791   "TARGET_SHMEDIA"
11792   "
11793 {
11794   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11795                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11796   DONE;
11797 }")
11798
11799 (define_expand "mextr5"
11800   [(match_operand:DI 0 "arith_reg_dest" "")
11801    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11802    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11803   "TARGET_SHMEDIA"
11804   "
11805 {
11806   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11807                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11808   DONE;
11809 }")
11810
11811 (define_expand "mextr6"
11812   [(match_operand:DI 0 "arith_reg_dest" "")
11813    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11814    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11815   "TARGET_SHMEDIA"
11816   "
11817 {
11818   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11819                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11820   DONE;
11821 }")
11822
11823 (define_expand "mextr7"
11824   [(match_operand:DI 0 "arith_reg_dest" "")
11825    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11826    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11827   "TARGET_SHMEDIA"
11828   "
11829 {
11830   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11831                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11832   DONE;
11833 }")
11834
11835 (define_expand "mmacfx_wl"
11836   [(match_operand:V2SI 0 "arith_reg_dest" "")
11837    (match_operand:V2HI 1 "extend_reg_operand" "")
11838    (match_operand:V2HI 2 "extend_reg_operand" "")
11839    (match_operand:V2SI 3 "arith_reg_operand" "")]
11840   "TARGET_SHMEDIA"
11841   "
11842 {
11843   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11844                               operands[1], operands[2]));
11845   DONE;
11846 }")
11847
11848 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11849 ;; is depend
11850 (define_insn "mmacfx_wl_i"
11851   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11852         (ss_plus:V2SI
11853          (match_operand:V2SI 1 "arith_reg_operand" "0")
11854          (ss_truncate:V2SI
11855           (ashift:V2DI
11856            (sign_extend:V2DI
11857             (mult:V2SI
11858              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11859              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11860            (const_int 1)))))]
11861   "TARGET_SHMEDIA"
11862   "mmacfx.wl    %2, %3, %0"
11863   [(set_attr "type" "mac_media")
11864    (set_attr "highpart" "depend")])
11865
11866 (define_expand "mmacnfx_wl"
11867   [(match_operand:V2SI 0 "arith_reg_dest" "")
11868    (match_operand:V2HI 1 "extend_reg_operand" "")
11869    (match_operand:V2HI 2 "extend_reg_operand" "")
11870    (match_operand:V2SI 3 "arith_reg_operand" "")]
11871   "TARGET_SHMEDIA"
11872   "
11873 {
11874   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11875                                operands[1], operands[2]));
11876   DONE;
11877 }")
11878
11879 (define_insn "mmacnfx_wl_i"
11880   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11881         (ss_minus:V2SI
11882          (match_operand:V2SI 1 "arith_reg_operand" "0")
11883          (ss_truncate:V2SI
11884           (ashift:V2DI
11885            (sign_extend:V2DI
11886             (mult:V2SI
11887              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11888              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11889            (const_int 1)))))]
11890   "TARGET_SHMEDIA"
11891   "mmacnfx.wl   %2, %3, %0"
11892   [(set_attr "type" "mac_media")
11893    (set_attr "highpart" "depend")])
11894
11895 (define_insn "mulv2si3"
11896   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11897         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11898                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11899   "TARGET_SHMEDIA"
11900   "mmul.l       %1, %2, %0"
11901   [(set_attr "type" "d2mpy_media")
11902    (set_attr "highpart" "depend")])
11903
11904 (define_insn "mulv4hi3"
11905   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11906         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11907                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11908   "TARGET_SHMEDIA"
11909   "mmul.w       %1, %2, %0"
11910   [(set_attr "type" "dmpy_media")
11911    (set_attr "highpart" "depend")])
11912
11913 (define_insn "mmulfx_l"
11914   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11915         (ss_truncate:V2SI
11916          (ashiftrt:V2DI
11917           (mult:V2DI
11918            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11919            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11920           (const_int 31))))]
11921   "TARGET_SHMEDIA"
11922   "mmulfx.l     %1, %2, %0"
11923   [(set_attr "type" "d2mpy_media")
11924    (set_attr "highpart" "depend")])
11925
11926 (define_insn "mmulfx_w"
11927   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11928         (ss_truncate:V4HI
11929          (ashiftrt:V4SI
11930           (mult:V4SI
11931            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11932            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11933           (const_int 15))))]
11934   "TARGET_SHMEDIA"
11935   "mmulfx.w     %1, %2, %0"
11936   [(set_attr "type" "dmpy_media")
11937    (set_attr "highpart" "depend")])
11938
11939 (define_insn "mmulfxrp_w"
11940   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11941         (ss_truncate:V4HI
11942          (ashiftrt:V4SI
11943           (plus:V4SI
11944            (mult:V4SI
11945             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11946             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11947            (const_int 16384))
11948           (const_int 15))))]
11949   "TARGET_SHMEDIA"
11950   "mmulfxrp.w   %1, %2, %0"
11951   [(set_attr "type" "dmpy_media")
11952    (set_attr "highpart" "depend")])
11953
11954
11955 (define_expand "mmulhi_wl"
11956   [(match_operand:V2SI 0 "arith_reg_dest" "")
11957    (match_operand:V4HI 1 "arith_reg_operand" "")
11958    (match_operand:V4HI 2 "arith_reg_operand" "")]
11959   "TARGET_SHMEDIA"
11960   "
11961 {
11962   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11963              (operands[0], operands[1], operands[2]));
11964   DONE;
11965 }")
11966
11967 (define_expand "mmullo_wl"
11968   [(match_operand:V2SI 0 "arith_reg_dest" "")
11969    (match_operand:V4HI 1 "arith_reg_operand" "")
11970    (match_operand:V4HI 2 "arith_reg_operand" "")]
11971   "TARGET_SHMEDIA"
11972   "
11973 {
11974   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11975              (operands[0], operands[1], operands[2]));
11976   DONE;
11977 }")
11978
11979 (define_insn "mmul23_wl"
11980   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11981         (vec_select:V2SI
11982          (mult:V4SI
11983           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11984           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11985          (parallel [(const_int 2) (const_int 3)])))]
11986   "TARGET_SHMEDIA"
11987   "* return (TARGET_LITTLE_ENDIAN
11988              ? \"mmulhi.wl      %1, %2, %0\"
11989              : \"mmullo.wl      %1, %2, %0\");"
11990   [(set_attr "type" "dmpy_media")
11991    (set (attr "highpart")
11992         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11993          (const_string "user")))])
11994
11995 (define_insn "mmul01_wl"
11996   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11997         (vec_select:V2SI
11998          (mult:V4SI
11999           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12000           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12001          (parallel [(const_int 0) (const_int 1)])))]
12002   "TARGET_SHMEDIA"
12003   "* return (TARGET_LITTLE_ENDIAN
12004              ? \"mmullo.wl      %1, %2, %0\"
12005              : \"mmulhi.wl      %1, %2, %0\");"
12006   [(set_attr "type" "dmpy_media")
12007    (set (attr "highpart")
12008         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12009          (const_string "user")))])
12010
12011
12012 (define_expand "mmulsum_wq"
12013   [(match_operand:DI 0 "arith_reg_dest" "")
12014    (match_operand:V4HI 1 "arith_reg_operand" "")
12015    (match_operand:V4HI 2 "arith_reg_operand" "")
12016    (match_operand:DI 3 "arith_reg_operand" "")]
12017   "TARGET_SHMEDIA"
12018   "
12019 {
12020   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12021                                operands[1], operands[2]));
12022   DONE;
12023 }")
12024
12025 (define_insn "mmulsum_wq_i"
12026   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12027         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12028          (plus:DI
12029           (plus:DI
12030            (vec_select:DI
12031             (mult:V4DI
12032              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12033              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12034             (parallel [(const_int 0)]))
12035            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12036                                      (sign_extend:V4DI (match_dup 3)))
12037                           (parallel [(const_int 1)])))
12038           (plus:DI
12039            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12040                                      (sign_extend:V4DI (match_dup 3)))
12041                           (parallel [(const_int 2)]))
12042            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12043                                      (sign_extend:V4DI (match_dup 3)))
12044                           (parallel [(const_int 3)]))))))]
12045   "TARGET_SHMEDIA"
12046   "mmulsum.wq   %2, %3, %0"
12047   [(set_attr "type" "mac_media")])
12048
12049 (define_expand "mperm_w"
12050   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12051    (match_operand:V4HI 1 "arith_reg_operand" "r")
12052    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12053   "TARGET_SHMEDIA"
12054   "
12055 {
12056   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12057              (operands[0], operands[1], operands[2]));
12058   DONE;
12059 }")
12060
12061 ; This use of vec_select isn't exactly correct according to rtl.texi
12062 ; (because not constant), but it seems a straightforward extension.
12063 (define_insn "mperm_w_little"
12064   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12065         (vec_select:V4HI
12066          (match_operand:V4HI 1 "arith_reg_operand" "r")
12067          (parallel
12068           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12069                             (const_int 2) (const_int 0))
12070            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12071            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12072            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12073   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12074   "mperm.w      %1, %N2, %0"
12075   [(set_attr "type" "arith_media")])
12076
12077 (define_insn "mperm_w_big"
12078   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12079         (vec_select:V4HI
12080          (match_operand:V4HI 1 "arith_reg_operand" "r")
12081          (parallel
12082           [(zero_extract:QI (not:QI (match_operand:QI 2
12083                                      "extend_reg_or_0_operand" "rZ"))
12084                             (const_int 2) (const_int 0))
12085            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12086            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12087            (zero_extract:QI (not:QI (match_dup 2))
12088                             (const_int 2) (const_int 6))])))]
12089   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12090   "mperm.w      %1, %N2, %0"
12091   [(set_attr "type" "arith_media")])
12092
12093 (define_insn "mperm_w0"
12094   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12095         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12096                                           "trunc_hi_operand" "r"))))]
12097   "TARGET_SHMEDIA"
12098   "mperm.w      %1, r63, %0"
12099   [(set_attr "type" "arith_media")
12100    (set_attr "highpart" "ignore")])
12101
12102 (define_expand "msad_ubq"
12103   [(match_operand:DI 0 "arith_reg_dest" "")
12104    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12105    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12106    (match_operand:DI 3 "arith_reg_operand" "")]
12107   "TARGET_SHMEDIA"
12108   "
12109 {
12110   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12111                              operands[1], operands[2]));
12112   DONE;
12113 }")
12114
12115 (define_insn "msad_ubq_i"
12116   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12117         (plus:DI
12118          (plus:DI
12119           (plus:DI
12120            (plus:DI
12121             (match_operand:DI 1 "arith_reg_operand" "0")
12122             (abs:DI (vec_select:DI
12123                      (minus:V8DI
12124                       (zero_extend:V8DI
12125                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12126                       (zero_extend:V8DI
12127                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12128                      (parallel [(const_int 0)]))))
12129            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12130                                               (zero_extend:V8DI (match_dup 3)))
12131                                   (parallel [(const_int 1)]))))
12132           (plus:DI
12133            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12134                                               (zero_extend:V8DI (match_dup 3)))
12135                                   (parallel [(const_int 2)])))
12136            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12137                                               (zero_extend:V8DI (match_dup 3)))
12138                                   (parallel [(const_int 3)])))))
12139          (plus:DI
12140           (plus:DI
12141            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12142                                               (zero_extend:V8DI (match_dup 3)))
12143                                   (parallel [(const_int 4)])))
12144            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12145                                               (zero_extend:V8DI (match_dup 3)))
12146                                   (parallel [(const_int 5)]))))
12147           (plus:DI
12148            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12149                                               (zero_extend:V8DI (match_dup 3)))
12150                                   (parallel [(const_int 6)])))
12151            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12152                                               (zero_extend:V8DI (match_dup 3)))
12153                                   (parallel [(const_int 7)])))))))]
12154   "TARGET_SHMEDIA"
12155   "msad.ubq     %N2, %N3, %0"
12156   [(set_attr "type" "mac_media")])
12157
12158 (define_insn "mshalds_l"
12159   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12160         (ss_truncate:V2SI
12161          (ashift:V2DI
12162           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12163           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12164                   (const_int 31)))))]
12165   "TARGET_SHMEDIA"
12166   "mshalds.l    %1, %2, %0"
12167   [(set_attr "type" "mcmp_media")
12168    (set_attr "highpart" "depend")])
12169
12170 (define_insn "mshalds_w"
12171   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12172         (ss_truncate:V4HI
12173          (ashift:V4SI
12174           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12175           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12176                   (const_int 15)))))]
12177   "TARGET_SHMEDIA"
12178   "mshalds.w    %1, %2, %0"
12179   [(set_attr "type" "mcmp_media")
12180    (set_attr "highpart" "depend")])
12181
12182 (define_insn "ashrv2si3"
12183   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12184         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12185                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12186   "TARGET_SHMEDIA"
12187   "mshard.l     %1, %2, %0"
12188   [(set_attr "type" "arith_media")
12189    (set_attr "highpart" "depend")])
12190
12191 (define_insn "ashrv4hi3"
12192   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12193         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12194                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12195   "TARGET_SHMEDIA"
12196   "mshard.w     %1, %2, %0"
12197   [(set_attr "type" "arith_media")
12198    (set_attr "highpart" "depend")])
12199
12200 (define_insn "mshards_q"
12201   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12202         (ss_truncate:HI
12203          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12204                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12205   "TARGET_SHMEDIA"
12206   "mshards.q    %1, %N2, %0"
12207   [(set_attr "type" "mcmp_media")])
12208
12209 (define_expand "mshfhi_b"
12210   [(match_operand:V8QI 0 "arith_reg_dest" "")
12211    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12212    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12213   "TARGET_SHMEDIA"
12214   "
12215 {
12216   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12217              (operands[0], operands[1], operands[2]));
12218   DONE;
12219 }")
12220
12221 (define_expand "mshflo_b"
12222   [(match_operand:V8QI 0 "arith_reg_dest" "")
12223    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12224    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12225   "TARGET_SHMEDIA"
12226   "
12227 {
12228   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12229              (operands[0], operands[1], operands[2]));
12230   DONE;
12231 }")
12232
12233 (define_insn "mshf4_b"
12234   [(set
12235     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12236     (vec_select:V8QI
12237      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12238                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12239      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12240                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12241   "TARGET_SHMEDIA"
12242   "* return (TARGET_LITTLE_ENDIAN
12243              ? \"mshfhi.b       %N1, %N2, %0\"
12244              : \"mshflo.b       %N1, %N2, %0\");"
12245   [(set_attr "type" "arith_media")
12246    (set (attr "highpart")
12247         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12248          (const_string "user")))])
12249
12250 (define_insn "mshf0_b"
12251   [(set
12252     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12253     (vec_select:V8QI
12254      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12255                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12256      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12257                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12258   "TARGET_SHMEDIA"
12259   "* return (TARGET_LITTLE_ENDIAN
12260              ? \"mshflo.b       %N1, %N2, %0\"
12261              : \"mshfhi.b       %N1, %N2, %0\");"
12262   [(set_attr "type" "arith_media")
12263    (set (attr "highpart")
12264         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12265          (const_string "user")))])
12266
12267 (define_expand "mshfhi_l"
12268   [(match_operand:V2SI 0 "arith_reg_dest" "")
12269    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12270    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12271   "TARGET_SHMEDIA"
12272   "
12273 {
12274   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12275              (operands[0], operands[1], operands[2]));
12276   DONE;
12277 }")
12278
12279 (define_expand "mshflo_l"
12280   [(match_operand:V2SI 0 "arith_reg_dest" "")
12281    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12282    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12283   "TARGET_SHMEDIA"
12284   "
12285 {
12286   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12287              (operands[0], operands[1], operands[2]));
12288   DONE;
12289 }")
12290
12291 (define_insn "mshf4_l"
12292   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12293         (vec_select:V2SI
12294          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12295                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12296          (parallel [(const_int 1) (const_int 3)])))]
12297   "TARGET_SHMEDIA"
12298   "* return (TARGET_LITTLE_ENDIAN
12299              ? \"mshfhi.l       %N1, %N2, %0\"
12300              : \"mshflo.l       %N1, %N2, %0\");"
12301   [(set_attr "type" "arith_media")
12302    (set (attr "highpart")
12303         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12304          (const_string "user")))])
12305
12306 (define_insn "mshf0_l"
12307   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12308         (vec_select:V2SI
12309          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12310                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12311          (parallel [(const_int 0) (const_int 2)])))]
12312   "TARGET_SHMEDIA"
12313   "* return (TARGET_LITTLE_ENDIAN
12314              ? \"mshflo.l       %N1, %N2, %0\"
12315              : \"mshfhi.l       %N1, %N2, %0\");"
12316   [(set_attr "type" "arith_media")
12317    (set (attr "highpart")
12318         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12319          (const_string "user")))])
12320
12321 (define_expand "mshfhi_w"
12322   [(match_operand:V4HI 0 "arith_reg_dest" "")
12323    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12324    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12325   "TARGET_SHMEDIA"
12326   "
12327 {
12328   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12329              (operands[0], operands[1], operands[2]));
12330   DONE;
12331 }")
12332
12333 (define_expand "mshflo_w"
12334   [(match_operand:V4HI 0 "arith_reg_dest" "")
12335    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12336    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12337   "TARGET_SHMEDIA"
12338   "
12339 {
12340   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12341              (operands[0], operands[1], operands[2]));
12342   DONE;
12343 }")
12344
12345 (define_insn "mshf4_w"
12346   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12347         (vec_select:V4HI
12348          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12349                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12350          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12351   "TARGET_SHMEDIA"
12352   "* return (TARGET_LITTLE_ENDIAN
12353              ? \"mshfhi.w       %N1, %N2, %0\"
12354              : \"mshflo.w       %N1, %N2, %0\");"
12355   [(set_attr "type" "arith_media")
12356    (set (attr "highpart")
12357         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12358          (const_string "user")))])
12359
12360 (define_insn "mshf0_w"
12361   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12362         (vec_select:V4HI
12363          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12364                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12365          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12366   "TARGET_SHMEDIA"
12367   "* return (TARGET_LITTLE_ENDIAN
12368              ? \"mshflo.w       %N1, %N2, %0\"
12369              : \"mshfhi.w       %N1, %N2, %0\");"
12370   [(set_attr "type" "arith_media")
12371    (set (attr "highpart")
12372         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12373          (const_string "user")))])
12374
12375 (define_insn "mshflo_w_x"
12376   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12377         (vec_select:V4HI
12378          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12379                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12380          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12381   "TARGET_SHMEDIA"
12382   "mshflo.w     %N1, %N2, %0"
12383   [(set_attr "type" "arith_media")
12384    (set_attr "highpart" "ignore")])
12385
12386 /* These are useful to expand ANDs and as combiner patterns.  */
12387 (define_insn_and_split "mshfhi_l_di"
12388   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12389         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12390                              (const_int 32))
12391                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12392                         (const_int -4294967296))))]
12393   "TARGET_SHMEDIA"
12394   "@
12395         mshfhi.l        %N1, %N2, %0
12396         #"
12397   "TARGET_SHMEDIA && reload_completed
12398    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12399   [(set (match_dup 3) (match_dup 4))
12400    (set (match_dup 5) (match_dup 6))]
12401   "
12402 {
12403   operands[3] = gen_lowpart (SImode, operands[0]);
12404   operands[4] = gen_highpart (SImode, operands[1]);
12405   operands[5] = gen_highpart (SImode, operands[0]);
12406   operands[6] = gen_highpart (SImode, operands[2]);
12407 }"
12408   [(set_attr "type" "arith_media")])
12409
12410 (define_insn "*mshfhi_l_di_rev"
12411   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12412         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12413                         (const_int -4294967296))
12414                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12415                              (const_int 32))))]
12416   "TARGET_SHMEDIA"
12417   "mshfhi.l     %N2, %N1, %0"
12418   [(set_attr "type" "arith_media")])
12419
12420 (define_split
12421   [(set (match_operand:DI 0 "arith_reg_dest" "")
12422         (ior:DI (zero_extend:DI (match_operand:SI 1
12423                                               "extend_reg_or_0_operand" ""))
12424                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12425                         (const_int -4294967296))))
12426    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12427   "TARGET_SHMEDIA"
12428   [(const_int 0)]
12429   "
12430 {
12431   emit_insn (gen_ashldi3_media (operands[3],
12432                                 simplify_gen_subreg (DImode, operands[1],
12433                                                      SImode, 0),
12434                                 GEN_INT (32)));
12435   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12436   DONE;
12437 }")
12438
12439 (define_insn "mshflo_l_di"
12440   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12441         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12442                         (const_int 4294967295))
12443                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12444                            (const_int 32))))]
12445
12446   "TARGET_SHMEDIA"
12447   "mshflo.l     %N1, %N2, %0"
12448   [(set_attr "type" "arith_media")
12449    (set_attr "highpart" "ignore")])
12450
12451 (define_insn "*mshflo_l_di_rev"
12452   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12453         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12454                            (const_int 32))
12455                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12456                         (const_int 4294967295))))]
12457
12458   "TARGET_SHMEDIA"
12459   "mshflo.l     %N2, %N1, %0"
12460   [(set_attr "type" "arith_media")
12461    (set_attr "highpart" "ignore")])
12462
12463 ;; Combiner pattern for trampoline initialization.
12464 (define_insn_and_split "*double_shori"
12465   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12466         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12467                            (const_int 32))
12468                 (match_operand:DI 2 "const_int_operand" "n")))]
12469   "TARGET_SHMEDIA
12470    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12471   "#"
12472   "rtx_equal_p (operands[0], operands[1])"
12473   [(const_int 0)]
12474   "
12475 {
12476   HOST_WIDE_INT v = INTVAL (operands[2]);
12477
12478   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12479   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12480   DONE;
12481 }"
12482   [(set_attr "highpart" "ignore")])
12483
12484
12485 (define_insn "*mshflo_l_di_x"
12486   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12487         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12488                                  "rZ"))
12489                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12490                            (const_int 32))))]
12491
12492   "TARGET_SHMEDIA"
12493   "mshflo.l     %N1, %N2, %0"
12494   [(set_attr "type" "arith_media")
12495    (set_attr "highpart" "ignore")])
12496
12497 (define_insn_and_split "concat_v2sf"
12498   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12499 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12500         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12501                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12502
12503   "TARGET_SHMEDIA"
12504   "@
12505         mshflo.l        %N1, %N2, %0
12506         #
12507         #"
12508   "TARGET_SHMEDIA && reload_completed
12509    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12510   [(set (match_dup 3) (match_dup 1))
12511    (set (match_dup 4) (match_dup 2))]
12512   "
12513 {
12514   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12515   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12516 }"
12517   [(set_attr "type" "arith_media")
12518    (set_attr "highpart" "ignore")])
12519
12520 (define_insn "*mshflo_l_di_x_rev"
12521   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12522         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12523                            (const_int 32))
12524                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12525
12526   "TARGET_SHMEDIA"
12527   "mshflo.l     %N2, %N1, %0"
12528   [(set_attr "type" "arith_media")
12529    (set_attr "highpart" "ignore")])
12530
12531 (define_insn "ashlv2si3"
12532   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12533         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12534                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12535   "TARGET_SHMEDIA"
12536   "mshlld.l     %1, %2, %0"
12537   [(set_attr "type" "arith_media")
12538    (set_attr "highpart" "depend")])
12539
12540 (define_split
12541   [(set (match_operand 0 "any_register_operand" "")
12542         (match_operator 3 "shift_operator"
12543           [(match_operand 1 "any_register_operand" "")
12544            (match_operand 2 "shift_count_reg_operand" "")]))]
12545   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12546   [(set (match_dup 0) (match_dup 3))]
12547   "
12548 {
12549   rtx count = operands[2];
12550   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12551
12552   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12553          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12554          || GET_CODE (count) == TRUNCATE)
12555     count = XEXP (count, 0);
12556   inner_mode = GET_MODE (count);
12557   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12558                                subreg_lowpart_offset (outer_mode, inner_mode));
12559   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12560                                 operands[1], count);
12561 }")
12562
12563 (define_insn "ashlv4hi3"
12564   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12565         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12566                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12567   "TARGET_SHMEDIA"
12568   "mshlld.w     %1, %2, %0"
12569   [(set_attr "type" "arith_media")
12570    (set_attr "highpart" "depend")])
12571
12572 (define_insn "lshrv2si3"
12573   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12574         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12575                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12576   "TARGET_SHMEDIA"
12577   "mshlrd.l     %1, %2, %0"
12578   [(set_attr "type" "arith_media")
12579    (set_attr "highpart" "depend")])
12580
12581 (define_insn "lshrv4hi3"
12582   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12583         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12584                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12585   "TARGET_SHMEDIA"
12586   "mshlrd.w     %1, %2, %0"
12587   [(set_attr "type" "arith_media")
12588    (set_attr "highpart" "depend")])
12589
12590 (define_insn "subv2si3"
12591   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12592         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12593                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12594   "TARGET_SHMEDIA"
12595   "msub.l       %N1, %2, %0"
12596   [(set_attr "type" "arith_media")
12597    (set_attr "highpart" "depend")])
12598
12599 (define_insn "subv4hi3"
12600   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12601         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12602                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12603   "TARGET_SHMEDIA"
12604   "msub.w       %N1, %2, %0"
12605   [(set_attr "type" "arith_media")
12606    (set_attr "highpart" "depend")])
12607
12608 (define_insn_and_split "subv2hi3"
12609   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12610         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12611                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12612   "TARGET_SHMEDIA"
12613   "#"
12614   "TARGET_SHMEDIA"
12615   [(const_int 0)]
12616   "
12617 {
12618   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12619   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12620   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12621   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12622   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12623
12624   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12625   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12626   DONE;
12627 }"
12628   [(set_attr "highpart" "must_split")])
12629
12630 (define_insn "sssubv2si3"
12631   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12632         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12633                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12634   "TARGET_SHMEDIA"
12635   "msubs.l      %N1, %2, %0"
12636   [(set_attr "type" "mcmp_media")
12637    (set_attr "highpart" "depend")])
12638
12639 (define_insn "ussubv8qi3"
12640   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12641         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12642                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12643   "TARGET_SHMEDIA"
12644   "msubs.ub     %N1, %2, %0"
12645   [(set_attr "type" "mcmp_media")
12646    (set_attr "highpart" "depend")])
12647
12648 (define_insn "sssubv4hi3"
12649   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12650         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12651                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12652   "TARGET_SHMEDIA"
12653   "msubs.w      %N1, %2, %0"
12654   [(set_attr "type" "mcmp_media")
12655    (set_attr "highpart" "depend")])
12656
12657 ;; Floating Point Intrinsics
12658
12659 (define_insn "fcosa_s"
12660   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12661         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12662                    UNSPEC_FCOSA))]
12663   "TARGET_SHMEDIA"
12664   "fcosa.s      %1, %0"
12665   [(set_attr "type" "atrans_media")])
12666
12667 (define_insn "fsina_s"
12668   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12669         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12670                    UNSPEC_FSINA))]
12671   "TARGET_SHMEDIA"
12672   "fsina.s      %1, %0"
12673   [(set_attr "type" "atrans_media")])
12674
12675 (define_insn "fipr"
12676   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12677         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12678                                                     "fp_arith_reg_operand" "f")
12679                                                    (match_operand:V4SF 2
12680                                                     "fp_arith_reg_operand" "f"))
12681                                          (parallel [(const_int 0)]))
12682                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12683                                          (parallel [(const_int 1)])))
12684                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12685                                          (parallel [(const_int 2)]))
12686                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12687                                          (parallel [(const_int 3)])))))]
12688   "TARGET_SHMEDIA"
12689   "fipr.s       %1, %2, %0"
12690   [(set_attr "type" "fparith_media")])
12691
12692 (define_insn "fsrra_s"
12693   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12694         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12695                    UNSPEC_FSRRA))]
12696   "TARGET_SHMEDIA"
12697   "fsrra.s      %1, %0"
12698   [(set_attr "type" "atrans_media")])
12699
12700 (define_insn "ftrv"
12701   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12702         (plus:V4SF
12703          (plus:V4SF
12704           (mult:V4SF
12705            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12706                             (parallel [(const_int 0) (const_int 5)
12707                                        (const_int 10) (const_int 15)]))
12708            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12709           (mult:V4SF
12710            (vec_select:V4SF (match_dup 1)
12711                             (parallel [(const_int 4) (const_int 9)
12712                                        (const_int 14) (const_int 3)]))
12713            (vec_select:V4SF (match_dup 2)
12714                             (parallel [(const_int 1) (const_int 2)
12715                                        (const_int 3) (const_int 0)]))))
12716          (plus:V4SF
12717           (mult:V4SF
12718            (vec_select:V4SF (match_dup 1)
12719                             (parallel [(const_int 8) (const_int 13)
12720                                        (const_int 2) (const_int 7)]))
12721            (vec_select:V4SF (match_dup 2)
12722                             (parallel [(const_int 2) (const_int 3)
12723                                        (const_int 0) (const_int 1)])))
12724           (mult:V4SF
12725            (vec_select:V4SF (match_dup 1)
12726                             (parallel [(const_int 12) (const_int 1)
12727                                        (const_int 6) (const_int 11)]))
12728            (vec_select:V4SF (match_dup 2)
12729                             (parallel [(const_int 3) (const_int 0)
12730                                        (const_int 1) (const_int 2)]))))))]
12731   "TARGET_SHMEDIA"
12732   "ftrv.s %1, %2, %0"
12733   [(set_attr "type" "fparith_media")])
12734
12735 (define_insn "ldhi_l"
12736   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12737         (zero_extract:SI
12738          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12739                                   (const_int 3))
12740                           (const_int -3)))
12741          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12742          (const_int 0)))]
12743   "TARGET_SHMEDIA32"
12744   "ldhi.l       %U1, %0"
12745   [(set_attr "type" "load_media")])
12746
12747 (define_insn "ldhi_q"
12748   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12749         (zero_extract:DI
12750          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12751                                   (const_int 7))
12752                           (const_int -7)))
12753          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12754          (const_int 0)))]
12755   "TARGET_SHMEDIA32"
12756   "ldhi.q       %U1, %0"
12757   [(set_attr "type" "load_media")])
12758
12759 (define_insn_and_split "*ldhi_q_comb0"
12760   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12761         (zero_extract:DI
12762          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12763                                             "register_operand" "r")
12764                                            (match_operand:SI 2
12765                                             "ua_offset" "I06"))
12766                                   (const_int 7))
12767                           (const_int -7)))
12768          (plus:SI (and:SI (match_dup 1) (const_int 7))
12769                   (const_int 1))
12770          (const_int 0)))]
12771   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12772   "#"
12773   ""
12774   [(pc)]
12775   "emit_insn (gen_ldhi_q (operands[0],
12776                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12777    DONE;")
12778
12779
12780 (define_insn_and_split "*ldhi_q_comb1"
12781   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12782         (zero_extract:DI
12783          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12784                                             "register_operand" "r")
12785                                            (match_operand:SI 2
12786                                             "ua_offset" "I06"))
12787                                   (const_int 7))
12788                           (const_int -7)))
12789          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12790                                                    "ua_offset" "I06"))
12791                           (const_int 7))
12792                   (const_int 1))
12793          (const_int 0)))]
12794   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12795    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12796   "#"
12797   ""
12798   [(pc)]
12799   "emit_insn (gen_ldhi_q (operands[0],
12800                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12801    DONE;")
12802
12803
12804 (define_insn "ldlo_l"
12805   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12806         (zero_extract:SI
12807          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12808                          (const_int -4)))
12809          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12810          (and:SI (match_dup 1) (const_int 3))))]
12811   "TARGET_SHMEDIA32"
12812   "ldlo.l       %U1, %0"
12813   [(set_attr "type" "load_media")])
12814
12815 (define_insn "ldlo_q"
12816   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12817         (zero_extract:DI
12818          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12819                          (const_int -8)))
12820          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12821          (and:SI (match_dup 1) (const_int 7))))]
12822   "TARGET_SHMEDIA32"
12823   "ldlo.q       %U1, %0"
12824   [(set_attr "type" "load_media")])
12825
12826 (define_insn_and_split "*ldlo_q_comb0"
12827   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12828         (zero_extract:DI
12829          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12830                                   (match_operand:SI 2 "ua_offset" "I06"))
12831                          (const_int -8)))
12832          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12833          (and:SI (match_dup 1) (const_int 7))))]
12834   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12835   "#"
12836   ""
12837   [(pc)]
12838   "emit_insn (gen_ldlo_q (operands[0],
12839                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12840    DONE;")
12841
12842 (define_insn_and_split "*ldlo_q_comb1"
12843   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12844         (zero_extract:DI
12845          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12846                                   (match_operand:SI 2 "ua_offset" "I06"))
12847                          (const_int -8)))
12848          (minus:SI (const_int 8)
12849                    (and:SI (plus:SI (match_dup 1)
12850                                     (match_operand:SI 3 "ua_offset" "I06"))
12851                            (const_int 7)))
12852          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12853   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12854    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12855   "#"
12856   ""
12857   [(pc)]
12858   "emit_insn (gen_ldlo_q (operands[0],
12859                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12860    DONE;")
12861
12862 (define_insn "sthi_l"
12863   [(set (zero_extract:SI
12864          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12865                                   (const_int 3))
12866                           (const_int -3)))
12867          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12868          (const_int 0))
12869         (match_operand:SI 1 "arith_reg_operand" "r"))]
12870   "TARGET_SHMEDIA32"
12871   "sthi.l       %U0, %1"
12872   [(set_attr "type" "ustore_media")])
12873
12874 ;; All unaligned stores are considered to be 'narrow' because they typically
12875 ;; operate on less that a quadword, and when they operate on a full quadword,
12876 ;; the vanilla store high / store low sequence will cause a stall if not
12877 ;; scheduled apart.
12878 (define_insn "sthi_q"
12879   [(set (zero_extract:DI
12880          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12881                                   (const_int 7))
12882                           (const_int -7)))
12883          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12884          (const_int 0))
12885         (match_operand:DI 1 "arith_reg_operand" "r"))]
12886   "TARGET_SHMEDIA32"
12887   "sthi.q       %U0, %1"
12888   [(set_attr "type" "ustore_media")])
12889
12890 (define_insn_and_split "*sthi_q_comb0"
12891   [(set (zero_extract:DI
12892          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12893                                             "register_operand" "r")
12894                                            (match_operand:SI 1 "ua_offset"
12895                                             "I06"))
12896                                   (const_int 7))
12897                           (const_int -7)))
12898          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12899          (const_int 0))
12900         (match_operand:DI 2 "arith_reg_operand" "r"))]
12901   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12902   "#"
12903   ""
12904   [(pc)]
12905   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12906                           operands[2]));
12907    DONE;")
12908
12909 (define_insn_and_split "*sthi_q_comb1"
12910   [(set (zero_extract:DI
12911          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12912                                             "register_operand" "r")
12913                                            (match_operand:SI 1 "ua_offset"
12914                                             "I06"))
12915                                   (const_int 7))
12916                           (const_int -7)))
12917          (plus:SI (and:SI (plus:SI (match_dup 0)
12918                                    (match_operand:SI 2 "ua_offset" "I06"))
12919                           (const_int 7))
12920                   (const_int 1))
12921          (const_int 0))
12922         (match_operand:DI 3 "arith_reg_operand" "r"))]
12923   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12924    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12925   "#"
12926   ""
12927   [(pc)]
12928   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12929                           operands[3]));
12930    DONE;")
12931
12932 ;; This is highpart user because the address is used as full 64 bit.
12933 (define_insn "stlo_l"
12934   [(set (zero_extract:SI
12935          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12936                          (const_int -4)))
12937          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12938          (and:SI (match_dup 0) (const_int 3)))
12939         (match_operand:SI 1 "arith_reg_operand" "r"))]
12940   "TARGET_SHMEDIA32"
12941   "stlo.l       %U0, %1"
12942   [(set_attr "type" "ustore_media")])
12943
12944 (define_insn "stlo_q"
12945   [(set (zero_extract:DI
12946          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12947                          (const_int -8)))
12948          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12949          (and:SI (match_dup 0) (const_int 7)))
12950         (match_operand:DI 1 "arith_reg_operand" "r"))]
12951   "TARGET_SHMEDIA32"
12952   "stlo.q       %U0, %1"
12953   [(set_attr "type" "ustore_media")])
12954
12955 (define_insn_and_split "*stlo_q_comb0"
12956   [(set (zero_extract:DI
12957          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12958                                   (match_operand:SI 1 "ua_offset" "I06"))
12959                          (const_int -8)))
12960          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12961          (and:SI (match_dup 0) (const_int 7)))
12962         (match_operand:DI 2 "arith_reg_operand" "r"))]
12963   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12964   "#"
12965   ""
12966   [(pc)]
12967   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12968                           operands[2]));
12969    DONE;")
12970
12971 (define_insn_and_split "*stlo_q_comb1"
12972   [(set (zero_extract:DI
12973          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12974                                   (match_operand:SI 1 "ua_offset" "I06"))
12975                          (const_int -8)))
12976          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12977                                                   (match_operand:SI 2
12978                                                    "ua_offset" "I06"))
12979                                          (const_int 7)))
12980          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12981         (match_operand:DI 3 "arith_reg_operand" "r"))]
12982   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12983   "#"
12984   ""
12985   [(pc)]
12986   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12987                           operands[3]));
12988    DONE;")
12989
12990 (define_insn "ldhi_l64"
12991   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12992         (zero_extract:SI
12993          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12994                                   (const_int 3))
12995                           (const_int -3)))
12996          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12997          (const_int 0)))]
12998   "TARGET_SHMEDIA64"
12999   "ldhi.l       %U1, %0"
13000   [(set_attr "type" "load_media")])
13001
13002 (define_insn "ldhi_q64"
13003   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13004         (zero_extract:DI
13005          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13006                                   (const_int 7))
13007                           (const_int -7)))
13008          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13009          (const_int 0)))]
13010   "TARGET_SHMEDIA64"
13011   "ldhi.q       %U1, %0"
13012   [(set_attr "type" "load_media")])
13013
13014 (define_insn "ldlo_l64"
13015   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13016         (zero_extract:SI
13017          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13018                          (const_int -4)))
13019          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13020          (and:DI (match_dup 1) (const_int 3))))]
13021   "TARGET_SHMEDIA64"
13022   "ldlo.l       %U1, %0"
13023   [(set_attr "type" "load_media")])
13024
13025 (define_insn "ldlo_q64"
13026   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13027         (zero_extract:DI
13028          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13029                          (const_int -8)))
13030          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13031          (and:DI (match_dup 1) (const_int 7))))]
13032   "TARGET_SHMEDIA64"
13033   "ldlo.q       %U1, %0"
13034   [(set_attr "type" "load_media")])
13035
13036 (define_insn "sthi_l64"
13037   [(set (zero_extract:SI
13038          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13039                                   (const_int 3))
13040                           (const_int -3)))
13041          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13042          (const_int 0))
13043         (match_operand:SI 1 "arith_reg_operand" "r"))]
13044   "TARGET_SHMEDIA64"
13045   "sthi.l       %U0, %1"
13046   [(set_attr "type" "ustore_media")])
13047
13048 (define_insn "sthi_q64"
13049   [(set (zero_extract:DI
13050          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13051                                   (const_int 7))
13052                           (const_int -7)))
13053          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13054          (const_int 0))
13055         (match_operand:DI 1 "arith_reg_operand" "r"))]
13056   "TARGET_SHMEDIA64"
13057   "sthi.q       %U0, %1"
13058   [(set_attr "type" "ustore_media")])
13059
13060 (define_insn "stlo_l64"
13061   [(set (zero_extract:SI
13062          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13063                          (const_int -4)))
13064          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13065          (and:DI (match_dup 0) (const_int 3)))
13066         (match_operand:SI 1 "arith_reg_operand" "r"))]
13067   "TARGET_SHMEDIA64"
13068   "stlo.l       %U0, %1"
13069   [(set_attr "type" "ustore_media")])
13070
13071 (define_insn "stlo_q64"
13072   [(set (zero_extract:DI
13073          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13074                          (const_int -8)))
13075          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13076          (and:DI (match_dup 0) (const_int 7)))
13077         (match_operand:DI 1 "arith_reg_operand" "r"))]
13078   "TARGET_SHMEDIA64"
13079   "stlo.q       %U0, %1"
13080   [(set_attr "type" "ustore_media")])
13081
13082 (define_insn "nsb"
13083   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13084         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13085                    UNSPEC_NSB))]
13086   "TARGET_SHMEDIA"
13087   "nsb  %1, %0"
13088   [(set_attr "type" "arith_media")])
13089
13090 (define_insn "nsbsi"
13091   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13092         (zero_extend:SI
13093          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13094                     UNSPEC_NSB)))]
13095   "TARGET_SHMEDIA"
13096   "nsb  %1, %0"
13097   [(set_attr "type" "arith_media")])
13098
13099 (define_insn "nsbdi"
13100   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13101         (zero_extend:DI
13102          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13103                     UNSPEC_NSB)))]
13104   "TARGET_SHMEDIA"
13105   "nsb  %1, %0"
13106   [(set_attr "type" "arith_media")])
13107
13108 (define_expand "ffsdi2"
13109   [(set (match_operand:DI 0 "arith_reg_dest" "")
13110         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13111   "TARGET_SHMEDIA"
13112   "
13113 {
13114   rtx scratch = gen_reg_rtx (DImode);
13115   rtx last;
13116
13117   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13118   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13119   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13120   emit_insn (gen_nsbdi (scratch, scratch));
13121   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13122   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13123   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13124   REG_NOTES (last)
13125     = gen_rtx_EXPR_LIST (REG_EQUAL,
13126                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13127   DONE;
13128 }")
13129
13130 (define_expand "ffssi2"
13131   [(set (match_operand:SI 0 "arith_reg_dest" "")
13132         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13133   "TARGET_SHMEDIA"
13134   "
13135 {
13136   rtx scratch = gen_reg_rtx (SImode);
13137   rtx discratch = gen_reg_rtx (DImode);
13138   rtx last;
13139
13140   emit_insn (gen_adddi3 (discratch,
13141                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13142                          constm1_rtx));
13143   emit_insn (gen_andcdi3 (discratch,
13144                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13145                           discratch));
13146   emit_insn (gen_nsbsi (scratch, discratch));
13147   last = emit_insn (gen_subsi3 (operands[0],
13148                                 force_reg (SImode, GEN_INT (63)), scratch));
13149   REG_NOTES (last)
13150     = gen_rtx_EXPR_LIST (REG_EQUAL,
13151                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13152   DONE;
13153 }")
13154
13155 (define_insn "byterev"
13156   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13157         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13158                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13159                                     (const_int 4) (const_int 3) (const_int 2)
13160                                     (const_int 1) (const_int 0)])))]
13161   "TARGET_SHMEDIA"
13162   "byterev      %1, %0"
13163   [(set_attr "type" "arith_media")])
13164
13165 (define_insn "*prefetch_media"
13166   [(prefetch (match_operand:QI 0 "address_operand" "p")
13167              (match_operand:SI 1 "const_int_operand" "n")
13168              (match_operand:SI 2 "const_int_operand" "n"))]
13169   "TARGET_SHMEDIA"
13170   "*
13171 {
13172   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13173   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13174   return \"\";
13175 }"
13176   [(set_attr "type" "other")])
13177
13178 (define_insn "*prefetch_i4"
13179   [(prefetch (match_operand:SI 0 "register_operand" "r")
13180              (match_operand:SI 1 "const_int_operand" "n")
13181              (match_operand:SI 2 "const_int_operand" "n"))]
13182   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13183   "*
13184 {
13185   return \"pref @%0\";
13186 }"
13187   [(set_attr "type" "other")])
13188
13189 (define_expand "prefetch"
13190   [(prefetch (match_operand 0 "address_operand" "p")
13191              (match_operand:SI 1 "const_int_operand" "n")
13192              (match_operand:SI 2 "const_int_operand" "n"))]
13193   "TARGET_HARD_SH4 || TARGET_SH5"
13194   "
13195 {
13196   if (GET_MODE (operands[0]) != Pmode
13197       || GET_CODE (operands[1]) != CONST_INT
13198       || GET_CODE (operands[2]) != CONST_INT)
13199     FAIL;
13200   if (! TARGET_SHMEDIA)
13201     operands[0] = force_reg (Pmode, operands[0]);
13202 }")
13203
13204 (define_insn "alloco_i"
13205   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13206         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13207   "TARGET_SHMEDIA32"
13208   "*
13209 {
13210   rtx xops[2];
13211
13212   if (GET_CODE (operands[0]) == PLUS)
13213     {
13214       xops[0] = XEXP (operands[0], 0);
13215       xops[1] = XEXP (operands[0], 1);
13216     }
13217   else
13218     {
13219       xops[0] = operands[0];
13220       xops[1] = const0_rtx;
13221     }
13222   output_asm_insn (\"alloco   %0, %1\", xops);
13223   return \"\";
13224 }"
13225   [(set_attr "type" "other")])
13226
13227 (define_split
13228   [(set (match_operand 0 "any_register_operand" "")
13229         (match_operand 1 "" ""))]
13230   "TARGET_SHMEDIA && reload_completed"
13231   [(set (match_dup 0) (match_dup 1))]
13232   "
13233 {
13234   int n_changes = 0;
13235
13236   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13237   if (!n_changes)
13238     FAIL;
13239 }")
13240
13241 ; Stack Protector Patterns
13242
13243 (define_expand "stack_protect_set"
13244   [(set (match_operand 0 "memory_operand" "")
13245         (match_operand 1 "memory_operand" ""))]
13246   ""
13247 {
13248   if (TARGET_SHMEDIA)
13249     {
13250       if (TARGET_SHMEDIA64)
13251         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13252       else
13253         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13254     }
13255   else
13256     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13257
13258   DONE;
13259 })
13260
13261 (define_insn "stack_protect_set_si"
13262   [(set (match_operand:SI 0 "memory_operand" "=m")
13263         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13264    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13265   "!TARGET_SHMEDIA"
13266   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13267   [(set_attr "type" "other")
13268    (set_attr "length" "6")])
13269
13270 (define_insn "stack_protect_set_si_media"
13271   [(set (match_operand:SI 0 "memory_operand" "=m")
13272         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13273    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13274   "TARGET_SHMEDIA"
13275   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13276   [(set_attr "type" "other")
13277    (set_attr "length" "12")])
13278
13279 (define_insn "stack_protect_set_di_media"
13280   [(set (match_operand:DI 0 "memory_operand" "=m")
13281         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13282    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13283   "TARGET_SHMEDIA64"
13284   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13285   [(set_attr "type" "other")
13286    (set_attr "length" "12")])
13287
13288 (define_expand "stack_protect_test"
13289   [(match_operand 0 "memory_operand" "")
13290    (match_operand 1 "memory_operand" "")
13291    (match_operand 2 "" "")]
13292   ""
13293 {
13294   if (TARGET_SHMEDIA)
13295     {
13296       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13297
13298       if (TARGET_SHMEDIA64)
13299         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13300                                                     operands[1]));
13301       else
13302         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13303                                                     operands[1]));
13304
13305       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13306     }
13307   else
13308     {
13309       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13310       emit_jump_insn (gen_branch_true (operands[2]));
13311     }
13312
13313   DONE;
13314 })
13315
13316 (define_insn "stack_protect_test_si"
13317   [(set (reg:SI T_REG)
13318         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13319                     (match_operand:SI 1 "memory_operand" "m")]
13320                    UNSPEC_SP_TEST))
13321   (set (match_scratch:SI 2 "=&r") (const_int 0))
13322   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13323   "!TARGET_SHMEDIA"
13324   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13325   [(set_attr "type" "other")
13326    (set_attr "length" "10")])
13327
13328 (define_insn "stack_protect_test_si_media"
13329   [(set (match_operand:SI 0 "register_operand" "=&r")
13330         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13331                     (match_operand:SI 2 "memory_operand" "m")]
13332                    UNSPEC_SP_TEST))
13333   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13334   "TARGET_SHMEDIA"
13335   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13336   [(set_attr "type" "other")
13337    (set_attr "length" "16")])
13338
13339 (define_insn "stack_protect_test_di_media"
13340   [(set (match_operand:DI 0 "register_operand" "=&r")
13341         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13342                     (match_operand:DI 2 "memory_operand" "m")]
13343                    UNSPEC_SP_TEST))
13344   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13345   "TARGET_SHMEDIA64"
13346   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13347   [(set_attr "type" "other")
13348    (set_attr "length" "16")])