OSDN Git Service

* config/sh/sh.md (divsi_inv_m3): Handle zero dividend
[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, 2007 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 3, 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 COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
26
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
29
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
31
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
34
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
37
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
42 ;; Special constraints for SH machine description:
43 ;;
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
48 ;;
49 ;; Special formats used for outputting SH instructions:
50 ;;
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
58 ;;
59 ;; Special predicates:
60 ;;
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
66
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
70
71 (define_constants [
72   (AP_REG       145)
73   (PR_REG       146)
74   (T_REG        147)
75   (GBR_REG      144)
76   (MACH_REG     148)
77   (MACL_REG     149)
78   (FPUL_REG     150)
79   (RAP_REG      152)
80
81   (FPSCR_REG    151)
82
83   (PIC_REG      12)
84   (FP_REG       14)
85   (SP_REG       15)
86
87   (PR_MEDIA_REG 18)
88   (T_MEDIA_REG  19)
89
90   (R0_REG       0)
91   (R1_REG       1)
92   (R2_REG       2)
93   (R3_REG       3)
94   (R4_REG       4)
95   (R5_REG       5)
96   (R6_REG       6)
97   (R7_REG       7)
98   (R8_REG       8)
99   (R9_REG       9)
100   (R10_REG      10)
101   (R20_REG      20)
102   (R21_REG      21)
103   (R22_REG      22)
104   (R23_REG      23)
105
106   (DR0_REG      64)
107   (DR2_REG      66)
108   (DR4_REG      68)
109   (FR23_REG     87)
110
111   (TR0_REG      128)
112   (TR1_REG      129)
113   (TR2_REG      130)
114
115   (XD0_REG      136)
116
117   ;; These are used with unspec.
118   (UNSPEC_COMPACT_ARGS  0)
119   (UNSPEC_MOVA          1)
120   (UNSPEC_CASESI        2)
121   (UNSPEC_DATALABEL     3)
122   (UNSPEC_BBR           4)
123   (UNSPEC_SFUNC         5)
124   (UNSPEC_PIC           6)
125   (UNSPEC_GOT           7)
126   (UNSPEC_GOTOFF        8)
127   (UNSPEC_PLT           9)
128   (UNSPEC_CALLER        10)
129   (UNSPEC_GOTPLT        11)
130   (UNSPEC_ICACHE        12)
131   (UNSPEC_INIT_TRAMP    13)
132   (UNSPEC_FCOSA         14)
133   (UNSPEC_FSRRA         15)
134   (UNSPEC_FSINA         16)
135   (UNSPEC_NSB           17)
136   (UNSPEC_ALLOCO        18)
137   (UNSPEC_TLSGD         20)
138   (UNSPEC_TLSLDM        21)
139   (UNSPEC_TLSIE         22)
140   (UNSPEC_DTPOFF        23)
141   (UNSPEC_GOTTPOFF      24)
142   (UNSPEC_TPOFF         25)
143   (UNSPEC_RA            26)
144   (UNSPEC_DIV_INV_M0    30)
145   (UNSPEC_DIV_INV_M1    31)
146   (UNSPEC_DIV_INV_M2    32)
147   (UNSPEC_DIV_INV_M3    33)
148   (UNSPEC_DIV_INV20     34)
149   (UNSPEC_DIV_INV_TABLE 37)
150   (UNSPEC_ASHIFTRT      35)
151   (UNSPEC_THUNK         36)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
155
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
164   (UNSPECV_EH_RETURN    12)
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 ;; fstore       floating point register to memory
207 ;; move         general purpose register to register
208 ;; movi8        8-bit immediate to general purpose register
209 ;; mt_group     other sh4 mt instructions
210 ;; fmove        register to register, floating point
211 ;; smpy         word precision integer multiply
212 ;; dmpy         longword or doublelongword precision integer multiply
213 ;; return       rts
214 ;; pload        load of pr reg, which can't be put into delay slot of rts
215 ;; prset        copy register to pr reg, ditto
216 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
217 ;; prget        copy pr to register, ditto
218 ;; pcload       pc relative load of constant value
219 ;; pcfload      Likewise, but load to fp register.
220 ;; pcload_si    Likewise, SImode variant for general register.
221 ;; rte          return from exception
222 ;; sfunc        special function call with known used registers
223 ;; call         function call
224 ;; fp           floating point
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv         floating point divide (or square root)
227 ;; gp_fpul      move from general purpose register to fpul
228 ;; fpul_gp      move from fpul to general purpose register
229 ;; mac_gp       move from mac[lh] to general purpose register
230 ;; gp_mac       move from general purpose register to mac[lh]
231 ;; mac_mem      move from mac[lh] to memory
232 ;; mem_mac      move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s       fix_truncsfsi2_i4
235 ;; dfdiv        double precision floating point divide (or square root)
236 ;; cwb          ic_invalidate_line_i
237 ;; movua        SH4a unaligned load
238 ;; fsrra        square root reciprocal approximate
239 ;; fsca         sine and cosine approximate
240 ;; tls_load     load TLS related address
241 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media    SHmedia compare instructions
244 ;; dfdiv_media  SHmedia double precision divide and square root
245 ;; dfmul_media  SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media   SHmedia longword multiply
249 ;; fcmp_media   SHmedia floating point compare instructions
250 ;; fdiv_media   SHmedia single precision divide and square root
251 ;; fload_media  SHmedia floating point register load instructions
252 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media  SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media   SHmedia unconditional branch instructions
259 ;; load_media   SHmedia general register load instructions
260 ;; pt_media     SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media  SHmedia ptabs instruction
262 ;; store_media  SHmedia general register store instructions
263 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media    SHmedia mac-style fixed point operations
265 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil          no-op move, will be deleted.
269
270 (define_attr "type"
271  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
272   (const_string "other"))
273
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
276 ;;
277 ;; mt_group      SH4 "mt" group instructions.
278 ;;
279 ;; ex_group      SH4 "ex" group instructions.
280 ;;
281 ;; ls_group      SH4 "ls" group instructions.
282 ;;
283
284 (define_attr "insn_class"
285   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289          (eq_attr "type" "cbranch,jump") (const_string "br_group")
290          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291            (const_string "fe_group")
292          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
293         (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
297
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
299
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
301
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
305 ;; state.
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
309
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long.  Something in the
312 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
315 ; 2 bytes.
316
317 ;; The maximum range used for SImode constant pool entries is 1018.  A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table.  That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
329 ;;
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
332
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
334 ;; inside an le.
335 (define_attr "short_cbranch_p" "no,yes"
336   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
337          (const_string "no")
338          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
339          (const_string "yes")
340          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
341          (const_string "no")
342          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
343          (const_string "yes")
344          ] (const_string "no")))
345
346 (define_attr "med_branch_p" "no,yes"
347   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
348               (const_int 1988))
349          (const_string "yes")
350          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
351          (const_string "no")
352          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
353               (const_int 8186))
354          (const_string "yes")
355          ] (const_string "no")))
356
357 (define_attr "med_cbranch_p" "no,yes"
358   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
359               (const_int 1986))
360          (const_string "yes")
361          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
364                (const_int 8184))
365          (const_string "yes")
366          ] (const_string "no")))
367
368 (define_attr "braf_branch_p" "no,yes"
369   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
370          (const_string "no")
371          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
372               (const_int 20660))
373          (const_string "yes")
374          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
377               (const_int 65530))
378          (const_string "yes")
379          ] (const_string "no")))
380
381 (define_attr "braf_cbranch_p" "no,yes"
382   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
385               (const_int 20658))
386          (const_string "yes")
387          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
390               (const_int 65528))
391          (const_string "yes")
392          ] (const_string "no")))
393
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
400
401 ; All other instructions are two bytes long by default.
402
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406   (cond [(eq_attr "type" "cbranch")
407          (cond [(eq_attr "short_cbranch_p" "yes")
408                 (const_int 2)
409                 (eq_attr "med_cbranch_p" "yes")
410                 (const_int 6)
411                 (eq_attr "braf_cbranch_p" "yes")
412                 (const_int 12)
413 ;; ??? using pc is not computed transitively.
414                 (ne (match_dup 0) (match_dup 0))
415                 (const_int 14)
416                 (ne (symbol_ref ("flag_pic")) (const_int 0))
417                 (const_int 24)
418                 ] (const_int 16))
419          (eq_attr "type" "jump")
420          (cond [(eq_attr "med_branch_p" "yes")
421                 (const_int 2)
422                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
423                          (const_int 0))
424                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
425                               (symbol_ref "INSN"))
426                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427                               (symbol_ref "code_for_indirect_jump_scratch"))))
428                 (cond [(eq_attr "braf_branch_p" "yes")
429                        (const_int 6)
430                        (eq (symbol_ref "flag_pic") (const_int 0))
431                        (const_int 10)
432                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
433                        (const_int 10)] (const_int 18))
434                 (eq_attr "braf_branch_p" "yes")
435                 (const_int 10)
436 ;; ??? using pc is not computed transitively.
437                 (ne (match_dup 0) (match_dup 0))
438                 (const_int 12)
439                 (ne (symbol_ref ("flag_pic")) (const_int 0))
440                 (const_int 22)
441                 ] (const_int 14))
442          (eq_attr "type" "pt_media")
443          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444                        (const_int 20) (const_int 12))
445          (and (eq_attr "type" "jump_media")
446               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
447          (const_int 8)
448          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
449                          (const_int 4)
450                          (const_int 2))))
451
452 ;; DFA descriptions for the pipelines
453
454 (include "sh1.md")
455 (include "shmedia.md")
456 (include "sh4.md")
457
458 (include "predicates.md")
459 (include "constraints.md")
460
461 ;; Definitions for filling delay slots
462
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
464
465 (define_attr "banked" "yes,no" 
466         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
467                    (const_int 1))
468                (const_string "yes")]
469               (const_string "no")))
470
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
474                    (const_int 0))
475                (const_string "no")]
476               (const_string "yes")))
477
478 (define_attr "interrupt_function" "no,yes"
479   (const (symbol_ref "current_function_interrupt")))
480
481 (define_attr "in_delay_slot" "yes,no"
482   (cond [(eq_attr "type" "cbranch") (const_string "no")
483          (eq_attr "type" "pcload,pcload_si") (const_string "no")
484          (eq_attr "needs_delay_slot" "yes") (const_string "no")
485          (eq_attr "length" "2") (const_string "yes")
486          ] (const_string "no")))
487
488 (define_attr "cond_delay_slot" "yes,no"
489   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490          ] (const_string "no")))
491
492 (define_attr "is_sfunc" ""
493   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
494
495 (define_attr "is_mac_media" ""
496   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
497
498 (define_attr "branch_zero" "yes,no"
499   (cond [(eq_attr "type" "!cbranch") (const_string "no")
500          (ne (symbol_ref "(next_active_insn (insn)\
501                            == (prev_active_insn\
502                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503                           && get_attr_length (next_active_insn (insn)) == 2")
504              (const_int 0))
505          (const_string "yes")]
506         (const_string "no")))
507
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512         (const_string "no")))
513
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519          (const_string "yes")]
520         (const_string "no")))
521
522 (define_attr "any_int_load" "yes,no"
523   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524          (const_string "yes")]
525         (const_string "no")))
526
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528   (const_string "user"))
529
530 (define_delay
531   (eq_attr "needs_delay_slot" "yes")
532   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
533
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
538
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
541
542 (define_delay
543   (eq_attr "type" "return")
544   [(and (eq_attr "in_delay_slot" "yes")
545         (ior (and (eq_attr "interrupt_function" "no")
546                   (eq_attr "type" "!pload,prset"))
547              (and (eq_attr "interrupt_function" "yes")
548                   (ior
549                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
550                    (eq_attr "hit_stack" "no")
551                    (eq_attr "banked" "no"))))) (nil) (nil)])
552
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
555
556 (define_delay
557   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558   [(and (eq_attr "in_delay_slot" "yes")
559         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
560
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
563
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
567
568 (define_delay
569   (and (eq_attr "type" "cbranch")
570        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571   ;; SH2e has a hardware bug that pretty much prohibits the use of
572   ;; annuled delay slots.
573   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
575 \f
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
579
580 (define_insn ""
581   [(set (reg:SI T_REG)
582         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583                        (match_operand:SI 1 "arith_operand" "K08,r"))
584                (const_int 0)))]
585   "TARGET_SH1"
586   "tst  %1,%0"
587   [(set_attr "type" "mt_group")])
588
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
594
595 (define_insn "cmpeqsi_t"
596   [(set (reg:SI T_REG)
597         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
599   "TARGET_SH1"
600   "@
601         tst     %0,%0
602         cmp/eq  %1,%0
603         cmp/eq  %1,%0"
604    [(set_attr "type" "mt_group")])
605
606 (define_insn "cmpgtsi_t"
607   [(set (reg:SI T_REG)
608         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
610   "TARGET_SH1"
611   "@
612         cmp/gt  %1,%0
613         cmp/pl  %0"
614    [(set_attr "type" "mt_group")])
615
616 (define_insn "cmpgesi_t"
617   [(set (reg:SI T_REG)
618         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
620   "TARGET_SH1"
621   "@
622         cmp/ge  %1,%0
623         cmp/pz  %0"
624    [(set_attr "type" "mt_group")])
625
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
629
630 (define_expand "cbranchsi4"
631   [(set (pc)
632         (if_then_else (match_operator 0 "comparison_operator"
633                         [(match_operand:SI 1 "arith_operand" "")
634                          (match_operand:SI 2 "arith_operand" "")])
635                       (label_ref (match_operand 3 "" ""))
636                       (pc)))
637    (clobber (reg:SI T_REG))]
638   "TARGET_CBRANCHDI4"
639   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
640
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
644
645 (define_insn_and_split "cmpgeusi_t"
646   [(set (reg:SI T_REG)
647         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
649   "TARGET_SH1"
650   "cmp/hs       %1,%0"
651   "&& operands[0] == CONST0_RTX (SImode)"
652   [(pc)]
653   "
654 {
655   emit_insn (gen_sett ());
656   DONE;
657 }"
658    [(set_attr "type" "mt_group")])
659
660 (define_insn "cmpgtusi_t"
661   [(set (reg:SI T_REG)
662         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663                 (match_operand:SI 1 "arith_reg_operand" "r")))]
664   "TARGET_SH1"
665   "cmp/hi       %1,%0"
666    [(set_attr "type" "mt_group")])
667
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
670
671 (define_expand "cmpsi"
672   [(set (reg:SI T_REG)
673         (compare (match_operand:SI 0 "cmpsi_operand" "")
674                  (match_operand:SI 1 "arith_operand" "")))]
675   "TARGET_SH1 || TARGET_SHMEDIA"
676   "
677 {
678   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679       && GET_CODE (operands[1]) != CONST_INT)
680     operands[0] = copy_to_mode_reg (SImode, operands[0]);
681   sh_compare_op0 = operands[0];
682   sh_compare_op1 = operands[1];
683   DONE;
684 }")
685 \f
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
689
690
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
695
696 (define_expand "cbranchdi4"
697   [(set (pc)
698         (if_then_else (match_operator 0 "comparison_operator"
699                         [(match_operand:DI 1 "arith_operand" "")
700                          (match_operand:DI 2 "arith_operand" "")])
701                       (label_ref (match_operand 3 "" ""))
702                       (pc)))
703    (clobber (match_dup 4))
704    (clobber (reg:SI T_REG))]
705   "TARGET_CBRANCHDI4"
706   "
707 {
708   enum rtx_code comparison;
709
710   if (TARGET_EXPAND_CBRANCHDI4)
711     {
712       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
713         DONE;
714     }
715   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716   if (comparison != GET_CODE (operands[0]))
717     operands[0]
718       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719    operands[4] = gen_rtx_SCRATCH (SImode);
720 }")
721
722 (define_insn_and_split "cbranchdi4_i"
723   [(set (pc)
724         (if_then_else (match_operator 0 "comparison_operator"
725                         [(match_operand:DI 1 "arith_operand" "r,r")
726                          (match_operand:DI 2 "arith_operand" "rN,i")])
727                       (label_ref (match_operand 3 "" ""))
728                       (pc)))
729    (clobber (match_scratch:SI 4 "=X,&r"))
730    (clobber (reg:SI T_REG))]
731   "TARGET_CBRANCHDI4"
732   "#"
733   "&& reload_completed"
734   [(pc)]
735   "
736 {
737   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
738     FAIL;
739   DONE;
740 }")
741
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
745
746 (define_insn ""
747   [(set (reg:SI T_REG)
748         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749                        (match_operand:DI 1 "arith_operand" "r"))
750                (const_int 0)))]
751   "TARGET_SH1"
752   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
753                                  insn, operands);"
754   [(set_attr "length" "6")
755    (set_attr "type" "arith3b")])
756
757 (define_insn "cmpeqdi_t"
758   [(set (reg:SI T_REG)
759         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
761   "TARGET_SH1"
762   "@
763         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
764         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765   [(set_attr "length" "6")
766    (set_attr "type" "arith3b")])
767
768 (define_split
769   [(set (reg:SI T_REG)
770         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
774 ;; may be created.
775   "TARGET_SH1 && reload_completed && optimize"
776   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778                            (label_ref (match_dup 6))
779                            (pc)))
780    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
781    (match_dup 6)]
782   "
783 {
784   operands[2]
785     = gen_rtx_REG (SImode,
786                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
787   operands[3]
788     = (operands[1] == const0_rtx
789        ? const0_rtx
790        : gen_rtx_REG (SImode,
791                       true_regnum (operands[1])
792                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793   operands[4] = gen_lowpart (SImode, operands[0]);
794   operands[5] = gen_lowpart (SImode, operands[1]);
795   operands[6] = gen_label_rtx ();
796 }")
797
798 (define_insn "cmpgtdi_t"
799   [(set (reg:SI T_REG)
800         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
802   "TARGET_SH2"
803   "@
804         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806   [(set_attr "length" "8")
807    (set_attr "type" "arith3")])
808
809 (define_insn "cmpgedi_t"
810   [(set (reg:SI T_REG)
811         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
813   "TARGET_SH2"
814   "@
815         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
816         cmp/pz\\t%S0"
817   [(set_attr "length" "8,2")
818    (set_attr "type" "arith3,mt_group")])
819 \f
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
823
824 (define_insn "cmpgeudi_t"
825   [(set (reg:SI T_REG)
826         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827                 (match_operand:DI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH2"
829   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830   [(set_attr "length" "8")
831    (set_attr "type" "arith3")])
832
833 (define_insn "cmpgtudi_t"
834   [(set (reg:SI T_REG)
835         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836                 (match_operand:DI 1 "arith_reg_operand" "r")))]
837   "TARGET_SH2"
838   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839   [(set_attr "length" "8")
840    (set_attr "type" "arith3")])
841
842 (define_insn "cmpeqsi_media"
843   [(set (match_operand:SI 0 "register_operand" "=r")
844         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845                (match_operand:SI 2 "cmp_operand" "Nr")))]
846   "TARGET_SHMEDIA"
847   "cmpeq        %1, %N2, %0"
848   [(set_attr "type" "cmp_media")])
849
850 (define_insn "cmpeqdi_media"
851   [(set (match_operand:SI 0 "register_operand" "=r")
852         (eq:SI (match_operand:DI 1 "register_operand" "%r")
853                (match_operand:DI 2 "cmp_operand" "Nr")))]
854   "TARGET_SHMEDIA"
855   "cmpeq        %1, %N2, %0"
856   [(set_attr "type" "cmp_media")])
857
858 (define_insn "cmpgtsi_media"
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861                (match_operand:SI 2 "cmp_operand" "rN")))]
862   "TARGET_SHMEDIA"
863   "cmpgt        %N1, %N2, %0"
864   [(set_attr "type" "cmp_media")])
865
866 (define_insn "cmpgtdi_media"
867   [(set (match_operand:SI 0 "register_operand" "=r")
868         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
870   "TARGET_SHMEDIA"
871   "cmpgt        %N1, %N2, %0"
872   [(set_attr "type" "cmp_media")])
873
874 (define_insn "cmpgtusi_media"
875   [(set (match_operand:SI 0 "register_operand" "=r")
876         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877                 (match_operand:SI 2 "cmp_operand" "rN")))]
878   "TARGET_SHMEDIA"
879   "cmpgtu       %N1, %N2, %0"
880   [(set_attr "type" "cmp_media")])
881
882 (define_insn "cmpgtudi_media"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886   "TARGET_SHMEDIA"
887   "cmpgtu       %N1, %N2, %0"
888   [(set_attr "type" "cmp_media")])
889
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
894   "TARGET_SHMEDIA"
895   "cmpgtu       %1,r63,%0"
896   [(set_attr "type" "cmp_media")])
897
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
900
901 (define_expand "cmpdi"
902   [(set (reg:SI T_REG)
903         (compare (match_operand:DI 0 "arith_operand" "")
904                  (match_operand:DI 1 "arith_operand" "")))]
905   "TARGET_SH2 || TARGET_SHMEDIA"
906   "
907 {
908   sh_compare_op0 = operands[0];
909   sh_compare_op1 = operands[1];
910   DONE;
911 }")
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
915
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
918
919 (define_insn "movdicc_false"
920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
922                              (const_int 0))
923          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924          (match_operand:DI 3 "arith_reg_operand" "0")))]
925   "TARGET_SHMEDIA"
926   "cmveq        %1, %N2, %0"
927   [(set_attr "type" "arith_media")])
928
929 (define_insn "movdicc_true"
930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
932                              (const_int 0))
933          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934          (match_operand:DI 3 "arith_reg_operand" "0")))]
935   "TARGET_SHMEDIA"
936   "cmvne        %1, %N2, %0"
937   [(set_attr "type" "arith_media")])
938
939 (define_peephole2
940   [(set (match_operand:DI 0 "arith_reg_dest" "")
941         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942                            [(match_operand:DI 1 "arith_reg_operand" "")
943                             (const_int 0)])
944          (match_operand:DI 2 "arith_reg_dest" "")
945          (match_dup 0)))
946    (set (match_dup 2) (match_dup 0))]
947   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
948   [(set (match_dup 2)
949         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
950   "
951 {
952   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953                                 VOIDmode, operands[1], CONST0_RTX (DImode));
954 }")
955
956 (define_peephole2
957   [(set (match_operand:DI 0 "general_movdst_operand" "")
958         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959    (set (match_operand:DI 2 "arith_reg_dest" "")
960         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961                            [(match_operand:DI 3 "arith_reg_operand" "")
962                             (const_int 0)])
963          (match_dup 0)
964          (match_dup 2)))]
965   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
966   [(set (match_dup 2)
967         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
968   "")
969
970 (define_expand "movdicc"
971   [(set (match_operand:DI 0 "register_operand" "")
972         (if_then_else:DI (match_operand 1 "comparison_operator" "")
973                          (match_operand:DI 2 "register_operand" "")
974                          (match_operand:DI 3 "register_operand" "")))]
975   "TARGET_SHMEDIA"
976   "
977 {
978   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979       && GET_MODE (sh_compare_op0) == DImode
980       && sh_compare_op1 == const0_rtx)
981     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982                                   sh_compare_op0, sh_compare_op1);
983   else
984     {
985       rtx tmp;
986
987       if (!can_create_pseudo_p ())
988         FAIL;
989
990       tmp = gen_reg_rtx (DImode);
991
992       switch (GET_CODE (operands[1]))
993         {
994         case EQ:
995           emit_insn (gen_seq (tmp));
996           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997           break;
998
999         case NE:
1000           emit_insn (gen_seq (tmp));
1001           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002           break;
1003
1004         case GT:
1005           emit_insn (gen_sgt (tmp));
1006           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1007           break;
1008
1009         case LT:
1010           emit_insn (gen_slt (tmp));
1011           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012           break;
1013
1014         case GE:
1015           emit_insn (gen_slt (tmp));
1016           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1017           break;
1018
1019         case LE:
1020           emit_insn (gen_sgt (tmp));
1021           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1022           break;
1023
1024         case GTU:
1025           emit_insn (gen_sgtu (tmp));
1026           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1027           break;
1028
1029         case LTU:
1030           emit_insn (gen_sltu (tmp));
1031           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1032           break;
1033
1034         case GEU:
1035           emit_insn (gen_sltu (tmp));
1036           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1037           break;
1038
1039         case LEU:
1040           emit_insn (gen_sgtu (tmp));
1041           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1042           break;
1043
1044         case UNORDERED:
1045           emit_insn (gen_sunordered (tmp));
1046           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1047           break;
1048
1049         case ORDERED:
1050           emit_insn (gen_sunordered (tmp));
1051           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1052           break;
1053
1054         case UNEQ:
1055         case UNGE:
1056         case UNGT:
1057         case UNLE:
1058         case UNLT:
1059         case LTGT:
1060           FAIL;
1061
1062         default:
1063           gcc_unreachable ();
1064         }
1065     }
1066 }")
1067
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1073                           (const_int 0))
1074          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075          (match_operand:SI 3 "arith_reg_operand" "0")))]
1076   "TARGET_SHMEDIA"
1077   "cmveq        %1, %N2, %0"
1078   [(set_attr "type" "arith_media")])
1079
1080 (define_insn "movsicc_true"
1081   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1083                           (const_int 0))
1084          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085          (match_operand:SI 3 "arith_reg_operand" "0")))]
1086   "TARGET_SHMEDIA"
1087   "cmvne        %1, %N2, %0"
1088   [(set_attr "type" "arith_media")])
1089
1090 (define_peephole2
1091   [(set (match_operand:SI 0 "arith_reg_dest" "")
1092         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093                            [(match_operand:SI 1 "arith_reg_operand" "")
1094                             (const_int 0)])
1095          (match_operand:SI 2 "arith_reg_dest" "")
1096          (match_dup 0)))
1097    (set (match_dup 2) (match_dup 0))]
1098   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1099   [(set (match_dup 2)
1100         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1101   "
1102 {
1103   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1105 }")
1106
1107 (define_peephole2
1108   [(set (match_operand:SI 0 "general_movdst_operand" "")
1109         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110    (set (match_operand:SI 2 "arith_reg_dest" "")
1111         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112                            [(match_operand:SI 3 "arith_reg_operand" "")
1113                             (const_int 0)])
1114          (match_dup 0)
1115          (match_dup 2)))]
1116   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1118   [(set (match_dup 2)
1119         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1120   "
1121 {
1122   replace_rtx (operands[4], operands[0], operands[1]);
1123 }")
1124
1125 (define_peephole2
1126   [(set (match_operand 0 "any_register_operand" "")
1127         (match_operand 1 "any_register_operand" ""))
1128    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138    && (REGNO_REG_CLASS (REGNO (operands[0]))
1139        == REGNO_REG_CLASS (REGNO (operands[2])))
1140    && (REGNO_REG_CLASS (REGNO (operands[1]))
1141        == REGNO_REG_CLASS (REGNO (operands[0])))"
1142   [(set (match_dup 0) (match_dup 3))
1143    (set (match_dup 4) (match_dup 5))]
1144   "
1145 {
1146   rtx set1, set2;
1147   rtx replacements[4];
1148
1149   /* We want to replace occurrences of operands[0] with operands[1] and
1150      operands[2] with operands[0] in operands[4]/operands[5].
1151      Doing just two replace_rtx calls naively would result in the second
1152      replacement undoing all that the first did if operands[1] and operands[2]
1153      are identical, so we must do this simultaneously.  */
1154   replacements[0] = operands[0];
1155   replacements[1] = operands[1];
1156   replacements[2] = operands[2];
1157   replacements[3] = operands[0];
1158   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1161     FAIL;
1162
1163   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166   /* The operands array is aliased to recog_data.operand, which gets
1167      clobbered by extract_insn, so finish with it now.  */
1168   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171      always uses emit_insn.  */
1172   /* Check that we don't violate matching constraints or earlyclobbers.  */
1173   extract_insn (emit_insn (set1));
1174   if (! constrain_operands (1))
1175     goto failure;
1176   extract_insn (emit (set2));
1177   if (! constrain_operands (1))
1178     {
1179       rtx tmp;
1180     failure:
1181       tmp = replacements[0];
1182       replacements[0] = replacements[1];
1183       replacements[1] = tmp;
1184       tmp = replacements[2];
1185       replacements[2] = replacements[3];
1186       replacements[3] = tmp;
1187       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1188       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1189       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1190       FAIL;
1191     }
1192   DONE;
1193 }")
1194
1195 ;; The register allocator is rather clumsy in handling multi-way conditional
1196 ;; moves, so allow the combiner to make them, and we split them up after
1197 ;; reload.  */
1198 (define_insn_and_split "*movsicc_umin"
1199   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1200         (umin:SI (if_then_else:SI
1201                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1202                        (const_int 0))
1203                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1204                    (match_operand:SI 3 "register_operand" "0"))
1205                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1206    (clobber (match_scratch:SI 5 "=&r"))]
1207   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1208   "#"
1209   "TARGET_SHMEDIA && reload_completed"
1210   [(pc)]
1211   "
1212 {
1213   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1214                                 operands[3]));
1215   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1216   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1217                                 operands[0]));
1218   DONE;
1219 }")
1220
1221 (define_insn "*movsicc_t_false"
1222   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1223         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1224                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1225                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1226   "TARGET_PRETEND_CMOVE
1227    && (arith_reg_operand (operands[1], SImode)
1228        || (immediate_operand (operands[1], SImode)
1229            && satisfies_constraint_I08 (operands[1])))"
1230   "bt 0f\;mov %1,%0\\n0:"
1231   [(set_attr "type" "mt_group,arith") ;; poor approximation
1232    (set_attr "length" "4")])
1233
1234 (define_insn "*movsicc_t_true"
1235   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1236         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1237                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1238                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1239   "TARGET_PRETEND_CMOVE
1240    && (arith_reg_operand (operands[1], SImode)
1241        || (immediate_operand (operands[1], SImode)
1242            && satisfies_constraint_I08 (operands[1])))"
1243   "bf 0f\;mov %1,%0\\n0:"
1244   [(set_attr "type" "mt_group,arith") ;; poor approximation
1245    (set_attr "length" "4")])
1246
1247 (define_expand "movsicc"
1248   [(set (match_operand:SI 0 "arith_reg_dest" "")
1249         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1250                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1251                          (match_operand:SI 3 "arith_reg_operand" "")))]
1252   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1253   "
1254 {
1255   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1256       && GET_MODE (sh_compare_op0) == SImode
1257       && (TARGET_SHMEDIA
1258           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1259       && sh_compare_op1 == const0_rtx)
1260     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1261                                   sh_compare_op0, sh_compare_op1);
1262   else if (TARGET_PRETEND_CMOVE)
1263     {
1264       enum rtx_code code = GET_CODE (operands[1]);
1265       enum rtx_code new_code = code;
1266       rtx tmp;
1267
1268       if (! currently_expanding_to_rtl)
1269         FAIL;
1270       switch (code)
1271         {
1272         case LT: case LE: case LEU: case LTU:
1273           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1274             break;
1275         case NE:
1276           new_code = reverse_condition (code);
1277           break;
1278         case EQ: case GT: case GE: case GEU: case GTU:
1279           break;
1280         default:
1281           FAIL;
1282         }
1283       tmp = prepare_scc_operands (new_code);
1284       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1285                                     tmp, const0_rtx);
1286     }
1287   else
1288     {
1289       rtx tmp;
1290
1291       if (!can_create_pseudo_p ())
1292         FAIL;
1293
1294       tmp = gen_reg_rtx (SImode);
1295
1296       switch (GET_CODE (operands[1]))
1297         {
1298         case EQ:
1299           emit_insn (gen_seq (tmp));
1300           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1301           break;
1302
1303         case NE:
1304           emit_insn (gen_seq (tmp));
1305           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1306           break;
1307
1308         case GT:
1309           emit_insn (gen_sgt (tmp));
1310           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1311           break;
1312
1313         case LT:
1314           emit_insn (gen_slt (tmp));
1315           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1316           break;
1317
1318         case GE:
1319           emit_insn (gen_slt (tmp));
1320           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1321           break;
1322
1323         case LE:
1324           emit_insn (gen_sgt (tmp));
1325           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1326           break;
1327
1328         case GTU:
1329           emit_insn (gen_sgtu (tmp));
1330           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1331           break;
1332
1333         case LTU:
1334           emit_insn (gen_sltu (tmp));
1335           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1336           break;
1337
1338         case GEU:
1339           emit_insn (gen_sltu (tmp));
1340           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1341           break;
1342
1343         case LEU:
1344           emit_insn (gen_sgtu (tmp));
1345           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1346           break;
1347
1348         case UNORDERED:
1349           emit_insn (gen_sunordered (tmp));
1350           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1351           break;
1352
1353         case ORDERED:
1354           emit_insn (gen_sunordered (tmp));
1355           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1356           break;
1357
1358         case UNEQ:
1359         case UNGE:
1360         case UNGT:
1361         case UNLE:
1362         case UNLT:
1363         case LTGT:
1364           FAIL;
1365
1366         default:
1367           abort ();
1368         }
1369     }
1370 }")
1371
1372 (define_expand "movqicc"
1373   [(set (match_operand:QI 0 "register_operand" "")
1374         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375                          (match_operand:QI 2 "register_operand" "")
1376                          (match_operand:QI 3 "register_operand" "")))]
1377   "TARGET_SHMEDIA"
1378   "
1379 {
1380   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1381   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1382   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1383   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1384   DONE;
1385 }")
1386 \f
1387 ;; -------------------------------------------------------------------------
1388 ;; Addition instructions
1389 ;; -------------------------------------------------------------------------
1390
1391 (define_expand "adddi3"
1392   [(set (match_operand:DI 0 "arith_reg_operand" "")
1393         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1394                  (match_operand:DI 2 "arith_operand" "")))]
1395   ""
1396   "
1397 {
1398   if (TARGET_SH1)
1399     {
1400       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1401         FAIL;
1402       operands[2] = force_reg (DImode, operands[2]);
1403       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1404       DONE;
1405     }
1406 }")
1407
1408 (define_insn "*adddi3_media"
1409   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1410         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1411                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1412   "TARGET_SHMEDIA"
1413   "@
1414         add     %1, %2, %0
1415         addi    %1, %2, %0"
1416   [(set_attr "type" "arith_media")])
1417
1418 (define_insn "*adddisi3_media"
1419   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1420         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1422   "TARGET_SHMEDIA"
1423   "@
1424         add.l   %1, %2, %0
1425         addi.l  %1, %2, %0"
1426   [(set_attr "type" "arith_media")
1427    (set_attr "highpart" "ignore")])
1428
1429 (define_insn "adddi3z_media"
1430   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1431         (zero_extend:DI
1432          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1433                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1434   "TARGET_SHMEDIA"
1435   "addz.l       %1, %N2, %0"
1436   [(set_attr "type" "arith_media")
1437    (set_attr "highpart" "ignore")])
1438
1439 (define_insn "adddi3_compact"
1440   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1441         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1442                  (match_operand:DI 2 "arith_reg_operand" "r")))
1443    (clobber (reg:SI T_REG))]
1444   "TARGET_SH1"
1445   "#"
1446   [(set_attr "length" "6")])
1447
1448 (define_split
1449   [(set (match_operand:DI 0 "arith_reg_dest" "")
1450         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1451                  (match_operand:DI 2 "arith_reg_operand" "")))
1452    (clobber (reg:SI T_REG))]
1453   "TARGET_SH1 && reload_completed"
1454   [(const_int 0)]
1455   "
1456 {
1457   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1458   high0 = gen_rtx_REG (SImode,
1459                        true_regnum (operands[0])
1460                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461   high2 = gen_rtx_REG (SImode,
1462                        true_regnum (operands[2])
1463                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464   emit_insn (gen_clrt ());
1465   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1466   emit_insn (gen_addc1 (high0, high0, high2));
1467   DONE;
1468 }")
1469
1470 (define_insn "addc"
1471   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1472         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1473                           (match_operand:SI 2 "arith_reg_operand" "r"))
1474                  (reg:SI T_REG)))
1475    (set (reg:SI T_REG)
1476         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1477   "TARGET_SH1"
1478   "addc %2,%0"
1479   [(set_attr "type" "arith")])
1480
1481 (define_insn "addc1"
1482   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1483         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1484                           (match_operand:SI 2 "arith_reg_operand" "r"))
1485                  (reg:SI T_REG)))
1486    (clobber (reg:SI T_REG))]
1487   "TARGET_SH1"
1488   "addc %2,%0"
1489   [(set_attr "type" "arith")])
1490
1491 (define_expand "addsi3"
1492   [(set (match_operand:SI 0 "arith_reg_operand" "")
1493         (plus:SI (match_operand:SI 1 "arith_operand" "")
1494                  (match_operand:SI 2 "arith_operand" "")))]
1495   ""
1496   "
1497 {
1498   if (TARGET_SHMEDIA)
1499     operands[1] = force_reg (SImode, operands[1]);
1500 }")
1501
1502 (define_insn "addsi3_media"
1503   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1504         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1505                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1506   "TARGET_SHMEDIA"
1507   "@
1508         add.l   %1, %2, %0
1509         addi.l  %1, %2, %0"
1510   [(set_attr "type" "arith_media")
1511    (set_attr "highpart" "ignore")])
1512
1513 (define_insn "addsidi3_media"
1514   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1515         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1516                                   "%r,r")
1517                                  (match_operand:SI 2 "arith_operand"
1518                                   "r,I10"))))]
1519   "TARGET_SHMEDIA"
1520   "@
1521         add.l   %1, %2, %0
1522         addi.l  %1, %2, %0"
1523   [(set_attr "type" "arith_media")
1524    (set_attr "highpart" "ignore")])
1525
1526 (define_insn "*addsi3_compact"
1527   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1528         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1529                  (match_operand:SI 2 "arith_operand" "rI08")))]
1530   "TARGET_SH1"
1531   "add  %2,%0"
1532   [(set_attr "type" "arith")])
1533
1534 ;; -------------------------------------------------------------------------
1535 ;; Subtraction instructions
1536 ;; -------------------------------------------------------------------------
1537
1538 (define_expand "subdi3"
1539   [(set (match_operand:DI 0 "arith_reg_operand" "")
1540         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1541                   (match_operand:DI 2 "arith_reg_operand" "")))]
1542   ""
1543   "
1544 {
1545   if (TARGET_SH1)
1546     {
1547       operands[1] = force_reg (DImode, operands[1]);
1548       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1549       DONE;
1550     }
1551 }")
1552
1553 (define_insn "*subdi3_media"
1554   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1555         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1556                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1557   "TARGET_SHMEDIA"
1558   "sub  %N1, %2, %0"
1559   [(set_attr "type" "arith_media")])
1560   
1561 (define_insn "subdisi3_media"
1562   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1563         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1564                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1565   "TARGET_SHMEDIA"
1566   "sub.l        %N1, %2, %0"
1567   [(set_attr "type" "arith_media")
1568    (set_attr "highpart" "ignore")])
1569
1570 (define_insn "subdi3_compact"
1571   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1572         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1573                  (match_operand:DI 2 "arith_reg_operand" "r")))
1574    (clobber (reg:SI T_REG))]
1575   "TARGET_SH1"
1576   "#"
1577   [(set_attr "length" "6")])
1578
1579 (define_split
1580   [(set (match_operand:DI 0 "arith_reg_dest" "")
1581         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1582                   (match_operand:DI 2 "arith_reg_operand" "")))
1583    (clobber (reg:SI T_REG))]
1584   "TARGET_SH1 && reload_completed"
1585   [(const_int 0)]
1586   "
1587 {
1588   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1589   high0 = gen_rtx_REG (SImode,
1590                        true_regnum (operands[0])
1591                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1592   high2 = gen_rtx_REG (SImode,
1593                        true_regnum (operands[2])
1594                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595   emit_insn (gen_clrt ());
1596   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1597   emit_insn (gen_subc1 (high0, high0, high2));
1598   DONE;
1599 }")
1600
1601 (define_insn "subc"
1602   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1603         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1604                             (match_operand:SI 2 "arith_reg_operand" "r"))
1605                   (reg:SI T_REG)))
1606    (set (reg:SI T_REG)
1607         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1608                           (reg:SI T_REG))
1609                 (match_dup 1)))]
1610   "TARGET_SH1"
1611   "subc %2,%0"
1612   [(set_attr "type" "arith")])
1613
1614 (define_insn "subc1"
1615   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1616         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1617                             (match_operand:SI 2 "arith_reg_operand" "r"))
1618                   (reg:SI T_REG)))
1619    (clobber (reg:SI T_REG))]
1620   "TARGET_SH1"
1621   "subc %2,%0"
1622   [(set_attr "type" "arith")])
1623
1624 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1625 ;; pattern for this case.  This helps multimedia applications that compute
1626 ;; the sum of absolute differences.
1627 (define_insn "mov_neg_si_t"
1628   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1629   "TARGET_SH1"
1630   "subc %0,%0"
1631   [(set_attr "type" "arith")])
1632
1633 (define_insn "*subsi3_internal"
1634   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1635         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1636                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1637   "TARGET_SH1"
1638   "sub  %2,%0"
1639   [(set_attr "type" "arith")])
1640
1641 (define_insn_and_split "*subsi3_media"
1642   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1643         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1644                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1645   "TARGET_SHMEDIA
1646    && (operands[1] != constm1_rtx
1647        || (GET_CODE (operands[2]) != TRUNCATE
1648            && GET_CODE (operands[2]) != SUBREG))"
1649   "sub.l        %N1, %2, %0"
1650   "operands[1] == constm1_rtx"
1651   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1652   ""
1653   [(set_attr "type" "arith_media")
1654    (set_attr "highpart" "ignore")])
1655
1656 (define_split
1657   [(set (match_operand:SI 0 "arith_reg_dest" "")
1658         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1659                                                        "general_extend_operand"
1660                                                        "") 0)) 0)))]
1661   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1662   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1663    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1664   "")
1665
1666 (define_split
1667   [(set (match_operand:SI 0 "arith_reg_dest" "")
1668         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669                                                        "general_extend_operand"
1670                                                        "") 0)) 3)))]
1671   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1672   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1674   "")
1675 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1676 ;; will sometimes save one instruction.  Otherwise we might get
1677 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1678 ;; are the same.
1679
1680 (define_expand "subsi3"
1681   [(set (match_operand:SI 0 "arith_reg_operand" "")
1682         (minus:SI (match_operand:SI 1 "arith_operand" "")
1683                   (match_operand:SI 2 "arith_reg_operand" "")))]
1684   ""
1685   "
1686 {
1687   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1688     {
1689       emit_insn (gen_negsi2 (operands[0], operands[2]));
1690       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1691       DONE;
1692     }
1693   if (TARGET_SHMEDIA)
1694     {
1695       if (!can_create_pseudo_p ()
1696           && ! arith_reg_or_0_operand (operands[1], SImode))
1697         FAIL;
1698       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1699         operands[1] = force_reg (SImode, operands[1]);
1700     }
1701 }")
1702 \f
1703 ;; -------------------------------------------------------------------------
1704 ;; Division instructions
1705 ;; -------------------------------------------------------------------------
1706
1707 ;; We take advantage of the library routines which don't clobber as many
1708 ;; registers as a normal function call would.
1709
1710 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1711 ;; also has an effect on the register that holds the address of the sfunc.
1712 ;; To make this work, we have an extra dummy insn that shows the use
1713 ;; of this register for reorg.
1714
1715 (define_insn "use_sfunc_addr"
1716   [(set (reg:SI PR_REG)
1717         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1718   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1719   ""
1720   [(set_attr "length" "0")])
1721
1722 (define_insn "udivsi3_sh2a"
1723   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1724         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1725                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1726   "TARGET_SH2A"
1727   "divu %2,%1"
1728   [(set_attr "type" "arith")
1729    (set_attr "in_delay_slot" "no")])
1730
1731 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1732 ;; hard register 0.  If we used hard register 0, then the next instruction
1733 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1734 ;; gets allocated to a stack slot that needs its address reloaded, then
1735 ;; there is nothing to prevent reload from using r0 to reload the address.
1736 ;; This reload would clobber the value in r0 we are trying to store.
1737 ;; If we let reload allocate r0, then this problem can never happen.
1738
1739 (define_insn "udivsi3_i1"
1740   [(set (match_operand:SI 0 "register_operand" "=z")
1741         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1742    (clobber (reg:SI T_REG))
1743    (clobber (reg:SI PR_REG))
1744    (clobber (reg:SI R4_REG))
1745    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1746   "TARGET_SH1 && ! TARGET_SH4"
1747   "jsr  @%1%#"
1748   [(set_attr "type" "sfunc")
1749    (set_attr "needs_delay_slot" "yes")])
1750
1751 ; Since shmedia-nofpu code could be linked against shcompact code, and
1752 ; the udivsi3 libcall has the same name, we must consider all registers
1753 ; clobbered that are in the union of the registers clobbered by the
1754 ; shmedia and the shcompact implementation.  Note, if the shcompact
1755 ; implementation actually used shcompact code, we'd need to clobber
1756 ; also r23 and fr23.
1757 (define_insn "udivsi3_i1_media"
1758   [(set (match_operand:SI 0 "register_operand" "=z")
1759         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760    (clobber (reg:SI T_MEDIA_REG))
1761    (clobber (reg:SI PR_MEDIA_REG))
1762    (clobber (reg:SI R20_REG))
1763    (clobber (reg:SI R21_REG))
1764    (clobber (reg:SI R22_REG))
1765    (clobber (reg:DI TR0_REG))
1766    (clobber (reg:DI TR1_REG))
1767    (clobber (reg:DI TR2_REG))
1768    (use (match_operand 1 "target_reg_operand" "b"))]
1769   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1770   "blink        %1, r18"
1771   [(set_attr "type" "sfunc")
1772    (set_attr "needs_delay_slot" "yes")])
1773
1774 (define_expand "udivsi3_i4_media"
1775   [(set (match_dup 3)
1776         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1777    (set (match_dup 4)
1778         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779    (set (match_dup 5) (float:DF (match_dup 3)))
1780    (set (match_dup 6) (float:DF (match_dup 4)))
1781    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782    (set (match_dup 8) (fix:DI (match_dup 7)))
1783    (set (match_operand:SI 0 "register_operand" "")
1784         (truncate:SI (match_dup 8)))]
1785   "TARGET_SHMEDIA_FPU"
1786   "
1787 {
1788   operands[3] = gen_reg_rtx (DImode);
1789   operands[4] = gen_reg_rtx (DImode);
1790   operands[5] = gen_reg_rtx (DFmode);
1791   operands[6] = gen_reg_rtx (DFmode);
1792   operands[7] = gen_reg_rtx (DFmode);
1793   operands[8] = gen_reg_rtx (DImode);
1794 }")
1795
1796 (define_insn "udivsi3_i4"
1797   [(set (match_operand:SI 0 "register_operand" "=y")
1798         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799    (clobber (reg:SI T_REG))
1800    (clobber (reg:SI PR_REG))
1801    (clobber (reg:DF DR0_REG))
1802    (clobber (reg:DF DR2_REG))
1803    (clobber (reg:DF DR4_REG))
1804    (clobber (reg:SI R0_REG))
1805    (clobber (reg:SI R1_REG))
1806    (clobber (reg:SI R4_REG))
1807    (clobber (reg:SI R5_REG))
1808    (use (reg:PSI FPSCR_REG))
1809    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1811   "jsr  @%1%#"
1812   [(set_attr "type" "sfunc")
1813    (set_attr "fp_mode" "double")
1814    (set_attr "needs_delay_slot" "yes")])
1815
1816 (define_insn "udivsi3_i4_single"
1817   [(set (match_operand:SI 0 "register_operand" "=y")
1818         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819    (clobber (reg:SI T_REG))
1820    (clobber (reg:SI PR_REG))
1821    (clobber (reg:DF DR0_REG))
1822    (clobber (reg:DF DR2_REG))
1823    (clobber (reg:DF DR4_REG))
1824    (clobber (reg:SI R0_REG))
1825    (clobber (reg:SI R1_REG))
1826    (clobber (reg:SI R4_REG))
1827    (clobber (reg:SI R5_REG))
1828    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1830   "jsr  @%1%#"
1831   [(set_attr "type" "sfunc")
1832    (set_attr "needs_delay_slot" "yes")])
1833
1834 (define_insn "udivsi3_i4_int"
1835   [(set (match_operand:SI 0 "register_operand" "=z")
1836         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837    (clobber (reg:SI T_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI PR_REG))
1840    (clobber (reg:SI MACH_REG))
1841    (clobber (reg:SI MACL_REG))
1842    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843   "TARGET_SH1"
1844   "jsr  @%1%#"
1845   [(set_attr "type" "sfunc")
1846    (set_attr "needs_delay_slot" "yes")])
1847
1848
1849 (define_expand "udivsi3"
1850   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853    (parallel [(set (match_operand:SI 0 "register_operand" "")
1854                    (udiv:SI (reg:SI R4_REG)
1855                             (reg:SI R5_REG)))
1856               (clobber (reg:SI T_REG))
1857               (clobber (reg:SI PR_REG))
1858               (clobber (reg:SI R4_REG))
1859               (use (match_dup 3))])]
1860   ""
1861   "
1862 {
1863   rtx last;
1864
1865   operands[3] = gen_reg_rtx (Pmode);
1866   /* Emit the move of the address to a pseudo outside of the libcall.  */
1867   if (TARGET_DIVIDE_CALL_TABLE)
1868     {
1869       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870          that causes problems when the divide code is supposed to come from a
1871          separate library.  Division by zero is undefined, so dividing 1 can be
1872          implemented by comparing with the divisor.  */
1873       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1874         {
1875           emit_insn (gen_cmpsi (operands[1], operands[2]));
1876           emit_insn (gen_sgeu (operands[0]));
1877           DONE;
1878         }
1879       else if (operands[2] == const0_rtx)
1880         {
1881           emit_move_insn (operands[0], operands[2]);
1882           DONE;
1883         }
1884       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1886     }
1887   else if (TARGET_DIVIDE_CALL_FP)
1888     {
1889       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890       if (TARGET_FPU_SINGLE)
1891         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1892       else
1893         last = gen_udivsi3_i4 (operands[0], operands[3]);
1894     }
1895   else if (TARGET_SHMEDIA_FPU)
1896     {
1897       operands[1] = force_reg (SImode, operands[1]);
1898       operands[2] = force_reg (SImode, operands[2]);
1899       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1900       DONE;
1901     }
1902   else if (TARGET_SH2A)
1903     {
1904       operands[1] = force_reg (SImode, operands[1]);
1905       operands[2] = force_reg (SImode, operands[2]);
1906       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1907       DONE;
1908     }
1909   else if (TARGET_SH5)
1910     {
1911       function_symbol (operands[3],
1912                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1913                        SFUNC_STATIC);
1914
1915       if (TARGET_SHMEDIA)
1916         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917       else if (TARGET_FPU_ANY)
1918         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1919       else
1920         last = gen_udivsi3_i1 (operands[0], operands[3]);
1921     }
1922   else
1923     {
1924       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925       last = gen_udivsi3_i1 (operands[0], operands[3]);
1926     }
1927   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1929   emit_insn (last);
1930   DONE;
1931 }")
1932
1933 (define_insn "divsi3_sh2a"
1934   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1937   "TARGET_SH2A"
1938   "divs %2,%1"
1939   [(set_attr "type" "arith")
1940    (set_attr "in_delay_slot" "no")])
1941
1942 (define_insn "divsi3_i1"
1943   [(set (match_operand:SI 0 "register_operand" "=z")
1944         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945    (clobber (reg:SI T_REG))
1946    (clobber (reg:SI PR_REG))
1947    (clobber (reg:SI R1_REG))
1948    (clobber (reg:SI R2_REG))
1949    (clobber (reg:SI R3_REG))
1950    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951   "TARGET_SH1 && ! TARGET_SH4"
1952   "jsr  @%1%#"
1953   [(set_attr "type" "sfunc")
1954    (set_attr "needs_delay_slot" "yes")])
1955
1956 (define_insn "divsi3_i1_media"
1957   [(set (match_operand:SI 0 "register_operand" "=z")
1958         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959    (clobber (reg:SI T_MEDIA_REG))
1960    (clobber (reg:SI PR_MEDIA_REG))
1961    (clobber (reg:SI R1_REG))
1962    (clobber (reg:SI R20_REG))
1963    (clobber (reg:SI R21_REG))
1964    (clobber (reg:SI TR0_REG))
1965    (use (match_operand 1 "target_reg_operand" "b"))]
1966   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1967   "blink        %1, r18"
1968   [(set_attr "type" "sfunc")])
1969
1970 (define_insn "divsi3_media_2"
1971   [(set (match_operand:SI 0 "register_operand" "=z")
1972         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973    (clobber (reg:SI T_MEDIA_REG))
1974    (clobber (reg:SI PR_MEDIA_REG))
1975    (clobber (reg:SI R1_REG))
1976    (clobber (reg:SI R21_REG))
1977    (clobber (reg:SI TR0_REG))
1978    (use (reg:SI R20_REG))
1979    (use (match_operand 1 "target_reg_operand" "b"))]
1980   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1981   "blink        %1, r18"
1982   [(set_attr "type" "sfunc")])
1983
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988   [(set (match_operand:SI 0 "register_operand" "=r")
1989         (div:SI (match_operand:SI 1 "register_operand" "r")
1990                 (match_operand:SI 2 "register_operand" "r")))
1991    (clobber (reg:SI R4_REG))
1992    (clobber (reg:SI R5_REG))
1993    (clobber (reg:SI T_MEDIA_REG))
1994    (clobber (reg:SI PR_MEDIA_REG))
1995    (clobber (reg:SI R1_REG))
1996    (clobber (reg:SI R21_REG))
1997    (clobber (reg:SI TR0_REG))
1998    (clobber (reg:SI R20_REG))
1999    (use (match_operand:SI 3 "register_operand" "r"))]
2000   "TARGET_SHMEDIA"
2001   "#"
2002   "&& (high_life_started || reload_completed)"
2003   [(set (match_dup 0) (match_dup 3))]
2004   ""
2005   [(set_attr "highpart" "must_split")])
2006
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009   [(set (match_operand:SI 0 "register_operand" "=z")
2010         (div:SI (match_operand:SI 1 "register_operand" "r")
2011                 (match_operand:SI 2 "register_operand" "r")))
2012    (clobber (reg:SI R4_REG))
2013    (clobber (reg:SI R5_REG))
2014    (clobber (reg:SI T_MEDIA_REG))
2015    (clobber (reg:SI PR_MEDIA_REG))
2016    (clobber (reg:SI R1_REG))
2017    (clobber (reg:SI R21_REG))
2018    (clobber (reg:SI TR0_REG))
2019    (clobber (reg:SI R20_REG))
2020    (use (unspec:SI [(match_dup 1)
2021                     (match_operand:SI 3 "" "")
2022                     (unspec:SI [(match_operand:SI 4 "" "")
2023                                 (match_dup 3)
2024                                 (match_operand:DI 5 "" "")]
2025                      UNSPEC_DIV_INV_M2)
2026                     (match_operand:DI 6 "" "")
2027                     (const_int 0)
2028                     (const_int 0)]
2029          UNSPEC_DIV_INV_M3))]
2030   "TARGET_SHMEDIA"
2031   "#"
2032   "&& (high_life_started || reload_completed)"
2033   [(pc)]
2034   "
2035 {
2036   const char *name = sh_divsi3_libfunc;
2037   enum sh_function_kind kind = SFUNC_GOT;
2038   rtx sym;
2039
2040   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042   while (TARGET_DIVIDE_INV_CALL2)
2043     {
2044       rtx x = operands[3];
2045
2046       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2047         break;
2048       x = XVECEXP (x, 0, 0);
2049       name = \"__sdivsi3_2\";
2050       kind = SFUNC_STATIC;
2051       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2052       break;
2053     }
2054   sym = function_symbol (NULL, name, kind);
2055   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2056   DONE;
2057 }"
2058   [(set_attr "highpart" "must_split")])
2059
2060 (define_expand "divsi3_i4_media"
2061   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064    (set (match_operand:SI 0 "register_operand" "=r")
2065         (fix:SI (match_dup 5)))]
2066   "TARGET_SHMEDIA_FPU"
2067   "
2068 {
2069   operands[3] = gen_reg_rtx (DFmode);
2070   operands[4] = gen_reg_rtx (DFmode);
2071   operands[5] = gen_reg_rtx (DFmode);
2072 }")
2073
2074 (define_insn "divsi3_i4"
2075   [(set (match_operand:SI 0 "register_operand" "=y")
2076         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077    (clobber (reg:SI PR_REG))
2078    (clobber (reg:DF DR0_REG))
2079    (clobber (reg:DF DR2_REG))
2080    (use (reg:PSI FPSCR_REG))
2081    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2083   "jsr  @%1%#"
2084   [(set_attr "type" "sfunc")
2085    (set_attr "fp_mode" "double")
2086    (set_attr "needs_delay_slot" "yes")])
2087
2088 (define_insn "divsi3_i4_single"
2089   [(set (match_operand:SI 0 "register_operand" "=y")
2090         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091    (clobber (reg:SI PR_REG))
2092    (clobber (reg:DF DR0_REG))
2093    (clobber (reg:DF DR2_REG))
2094    (clobber (reg:SI R2_REG))
2095    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2097   "jsr  @%1%#"
2098   [(set_attr "type" "sfunc")
2099    (set_attr "needs_delay_slot" "yes")])
2100
2101 (define_insn "divsi3_i4_int"
2102   [(set (match_operand:SI 0 "register_operand" "=z")
2103         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104    (clobber (reg:SI T_REG))
2105    (clobber (reg:SI PR_REG))
2106    (clobber (reg:SI R1_REG))
2107    (clobber (reg:SI MACH_REG))
2108    (clobber (reg:SI MACL_REG))
2109    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110   "TARGET_SH1"
2111   "jsr  @%1%#"
2112   [(set_attr "type" "sfunc")
2113    (set_attr "needs_delay_slot" "yes")])
2114
2115 (define_expand "divsi3"
2116   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119    (parallel [(set (match_operand:SI 0 "register_operand" "")
2120                    (div:SI (reg:SI R4_REG)
2121                            (reg:SI R5_REG)))
2122               (clobber (reg:SI T_REG))
2123               (clobber (reg:SI PR_REG))
2124               (clobber (reg:SI R1_REG))
2125               (clobber (reg:SI R2_REG))
2126               (clobber (reg:SI R3_REG))
2127               (use (match_dup 3))])]
2128   ""
2129   "
2130 {
2131   rtx last;
2132
2133   operands[3] = gen_reg_rtx (Pmode);
2134   /* Emit the move of the address to a pseudo outside of the libcall.  */
2135   if (TARGET_DIVIDE_CALL_TABLE)
2136     {
2137       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138       last = gen_divsi3_i4_int (operands[0], operands[3]);
2139     }
2140   else if (TARGET_DIVIDE_CALL_FP)
2141     {
2142       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143       if (TARGET_FPU_SINGLE)
2144         last = gen_divsi3_i4_single (operands[0], operands[3]);
2145       else
2146         last = gen_divsi3_i4 (operands[0], operands[3]);
2147     }
2148   else if (TARGET_SH2A)
2149     {
2150       operands[1] = force_reg (SImode, operands[1]);
2151       operands[2] = force_reg (SImode, operands[2]);
2152       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2153       DONE;
2154     }
2155   else if (TARGET_DIVIDE_INV)
2156     {
2157       rtx dividend = operands[1];
2158       rtx divisor = operands[2];
2159       rtx tab_base;
2160       rtx nsb_res = gen_reg_rtx (DImode);
2161       rtx norm64 = gen_reg_rtx (DImode);
2162       rtx tab_ix = gen_reg_rtx (DImode);
2163       rtx norm32 = gen_reg_rtx (SImode);
2164       rtx i92 = force_reg (DImode, GEN_INT (92));
2165       rtx scratch0a = gen_reg_rtx (DImode);
2166       rtx scratch0b = gen_reg_rtx (DImode);
2167       rtx inv0 = gen_reg_rtx (SImode);
2168       rtx scratch1a = gen_reg_rtx (DImode);
2169       rtx scratch1b = gen_reg_rtx (DImode);
2170       rtx shift = gen_reg_rtx (DImode);
2171       rtx i2p27, i43;
2172       rtx inv1 = gen_reg_rtx (SImode);
2173       rtx scratch2a = gen_reg_rtx (DImode);
2174       rtx scratch2b = gen_reg_rtx (SImode);
2175       rtx inv2 = gen_reg_rtx (SImode);
2176       rtx scratch3a = gen_reg_rtx (DImode);
2177       rtx scratch3b = gen_reg_rtx (DImode);
2178       rtx scratch3c = gen_reg_rtx (DImode);
2179       rtx scratch3d = gen_reg_rtx (SImode);
2180       rtx scratch3e = gen_reg_rtx (DImode);
2181       rtx result = gen_reg_rtx (SImode);
2182
2183       if (! arith_reg_or_0_operand (dividend, SImode))
2184         dividend = force_reg (SImode, dividend);
2185       if (! arith_reg_operand (divisor, SImode))
2186         divisor = force_reg (SImode, divisor);
2187       if (flag_pic && Pmode != DImode)
2188         {
2189           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190           tab_base = gen_datalabel_ref (tab_base);
2191           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2192         }
2193       else
2194         {
2195           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196           tab_base = gen_datalabel_ref (tab_base);
2197           tab_base = force_reg (DImode, tab_base);
2198         }
2199       if (TARGET_DIVIDE_INV20U)
2200         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2201       else
2202         i2p27 = GEN_INT (0);
2203       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204         i43 = force_reg (DImode, GEN_INT (43));
2205       else
2206         i43 = GEN_INT (0);
2207       emit_insn (gen_nsbdi (nsb_res,
2208                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209       emit_insn (gen_ashldi3_media (norm64,
2210                                     gen_rtx_SUBREG (DImode, divisor, 0),
2211                                     nsb_res));
2212       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215                                    inv0, scratch0a, scratch0b,
2216                                    scratch1a, scratch1b));
2217       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2219                                    scratch2a));
2220       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2221                                    i2p27, i43,
2222                                    scratch3a, scratch3b, scratch3c,
2223                                    scratch2a, scratch2b, scratch3d, scratch3e));
2224       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226       else if (TARGET_DIVIDE_INV_FP)
2227         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230                                      gen_reg_rtx (DFmode)));
2231       else
2232         emit_move_insn (operands[0], result);
2233       DONE;
2234     }
2235   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2236     {
2237       operands[1] = force_reg (SImode, operands[1]);
2238       operands[2] = force_reg (SImode, operands[2]);
2239       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2240       DONE;
2241     }
2242   else if (TARGET_SH5)
2243     {
2244       if (TARGET_DIVIDE_CALL2)
2245         {
2246           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247           tab_base = gen_datalabel_ref (tab_base);
2248           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2249         }
2250       if (TARGET_FPU_ANY && TARGET_SH1)
2251         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252       else if (TARGET_DIVIDE_CALL2)
2253         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2254       else
2255         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2256
2257       if (TARGET_SHMEDIA)
2258         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259                 (operands[0], operands[3]));
2260       else if (TARGET_FPU_ANY)
2261         last = gen_divsi3_i4_single (operands[0], operands[3]);
2262       else
2263         last = gen_divsi3_i1 (operands[0], operands[3]);
2264     }
2265   else
2266     {
2267       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268       last = gen_divsi3_i1 (operands[0], operands[3]);
2269     }
2270   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2272   emit_insn (last);
2273   DONE;
2274 }")
2275
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload.  See PR27117.
2280
2281 (define_insn "divsi_inv_qitable"
2282   [(set (match_operand:DI 0 "register_operand" "=r")
2283         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284                                     (match_operand:DI 2 "register_operand" "r")]
2285                          UNSPEC_DIV_INV_TABLE)))]
2286   "TARGET_SHMEDIA"
2287   "@
2288         ldx.ub  %1, %2, %0"
2289   [(set_attr "type" "load_media")
2290    (set_attr "highpart" "user")])
2291
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294   [(set (match_operand:DI 0 "register_operand" "=r")
2295         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296                                     (match_operand:DI 2 "register_operand" "r")]
2297                          UNSPEC_DIV_INV_TABLE)))]
2298   "TARGET_SHMEDIA"
2299   "@
2300         ldx.w   %1, %2, %0"
2301   [(set_attr "type" "load_media")
2302    (set_attr "highpart" "user")])
2303
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307   [(set (match_operand:SI 0 "register_operand" "=r")
2308         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309                     (match_operand:DI 2 "register_operand" "r")
2310                     (match_operand:SI 3 "register_operand" "r")]
2311          UNSPEC_DIV_INV_M0))
2312    (clobber (match_operand:DI 4 "register_operand" "=r"))
2313    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2314   "TARGET_SHMEDIA"
2315   "
2316 {
2317 /*
2318 tab_base: r20
2319 tab_ix: r21
2320 norm32: r25
2321  ldx.ub r20, r21, r19 // u0.8
2322  shlli r21, 1, r21
2323  muls.l r25, r19, r19 // s2.38
2324  ldx.w r20, r21, r21  // s2.14
2325  shari r19, 24, r19   // truncate to s2.14
2326  sub r21, r19, r19    // some 11 bit inverse in s1.14
2327 */
2328
2329   rtx inv0 = operands[0];
2330   rtx tab_base = operands[1];
2331   rtx tab_ix = operands[2];
2332   rtx norm32 = operands[3];
2333   rtx scratch0 = operands[4];
2334   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335   rtx scratch1 = operands[5];
2336
2337   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2343   DONE;
2344 }")
2345
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348   [(set (match_operand:SI 0 "register_operand" "=r")
2349         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350                     (match_operand:DI 2 "register_operand" "r")
2351                     (match_operand:SI 3 "register_operand" "r")]
2352          UNSPEC_DIV_INV_M1))
2353    (clobber (match_operand:SI 4 "register_operand" "=r"))
2354    (clobber (match_operand:DI 5 "register_operand" "=r"))
2355    (clobber (match_operand:DI 6 "register_operand" "=r"))
2356    (clobber (match_operand:DI 7 "register_operand" "=r"))
2357    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2358   "TARGET_SHMEDIA"
2359   "#"
2360   "&& !can_create_pseudo_p ()"
2361   [(pc)]
2362   "
2363 {
2364 /* inv0: r19
2365  muls.l r19, r19, r18 // u0.28
2366  muls.l r25, r18, r18 // s2.58
2367  shlli r19, 45, r0    // multiply by two and convert to s2.58
2368  sub r0, r18, r18
2369  shari r18, 28, r18   // some 18 bit inverse in s1.30
2370 */
2371
2372   rtx inv1 = operands[0];
2373   rtx tab_base = operands[1];
2374   rtx tab_ix = operands[2];
2375   rtx norm32 = operands[3];
2376   rtx inv0 = operands[4];
2377   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378   rtx scratch0a = operands[5];
2379   rtx scratch0b = operands[6];
2380   rtx scratch0 = operands[7];
2381   rtx scratch1 = operands[8];
2382   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2383
2384   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385                                scratch0a, scratch0b));
2386   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2391   DONE;
2392 }")
2393
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396   [(set (match_operand:SI 0 "register_operand" "=r")
2397         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398                     (match_operand:SI 2 "register_operand" "r")
2399                     (match_operand:DI 3 "register_operand" "r")]
2400          UNSPEC_DIV_INV_M2))
2401    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2402   "TARGET_SHMEDIA"
2403   "#"
2404   "&& !can_create_pseudo_p ()"
2405   [(pc)]
2406   "
2407 {
2408 /*
2409  muls.l r18, r25, r0  // s2.60
2410  shari r0, 16, r0     // s-16.44
2411   sub
2412  muls.l r0, r18, r19  // s-16.74
2413  shari r19, 30, r19   // s-16.44
2414 */
2415   rtx inv2 = operands[0];
2416   rtx norm32 = operands[1];
2417   rtx inv1 = operands[2];
2418   rtx i92 = operands[3];
2419   rtx scratch0 = operands[4];
2420   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2421
2422   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2427   DONE;
2428 }")
2429
2430 (define_insn_and_split "divsi_inv_m3"
2431   [(set (match_operand:SI 0 "register_operand" "=r")
2432         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2438          UNSPEC_DIV_INV_M3))
2439    (clobber (match_operand:DI 7 "register_operand" "=r"))
2440    (clobber (match_operand:DI 8 "register_operand" "=r"))
2441    (clobber (match_operand:DI 9 "register_operand" "=r"))
2442    (clobber (match_operand:DI 10 "register_operand" "=r"))
2443    (clobber (match_operand:SI 11 "register_operand" "=r"))
2444    (clobber (match_operand:SI 12 "register_operand" "=r"))
2445    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2446   "TARGET_SHMEDIA"
2447   "#"
2448   "&& !can_create_pseudo_p ()"
2449   [(pc)]
2450   "
2451 {
2452 /*
2453   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2454   r0: scratch0  r19: scratch1 r21: scratch2
2455
2456   muls.l r18, r4, r25 // s32.30
2457  muls.l r19, r4, r19  // s15.30
2458  shari r25, 63, r21
2459   shari r19, 14, r19  // s18.-14
2460  sub r25, r19, r0
2461  shard r0, r1, r0
2462  sub r0, r21, r0
2463 */
2464
2465   rtx result = operands[0];
2466   rtx dividend = operands[1];
2467   rtx inv1 = operands[2];
2468   rtx inv2 = operands[3];
2469   rtx shift = operands[4];
2470   rtx scratch0 = operands[7];
2471   rtx scratch1 = operands[8];
2472   rtx scratch2 = operands[9];
2473
2474   if (satisfies_constraint_N (dividend))
2475     {
2476       emit_move_insn (result, dividend);
2477       DONE;
2478     }
2479
2480   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2481   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2482   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2483   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2484   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2485   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2486   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2487   DONE;
2488 }")
2489
2490 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2491 ;; inv1: tab_base, tab_ix, norm32
2492 ;; inv2: norm32, inv1, i92
2493 (define_insn_and_split "divsi_inv_m1_3"
2494   [(set (match_operand:SI 0 "register_operand" "=r")
2495         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2496                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2497                                 (match_operand:DI 3 "register_operand" "r")
2498                                 (match_operand:SI 4 "register_operand" "r")]
2499                      UNSPEC_DIV_INV_M1)
2500                     (unspec:SI [(match_dup 4)
2501                                 (unspec:SI [(match_dup 2)
2502                                             (match_dup 3)
2503                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2504                                 (match_operand:SI 5 "" "")]
2505                      UNSPEC_DIV_INV_M2)
2506                     (match_operand:DI 6 "register_operand" "r")
2507                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2508                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2509          UNSPEC_DIV_INV_M3))
2510    (clobber (match_operand:DI 9 "register_operand" "=r"))
2511    (clobber (match_operand:DI 10 "register_operand" "=r"))
2512    (clobber (match_operand:DI 11 "register_operand" "=r"))
2513    (clobber (match_operand:DI 12 "register_operand" "=r"))
2514    (clobber (match_operand:SI 13 "register_operand" "=r"))
2515    (clobber (match_operand:SI 14 "register_operand" "=r"))
2516    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2517   "TARGET_SHMEDIA
2518    && (TARGET_DIVIDE_INV_MINLAT
2519        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2520   "#"
2521   "&& !can_create_pseudo_p ()"
2522   [(pc)]
2523   "
2524 {
2525   rtx result = operands[0];
2526   rtx dividend = operands[1];
2527   rtx tab_base = operands[2];
2528   rtx tab_ix = operands[3];
2529   rtx norm32 = operands[4];
2530   /* rtx i92 = operands[5]; */
2531   rtx shift = operands[6];
2532   rtx i2p27 = operands[7];
2533   rtx i43 = operands[8];
2534   rtx scratch0 = operands[9];
2535   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2536   rtx scratch1 = operands[10];
2537   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2538   rtx scratch2 = operands[11];
2539   rtx scratch3 = operands[12];
2540   rtx scratch4 = operands[13];
2541   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2542   rtx scratch5 = operands[14];
2543   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2544   rtx scratch6 = operands[15];
2545
2546   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2547                                scratch0, scratch1));
2548   /* inv0 == scratch4 */
2549   if (! TARGET_DIVIDE_INV20U)
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2552       i2p27 = scratch0;
2553       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2554     }
2555   else
2556     {
2557       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2558       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2559     }
2560   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2561   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2562   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2563   /* inv1 == scratch4 */
2564
2565   if (TARGET_DIVIDE_INV_MINLAT)
2566     {
2567       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2568       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2569       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2570       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2571       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2572       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2573       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2574       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2575       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2576       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2577       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2578     }
2579   else
2580     {
2581       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2582       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2583       emit_insn (gen_nsbdi (scratch6,
2584                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2585       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2586       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2587       emit_insn (gen_divsi_inv20 (scratch2,
2588                                   norm32, scratch4, dividend,
2589                                   scratch6, scratch3, i43,
2590                                   /* scratch0 may be shared with i2p27.  */
2591                                   scratch0, scratch1, scratch5,
2592                                   label, label, i2p27));
2593     }
2594   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2595   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2596   DONE;
2597 }")
2598
2599 (define_insn "divsi_inv20"
2600   [(set (match_operand:DI 0 "register_operand" "=&r")
2601         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2602                     (match_operand:SI 2 "register_operand" "r")
2603                     (match_operand:SI 3 "register_operand" "r")
2604                     (match_operand:DI 4 "register_operand" "r")
2605                     (match_operand:DI 5 "register_operand" "r")
2606                     (match_operand:DI 6 "register_operand" "r")
2607                     (match_operand:DI 12 "register_operand" "r")
2608                     (match_operand 10 "target_operand" "b")
2609                     (match_operand 11 "immediate_operand" "i")]
2610          UNSPEC_DIV_INV20))
2611    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2612    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2613    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2614   "TARGET_SHMEDIA
2615    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2616   "*
2617 {
2618 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2619              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2620              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2621              %10 label (tr), %11 label (imm)
2622
2623  muls.l inv1, norm32, scratch0  // s2.60
2624   muls.l inv1, dividend, result // s32.30
2625   xor i2p27, result_sign, round_scratch
2626  bge/u dividend_nsb, i43, tr.. (label)
2627  shari scratch0, 16, scratch0   // s-16.44
2628  muls.l sratch0_si, inv1, scratch0 // s-16.74
2629   sub result, round_scratch, result
2630   shari dividend, 14, scratch1   // s19.-14
2631  shari scratch0, 30, scratch0   // s-16.44
2632  muls.l scratch0, scratch1, round_scratch // s15.30
2633 label:
2634  sub result, round_scratch, result */
2635
2636   int likely = TARGET_DIVIDE_INV20L;
2637
2638   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2639   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2640   output_asm_insn (likely
2641                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2642                    : \"bge/u\t%4, %6, %10\", operands);
2643   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2644   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2645   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2646   return (likely
2647           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2648           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2649 }")
2650
2651 (define_insn_and_split "divsi_inv_fp"
2652   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2653         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2654                 (match_operand:SI 2 "register_operand" "rf")))
2655    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2656    (clobber (match_operand:SI 4 "register_operand" "=r"))
2657    (clobber (match_operand:SI 5 "register_operand" "=r"))
2658    (clobber (match_operand:DF 6 "register_operand" "=r"))
2659    (clobber (match_operand:DF 7 "register_operand" "=r"))
2660    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2661   "TARGET_SHMEDIA_FPU"
2662   "#"
2663   "&& (high_life_started || reload_completed)"
2664   [(set (match_dup 0) (match_dup 3))]
2665   ""
2666   [(set_attr "highpart" "must_split")])
2667
2668 ;; If a matching group of divide-by-inverse instructions is in the same
2669 ;; basic block after gcse & loop optimizations, we want to transform them
2670 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2671 (define_insn_and_split "*divsi_inv_fp_combine"
2672   [(set (match_operand:SI 0 "register_operand" "=f")
2673         (div:SI (match_operand:SI 1 "register_operand" "f")
2674                 (match_operand:SI 2 "register_operand" "f")))
2675    (use (unspec:SI [(match_dup 1)
2676                     (match_operand:SI 3 "" "")
2677                     (unspec:SI [(match_operand:SI 4 "" "")
2678                                 (match_dup 3)
2679                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2680                     (match_operand:DI 6 "" "")
2681                     (const_int 0)
2682                     (const_int 0)] UNSPEC_DIV_INV_M3))
2683    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2684    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2685    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2686    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2687    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2688   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2689   "#"
2690   "&& 1"
2691   [(set (match_dup 9) (float:DF (match_dup 1)))
2692    (set (match_dup 10) (float:DF (match_dup 2)))
2693    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2694    (set (match_dup 8)
2695         (fix:SI (match_dup 11)))
2696    (set (match_dup 0) (match_dup 8))]
2697   "
2698 {
2699   if (! fp_arith_reg_operand (operands[1], SImode))
2700     {
2701       emit_move_insn (operands[7], operands[1]);
2702       operands[1] = operands[7];
2703     }
2704   if (! fp_arith_reg_operand (operands[2], SImode))
2705     {
2706       emit_move_insn (operands[8], operands[2]);
2707       operands[2] = operands[8];
2708     }
2709 }"
2710   [(set_attr "highpart" "must_split")])
2711 \f
2712 ;; -------------------------------------------------------------------------
2713 ;; Multiplication instructions
2714 ;; -------------------------------------------------------------------------
2715
2716 (define_insn "umulhisi3_i"
2717   [(set (reg:SI MACL_REG)
2718         (mult:SI (zero_extend:SI
2719                   (match_operand:HI 0 "arith_reg_operand" "r"))
2720                  (zero_extend:SI
2721                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2722   "TARGET_SH1"
2723   "mulu.w       %1,%0"
2724   [(set_attr "type" "smpy")])
2725
2726 (define_insn "mulhisi3_i"
2727   [(set (reg:SI MACL_REG)
2728         (mult:SI (sign_extend:SI
2729                   (match_operand:HI 0 "arith_reg_operand" "r"))
2730                  (sign_extend:SI
2731                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2732   "TARGET_SH1"
2733   "muls.w       %1,%0"
2734   [(set_attr "type" "smpy")])
2735
2736 (define_expand "mulhisi3"
2737   [(set (reg:SI MACL_REG)
2738         (mult:SI (sign_extend:SI
2739                   (match_operand:HI 1 "arith_reg_operand" ""))
2740                  (sign_extend:SI
2741                   (match_operand:HI 2 "arith_reg_operand" ""))))
2742    (set (match_operand:SI 0 "arith_reg_operand" "")
2743         (reg:SI MACL_REG))]
2744   "TARGET_SH1"
2745   "
2746 {
2747   rtx insn, macl;
2748
2749   macl = gen_rtx_REG (SImode, MACL_REG);
2750   start_sequence ();
2751   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2752   insn = get_insns ();  
2753   end_sequence ();
2754   /* expand_binop can't find a suitable code in umul_widen_optab to
2755      make a REG_EQUAL note from, so make one here.
2756      See also smulsi3_highpart.
2757      ??? Alternatively, we could put this at the calling site of expand_binop,
2758      i.e. expand_expr.  */
2759   /* Use emit_libcall_block for loop invariant code motion and to make
2760      a REG_EQUAL note.  */
2761   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2762
2763   DONE;
2764 }")
2765
2766 (define_expand "umulhisi3"
2767   [(set (reg:SI MACL_REG)
2768         (mult:SI (zero_extend:SI
2769                   (match_operand:HI 1 "arith_reg_operand" ""))
2770                  (zero_extend:SI
2771                   (match_operand:HI 2 "arith_reg_operand" ""))))
2772    (set (match_operand:SI 0 "arith_reg_operand" "")
2773         (reg:SI MACL_REG))]
2774   "TARGET_SH1"
2775   "
2776 {
2777   rtx insn, macl;
2778
2779   macl = gen_rtx_REG (SImode, MACL_REG);
2780   start_sequence ();
2781   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2782   insn = get_insns ();  
2783   end_sequence ();
2784   /* expand_binop can't find a suitable code in umul_widen_optab to
2785      make a REG_EQUAL note from, so make one here.
2786      See also smulsi3_highpart.
2787      ??? Alternatively, we could put this at the calling site of expand_binop,
2788      i.e. expand_expr.  */
2789   /* Use emit_libcall_block for loop invariant code motion and to make
2790      a REG_EQUAL note.  */
2791   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2792
2793   DONE;
2794 }")
2795
2796 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2797 ;; a call to a routine which clobbers known registers.
2798
2799 (define_insn ""
2800   [(set (match_operand:SI 1 "register_operand" "=z")
2801         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2802    (clobber (reg:SI MACL_REG))
2803    (clobber (reg:SI T_REG))
2804    (clobber (reg:SI PR_REG))
2805    (clobber (reg:SI R3_REG))
2806    (clobber (reg:SI R2_REG))
2807    (clobber (reg:SI R1_REG))
2808    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2809   "TARGET_SH1"
2810   "jsr  @%0%#"
2811   [(set_attr "type" "sfunc")
2812    (set_attr "needs_delay_slot" "yes")])
2813
2814 (define_expand "mulsi3_call"
2815   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2816    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2817    (parallel[(set (match_operand:SI 0 "register_operand" "")
2818                   (mult:SI (reg:SI R4_REG)
2819                            (reg:SI R5_REG)))
2820              (clobber (reg:SI MACL_REG))
2821              (clobber (reg:SI T_REG))
2822              (clobber (reg:SI PR_REG))
2823              (clobber (reg:SI R3_REG))
2824              (clobber (reg:SI R2_REG))
2825              (clobber (reg:SI R1_REG))
2826              (use (match_operand:SI 3 "register_operand" ""))])]
2827   "TARGET_SH1"
2828   "")
2829
2830 (define_insn "mul_r"
2831   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2832         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2833                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2834   "TARGET_SH2A"
2835   "mulr %2,%0"
2836   [(set_attr "type" "dmpy")])
2837
2838 (define_insn "mul_l"
2839   [(set (reg:SI MACL_REG)
2840         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2841                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2842   "TARGET_SH2"
2843   "mul.l        %1,%0"
2844   [(set_attr "type" "dmpy")])
2845
2846 (define_expand "mulsi3"
2847   [(set (reg:SI MACL_REG)
2848         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2849                   (match_operand:SI 2 "arith_reg_operand" "")))
2850    (set (match_operand:SI 0 "arith_reg_operand" "")
2851         (reg:SI MACL_REG))]
2852   "TARGET_SH1"
2853   "
2854 {
2855   if (!TARGET_SH2)
2856     {
2857       /* The address must be set outside the libcall,
2858          since it goes into a pseudo.  */
2859       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2860       rtx addr = force_reg (SImode, sym);
2861       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2862                                    operands[2], addr);
2863       emit_insn (insns);
2864     }
2865   else
2866     {
2867       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2868
2869       emit_insn (gen_mul_l (operands[1], operands[2]));
2870       /* consec_sets_giv can only recognize the first insn that sets a
2871          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2872          note.  */
2873       emit_insn (gen_movsi_i ((operands[0]), macl));
2874     }
2875   DONE;
2876 }")
2877
2878 (define_insn "mulsidi3_i"
2879   [(set (reg:SI MACH_REG)
2880         (truncate:SI
2881          (lshiftrt:DI
2882           (mult:DI
2883            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2884            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2885           (const_int 32))))
2886    (set (reg:SI MACL_REG)
2887         (mult:SI (match_dup 0)
2888                  (match_dup 1)))]
2889   "TARGET_SH2"
2890   "dmuls.l      %1,%0"
2891   [(set_attr "type" "dmpy")])
2892
2893 (define_expand "mulsidi3"
2894   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2895         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2896                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2897   "TARGET_SH2 || TARGET_SHMEDIA"
2898   "
2899 {
2900   if (TARGET_SH2)
2901     {
2902        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2903                                         operands[2]));
2904        DONE;
2905     }
2906 }")
2907
2908 (define_insn "mulsidi3_media"
2909   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2910         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2911                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2912   "TARGET_SHMEDIA"
2913   "muls.l       %1, %2, %0"
2914   [(set_attr "type" "dmpy_media")
2915    (set_attr "highpart" "ignore")])
2916
2917 (define_insn "mulsidi3_compact"
2918   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2919         (mult:DI
2920          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2921          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2922    (clobber (reg:SI MACH_REG))
2923    (clobber (reg:SI MACL_REG))]
2924   "TARGET_SH2"
2925   "#")
2926
2927 (define_split
2928   [(set (match_operand:DI 0 "arith_reg_dest" "")
2929         (mult:DI
2930          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2931          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2932    (clobber (reg:SI MACH_REG))
2933    (clobber (reg:SI MACL_REG))]
2934   "TARGET_SH2"
2935   [(const_int 0)]
2936   "
2937 {
2938   rtx low_dst = gen_lowpart (SImode, operands[0]);
2939   rtx high_dst = gen_highpart (SImode, operands[0]);
2940
2941   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2942
2943   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2944   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2945   /* We need something to tag the possible REG_EQUAL notes on to.  */
2946   emit_move_insn (operands[0], operands[0]);
2947   DONE;
2948 }")
2949
2950 (define_insn "umulsidi3_i"
2951   [(set (reg:SI MACH_REG)
2952         (truncate:SI
2953          (lshiftrt:DI
2954           (mult:DI
2955            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2956            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2957           (const_int 32))))
2958    (set (reg:SI MACL_REG)
2959         (mult:SI (match_dup 0)
2960                  (match_dup 1)))]
2961   "TARGET_SH2"
2962   "dmulu.l      %1,%0"
2963   [(set_attr "type" "dmpy")])
2964
2965 (define_expand "umulsidi3"
2966   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2967         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2968                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2969   "TARGET_SH2 || TARGET_SHMEDIA"
2970   "
2971 {
2972   if (TARGET_SH2)
2973     {
2974        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2975                                          operands[2]));
2976        DONE;
2977     }
2978 }")
2979
2980 (define_insn "umulsidi3_media"
2981   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2982         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2983                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2984   "TARGET_SHMEDIA"
2985   "mulu.l       %1, %2, %0"
2986   [(set_attr "type" "dmpy_media")
2987    (set_attr "highpart" "ignore")])
2988
2989 (define_insn "umulsidi3_compact"
2990   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2991         (mult:DI
2992          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2993          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2994    (clobber (reg:SI MACH_REG))
2995    (clobber (reg:SI MACL_REG))]
2996   "TARGET_SH2"
2997   "#")
2998
2999 (define_split
3000   [(set (match_operand:DI 0 "arith_reg_dest" "")
3001         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3002                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3003    (clobber (reg:SI MACH_REG))
3004    (clobber (reg:SI MACL_REG))]
3005   "TARGET_SH2"
3006   [(const_int 0)]
3007   "
3008 {
3009   rtx low_dst = gen_lowpart (SImode, operands[0]);
3010   rtx high_dst = gen_highpart (SImode, operands[0]);
3011
3012   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3013
3014   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3015   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3016   /* We need something to tag the possible REG_EQUAL notes on to.  */
3017   emit_move_insn (operands[0], operands[0]);
3018   DONE;
3019 }")
3020
3021 (define_insn "smulsi3_highpart_i"
3022   [(set (reg:SI MACH_REG)
3023         (truncate:SI
3024          (lshiftrt:DI
3025           (mult:DI
3026            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3027            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3028           (const_int 32))))
3029    (clobber (reg:SI MACL_REG))]
3030   "TARGET_SH2"
3031   "dmuls.l      %1,%0"
3032   [(set_attr "type" "dmpy")])
3033
3034 (define_expand "smulsi3_highpart"
3035   [(parallel
3036     [(set (reg:SI MACH_REG)
3037           (truncate:SI
3038            (lshiftrt:DI
3039             (mult:DI
3040              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3041              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3042             (const_int 32))))
3043     (clobber (reg:SI MACL_REG))])
3044    (set (match_operand:SI 0 "arith_reg_operand" "")
3045         (reg:SI MACH_REG))]
3046   "TARGET_SH2"
3047   "
3048 {
3049   rtx insn, mach;
3050
3051   mach = gen_rtx_REG (SImode, MACH_REG);
3052   start_sequence ();
3053   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3054   insn = get_insns ();  
3055   end_sequence ();
3056   /* expand_binop can't find a suitable code in mul_highpart_optab to
3057      make a REG_EQUAL note from, so make one here.
3058      See also {,u}mulhisi.
3059      ??? Alternatively, we could put this at the calling site of expand_binop,
3060      i.e. expand_mult_highpart.  */
3061   /* Use emit_libcall_block for loop invariant code motion and to make
3062      a REG_EQUAL note.  */
3063   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3064
3065   DONE;
3066 }")
3067
3068 (define_insn "umulsi3_highpart_i"
3069   [(set (reg:SI MACH_REG)
3070         (truncate:SI
3071          (lshiftrt:DI
3072           (mult:DI
3073            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3074            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3075           (const_int 32))))
3076    (clobber (reg:SI MACL_REG))]
3077   "TARGET_SH2"
3078   "dmulu.l      %1,%0"
3079   [(set_attr "type" "dmpy")])
3080
3081 (define_expand "umulsi3_highpart"
3082   [(parallel
3083     [(set (reg:SI MACH_REG)
3084           (truncate:SI
3085            (lshiftrt:DI
3086             (mult:DI
3087              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3088              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3089             (const_int 32))))
3090     (clobber (reg:SI MACL_REG))])
3091    (set (match_operand:SI 0 "arith_reg_operand" "")
3092         (reg:SI MACH_REG))]
3093   "TARGET_SH2"
3094   "
3095 {
3096   rtx insn, mach;
3097
3098   mach = gen_rtx_REG (SImode, MACH_REG);
3099   start_sequence ();
3100   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3101   insn = get_insns ();  
3102   end_sequence ();
3103   /* Use emit_libcall_block for loop invariant code motion and to make
3104      a REG_EQUAL note.  */
3105   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3106
3107   DONE;
3108 }")
3109
3110 (define_insn_and_split "muldi3"
3111   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3112         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3113                  (match_operand:DI 2 "arith_reg_operand" "r")))
3114    (clobber (match_scratch:DI 3 "=&r"))
3115    (clobber (match_scratch:DI 4 "=r"))]
3116   "TARGET_SHMEDIA"
3117   "#"
3118   "reload_completed"
3119   [(const_int 0)]
3120   "
3121 {
3122   rtx op3_v2si, op2_v2si;
3123
3124   op3_v2si = operands[3];
3125   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3126     {
3127       op3_v2si = XEXP (op3_v2si, 0);
3128       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3129     }
3130   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3131   op2_v2si = operands[2];
3132   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3133     {
3134       op2_v2si = XEXP (op2_v2si, 0);
3135       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3136     }
3137   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3138   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3139   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3140   emit_insn (gen_umulsidi3_media (operands[4],
3141                                  sh_gen_truncate (SImode, operands[1], 0),
3142                                  sh_gen_truncate (SImode, operands[2], 0)));
3143   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3144   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3145   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3146   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3147   DONE;
3148 }")
3149
3150 \f
3151 ;; -------------------------------------------------------------------------
3152 ;; Logical operations
3153 ;; -------------------------------------------------------------------------
3154
3155 (define_insn "*andsi3_compact"
3156   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3157         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3158                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3159   "TARGET_SH1"
3160   "and  %2,%0"
3161   [(set_attr "type" "arith")])
3162
3163 (define_insn "*andsi3_media"
3164   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3165         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3166                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3167   "TARGET_SHMEDIA"
3168   "@
3169         and     %1, %2, %0
3170         andi    %1, %2, %0"
3171   [(set_attr "type" "arith_media")])
3172
3173 ;; If the constant is 255, then emit an extu.b instruction instead of an
3174 ;; and, since that will give better code.
3175
3176 (define_expand "andsi3"
3177   [(set (match_operand:SI 0 "arith_reg_operand" "")
3178         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3179                 (match_operand:SI 2 "logical_operand" "")))]
3180   ""
3181   "
3182 {
3183   if (TARGET_SH1
3184       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3185     {
3186       emit_insn (gen_zero_extendqisi2 (operands[0],
3187                                        gen_lowpart (QImode, operands[1])));
3188       DONE;
3189     }
3190 }")
3191
3192 (define_insn_and_split "anddi3"
3193   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3194         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3195                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3196   "TARGET_SHMEDIA"
3197   "@
3198         and     %1, %2, %0
3199         andi    %1, %2, %0
3200         #"
3201   "reload_completed
3202    && ! logical_operand (operands[2], DImode)"
3203   [(const_int 0)]
3204   "
3205 {
3206   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3207     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3208   else
3209     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3210   DONE;
3211 }"
3212   [(set_attr "type" "arith_media")])
3213
3214 (define_insn "andcsi3"
3215   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3216         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3217                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3218   "TARGET_SHMEDIA"
3219   "andc %1,%2,%0"
3220   [(set_attr "type" "arith_media")])
3221
3222 (define_insn "andcdi3"
3223   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3224         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3225                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3226   "TARGET_SHMEDIA"
3227   "andc %1,%2,%0"
3228   [(set_attr "type" "arith_media")])
3229
3230 (define_expand "iorsi3"
3231   [(set (match_operand:SI 0 "arith_reg_operand" "")
3232         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3233                 (match_operand:SI 2 "logical_operand" "")))]
3234   ""
3235   "")
3236
3237 (define_insn "*iorsi3_compact"
3238   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3239         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3240                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3241   "TARGET_SH1"
3242   "or   %2,%0"
3243   [(set_attr "type" "arith")])
3244
3245 (define_insn "*iorsi3_media"
3246   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3247         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3248                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3249   "TARGET_SHMEDIA"
3250   "@
3251         or      %1, %2, %0
3252         ori     %1, %2, %0"
3253   [(set_attr "type" "arith_media")])
3254
3255 (define_insn "iordi3"
3256   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3257         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3258                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3259   "TARGET_SHMEDIA"
3260   "@
3261         or      %1, %2, %0
3262         ori     %1, %2, %0"
3263   [(set_attr "type" "arith_media")])
3264
3265 (define_insn_and_split "*logical_sidi3"
3266   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3267         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3268                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3269                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3270   "TARGET_SHMEDIA"
3271   "#"
3272   "&& reload_completed"
3273   [(set (match_dup 0) (match_dup 3))]
3274   "
3275 {
3276   operands[3]
3277     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3278                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3279                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3280 }")
3281
3282 (define_insn_and_split "*logical_sidisi3"
3283   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3284         (truncate:SI (sign_extend:DI
3285                         (match_operator:SI 3 "logical_operator"
3286                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3287                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3288   "TARGET_SHMEDIA"
3289   "#"
3290   "&& 1"
3291   [(set (match_dup 0) (match_dup 3))])
3292
3293 (define_insn_and_split "*logical_sidi3_2"
3294   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295         (sign_extend:DI (truncate:SI (sign_extend:DI
3296                         (match_operator:SI 3 "logical_operator"
3297                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3298                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3299   "TARGET_SHMEDIA"
3300   "#"
3301   "&& 1"
3302   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3303
3304 (define_expand "xorsi3"
3305   [(set (match_operand:SI 0 "arith_reg_operand" "")
3306         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3307                 (match_operand:SI 2 "xor_operand" "")))]
3308   ""
3309   "")
3310
3311 (define_insn "*xorsi3_compact"
3312   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3313         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3314                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3315   "TARGET_SH1"
3316   "xor  %2,%0"
3317   [(set_attr "type" "arith")])
3318
3319 (define_insn "*xorsi3_media"
3320   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3321         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3322                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3323   "TARGET_SHMEDIA"
3324   "@
3325         xor     %1, %2, %0
3326         xori    %1, %2, %0"
3327   [(set_attr "type" "arith_media")])
3328
3329 (define_insn "xordi3"
3330   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3331         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3332                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3333   "TARGET_SHMEDIA"
3334   "@
3335         xor     %1, %2, %0
3336         xori    %1, %2, %0"
3337   [(set_attr "type" "arith_media")])
3338
3339 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3340 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3341 (define_split
3342   [(set (match_operand:DI 0 "arith_reg_dest" "")
3343         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3344                           [(match_operand 1 "any_register_operand" "")
3345                            (match_operand 2 "any_register_operand" "")])))]
3346   "TARGET_SHMEDIA"
3347   [(set (match_dup 5) (match_dup 4))
3348    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3349 "
3350 {
3351   enum machine_mode inmode = GET_MODE (operands[1]);
3352   int offset = 0;
3353
3354   if (GET_CODE (operands[0]) == SUBREG)
3355     {
3356       offset = SUBREG_BYTE (operands[0]);
3357       operands[0] = SUBREG_REG (operands[0]);
3358     }
3359   gcc_assert (GET_CODE (operands[0]) == REG);
3360   if (! TARGET_LITTLE_ENDIAN)
3361     offset += 8 - GET_MODE_SIZE (inmode);
3362   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3363 }")
3364 \f
3365 ;; -------------------------------------------------------------------------
3366 ;; Shifts and rotates
3367 ;; -------------------------------------------------------------------------
3368
3369 (define_expand "rotldi3"
3370   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3371         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3372                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3373   "TARGET_SHMEDIA"
3374   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3375
3376 (define_insn "rotldi3_mextr"
3377   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3378         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3379                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3380   "TARGET_SHMEDIA"
3381   "*
3382 {
3383   static char templ[16];
3384
3385   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3386            8 - (int) (INTVAL (operands[2]) >> 3));
3387   return templ;
3388 }"
3389   [(set_attr "type" "arith_media")])
3390
3391 (define_expand "rotrdi3"
3392   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3393         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3394                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3395   "TARGET_SHMEDIA"
3396   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3397
3398 (define_insn "rotrdi3_mextr"
3399   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3400         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3401                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3402   "TARGET_SHMEDIA"
3403   "*
3404 {
3405   static char templ[16];
3406
3407   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3408   return templ;
3409 }"
3410   [(set_attr "type" "arith_media")])
3411
3412 (define_split
3413   [(set (match_operand:DI 0 "arith_reg_dest" "")
3414         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3415                                          "ua_address_operand" "")))
3416                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3417                            (const_int 8))))
3418    (clobber (match_operand:DI 3 "register_operand" ""))]
3419   "TARGET_SHMEDIA"
3420   [(match_dup 4) (match_dup 5)]
3421   "
3422 {
3423   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3424                  (operands[3], operands[1]));
3425   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3426                               GEN_INT (56), GEN_INT (8));
3427 }")
3428
3429 (define_insn "rotlsi3_1"
3430   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3431         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3432                    (const_int 1)))
3433    (set (reg:SI T_REG)
3434         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3435   "TARGET_SH1"
3436   "rotl %0"
3437   [(set_attr "type" "arith")])
3438
3439 (define_insn "rotlsi3_31"
3440   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3441         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3442                    (const_int 31)))
3443    (clobber (reg:SI T_REG))]
3444   "TARGET_SH1"
3445   "rotr %0"
3446   [(set_attr "type" "arith")])
3447
3448 (define_insn "rotlsi3_16"
3449   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3450         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3451                    (const_int 16)))]
3452   "TARGET_SH1"
3453   "swap.w       %1,%0"
3454   [(set_attr "type" "arith")])
3455
3456 (define_expand "rotlsi3"
3457   [(set (match_operand:SI 0 "arith_reg_dest" "")
3458         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3459                    (match_operand:SI 2 "immediate_operand" "")))]
3460   "TARGET_SH1"
3461   "
3462 {
3463   static const char rot_tab[] = {
3464     000, 000, 000, 000, 000, 000, 010, 001,
3465     001, 001, 011, 013, 003, 003, 003, 003,
3466     003, 003, 003, 003, 003, 013, 012, 002,
3467     002, 002, 010, 000, 000, 000, 000, 000,
3468   };
3469
3470   int count, choice;
3471
3472   if (GET_CODE (operands[2]) != CONST_INT)
3473     FAIL;
3474   count = INTVAL (operands[2]);
3475   choice = rot_tab[count];
3476   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3477     FAIL;
3478   choice &= 7;
3479   switch (choice)
3480     {
3481     case 0:
3482       emit_move_insn (operands[0], operands[1]);
3483       count -= (count & 16) * 2;
3484       break;
3485     case 3:
3486      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3487      count -= 16;
3488      break;
3489     case 1:
3490     case 2:
3491       {
3492         rtx parts[2];
3493         parts[0] = gen_reg_rtx (SImode);
3494         parts[1] = gen_reg_rtx (SImode);
3495         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3496         emit_move_insn (parts[choice-1], operands[1]);
3497         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3498         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3499         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3500         count = (count & ~16) - 8;
3501       }
3502     }
3503
3504   for (; count > 0; count--)
3505     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3506   for (; count < 0; count++)
3507     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3508
3509   DONE;
3510 }")
3511
3512 (define_insn "*rotlhi3_8"
3513   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3514         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3515                    (const_int 8)))]
3516   "TARGET_SH1"
3517   "swap.b       %1,%0"
3518   [(set_attr "type" "arith")])
3519
3520 (define_expand "rotlhi3"
3521   [(set (match_operand:HI 0 "arith_reg_operand" "")
3522         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3523                    (match_operand:HI 2 "immediate_operand" "")))]
3524   "TARGET_SH1"
3525   "
3526 {
3527   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3528     FAIL;
3529 }")
3530
3531 ;;
3532 ;; shift left
3533
3534 (define_insn "ashlsi3_sh2a"
3535   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3536         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3537                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3538   "TARGET_SH2A"
3539   "shad %2,%0"
3540   [(set_attr "type" "arith")
3541    (set_attr "length" "4")])
3542
3543 ;; This pattern is used by init_expmed for computing the costs of shift
3544 ;; insns.
3545
3546 (define_insn_and_split "ashlsi3_std"
3547   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3548         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3549                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3550    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3551   "TARGET_SH3
3552    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3553   "@
3554    shld %2,%0
3555    add  %0,%0
3556    shll%O2      %0
3557    #"
3558   "TARGET_SH3
3559    && reload_completed
3560    && GET_CODE (operands[2]) == CONST_INT
3561    && ! satisfies_constraint_P27 (operands[2])"
3562   [(set (match_dup 3) (match_dup 2))
3563    (parallel
3564     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3565      (clobber (match_dup 4))])]
3566   "operands[4] = gen_rtx_SCRATCH (SImode);"
3567   [(set_attr "length" "*,*,*,4")
3568    (set_attr "type" "dyn_shift,arith,arith,arith")])
3569
3570 (define_insn "ashlhi3_k"
3571   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3572         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3573                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3574   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3575   "@
3576         add     %0,%0
3577         shll%O2 %0"
3578   [(set_attr "type" "arith")])
3579
3580 (define_insn "ashlsi3_n"
3581   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3582         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3583                    (match_operand:SI 2 "const_int_operand" "n")))
3584    (clobber (reg:SI T_REG))]
3585   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3586   "#"
3587   [(set (attr "length")
3588         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3589                (const_string "2")
3590                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3591                (const_string "4")
3592                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3593                (const_string "6")]
3594               (const_string "8")))
3595    (set_attr "type" "arith")])
3596
3597 (define_split
3598   [(set (match_operand:SI 0 "arith_reg_dest" "")
3599         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3600                    (match_operand:SI 2 "const_int_operand" "")))
3601    (clobber (reg:SI T_REG))]
3602   "TARGET_SH1 && reload_completed"
3603   [(use (reg:SI R0_REG))]
3604   "
3605 {
3606   gen_shifty_op (ASHIFT, operands);
3607   DONE;
3608 }")
3609
3610 (define_insn "ashlsi3_media"
3611   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3612         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3613                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3614   "TARGET_SHMEDIA"
3615   "@
3616         shlld.l %1, %2, %0
3617         shlli.l %1, %2, %0"
3618   [(set_attr "type" "arith_media")
3619    (set_attr "highpart" "ignore")])
3620
3621 (define_expand "ashlsi3"
3622   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3623                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3624                               (match_operand:SI 2 "nonmemory_operand" "")))
3625               (clobber (reg:SI T_REG))])]
3626   ""
3627   "
3628 {
3629   if (TARGET_SHMEDIA)
3630     {
3631       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3632       DONE;
3633     }
3634   if (GET_CODE (operands[2]) == CONST_INT
3635       && sh_dynamicalize_shift_p (operands[2]))
3636     operands[2] = force_reg (SImode, operands[2]);
3637   if (TARGET_SH3)
3638     {
3639       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3640       DONE;
3641     }
3642   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3643     FAIL;
3644 }")
3645
3646 (define_insn "*ashlhi3_n"
3647   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3648         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3649                    (match_operand:HI 2 "const_int_operand" "n")))
3650    (clobber (reg:SI T_REG))]
3651   "TARGET_SH1"
3652   "#"
3653   [(set (attr "length")
3654         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3655                (const_string "2")
3656                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3657                (const_string "4")]
3658               (const_string "6")))
3659    (set_attr "type" "arith")])
3660
3661 (define_expand "ashlhi3"
3662   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3663                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3664                               (match_operand:SI 2 "nonmemory_operand" "")))
3665               (clobber (reg:SI T_REG))])]
3666   "TARGET_SH1"
3667   "
3668 {
3669   if (GET_CODE (operands[2]) != CONST_INT)
3670     FAIL;
3671   /* It may be possible to call gen_ashlhi3 directly with more generic
3672      operands.  Make sure operands[1] is a HImode register here.  */
3673   if (!arith_reg_operand (operands[1], HImode))
3674     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3675 }")
3676
3677 (define_split
3678   [(set (match_operand:HI 0 "arith_reg_dest" "")
3679         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3680                    (match_operand:HI 2 "const_int_operand" "")))
3681    (clobber (reg:SI T_REG))]
3682   "TARGET_SH1 && reload_completed"
3683   [(use (reg:SI R0_REG))]
3684   "
3685 {
3686   gen_shifty_hi_op (ASHIFT, operands);
3687   DONE;
3688 }")
3689
3690 ;
3691 ; arithmetic shift right
3692 ;
3693
3694 (define_insn "ashrsi3_sh2a"
3695   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3696         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3697                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3698   "TARGET_SH2A"
3699   "shad %2,%0"
3700   [(set_attr "type" "dyn_shift")
3701    (set_attr "length" "4")])
3702
3703 (define_insn "ashrsi3_k"
3704   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3705         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3706                      (match_operand:SI 2 "const_int_operand" "M")))
3707    (clobber (reg:SI T_REG))]
3708   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3709   "shar %0"
3710   [(set_attr "type" "arith")])
3711
3712 ;; We can't do HImode right shifts correctly unless we start out with an
3713 ;; explicit zero / sign extension; doing that would result in worse overall
3714 ;; code, so just let the machine independent code widen the mode.
3715 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3716
3717
3718 ;; ??? This should be a define expand.
3719
3720 (define_insn "ashrsi2_16"
3721   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3722         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3723                      (const_int 16)))]
3724   "TARGET_SH1"
3725   "#"
3726   [(set_attr "length" "4")])
3727
3728 (define_split
3729   [(set (match_operand:SI 0 "arith_reg_dest" "")
3730         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3731                      (const_int 16)))]
3732   "TARGET_SH1"
3733   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3734    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3735   "operands[2] = gen_lowpart (HImode, operands[0]);")
3736
3737 ;; ??? This should be a define expand.
3738
3739 (define_insn "ashrsi2_31"
3740   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3742                      (const_int 31)))
3743    (clobber (reg:SI T_REG))]
3744   "TARGET_SH1"
3745   "#"
3746   [(set_attr "length" "4")])
3747
3748 (define_split
3749   [(set (match_operand:SI 0 "arith_reg_dest" "")
3750         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3751                      (const_int 31)))
3752    (clobber (reg:SI T_REG))]
3753   "TARGET_SH1"
3754   [(const_int 0)]
3755   "
3756 {
3757   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3758   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3759   DONE;
3760 }")
3761
3762 (define_peephole2
3763   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3764    (set (reg:SI T_REG)
3765         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3766   "TARGET_SH1
3767    && peep2_reg_dead_p (2, operands[0])
3768    && peep2_reg_dead_p (2, operands[1])"
3769   [(const_int 0)]
3770   "
3771 {
3772   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3773   DONE;
3774 }")
3775
3776 (define_insn "ashlsi_c"
3777   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3778         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3779    (set (reg:SI T_REG)
3780         (lt:SI (match_dup 1) (const_int 0)))]
3781   "TARGET_SH1"
3782   "shll %0"
3783   [(set_attr "type" "arith")])
3784
3785 (define_insn "*ashlsi_c_void"
3786   [(set (reg:SI T_REG)
3787         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3788    (clobber (match_scratch:SI 1 "=0"))]
3789   "TARGET_SH1 && cse_not_expected"
3790   "shll %0"
3791   [(set_attr "type" "arith")])
3792
3793 (define_insn "ashrsi3_d"
3794   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3795         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3796                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3797   "TARGET_SH3"
3798   "shad %2,%0"
3799   [(set_attr "type" "dyn_shift")])
3800
3801 (define_insn "ashrsi3_n"
3802   [(set (reg:SI R4_REG)
3803         (ashiftrt:SI (reg:SI R4_REG)
3804                      (match_operand:SI 0 "const_int_operand" "i")))
3805    (clobber (reg:SI T_REG))
3806    (clobber (reg:SI PR_REG))
3807    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3808   "TARGET_SH1"
3809   "jsr  @%1%#"
3810   [(set_attr "type" "sfunc")
3811    (set_attr "needs_delay_slot" "yes")])
3812
3813 (define_insn "ashrsi3_media"
3814   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3815         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3816                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3817   "TARGET_SHMEDIA"
3818   "@
3819         shard.l %1, %2, %0
3820         shari.l %1, %2, %0"
3821   [(set_attr "type" "arith_media")
3822    (set_attr "highpart" "ignore")])
3823
3824 (define_expand "ashrsi3"
3825   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3826                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3827                                 (match_operand:SI 2 "nonmemory_operand" "")))
3828               (clobber (reg:SI T_REG))])]
3829   ""
3830   "
3831 {
3832   if (TARGET_SHMEDIA)
3833     {
3834       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3835       DONE;
3836     }
3837   if (expand_ashiftrt (operands))
3838     DONE;
3839   else
3840     FAIL;
3841 }")
3842
3843 ;; logical shift right
3844
3845 (define_insn "lshrsi3_sh2a"
3846   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3847         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3848                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3849   "TARGET_SH2A"
3850   "shld %2,%0"
3851   [(set_attr "type" "dyn_shift")
3852    (set_attr "length" "4")])
3853
3854 (define_insn "lshrsi3_d"
3855   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3856         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3857                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3858   "TARGET_SH3"
3859   "shld %2,%0"
3860   [(set_attr "type" "dyn_shift")])
3861
3862 ;;  Only the single bit shift clobbers the T bit.
3863
3864 (define_insn "lshrsi3_m"
3865   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3866         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3867                      (match_operand:SI 2 "const_int_operand" "M")))
3868    (clobber (reg:SI T_REG))]
3869   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3870   "shlr %0"
3871   [(set_attr "type" "arith")])
3872
3873 (define_insn "lshrsi3_k"
3874   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3875         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3876                      (match_operand:SI 2 "const_int_operand" "P27")))]
3877   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3878    && ! satisfies_constraint_M (operands[2])"
3879   "shlr%O2      %0"
3880   [(set_attr "type" "arith")])
3881
3882 (define_insn "lshrsi3_n"
3883   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3884         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3885                      (match_operand:SI 2 "const_int_operand" "n")))
3886    (clobber (reg:SI T_REG))]
3887   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3888   "#"
3889   [(set (attr "length")
3890         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3891                (const_string "2")
3892                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3893                (const_string "4")
3894                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3895                (const_string "6")]
3896               (const_string "8")))
3897    (set_attr "type" "arith")])
3898
3899 (define_split
3900   [(set (match_operand:SI 0 "arith_reg_dest" "")
3901         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3902                      (match_operand:SI 2 "const_int_operand" "")))
3903    (clobber (reg:SI T_REG))]
3904   "TARGET_SH1 && reload_completed"
3905   [(use (reg:SI R0_REG))]
3906   "
3907 {
3908   gen_shifty_op (LSHIFTRT, operands);
3909   DONE;
3910 }")
3911
3912 (define_insn "lshrsi3_media"
3913   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3914         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3915                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3916   "TARGET_SHMEDIA"
3917   "@
3918         shlrd.l %1, %2, %0
3919         shlri.l %1, %2, %0"
3920   [(set_attr "type" "arith_media")
3921    (set_attr "highpart" "ignore")])
3922
3923 (define_expand "lshrsi3"
3924   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3925                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3926                                 (match_operand:SI 2 "nonmemory_operand" "")))
3927               (clobber (reg:SI T_REG))])]
3928   ""
3929   "
3930 {
3931   if (TARGET_SHMEDIA)
3932     {
3933       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3934       DONE;
3935     }
3936   if (GET_CODE (operands[2]) == CONST_INT
3937       && sh_dynamicalize_shift_p (operands[2]))
3938     operands[2] = force_reg (SImode, operands[2]);
3939   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3940     {
3941       rtx count = copy_to_mode_reg (SImode, operands[2]);
3942       emit_insn (gen_negsi2 (count, count));
3943       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3944       DONE;
3945     }
3946   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3947     FAIL;
3948 }")
3949
3950 ;; ??? This should be a define expand.
3951
3952 (define_insn "ashldi3_k"
3953   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3954         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3955                    (const_int 1)))
3956    (clobber (reg:SI T_REG))]
3957   "TARGET_SH1"
3958   "shll %R0\;rotcl      %S0"
3959   [(set_attr "length" "4")
3960    (set_attr "type" "arith")])
3961
3962 (define_insn "ashldi3_media"
3963   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3964         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3965                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3966   "TARGET_SHMEDIA"
3967   "@
3968         shlld   %1, %2, %0
3969         shlli   %1, %2, %0"
3970   [(set_attr "type" "arith_media")])
3971
3972 (define_insn "*ashldisi3_media"
3973   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3974         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3975                    (match_operand:DI 2 "const_int_operand" "n")))]
3976   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3977   "shlli.l      %1, %2, %0"
3978   [(set_attr "type" "arith_media")
3979    (set_attr "highpart" "ignore")])
3980
3981 (define_expand "ashldi3"
3982   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3983                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3984                               (match_operand:DI 2 "immediate_operand" "")))
3985               (clobber (reg:SI T_REG))])]
3986   ""
3987   "
3988 {
3989   if (TARGET_SHMEDIA)
3990     {
3991       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3992       DONE;
3993     }
3994   if (GET_CODE (operands[2]) != CONST_INT
3995       || INTVAL (operands[2]) != 1)
3996     FAIL;
3997 }")
3998
3999 ;; ??? This should be a define expand.
4000
4001 (define_insn "lshrdi3_k"
4002   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4003         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4004                      (const_int 1)))
4005    (clobber (reg:SI T_REG))]
4006   "TARGET_SH1"
4007   "shlr %S0\;rotcr      %R0"
4008   [(set_attr "length" "4")
4009    (set_attr "type" "arith")])
4010
4011 (define_insn "lshrdi3_media"
4012   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4013         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4014                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4015   "TARGET_SHMEDIA
4016    && (arith_reg_dest (operands[0], DImode)
4017        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4018   "@
4019         shlrd   %1, %2, %0
4020         shlri   %1, %2, %0"
4021   [(set_attr "type" "arith_media")])
4022
4023 (define_insn "*lshrdisi3_media"
4024   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4025         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4026                      (match_operand:DI 2 "const_int_operand" "n")))]
4027   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4028   "shlri.l      %1, %2, %0"
4029   [(set_attr "type" "arith_media")
4030    (set_attr "highpart" "ignore")])
4031
4032 (define_expand "lshrdi3"
4033   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4034                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4035                                (match_operand:DI 2 "immediate_operand" "")))
4036              (clobber (reg:SI T_REG))])]
4037   ""
4038   "
4039 {
4040   if (TARGET_SHMEDIA)
4041     {
4042       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4043       DONE;
4044     }
4045   if (GET_CODE (operands[2]) != CONST_INT
4046       || INTVAL (operands[2]) != 1)
4047     FAIL;
4048 }")
4049
4050 ;; ??? This should be a define expand.
4051
4052 (define_insn "ashrdi3_k"
4053   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4054         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4055                      (const_int 1)))
4056    (clobber (reg:SI T_REG))]
4057   "TARGET_SH1"
4058   "shar %S0\;rotcr      %R0"
4059   [(set_attr "length" "4")
4060    (set_attr "type" "arith")])
4061
4062 (define_insn "ashrdi3_media"
4063   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4064         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4065                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4066   "TARGET_SHMEDIA
4067    && (arith_reg_dest (operands[0], DImode)
4068        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4069   "@
4070         shard   %1, %2, %0
4071         shari   %1, %2, %0"
4072   [(set_attr "type" "arith_media")])
4073
4074 (define_insn "*ashrdisi3_media"
4075   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4076         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4077                      (match_operand:DI 2 "const_int_operand" "n")))]
4078   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4079   "shari.l      %1, %2, %0"
4080   [(set_attr "type" "arith_media")
4081    (set_attr "highpart" "ignore")])
4082
4083 (define_insn "ashrdisi3_media_high"
4084   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4085         (truncate:SI
4086            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4087                         (match_operand:DI 2 "const_int_operand" "n"))))]
4088   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4089   "shari        %1, %2, %0"
4090   [(set_attr "type" "arith_media")])
4091
4092 (define_insn "ashrdisi3_media_opaque"
4093   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4094         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4095                     (match_operand:DI 2 "const_int_operand" "n")]
4096          UNSPEC_ASHIFTRT))]
4097   "TARGET_SHMEDIA"
4098   "shari        %1, %2, %0"
4099   [(set_attr "type" "arith_media")])
4100
4101 (define_expand "ashrdi3"
4102   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4103                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4104                                 (match_operand:DI 2 "immediate_operand" "")))
4105               (clobber (reg:SI T_REG))])]
4106   ""
4107   "
4108 {
4109   if (TARGET_SHMEDIA)
4110     {
4111       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4112       DONE;
4113     }
4114   if (GET_CODE (operands[2]) != CONST_INT
4115       || INTVAL (operands[2]) != 1)
4116     FAIL;
4117 }")
4118
4119 ;; combined left/right shift
4120
4121 (define_split
4122   [(set (match_operand:SI 0 "register_operand" "")
4123         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4124                            (match_operand:SI 2 "const_int_operand" ""))
4125                 (match_operand:SI 3 "const_int_operand" "")))]
4126   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4127   [(use (reg:SI R0_REG))]
4128   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4129    DONE;")
4130
4131 (define_split
4132   [(set (match_operand:SI 0 "register_operand" "")
4133         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4134                            (match_operand:SI 2 "const_int_operand" ""))
4135                 (match_operand:SI 3 "const_int_operand" "")))
4136    (clobber (reg:SI T_REG))]
4137   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4138   [(use (reg:SI R0_REG))]
4139   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4140    DONE;")
4141
4142 (define_insn ""
4143   [(set (match_operand:SI 0 "register_operand" "=r")
4144         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4145                            (match_operand:SI 2 "const_int_operand" "n"))
4146                 (match_operand:SI 3 "const_int_operand" "n")))
4147    (clobber (reg:SI T_REG))]
4148   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4149  "#"
4150   [(set (attr "length")
4151         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4152                (const_string "4")
4153                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4154                (const_string "6")
4155                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4156                (const_string "8")
4157                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4158                (const_string "10")
4159                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4160                (const_string "12")
4161                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4162                (const_string "14")
4163                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4164                (const_string "16")]
4165               (const_string "18")))
4166    (set_attr "type" "arith")])
4167
4168 (define_insn ""
4169   [(set (match_operand:SI 0 "register_operand" "=z")
4170         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4171                            (match_operand:SI 2 "const_int_operand" "n"))
4172                 (match_operand:SI 3 "const_int_operand" "n")))
4173    (clobber (reg:SI T_REG))]
4174   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4175  "#"
4176   [(set (attr "length")
4177         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4178                (const_string "4")
4179                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4180                (const_string "6")
4181                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4182                (const_string "8")]
4183               (const_string "10")))
4184    (set_attr "type" "arith")])
4185
4186 ;; shift left / and combination with a scratch register: The combine pass
4187 ;; does not accept the individual instructions, even though they are
4188 ;; cheap.  But it needs a precise description so that it is usable after
4189 ;; reload.
4190 (define_insn "and_shl_scratch"
4191   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4192         (lshiftrt:SI
4193          (ashift:SI
4194           (and:SI
4195            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4196                         (match_operand:SI 2 "const_int_operand" "N,n"))
4197            (match_operand:SI 3 "" "0,r"))
4198           (match_operand:SI 4 "const_int_operand" "n,n"))
4199          (match_operand:SI 5 "const_int_operand" "n,n")))
4200    (clobber (reg:SI T_REG))]
4201   "TARGET_SH1"
4202   "#"
4203   [(set (attr "length")
4204         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4205                (const_string "4")
4206                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4207                (const_string "6")
4208                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4209                (const_string "8")
4210                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4211                (const_string "10")]
4212               (const_string "12")))
4213    (set_attr "type" "arith")])
4214
4215 (define_split
4216   [(set (match_operand:SI 0 "register_operand" "")
4217         (lshiftrt:SI
4218          (ashift:SI
4219           (and:SI
4220            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4221                         (match_operand:SI 2 "const_int_operand" ""))
4222            (match_operand:SI 3 "register_operand" ""))
4223           (match_operand:SI 4 "const_int_operand" ""))
4224          (match_operand:SI 5 "const_int_operand" "")))
4225    (clobber (reg:SI T_REG))]
4226   "TARGET_SH1"
4227   [(use (reg:SI R0_REG))]
4228   "
4229 {
4230   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4231
4232   if (INTVAL (operands[2]))
4233     {
4234       gen_shifty_op (LSHIFTRT, operands);
4235     }
4236   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4237   operands[2] = operands[4];
4238   gen_shifty_op (ASHIFT, operands);
4239   if (INTVAL (operands[5]))
4240     {
4241       operands[2] = operands[5];
4242       gen_shifty_op (LSHIFTRT, operands);
4243     }
4244   DONE;
4245 }")
4246
4247 ;; signed left/right shift combination.
4248 (define_split
4249   [(set (match_operand:SI 0 "register_operand" "")
4250         (sign_extract:SI
4251          (ashift:SI (match_operand:SI 1 "register_operand" "")
4252                     (match_operand:SI 2 "const_int_operand" ""))
4253          (match_operand:SI 3 "const_int_operand" "")
4254          (const_int 0)))
4255    (clobber (reg:SI T_REG))]
4256   "TARGET_SH1"
4257   [(use (reg:SI R0_REG))]
4258   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4259    DONE;")
4260
4261 (define_insn "shl_sext_ext"
4262   [(set (match_operand:SI 0 "register_operand" "=r")
4263         (sign_extract:SI
4264          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4265                     (match_operand:SI 2 "const_int_operand" "n"))
4266          (match_operand:SI 3 "const_int_operand" "n")
4267          (const_int 0)))
4268    (clobber (reg:SI T_REG))]
4269   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4270   "#"
4271   [(set (attr "length")
4272         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4273                (const_string "2")
4274                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4275                (const_string "4")
4276                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4277                (const_string "6")
4278                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4279                (const_string "8")
4280                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4281                (const_string "10")
4282                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4283                (const_string "12")
4284                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4285                (const_string "14")
4286                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4287                (const_string "16")]
4288               (const_string "18")))
4289     (set_attr "type" "arith")])
4290
4291 (define_insn "shl_sext_sub"
4292   [(set (match_operand:SI 0 "register_operand" "=z")
4293         (sign_extract:SI
4294          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4295                     (match_operand:SI 2 "const_int_operand" "n"))
4296          (match_operand:SI 3 "const_int_operand" "n")
4297          (const_int 0)))
4298    (clobber (reg:SI T_REG))]
4299   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4300   "#"
4301   [(set (attr "length")
4302         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4303                (const_string "6")
4304                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4305                (const_string "8")
4306                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4307                (const_string "10")
4308                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4309                (const_string "12")]
4310               (const_string "14")))
4311     (set_attr "type" "arith")])
4312
4313 ;; These patterns are found in expansions of DImode shifts by 16, and
4314 ;; allow the xtrct instruction to be generated from C source.
4315
4316 (define_insn "xtrct_left"
4317   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4318         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4319                            (const_int 16))
4320                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4321                              (const_int 16))))]
4322   "TARGET_SH1"
4323   "xtrct        %1,%0"
4324   [(set_attr "type" "arith")])
4325
4326 (define_insn "xtrct_right"
4327   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4328         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4329                              (const_int 16))
4330                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4331                            (const_int 16))))]
4332   "TARGET_SH1"
4333   "xtrct        %2,%0"
4334   [(set_attr "type" "arith")])
4335
4336 ;; -------------------------------------------------------------------------
4337 ;; Unary arithmetic
4338 ;; -------------------------------------------------------------------------
4339
4340 (define_insn "negc"
4341   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4342         (neg:SI (plus:SI (reg:SI T_REG)
4343                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4344    (set (reg:SI T_REG)
4345         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4346                (const_int 0)))]
4347   "TARGET_SH1"
4348   "negc %1,%0"
4349   [(set_attr "type" "arith")])
4350
4351 (define_insn "*negdi_media"
4352   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4353         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4354   "TARGET_SHMEDIA"
4355   "sub  r63, %1, %0"
4356   [(set_attr "type" "arith_media")])
4357
4358 (define_expand "negdi2"
4359   [(set (match_operand:DI 0 "arith_reg_operand" "")
4360         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4361   ""
4362   "
4363 {
4364   if (TARGET_SH1)
4365     {
4366       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4367       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4368
4369       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4370       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4371
4372       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4373       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4374
4375       emit_insn (gen_clrt ());
4376       emit_insn (gen_negc (low_dst, low_src));
4377       emit_insn (gen_negc (high_dst, high_src));
4378       DONE;
4379     }
4380 }")
4381
4382 (define_insn "negsi2"
4383   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4384         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4385   "TARGET_SH1"
4386   "neg  %1,%0"
4387   [(set_attr "type" "arith")])
4388
4389 (define_insn "one_cmplsi2"
4390   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4391         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4392   "TARGET_SH1"
4393   "not  %1,%0"
4394   [(set_attr "type" "arith")])
4395
4396 (define_expand "one_cmpldi2"
4397   [(set (match_operand:DI 0 "arith_reg_dest" "")
4398         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4399                 (const_int -1)))]
4400   "TARGET_SHMEDIA" "")
4401
4402 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4403    This can be used as some kind of conditional execution, which is useful
4404    for abs.  */
4405 (define_split
4406   [(set (match_operand:SI 0 "arith_reg_dest" "")
4407         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4408                          (match_operand:SI 1 "arith_reg_operand" ""))
4409                  (reg:SI T_REG)))]
4410   "TARGET_HARD_SH4"
4411   [(const_int 0)]
4412   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4413    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4414    DONE;")
4415
4416 (define_insn "cneg"
4417   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4418         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4419                       (match_operand:SI 1 "arith_reg_operand" "0")
4420                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4421   "TARGET_HARD_SH4"
4422   "bf 0f\;neg %2,%0\\n0:"
4423   [(set_attr "type" "arith") ;; poor approximation
4424    (set_attr "length" "4")])
4425
4426 \f
4427 ;; -------------------------------------------------------------------------
4428 ;; Zero extension instructions
4429 ;; -------------------------------------------------------------------------
4430
4431 (define_insn "zero_extendsidi2"
4432   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4433         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4434   "TARGET_SHMEDIA"
4435   "addz.l       %1, r63, %0"
4436   [(set_attr "type" "arith_media")
4437    (set_attr "highpart" "extend")])
4438
4439 (define_insn "zero_extendhidi2"
4440   [(set (match_operand:DI 0 "register_operand" "=r,r")
4441         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4442   "TARGET_SHMEDIA"
4443   "@
4444         #
4445         ld%M1.uw        %m1, %0"
4446   [(set_attr "type" "*,load_media")
4447    (set (attr "highpart")
4448         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4449                (const_string "user")]
4450               (const_string "ignore")))])
4451
4452 (define_split
4453   [(set (match_operand:DI 0 "register_operand" "")
4454         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4455   "TARGET_SHMEDIA && reload_completed"
4456   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4457    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4458   "
4459 {
4460   if (GET_CODE (operands[1]) == TRUNCATE)
4461     operands[1] = XEXP (operands[1], 0);
4462 }")
4463
4464 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4465 ;; reload the entire truncate expression.
4466 (define_insn_and_split "*loaddi_trunc"
4467   [(set (match_operand 0 "any_register_operand" "=r")
4468         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4469   "TARGET_SHMEDIA && reload_completed"
4470   "#"
4471   "TARGET_SHMEDIA && reload_completed"
4472   [(set (match_dup 0) (match_dup 1))]
4473   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4474
4475 (define_insn "zero_extendqidi2"
4476   [(set (match_operand:DI 0 "register_operand" "=r,r")
4477         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4478   "TARGET_SHMEDIA"
4479   "@
4480         andi    %1, 255, %0
4481         ld%M1.ub        %m1, %0"
4482   [(set_attr "type" "arith_media,load_media")
4483    (set (attr "highpart")
4484         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4485                (const_string "user")]
4486               (const_string "ignore")))])
4487
4488 (define_expand "zero_extendhisi2"
4489   [(set (match_operand:SI 0 "arith_reg_operand" "")
4490         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4491   ""
4492   "
4493 {
4494   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4495     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4496 }")
4497
4498 (define_insn "*zero_extendhisi2_compact"
4499   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4500         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4501   "TARGET_SH1"
4502   "extu.w       %1,%0"
4503   [(set_attr "type" "arith")])
4504
4505 (define_insn "*zero_extendhisi2_media"
4506   [(set (match_operand:SI 0 "register_operand" "=r,r")
4507         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4508   "TARGET_SHMEDIA"
4509   "@
4510         #
4511         ld%M1.uw        %m1, %0"
4512   [(set_attr "type" "arith_media,load_media")
4513    (set (attr "highpart")
4514         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4515                (const_string "user")]
4516               (const_string "ignore")))])
4517
4518 (define_split
4519   [(set (match_operand:SI 0 "register_operand" "")
4520         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4521   "TARGET_SHMEDIA && reload_completed"
4522   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4523    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4524   "
4525 {
4526   rtx op1 = operands[1];
4527
4528   if (GET_CODE (op1) == TRUNCATE)
4529     op1 = XEXP (op1, 0);
4530   operands[2]
4531     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4532                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4533 }")
4534
4535 (define_expand "zero_extendqisi2"
4536   [(set (match_operand:SI 0 "arith_reg_operand" "")
4537         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4538   ""
4539   "
4540 {
4541   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4542     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4543 }")
4544
4545 (define_insn "*zero_extendqisi2_compact"
4546   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4547         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4548   "TARGET_SH1"
4549   "extu.b       %1,%0"
4550   [(set_attr "type" "arith")])
4551
4552 (define_insn "*zero_extendqisi2_media"
4553   [(set (match_operand:SI 0 "register_operand" "=r,r")
4554         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4555   "TARGET_SHMEDIA"
4556   "@
4557         andi    %1, 255, %0
4558         ld%M1.ub        %m1, %0"
4559   [(set_attr "type" "arith_media,load_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 "ignore")))])
4564
4565 (define_insn "zero_extendqihi2"
4566   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4567         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4568   "TARGET_SH1"
4569   "extu.b       %1,%0"
4570   [(set_attr "type" "arith")])
4571
4572 ;; -------------------------------------------------------------------------
4573 ;; Sign extension instructions
4574 ;; -------------------------------------------------------------------------
4575
4576 ;; ??? This should be a define expand.
4577 ;; ??? Or perhaps it should be dropped?
4578
4579 ;; convert_move generates good code for SH[1-4].
4580 (define_insn "extendsidi2"
4581   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4582         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4583   "TARGET_SHMEDIA"
4584   "@
4585         add.l   %1, r63, %0
4586         ld%M1.l %m1, %0
4587         fmov.sl %1, %0"
4588   [(set_attr "type" "arith_media,load_media,fpconv_media")
4589    (set (attr "highpart")
4590         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4591                (const_string "user")]
4592               (const_string "extend")))])
4593
4594 (define_insn "extendhidi2"
4595   [(set (match_operand:DI 0 "register_operand" "=r,r")
4596         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4597   "TARGET_SHMEDIA"
4598   "@
4599         #
4600         ld%M1.w %m1, %0"
4601   [(set_attr "type" "*,load_media")
4602    (set (attr "highpart")
4603         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4604                (const_string "user")]
4605               (const_string "ignore")))])
4606
4607 (define_split
4608   [(set (match_operand:DI 0 "register_operand" "")
4609         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4610   "TARGET_SHMEDIA && reload_completed"
4611   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4612    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4613   "
4614 {
4615   if (GET_CODE (operands[1]) == TRUNCATE)
4616     operands[1] = XEXP (operands[1], 0);
4617 }")
4618
4619 (define_insn "extendqidi2"
4620   [(set (match_operand:DI 0 "register_operand" "=r,r")
4621         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4622   "TARGET_SHMEDIA"
4623   "@
4624         #
4625         ld%M1.b %m1, %0"
4626   [(set_attr "type" "*,load_media")
4627    (set (attr "highpart")
4628         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4629                (const_string "user")]
4630               (const_string "ignore")))])
4631
4632 (define_split
4633   [(set (match_operand:DI 0 "register_operand" "")
4634         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4635   "TARGET_SHMEDIA && reload_completed"
4636   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4637    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4638   "
4639 {
4640   if (GET_CODE (operands[1]) == TRUNCATE)
4641     operands[1] = XEXP (operands[1], 0);
4642 }")
4643
4644 (define_expand "extendhisi2"
4645   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4646         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4647   ""
4648   "")
4649
4650 (define_insn "*extendhisi2_compact"
4651   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4652         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4653   "TARGET_SH1"
4654   "@
4655         exts.w  %1,%0
4656         mov.w   %1,%0"
4657   [(set_attr "type" "arith,load")])
4658
4659 (define_insn "*extendhisi2_media"
4660   [(set (match_operand:SI 0 "register_operand" "=r,r")
4661         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4662   "TARGET_SHMEDIA"
4663   "@
4664         #
4665         ld%M1.w %m1, %0"
4666   [(set_attr "type" "arith_media,load_media")
4667    (set (attr "highpart")
4668         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4669                (const_string "user")]
4670               (const_string "ignore")))])
4671
4672 (define_split
4673   [(set (match_operand:SI 0 "register_operand" "")
4674         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4675   "TARGET_SHMEDIA && reload_completed"
4676   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4677    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4678   "
4679 {
4680   rtx op1 = operands[1];
4681   if (GET_CODE (op1) == TRUNCATE)
4682     op1 = XEXP (op1, 0);
4683   operands[2]
4684     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4685                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4686 }")
4687
4688 (define_expand "extendqisi2"
4689   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4690         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4691   ""
4692   "")
4693
4694 (define_insn "*extendqisi2_compact"
4695   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4696         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4697   "TARGET_SH1"
4698   "@
4699         exts.b  %1,%0
4700         mov.b   %1,%0"
4701   [(set_attr "type" "arith,load")])
4702
4703 (define_insn "*extendqisi2_media"
4704   [(set (match_operand:SI 0 "register_operand" "=r,r")
4705         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4706   "TARGET_SHMEDIA"
4707   "@
4708         #
4709         ld%M1.b %m1, %0"
4710   [(set_attr "type" "arith_media,load_media")
4711    (set (attr "highpart")
4712         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4713                (const_string "user")]
4714               (const_string "ignore")))])
4715
4716 (define_split
4717   [(set (match_operand:SI 0 "register_operand" "")
4718         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4719   "TARGET_SHMEDIA && reload_completed"
4720   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4721    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4722    "
4723 {
4724   rtx op1 = operands[1];
4725   if (GET_CODE (op1) == TRUNCATE)
4726     op1 = XEXP (op1, 0);
4727   operands[2]
4728     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4729                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4730 }")
4731
4732 (define_insn "extendqihi2"
4733   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4734         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4735   "TARGET_SH1"
4736   "@
4737         exts.b  %1,%0
4738         mov.b   %1,%0"
4739   [(set_attr "type" "arith,load")])
4740
4741 /* It would seem useful to combine the truncXi patterns into the movXi
4742    patterns, but unary operators are ignored when matching constraints,
4743    so we need separate patterns.  */
4744 (define_insn "truncdisi2"
4745   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4746         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4747   "TARGET_SHMEDIA"
4748   "@
4749         add.l   %1, r63, %0
4750         st%M0.l %m0, %1
4751         fst%M0.s        %m0, %T1
4752         fmov.ls %1, %0
4753         fmov.sl %T1, %0
4754         fmov.s  %T1, %0"
4755   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4756    (set (attr "highpart")
4757         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4758                (const_string "user")]
4759               (const_string "extend")))])
4760
4761 (define_insn "truncdihi2"
4762   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4763         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4764   "TARGET_SHMEDIA"
4765   "@
4766         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4767         st%M0.w %m0, %1"
4768   [(set_attr "type"   "arith_media,store_media")
4769    (set_attr "length" "8,4")
4770    (set (attr "highpart")
4771         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4772                (const_string "user")]
4773               (const_string "extend")))])
4774
4775 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4776 ; Because we use zero extension, we can't provide signed QImode compares
4777 ; using a simple compare or conditional branch insn.
4778 (define_insn "truncdiqi2"
4779   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4780         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4781   "TARGET_SHMEDIA"
4782   "@
4783         andi    %1, 255, %0
4784         st%M0.b %m0, %1"
4785   [(set_attr "type"   "arith_media,store")
4786    (set (attr "highpart")
4787         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4788                (const_string "user")]
4789               (const_string "extend")))])
4790 ;; -------------------------------------------------------------------------
4791 ;; Move instructions
4792 ;; -------------------------------------------------------------------------
4793
4794 ;; define push and pop so it is easy for sh.c
4795 ;; We can't use push and pop on SHcompact because the stack must always
4796 ;; be 8-byte aligned.
4797
4798 (define_expand "push"
4799   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4800         (match_operand:SI 0 "register_operand" "r,l,x"))]
4801   "TARGET_SH1 && ! TARGET_SH5"
4802   "")
4803
4804 (define_expand "pop"
4805   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4806         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4807   "TARGET_SH1 && ! TARGET_SH5"
4808   "")
4809
4810 (define_expand "push_e"
4811   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4812                    (match_operand:SF 0 "" ""))
4813               (use (reg:PSI FPSCR_REG))
4814               (clobber (scratch:SI))])]
4815   "TARGET_SH1 && ! TARGET_SH5"
4816   "")
4817
4818 (define_insn "push_fpul"
4819   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4820   "TARGET_SH2E && ! TARGET_SH5"
4821   "sts.l        fpul,@-r15"
4822   [(set_attr "type" "fstore")
4823    (set_attr "late_fp_use" "yes")
4824    (set_attr "hit_stack" "yes")])
4825
4826 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4827 ;; so use that.
4828 (define_expand "push_4"
4829   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4830                    (match_operand:DF 0 "" ""))
4831               (use (reg:PSI FPSCR_REG))
4832               (clobber (scratch:SI))])]
4833   "TARGET_SH1 && ! TARGET_SH5"
4834   "")
4835
4836 (define_expand "pop_e"
4837   [(parallel [(set (match_operand:SF 0 "" "")
4838               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4839               (use (reg:PSI FPSCR_REG))
4840               (clobber (scratch:SI))])]
4841   "TARGET_SH1 && ! TARGET_SH5"
4842   "")
4843
4844 (define_insn "pop_fpul"
4845   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4846   "TARGET_SH2E && ! TARGET_SH5"
4847   "lds.l        @r15+,fpul"
4848   [(set_attr "type" "load")
4849    (set_attr "hit_stack" "yes")])
4850
4851 (define_expand "pop_4"
4852   [(parallel [(set (match_operand:DF 0 "" "")
4853                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4854               (use (reg:PSI FPSCR_REG))
4855               (clobber (scratch:SI))])]
4856   "TARGET_SH1 && ! TARGET_SH5"
4857   "")
4858
4859 (define_expand "push_fpscr"
4860   [(const_int 0)]
4861   "TARGET_SH2E"
4862   "
4863 {
4864   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4865                                                  gen_rtx_PRE_DEC (Pmode,
4866                                                           stack_pointer_rtx)),
4867                                         get_fpscr_rtx ()));
4868   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4869   DONE;
4870 }")
4871
4872 (define_expand "pop_fpscr"
4873   [(const_int 0)]
4874   "TARGET_SH2E"
4875   "
4876 {
4877   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4878                                         gen_frame_mem (PSImode,
4879                                                  gen_rtx_POST_INC (Pmode,
4880                                                           stack_pointer_rtx))));
4881   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4882   DONE;
4883 }")
4884
4885 ;; These two patterns can happen as the result of optimization, when
4886 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4887 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4888
4889 (define_insn "clrt"
4890   [(set (reg:SI T_REG) (const_int 0))]
4891   "TARGET_SH1"
4892   "clrt")
4893
4894 (define_insn "sett"
4895   [(set (reg:SI T_REG) (const_int 1))]
4896   "TARGET_SH1"
4897   "sett")
4898
4899 ;; t/r must come after r/r, lest reload will try to reload stuff like
4900 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4901 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4902 (define_insn "movsi_i"
4903   [(set (match_operand:SI 0 "general_movdst_operand"
4904             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4905         (match_operand:SI 1 "general_movsrc_operand"
4906          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4907   "TARGET_SH1
4908    && ! TARGET_SH2E
4909    && ! TARGET_SH2A
4910    && (register_operand (operands[0], SImode)
4911        || register_operand (operands[1], SImode))"
4912   "@
4913         mov.l   %1,%0
4914         mov     %1,%0
4915         mov     %1,%0
4916         cmp/pl  %1
4917         mov.l   %1,%0
4918         sts     %1,%0
4919         sts     %1,%0
4920         movt    %0
4921         mov.l   %1,%0
4922         sts.l   %1,%0
4923         sts.l   %1,%0
4924         lds     %1,%0
4925         lds     %1,%0
4926         lds.l   %1,%0
4927         lds.l   %1,%0
4928         fake    %1,%0"
4929   [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4930    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4931
4932 ;; t/r must come after r/r, lest reload will try to reload stuff like
4933 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4934 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4935 ;; will require a reload.
4936 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4937 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4938 (define_insn "movsi_ie"
4939   [(set (match_operand:SI 0 "general_movdst_operand"
4940             "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4941         (match_operand:SI 1 "general_movsrc_operand"
4942          "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4943   "(TARGET_SH2E || TARGET_SH2A)
4944    && (register_operand (operands[0], SImode)
4945        || register_operand (operands[1], SImode))"
4946   "@
4947         mov.l   %1,%0
4948         mov     %1,%0
4949         mov     %1,%0
4950         movi20  %1,%0
4951         cmp/pl  %1
4952         mov.l   %1,%0
4953         sts     %1,%0
4954         sts     %1,%0
4955         movt    %0
4956         mov.l   %1,%0
4957         sts.l   %1,%0
4958         sts.l   %1,%0
4959         lds     %1,%0
4960         lds     %1,%0
4961         lds.l   %1,%0
4962         lds.l   %1,%0
4963         lds.l   %1,%0
4964         sts.l   %1,%0
4965         fake    %1,%0
4966         lds     %1,%0
4967         sts     %1,%0
4968         fsts    fpul,%0
4969         flds    %1,fpul
4970         fmov    %1,%0
4971         ! move optimized away"
4972   [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4973    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4974    (set_attr_alternative "length"
4975      [(const_int 2)
4976       (const_int 2)
4977       (const_int 2)
4978       (const_int 4)
4979       (const_int 2)
4980       (if_then_else
4981         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4982         (const_int 4) (const_int 2))
4983       (const_int 2)
4984       (const_int 2)
4985       (const_int 2)
4986       (if_then_else
4987         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4988         (const_int 4) (const_int 2))
4989       (const_int 2)
4990       (const_int 2)
4991       (const_int 2)
4992       (const_int 2)
4993       (const_int 2)
4994       (const_int 2)
4995       (const_int 2)
4996       (const_int 2)
4997       (const_int 2)
4998       (const_int 2)
4999       (const_int 2)
5000       (const_int 2)
5001       (const_int 2)
5002       (const_int 2)
5003       (const_int 0)])])
5004
5005 (define_insn "movsi_i_lowpart"
5006   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5007         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5008    "TARGET_SH1
5009     && (register_operand (operands[0], SImode)
5010         || register_operand (operands[1], SImode))"
5011   "@
5012         mov.l   %1,%0
5013         mov     %1,%0
5014         mov     %1,%0
5015         mov.l   %1,%0
5016         sts     %1,%0
5017         sts     %1,%0
5018         movt    %0
5019         mov.l   %1,%0
5020         fake    %1,%0"
5021   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5022
5023 (define_insn_and_split "load_ra"
5024   [(set (match_operand:SI 0 "general_movdst_operand" "")
5025         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5026   "TARGET_SH1"
5027   "#"
5028   "&& ! currently_expanding_to_rtl"
5029   [(set (match_dup 0) (match_dup 1))]
5030   "
5031 {
5032   if (TARGET_SHCOMPACT && current_function_saves_all_registers)
5033     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5034 }")
5035
5036 ;; The '?'s in the following constraints may not reflect the time taken
5037 ;; to perform the move. They are there to discourage the use of floating-
5038 ;; point registers for storing integer values.
5039 (define_insn "*movsi_media"
5040   [(set (match_operand:SI 0 "general_movdst_operand"
5041                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5042         (match_operand:SI 1 "general_movsrc_operand"
5043          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5044   "TARGET_SHMEDIA_FPU
5045    && (register_operand (operands[0], SImode)
5046        || sh_register_operand (operands[1], SImode)
5047        || GET_CODE (operands[1]) == TRUNCATE)"
5048   "@
5049         add.l   %1, r63, %0
5050         movi    %1, %0
5051         #
5052         ld%M1.l %m1, %0
5053         st%M0.l %m0, %N1
5054         fld%M1.s        %m1, %0
5055         fst%M0.s        %m0, %1
5056         fmov.ls %N1, %0
5057         fmov.sl %1, %0
5058         fmov.s  %1, %0
5059         ptabs   %1, %0
5060         gettr   %1, %0
5061         pt      %1, %0"
5062   [(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")
5063    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5064    (set (attr "highpart")
5065         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5066                (const_string "user")]
5067               (const_string "ignore")))])
5068
5069 (define_insn "*movsi_media_nofpu"
5070   [(set (match_operand:SI 0 "general_movdst_operand"
5071                 "=r,r,r,r,m,*b,r,*b")
5072         (match_operand:SI 1 "general_movsrc_operand"
5073          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5074   "TARGET_SHMEDIA
5075    && (register_operand (operands[0], SImode)
5076        || sh_register_operand (operands[1], SImode)
5077        || GET_CODE (operands[1]) == TRUNCATE)"
5078   "@
5079         add.l   %1, r63, %0
5080         movi    %1, %0
5081         #
5082         ld%M1.l %m1, %0
5083         st%M0.l %m0, %N1
5084         ptabs   %1, %0
5085         gettr   %1, %0
5086         pt      %1, %0"
5087   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5088    (set_attr "length" "4,4,8,4,4,4,4,12")
5089    (set (attr "highpart")
5090         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5091                (const_string "user")]
5092               (const_string "ignore")))])
5093
5094 (define_expand "movsi_const"
5095   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5096         (const:SI (sign_extend:SI
5097                    (truncate:HI
5098                     (ashiftrt:SI
5099                      (match_operand:DI 1 "immediate_operand" "s")
5100                      (const_int 16))))))
5101    (set (match_dup 0)
5102         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5103                 (const:SI
5104                   (zero_extend:SI
5105                    (truncate:HI (match_dup 1))))))]
5106   "TARGET_SHMEDIA && reload_completed
5107    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5108   "
5109 {
5110   if (GET_CODE (operands[1]) == LABEL_REF
5111       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5112     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5113   else if (GOTOFF_P (operands[1]))
5114     {
5115       rtx unspec = XEXP (operands[1], 0);
5116
5117       if (! UNSPEC_GOTOFF_P (unspec))
5118         {
5119           unspec = XEXP (unspec, 0);
5120           if (! UNSPEC_GOTOFF_P (unspec))
5121             abort ();
5122         }
5123       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5124           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5125         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5126     }
5127 }")
5128
5129 (define_expand "movsi_const_16bit"
5130   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5131         (const:SI (sign_extend:SI
5132                    (truncate:HI
5133                     (match_operand:DI 1 "immediate_operand" "s")))))]
5134   "TARGET_SHMEDIA && flag_pic && reload_completed
5135    && GET_CODE (operands[1]) == SYMBOL_REF"
5136   "")
5137
5138 (define_split
5139   [(set (match_operand:SI 0 "arith_reg_dest" "")
5140         (match_operand:SI 1 "immediate_operand" ""))]
5141   "TARGET_SHMEDIA && reload_completed
5142    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5143   [(const_int 0)]
5144   "
5145 {
5146   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5147
5148   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5149
5150   DONE;
5151 }")
5152
5153 (define_split
5154   [(set (match_operand:SI 0 "register_operand" "")
5155         (match_operand:SI 1 "immediate_operand" ""))]
5156   "TARGET_SHMEDIA && reload_completed
5157    && ((GET_CODE (operands[1]) == CONST_INT
5158         && ! satisfies_constraint_I16 (operands[1]))
5159        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5160   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5161
5162 (define_expand "movsi"
5163   [(set (match_operand:SI 0 "general_movdst_operand" "")
5164         (match_operand:SI 1 "general_movsrc_operand" ""))]
5165   ""
5166   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5167
5168 (define_expand "ic_invalidate_line"
5169   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5170                                 (match_dup 1)] UNSPEC_ICACHE)
5171               (clobber (scratch:SI))])]
5172   "TARGET_HARD_SH4 || TARGET_SH5"
5173   "
5174 {
5175   if (TARGET_SHMEDIA)
5176     {
5177       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5178       DONE;
5179     }
5180   else if (TARGET_SHCOMPACT)
5181     {
5182       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5183       operands[1] = force_reg (Pmode, operands[1]);
5184       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5185       DONE;
5186     }
5187   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5188     {
5189       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5190       DONE;
5191     }
5192   operands[0] = force_reg (Pmode, operands[0]);
5193   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5194                                                                Pmode)));
5195 }")
5196
5197 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5198 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5199 ;; the requirement *1*00 for associative address writes.  The alignment of
5200 ;; %0 implies that its least significant bit is cleared,
5201 ;; thus we clear the V bit of a matching entry if there is one.
5202 (define_insn "ic_invalidate_line_i"
5203   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5204                      (match_operand:SI 1 "register_operand" "r")]
5205                      UNSPEC_ICACHE)
5206    (clobber (match_scratch:SI 2 "=&r"))]
5207   "TARGET_HARD_SH4"
5208   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5209   [(set_attr "length" "8")
5210    (set_attr "type" "cwb")])
5211
5212 (define_insn "ic_invalidate_line_sh4a"
5213   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5214                     UNSPEC_ICACHE)]
5215   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5216   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5217   [(set_attr "length" "16")
5218    (set_attr "type" "cwb")])
5219
5220 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5221 ;; an add in the code that calculates the address.
5222 (define_insn "ic_invalidate_line_media"
5223   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5224                     UNSPEC_ICACHE)]
5225   "TARGET_SHMEDIA"
5226   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5227   [(set_attr "length" "16")
5228    (set_attr "type" "invalidate_line_media")])
5229
5230 (define_insn "ic_invalidate_line_compact"
5231   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5232                      (match_operand:SI 1 "register_operand" "r")]
5233                     UNSPEC_ICACHE)
5234    (clobber (reg:SI PR_REG))]
5235   "TARGET_SHCOMPACT"
5236   "jsr @%1%#"
5237   [(set_attr "type" "sfunc")
5238    (set_attr "needs_delay_slot" "yes")])
5239
5240 (define_expand "initialize_trampoline"
5241   [(match_operand:SI 0 "" "")
5242    (match_operand:SI 1 "" "")
5243    (match_operand:SI 2 "" "")]
5244   "TARGET_SHCOMPACT"
5245   "
5246 {
5247   rtx sfun, tramp;
5248
5249   tramp = force_reg (Pmode, operands[0]);
5250   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5251                                             SFUNC_STATIC));
5252   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5253   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5254
5255   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5256   DONE;
5257 }")
5258
5259 (define_insn "initialize_trampoline_compact"
5260   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5261                      (match_operand:SI 1 "register_operand" "r")
5262                      (reg:SI R2_REG) (reg:SI R3_REG)]
5263                     UNSPEC_INIT_TRAMP)
5264
5265    (clobber (reg:SI PR_REG))]
5266   "TARGET_SHCOMPACT"
5267   "jsr @%1%#"
5268   [(set_attr "type" "sfunc")
5269    (set_attr "needs_delay_slot" "yes")])
5270
5271 (define_insn "movqi_i"
5272   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5273         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5274   "TARGET_SH1
5275    && (arith_reg_operand (operands[0], QImode)
5276        || arith_reg_operand (operands[1], QImode))"
5277   "@
5278         mov     %1,%0
5279         mov     %1,%0
5280         mov.b   %1,%0
5281         mov.b   %1,%0
5282         movt    %0
5283         sts     %1,%0
5284         lds     %1,%0"
5285  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5286
5287 (define_insn "*movqi_media"
5288   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5289         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5290   "TARGET_SHMEDIA
5291    && (arith_reg_operand (operands[0], QImode)
5292        || extend_reg_or_0_operand (operands[1], QImode))"
5293   "@
5294         add.l   %1, r63, %0
5295         movi    %1, %0
5296         ld%M1.ub        %m1, %0
5297         st%M0.b %m0, %N1"
5298   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5299    (set (attr "highpart")
5300         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5301                (const_string "user")]
5302               (const_string "ignore")))])
5303
5304 (define_expand "movqi"
5305   [(set (match_operand:QI 0 "general_operand" "")
5306         (match_operand:QI 1 "general_operand"  ""))]
5307   ""
5308   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5309
5310 (define_expand "reload_inqi"
5311   [(set (match_operand:SI 2 "" "=&r")
5312         (match_operand:QI 1 "inqhi_operand" ""))
5313    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5314         (truncate:QI (match_dup 3)))]
5315   "TARGET_SHMEDIA"
5316   "
5317 {
5318   rtx inner = XEXP (operands[1], 0);
5319   int regno = REGNO (inner);
5320
5321   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5322   operands[1] = gen_rtx_REG (SImode, regno);
5323   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5324 }")
5325
5326 /* When storing r0, we have to avoid reg+reg addressing.  */
5327 (define_insn "movhi_i"
5328   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5329         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5330   "TARGET_SH1
5331    && (arith_reg_operand (operands[0], HImode)
5332        || arith_reg_operand (operands[1], HImode))
5333    && (GET_CODE (operands[0]) != MEM
5334        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5335        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5336        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5337   "@
5338         mov.w   %1,%0
5339         mov     %1,%0
5340         mov.w   %1,%0
5341         movt    %0
5342         mov.w   %1,%0
5343         sts     %1,%0
5344         lds     %1,%0
5345         fake    %1,%0"
5346   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5347
5348 (define_insn "*movhi_media"
5349   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5350         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5351   "TARGET_SHMEDIA
5352    && (arith_reg_operand (operands[0], HImode)
5353        || arith_reg_or_0_operand (operands[1], HImode))"
5354   "@
5355         add.l   %1, r63, %0
5356         movi    %1, %0
5357         #
5358         ld%M1.w %m1, %0
5359         st%M0.w %m0, %N1"
5360   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5361    (set (attr "highpart")
5362         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5363                (const_string "user")]
5364               (const_string "ignore")))])
5365
5366 (define_split
5367   [(set (match_operand:HI 0 "register_operand" "")
5368         (match_operand:HI 1 "immediate_operand" ""))]
5369   "TARGET_SHMEDIA && reload_completed
5370    && ! satisfies_constraint_I16 (operands[1])"
5371   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5372
5373 (define_expand "movhi"
5374   [(set (match_operand:HI 0 "general_movdst_operand" "")
5375         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5376   ""
5377   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5378
5379 (define_expand "reload_inhi"
5380   [(set (match_operand:SI 2 "" "=&r")
5381         (match_operand:HI 1 "inqhi_operand" ""))
5382    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5383         (truncate:HI (match_dup 3)))]
5384   "TARGET_SHMEDIA"
5385   "
5386 {
5387   rtx inner = XEXP (operands[1], 0);
5388   int regno = REGNO (inner);
5389
5390   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5391   operands[1] = gen_rtx_REG (SImode, regno);
5392   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5393 }")
5394
5395 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5396 ;; compiled with -m2 -ml -O3 -funroll-loops
5397 (define_insn "*movdi_i"
5398   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5399         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5400   "TARGET_SH1
5401    && (arith_reg_operand (operands[0], DImode)
5402        || arith_reg_operand (operands[1], DImode))"
5403   "* return output_movedouble (insn, operands, DImode);"
5404   [(set_attr "length" "4")
5405    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5406
5407 ;; If the output is a register and the input is memory or a register, we have
5408 ;; to be careful and see which word needs to be loaded first.
5409
5410 (define_split
5411   [(set (match_operand:DI 0 "general_movdst_operand" "")
5412         (match_operand:DI 1 "general_movsrc_operand" ""))]
5413   "TARGET_SH1 && reload_completed"
5414   [(set (match_dup 2) (match_dup 3))
5415    (set (match_dup 4) (match_dup 5))]
5416   "
5417 {
5418   int regno;
5419
5420   if ((GET_CODE (operands[0]) == MEM
5421        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5422       || (GET_CODE (operands[1]) == MEM
5423           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5424     FAIL;
5425
5426   switch (GET_CODE (operands[0]))
5427     {
5428     case REG:
5429       regno = REGNO (operands[0]);
5430       break;
5431     case SUBREG:
5432       regno = subreg_regno (operands[0]);
5433       break;
5434     case MEM:
5435       regno = -1;
5436       break;
5437     default:
5438       gcc_unreachable ();
5439     }
5440
5441   if (regno == -1
5442       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5443     {
5444       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5445       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5446       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5447       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5448     }
5449   else
5450     {
5451       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5452       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5453       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5454       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5455     }
5456
5457   if (operands[2] == 0 || operands[3] == 0
5458       || operands[4] == 0 || operands[5] == 0)
5459     FAIL;
5460 }")
5461
5462 ;; The '?'s in the following constraints may not reflect the time taken
5463 ;; to perform the move. They are there to discourage the use of floating-
5464 ;; point registers for storing integer values.
5465 (define_insn "*movdi_media"
5466   [(set (match_operand:DI 0 "general_movdst_operand"
5467                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5468         (match_operand:DI 1 "general_movsrc_operand"
5469          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5470   "TARGET_SHMEDIA_FPU
5471    && (register_operand (operands[0], DImode)
5472        || sh_register_operand (operands[1], DImode))"
5473   "@
5474         add     %1, r63, %0
5475         movi    %1, %0
5476         #
5477         ld%M1.q %m1, %0
5478         st%M0.q %m0, %N1
5479         fld%M1.d        %m1, %0
5480         fst%M0.d        %m0, %1
5481         fmov.qd %N1, %0
5482         fmov.dq %1, %0
5483         fmov.d  %1, %0
5484         ptabs   %1, %0
5485         gettr   %1, %0
5486         pt      %1, %0"
5487   [(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")
5488    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5489
5490 (define_insn "*movdi_media_nofpu"
5491   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5492         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5493   "TARGET_SHMEDIA
5494    && (register_operand (operands[0], DImode)
5495        || sh_register_operand (operands[1], DImode))"
5496   "@
5497         add     %1, r63, %0
5498         movi    %1, %0
5499         #
5500         ld%M1.q %m1, %0
5501         st%M0.q %m0, %N1
5502         ptabs   %1, %0
5503         gettr   %1, %0
5504         pt      %1, %0"
5505   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5506    (set_attr "length" "4,4,16,4,4,4,4,*")])
5507
5508 (define_insn "*movdi_media_I16"
5509   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5510         (match_operand:DI 1 "const_int_operand" "I16"))]
5511   "TARGET_SHMEDIA && reload_completed"
5512   "movi %1, %0"
5513   [(set_attr "type" "arith_media")
5514    (set_attr "length" "4")])
5515
5516 (define_split
5517   [(set (match_operand:DI 0 "arith_reg_dest" "")
5518         (match_operand:DI 1 "immediate_operand" ""))]
5519   "TARGET_SHMEDIA && reload_completed
5520    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5521   [(set (match_dup 0) (match_dup 1))]
5522   "
5523 {
5524   rtx insn;
5525
5526   if (TARGET_SHMEDIA64)
5527     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5528   else
5529     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5530
5531   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5532
5533   DONE;
5534 }")
5535
5536 (define_expand "movdi_const"
5537   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5538         (const:DI (sign_extend:DI
5539                    (truncate:HI
5540                     (ashiftrt:DI
5541                      (match_operand:DI 1 "immediate_operand" "s")
5542                      (const_int 48))))))
5543    (set (match_dup 0)
5544         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5545                 (const:DI
5546                  (zero_extend:DI
5547                   (truncate:HI
5548                    (ashiftrt:SI
5549                     (match_dup 1)
5550                     (const_int 32)))))))
5551    (set (match_dup 0)
5552         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5553                 (const:DI
5554                  (zero_extend:DI
5555                   (truncate:HI
5556                    (ashiftrt:SI
5557                     (match_dup 1)
5558                     (const_int 16)))))))
5559    (set (match_dup 0)
5560         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5561                 (const:DI
5562                  (zero_extend:DI
5563                   (truncate:HI
5564                    (match_dup 1))))))]
5565   "TARGET_SHMEDIA64 && reload_completed
5566    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5567   "
5568 {
5569   sh_mark_label (operands[1], 4);
5570 }")
5571
5572 (define_expand "movdi_const_32bit"
5573   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5574         (const:DI (sign_extend:DI
5575                    (truncate:HI
5576                     (ashiftrt:DI
5577                      (match_operand:DI 1 "immediate_operand" "s")
5578                      (const_int 16))))))
5579    (set (match_dup 0)
5580         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5581                 (const:DI
5582                  (zero_extend:DI
5583                   (truncate:HI
5584                    (match_dup 1))))))]
5585   "TARGET_SHMEDIA32 && reload_completed
5586    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5587   "
5588 {
5589   sh_mark_label (operands[1], 2);
5590 }")
5591
5592 (define_expand "movdi_const_16bit"
5593   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5594         (const:DI (sign_extend:DI
5595                    (truncate:HI
5596                     (match_operand:DI 1 "immediate_operand" "s")))))]
5597   "TARGET_SHMEDIA && flag_pic && reload_completed
5598    && GET_CODE (operands[1]) == SYMBOL_REF"
5599   "")
5600
5601 (define_split
5602   [(set (match_operand:DI 0 "ext_dest_operand" "")
5603         (match_operand:DI 1 "immediate_operand" ""))]
5604   "TARGET_SHMEDIA && reload_completed
5605    && GET_CODE (operands[1]) == CONST_INT
5606    && ! satisfies_constraint_I16 (operands[1])"
5607   [(set (match_dup 0) (match_dup 2))
5608    (match_dup 1)]
5609   "
5610 {
5611   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5612   unsigned HOST_WIDE_INT low = val;
5613   unsigned HOST_WIDE_INT high = val;
5614   unsigned HOST_WIDE_INT sign;
5615   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5616
5617   /* Zero-extend the 16 least-significant bits.  */
5618   low &= 0xffff;
5619
5620   /* Arithmetic shift right the word by 16 bits.  */
5621   high >>= 16;
5622   if (GET_CODE (operands[0]) == SUBREG
5623       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5624     {
5625       high &= 0xffff;
5626       high ^= 0x8000;
5627       high -= 0x8000;
5628     }
5629   else
5630     {
5631       sign = 1;
5632       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5633       high ^= sign;
5634       high -= sign;
5635     }
5636   do
5637     {
5638       /* If we can't generate the constant with a two-insn movi / shori
5639          sequence, try some other strategies.  */
5640       if (! CONST_OK_FOR_I16 (high))
5641         {
5642           /* Try constant load / left shift.  We know VAL != 0.  */
5643           val2 = val ^ (val-1);
5644           if (val2 > 0x1ffff)
5645             {
5646               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5647
5648               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5649                   || (! CONST_OK_FOR_I16 (high >> 16)
5650                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5651                 {
5652                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5653                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5654                                                    GEN_INT (trailing_zeroes));
5655                   break;
5656                 }
5657             }
5658           /* Try constant load / right shift.  */
5659           val2 = (val >> 15) + 1;
5660           if (val2 == (val2 & -val2))
5661             {
5662               int shift = 49 - exact_log2 (val2);
5663
5664               val2 = trunc_int_for_mode (val << shift, DImode);
5665               if (CONST_OK_FOR_I16 (val2))
5666                 {
5667                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5668                                                    GEN_INT (shift));
5669                   break;
5670                 }
5671             }
5672           /* Try mperm.w .  */
5673           val2 = val & 0xffff;
5674           if ((val >> 16 & 0xffff) == val2
5675               && (val >> 32 & 0xffff) == val2
5676               && (val >> 48 & 0xffff) == val2)
5677             {
5678               val2 = (HOST_WIDE_INT) val >> 48;
5679               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5680               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5681               break;
5682             }
5683           /* Try movi / mshflo.l  */
5684           val2 = (HOST_WIDE_INT) val >> 32;
5685           if (val2 == ((unsigned HOST_WIDE_INT)
5686                         trunc_int_for_mode (val, SImode)))
5687             {
5688               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5689                                              operands[0]);
5690               break;
5691             }
5692           /* Try movi / mshflo.l w/ r63.  */
5693           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5694           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5695             {
5696               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5697                                              const0_rtx);
5698               break;
5699             }
5700         }
5701       val2 = high;
5702       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5703     }
5704   while (0);
5705   operands[2] = GEN_INT (val2);
5706 }")
5707
5708 (define_split
5709   [(set (match_operand:DI 0 "ext_dest_operand" "")
5710         (match_operand:DI 1 "immediate_operand" ""))]
5711   "TARGET_SHMEDIA && reload_completed
5712    && GET_CODE (operands[1]) == CONST_DOUBLE"
5713   [(set (match_dup 0) (match_dup 2))
5714   (set (match_dup 0)
5715        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5716   "
5717 {
5718   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5719   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5720   unsigned HOST_WIDE_INT val = low;
5721   unsigned HOST_WIDE_INT sign;
5722
5723   /* Zero-extend the 16 least-significant bits.  */
5724   val &= 0xffff;
5725   operands[1] = GEN_INT (val);
5726
5727   /* Arithmetic shift right the double-word by 16 bits.  */
5728   low >>= 16;
5729   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5730   high >>= 16;
5731   sign = 1;
5732   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5733   high ^= sign;
5734   high -= sign;
5735
5736   /* This will only be true if high is a sign-extension of low, i.e.,
5737      it must be either 0 or (unsigned)-1, and be zero iff the
5738      most-significant bit of low is set.  */
5739   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5740     operands[2] = GEN_INT (low);
5741   else
5742     operands[2] = immed_double_const (low, high, DImode);
5743 }")
5744
5745 (define_insn "shori_media"
5746   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5747         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5748                            (const_int 16))
5749                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5750   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5751   "@
5752         shori   %u2, %0
5753         #"
5754   [(set_attr "type" "arith_media,*")])
5755
5756 (define_insn "*shori_media_si"
5757   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5758         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5759                            (const_int 16))
5760                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5761   "TARGET_SHMEDIA"
5762   "shori        %u2, %0")
5763
5764 (define_expand "movdi"
5765   [(set (match_operand:DI 0 "general_movdst_operand" "")
5766         (match_operand:DI 1 "general_movsrc_operand" ""))]
5767   ""
5768   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5769
5770 (define_insn "movdf_media"
5771   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5772         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5773   "TARGET_SHMEDIA_FPU
5774    && (register_operand (operands[0], DFmode)
5775        || sh_register_operand (operands[1], DFmode))"
5776   "@
5777         fmov.d  %1, %0
5778         fmov.qd %N1, %0
5779         fmov.dq %1, %0
5780         add     %1, r63, %0
5781         #
5782         fld%M1.d        %m1, %0
5783         fst%M0.d        %m0, %1
5784         ld%M1.q %m1, %0
5785         st%M0.q %m0, %N1"
5786   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5787
5788 (define_insn "movdf_media_nofpu"
5789   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5790         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5791   "TARGET_SHMEDIA
5792    && (register_operand (operands[0], DFmode)
5793        || sh_register_operand (operands[1], DFmode))"
5794   "@
5795         add     %1, r63, %0
5796         #
5797         ld%M1.q %m1, %0
5798         st%M0.q %m0, %N1"
5799   [(set_attr "type" "arith_media,*,load_media,store_media")])
5800
5801 (define_split
5802   [(set (match_operand:DF 0 "arith_reg_dest" "")
5803         (match_operand:DF 1 "immediate_operand" ""))]
5804   "TARGET_SHMEDIA && reload_completed"
5805   [(set (match_dup 3) (match_dup 2))]
5806   "
5807 {
5808   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5809   long values[2];
5810   REAL_VALUE_TYPE value;
5811
5812   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5813   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5814
5815   if (HOST_BITS_PER_WIDE_INT >= 64)
5816     operands[2] = immed_double_const ((unsigned long) values[endian]
5817                                       | ((HOST_WIDE_INT) values[1 - endian]
5818                                          << 32), 0, DImode);
5819   else
5820     {
5821       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5822       operands[2] = immed_double_const (values[endian], values[1 - endian],
5823                                         DImode);
5824     }
5825
5826   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5827 }")
5828
5829 ;; ??? This should be a define expand.
5830
5831 (define_insn "movdf_k"
5832   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5833         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5834   "TARGET_SH1
5835    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5836        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5837        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5838        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5839    && (arith_reg_operand (operands[0], DFmode)
5840        || arith_reg_operand (operands[1], DFmode))"
5841   "* return output_movedouble (insn, operands, DFmode);"
5842   [(set_attr "length" "4")
5843    (set_attr "type" "move,pcload,load,store")])
5844
5845 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5846 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5847 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5848 ;; the d/m/c/X alternative, which is split later into single-precision
5849 ;; instructions.  And when not optimizing, no splits are done before fixing
5850 ;; up pcloads, so we need usable length information for that.
5851 (define_insn "movdf_i4"
5852   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5853         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5854    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5855    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5856   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5857    && (arith_reg_operand (operands[0], DFmode)
5858        || arith_reg_operand (operands[1], DFmode))"
5859   "@
5860         fmov    %1,%0
5861         #
5862         #
5863         fmov.d  %1,%0
5864         fmov.d  %1,%0
5865         #
5866         #
5867         #
5868         #
5869         #"
5870   [(set_attr_alternative "length"
5871      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5872       (const_int 4)
5873       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5874       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5875       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5876       (const_int 4)
5877       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5878       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5879       ;; increment or decrement r15 explicitly.
5880       (if_then_else
5881        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5882        (const_int 10) (const_int 8))
5883       (if_then_else
5884        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5885        (const_int 10) (const_int 8))])
5886    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5887    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5888    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5889                                            (const_string "double")
5890                                            (const_string "none")))])
5891
5892 ;; Moving DFmode between fp/general registers through memory
5893 ;; (the top of the stack) is faster than moving through fpul even for
5894 ;; little endian.  Because the type of an instruction is important for its
5895 ;; scheduling,  it is beneficial to split these operations, rather than
5896 ;; emitting them in one single chunk, even if this will expose a stack
5897 ;; use that will prevent scheduling of other stack accesses beyond this
5898 ;; instruction.
5899 (define_split
5900   [(set (match_operand:DF 0 "register_operand" "")
5901         (match_operand:DF 1 "register_operand" ""))
5902    (use (match_operand:PSI 2 "fpscr_operand" ""))
5903    (clobber (match_scratch:SI 3 "=X"))]
5904   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5905    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5906   [(const_int 0)]
5907   "
5908 {
5909   rtx insn, tos;
5910
5911   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5912     {
5913       emit_move_insn (stack_pointer_rtx,
5914                       plus_constant (stack_pointer_rtx, -8));
5915       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5916     }
5917   else
5918     tos = gen_tmp_stack_mem (DFmode,
5919                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5920   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5921   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5922     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5923   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5924     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5925   else
5926     tos = gen_tmp_stack_mem (DFmode,
5927                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5928   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5929   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5930     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5931   else
5932     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5933   DONE;
5934 }")
5935
5936 ;; local-alloc sometimes allocates scratch registers even when not required,
5937 ;; so we must be prepared to handle these.
5938
5939 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5940 (define_split
5941   [(set (match_operand:DF 0 "general_movdst_operand" "")
5942         (match_operand:DF 1 "general_movsrc_operand"  ""))
5943    (use (match_operand:PSI 2 "fpscr_operand" ""))
5944    (clobber (match_scratch:SI 3 ""))]
5945   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5946    && reload_completed
5947    && true_regnum (operands[0]) < 16
5948    && true_regnum (operands[1]) < 16"
5949   [(set (match_dup 0) (match_dup 1))]
5950   "
5951 {
5952   /* If this was a reg <-> mem operation with base + index reg addressing,
5953      we have to handle this in a special way.  */
5954   rtx mem = operands[0];
5955   int store_p = 1;
5956   if (! memory_operand (mem, DFmode))
5957     {
5958       mem = operands[1];
5959       store_p = 0;
5960     }
5961   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5962     mem = SUBREG_REG (mem);
5963   if (GET_CODE (mem) == MEM)
5964     {
5965       rtx addr = XEXP (mem, 0);
5966       if (GET_CODE (addr) == PLUS
5967           && GET_CODE (XEXP (addr, 0)) == REG
5968           && GET_CODE (XEXP (addr, 1)) == REG)
5969         {
5970           int offset;
5971           rtx reg0 = gen_rtx_REG (Pmode, 0);
5972           rtx regop = operands[store_p], word0 ,word1;
5973
5974           if (GET_CODE (regop) == SUBREG)
5975             alter_subreg (&regop);
5976           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5977             offset = 2;
5978           else
5979             offset = 4;
5980           mem = copy_rtx (mem);
5981           PUT_MODE (mem, SImode);
5982           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5983           alter_subreg (&word0);
5984           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5985           alter_subreg (&word1);
5986           if (store_p || ! refers_to_regno_p (REGNO (word0),
5987                                               REGNO (word0) + 1, addr, 0))
5988             {
5989               emit_insn (store_p
5990                          ? gen_movsi_ie (mem, word0)
5991                          : gen_movsi_ie (word0, mem));
5992               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5993               mem = copy_rtx (mem);
5994               emit_insn (store_p
5995                          ? gen_movsi_ie (mem, word1)
5996                          : gen_movsi_ie (word1, mem));
5997               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5998             }
5999           else
6000             {
6001               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6002               emit_insn (gen_movsi_ie (word1, mem));
6003               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6004               mem = copy_rtx (mem);
6005               emit_insn (gen_movsi_ie (word0, mem));
6006             }
6007           DONE;
6008         }
6009     }
6010 }")
6011
6012 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6013 (define_split
6014   [(set (match_operand:DF 0 "register_operand" "")
6015         (match_operand:DF 1 "memory_operand"  ""))
6016    (use (match_operand:PSI 2 "fpscr_operand" ""))
6017    (clobber (reg:SI R0_REG))]
6018   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6019   [(parallel [(set (match_dup 0) (match_dup 1))
6020               (use (match_dup 2))
6021               (clobber (scratch:SI))])]
6022   "")
6023
6024 (define_expand "reload_indf__frn"
6025   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6026                    (match_operand:DF 1 "immediate_operand" "FQ"))
6027               (use (reg:PSI FPSCR_REG))
6028               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6029   "TARGET_SH1"
6030   "")
6031
6032 (define_expand "reload_outdf__RnFRm"
6033   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6034                    (match_operand:DF 1 "register_operand" "af,r"))
6035               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6036   "TARGET_SH1"
6037   "")
6038
6039 ;; Simplify no-op moves.
6040 (define_split
6041   [(set (match_operand:SF 0 "register_operand" "")
6042         (match_operand:SF 1 "register_operand" ""))
6043    (use (match_operand:PSI 2 "fpscr_operand" ""))
6044    (clobber (match_scratch:SI 3 ""))]
6045   "TARGET_SH2E && reload_completed
6046    && true_regnum (operands[0]) == true_regnum (operands[1])"
6047   [(set (match_dup 0) (match_dup 0))]
6048   "")
6049
6050 ;; fmovd substitute post-reload splits
6051 (define_split
6052   [(set (match_operand:DF 0 "register_operand" "")
6053         (match_operand:DF 1 "register_operand" ""))
6054    (use (match_operand:PSI 2 "fpscr_operand" ""))
6055    (clobber (match_scratch:SI 3 ""))]
6056   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6057    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6058    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6059   [(const_int 0)]
6060   "
6061 {
6062   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6063   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6064                            gen_rtx_REG (SFmode, src), operands[2]));
6065   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6066                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6067   DONE;
6068 }")
6069
6070 (define_split
6071   [(set (match_operand:DF 0 "register_operand" "")
6072         (mem:DF (match_operand:SI 1 "register_operand" "")))
6073    (use (match_operand:PSI 2 "fpscr_operand" ""))
6074    (clobber (match_scratch:SI 3 ""))]
6075   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6076    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6077    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6078   [(const_int 0)]
6079   "
6080 {
6081   int regno = true_regnum (operands[0]);
6082   rtx insn;
6083   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6084   rtx mem2
6085     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6086   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6087                                            regno + !! TARGET_LITTLE_ENDIAN),
6088                                   mem2, operands[2]));
6089   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6090   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6091                                                regno + ! TARGET_LITTLE_ENDIAN),
6092                                   change_address (mem, SFmode, NULL_RTX),
6093                                   operands[2]));
6094   DONE;
6095 }")
6096
6097 (define_split
6098   [(set (match_operand:DF 0 "register_operand" "")
6099         (match_operand:DF 1 "memory_operand" ""))
6100    (use (match_operand:PSI 2 "fpscr_operand" ""))
6101    (clobber (match_scratch:SI 3 ""))]
6102   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6103    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6104   [(const_int 0)]
6105   "
6106 {
6107   int regno = true_regnum (operands[0]);
6108   rtx addr, insn, adjust = NULL_RTX;
6109   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6110   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6111   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6112
6113   operands[1] = copy_rtx (mem2);
6114   addr = XEXP (mem2, 0);
6115   if (GET_CODE (addr) != POST_INC)
6116     {
6117       /* If we have to modify the stack pointer, the value that we have
6118          read with post-increment might be modified by an interrupt,
6119          so write it back.  */
6120       if (REGNO (addr) == STACK_POINTER_REGNUM)
6121         adjust = gen_push_e (reg0);
6122       else
6123         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6124       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6125     }
6126   addr = XEXP (addr, 0);
6127   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6128   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6129   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6130   if (adjust)
6131     emit_insn (adjust);
6132   else
6133     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6134   DONE;
6135 }")
6136
6137 (define_split
6138   [(set (match_operand:DF 0 "memory_operand" "")
6139         (match_operand:DF 1 "register_operand" ""))
6140    (use (match_operand:PSI 2 "fpscr_operand" ""))
6141    (clobber (match_scratch:SI 3 ""))]
6142   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6143    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6144   [(const_int 0)]
6145   "
6146 {
6147   int regno = true_regnum (operands[1]);
6148   rtx insn, addr, adjust = NULL_RTX;
6149
6150   operands[0] = copy_rtx (operands[0]);
6151   PUT_MODE (operands[0], SFmode);
6152   insn = emit_insn (gen_movsf_ie (operands[0],
6153                                   gen_rtx_REG (SFmode,
6154                                            regno + ! TARGET_LITTLE_ENDIAN),
6155                                   operands[2]));
6156   operands[0] = copy_rtx (operands[0]);
6157   addr = XEXP (operands[0], 0);
6158   if (GET_CODE (addr) != PRE_DEC)
6159     {
6160       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6161       emit_insn_before (adjust, insn);
6162       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6163     }
6164   addr = XEXP (addr, 0);
6165   if (! adjust)
6166     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6167   insn = emit_insn (gen_movsf_ie (operands[0],
6168                                   gen_rtx_REG (SFmode,
6169                                            regno + !! TARGET_LITTLE_ENDIAN),
6170                                   operands[2]));
6171   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6172   DONE;
6173 }")
6174
6175 ;; If the output is a register and the input is memory or a register, we have
6176 ;; to be careful and see which word needs to be loaded first.
6177
6178 (define_split
6179   [(set (match_operand:DF 0 "general_movdst_operand" "")
6180         (match_operand:DF 1 "general_movsrc_operand" ""))]
6181   "TARGET_SH1 && reload_completed"
6182   [(set (match_dup 2) (match_dup 3))
6183    (set (match_dup 4) (match_dup 5))]
6184   "
6185 {
6186   int regno;
6187
6188   if ((GET_CODE (operands[0]) == MEM
6189        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6190       || (GET_CODE (operands[1]) == MEM
6191           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6192     FAIL;
6193
6194   switch (GET_CODE (operands[0]))
6195     {
6196     case REG:
6197       regno = REGNO (operands[0]);
6198       break;
6199     case SUBREG:
6200       regno = subreg_regno (operands[0]);
6201       break;
6202     case MEM:
6203       regno = -1;
6204       break;
6205     default:
6206       gcc_unreachable ();
6207     }
6208
6209   if (regno == -1
6210       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6211     {
6212       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6213       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6214       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6215       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6216     }
6217   else
6218     {
6219       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6220       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6221       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6222       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6223     }
6224
6225   if (operands[2] == 0 || operands[3] == 0
6226       || operands[4] == 0 || operands[5] == 0)
6227     FAIL;
6228 }")
6229
6230 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6231 ;; used only once, let combine add in the index again.
6232
6233 (define_split
6234   [(set (match_operand:SI 0 "register_operand" "")
6235         (match_operand:SI 1 "" ""))
6236    (clobber (match_operand 2 "register_operand" ""))]
6237   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6238    && ALLOW_INDEXED_ADDRESS"
6239   [(use (reg:SI R0_REG))]
6240   "
6241 {
6242   rtx addr, reg, const_int;
6243
6244   if (GET_CODE (operands[1]) != MEM)
6245     FAIL;
6246   addr = XEXP (operands[1], 0);
6247   if (GET_CODE (addr) != PLUS)
6248     FAIL;
6249   reg = XEXP (addr, 0);
6250   const_int = XEXP (addr, 1);
6251   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6252          && GET_CODE (const_int) == CONST_INT))
6253     FAIL;
6254   emit_move_insn (operands[2], const_int);
6255   emit_move_insn (operands[0],
6256                   change_address (operands[1], VOIDmode,
6257                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6258   DONE;
6259 }")
6260
6261 (define_split
6262   [(set (match_operand:SI 1 "" "")
6263         (match_operand:SI 0 "register_operand" ""))
6264    (clobber (match_operand 2 "register_operand" ""))]
6265   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6266    && ALLOW_INDEXED_ADDRESS"
6267   [(use (reg:SI R0_REG))]
6268   "
6269 {
6270   rtx addr, reg, const_int;
6271
6272   if (GET_CODE (operands[1]) != MEM)
6273     FAIL;
6274   addr = XEXP (operands[1], 0);
6275   if (GET_CODE (addr) != PLUS)
6276     FAIL;
6277   reg = XEXP (addr, 0);
6278   const_int = XEXP (addr, 1);
6279   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6280          && GET_CODE (const_int) == CONST_INT))
6281     FAIL;
6282   emit_move_insn (operands[2], const_int);
6283   emit_move_insn (change_address (operands[1], VOIDmode,
6284                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6285                   operands[0]);
6286   DONE;
6287 }")
6288
6289 (define_expand "movdf"
6290   [(set (match_operand:DF 0 "general_movdst_operand" "")
6291         (match_operand:DF 1 "general_movsrc_operand" ""))]
6292   ""
6293   "
6294 {
6295   if (prepare_move_operands (operands, DFmode)) DONE;
6296   if (TARGET_SHMEDIA)
6297     {
6298       if (TARGET_SHMEDIA_FPU)
6299         emit_insn (gen_movdf_media (operands[0], operands[1]));
6300       else
6301         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6302       DONE;
6303     }
6304   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6305     {
6306       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6307       DONE;
6308     }
6309 }")
6310
6311 ;;This is incompatible with the way gcc uses subregs.
6312 ;;(define_insn "movv2sf_i"
6313 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6314 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6315 ;;  "TARGET_SHMEDIA_FPU
6316 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6317 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6318 ;;  "@
6319 ;;      #
6320 ;;      fld%M1.p        %m1, %0
6321 ;;      fst%M0.p        %m0, %1"
6322 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6323
6324 (define_insn_and_split "movv2sf_i"
6325   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6326         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6327   "TARGET_SHMEDIA_FPU"
6328   "#"
6329   "TARGET_SHMEDIA_FPU && reload_completed"
6330   [(set (match_dup 0) (match_dup 1))]
6331   "
6332 {
6333   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6334   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6335 }")
6336
6337 (define_expand "movv2sf"
6338   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6339         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6340   "TARGET_SHMEDIA_FPU"
6341   "
6342 {
6343   if (prepare_move_operands (operands, V2SFmode))
6344     DONE;
6345 }")
6346
6347 (define_expand "addv2sf3"
6348   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6349    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6350    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6351   "TARGET_SHMEDIA_FPU"
6352   "
6353 {
6354   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6355   DONE;
6356 }")
6357
6358 (define_expand "subv2sf3"
6359   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6360    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6361    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6362   "TARGET_SHMEDIA_FPU"
6363   "
6364 {
6365   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6366   DONE;
6367 }")
6368
6369 (define_expand "mulv2sf3"
6370   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6371    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6372    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6373   "TARGET_SHMEDIA_FPU"
6374   "
6375 {
6376   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6377   DONE;
6378 }")
6379
6380 (define_expand "divv2sf3"
6381   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6382    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6383    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6384   "TARGET_SHMEDIA_FPU"
6385   "
6386 {
6387   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6388   DONE;
6389 }")
6390
6391 (define_insn_and_split "*movv4sf_i"
6392   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6393         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6394   "TARGET_SHMEDIA_FPU"
6395   "#"
6396   "&& reload_completed"
6397   [(const_int 0)]
6398   "
6399 {
6400   int i;
6401
6402   for (i = 0; i < 4/2; i++)
6403     {
6404       rtx x, y;
6405
6406       if (GET_CODE (operands[0]) == MEM)
6407         x = adjust_address (operands[0], V2SFmode,
6408                             i * GET_MODE_SIZE (V2SFmode));
6409       else
6410         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6411
6412       if (GET_CODE (operands[1]) == MEM)
6413         y = adjust_address (operands[1], V2SFmode,
6414                             i * GET_MODE_SIZE (V2SFmode));
6415       else
6416         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6417
6418       emit_insn (gen_movv2sf_i (x, y));
6419     }
6420
6421   DONE;
6422 }"
6423   [(set_attr "length" "8")])
6424
6425 (define_expand "movv4sf"
6426   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6427         (match_operand:V4SF 1 "general_operand" ""))]
6428   "TARGET_SHMEDIA_FPU"
6429   "
6430 {
6431   if (prepare_move_operands (operands, V4SFmode))
6432     DONE;
6433 }")
6434
6435 (define_insn_and_split "*movv16sf_i"
6436   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6437         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6438   "TARGET_SHMEDIA_FPU"
6439   "#"
6440   "&& reload_completed"
6441   [(const_int 0)]
6442   "
6443 {
6444   int i;
6445
6446   for (i = 0; i < 16/2; i++)
6447     {
6448       rtx x,y;
6449
6450       if (GET_CODE (operands[0]) == MEM)
6451         x = adjust_address (operands[0], V2SFmode,
6452                             i * GET_MODE_SIZE (V2SFmode));
6453       else
6454         {
6455           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6456           alter_subreg (&x);
6457         }
6458
6459       if (GET_CODE (operands[1]) == MEM)
6460         y = adjust_address (operands[1], V2SFmode,
6461                             i * GET_MODE_SIZE (V2SFmode));
6462       else
6463         {
6464           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6465           alter_subreg (&y);
6466         }
6467
6468       emit_insn (gen_movv2sf_i (x, y));
6469     }
6470
6471   DONE;
6472 }"
6473   [(set_attr "length" "32")])
6474
6475 (define_expand "movv16sf"
6476   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6477         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6478   "TARGET_SHMEDIA_FPU"
6479   "
6480 {
6481   if (prepare_move_operands (operands, V16SFmode))
6482     DONE;
6483 }")
6484
6485 (define_insn "movsf_media"
6486   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6487         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6488   "TARGET_SHMEDIA_FPU
6489    && (register_operand (operands[0], SFmode)
6490        || sh_register_operand (operands[1], SFmode))"
6491   "@
6492         fmov.s  %1, %0
6493         fmov.ls %N1, %0
6494         fmov.sl %1, %0
6495         add.l   %1, r63, %0
6496         #
6497         fld%M1.s        %m1, %0
6498         fst%M0.s        %m0, %1
6499         ld%M1.l %m1, %0
6500         st%M0.l %m0, %N1"
6501   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6502    (set (attr "highpart")
6503         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6504                (const_string "user")]
6505               (const_string "ignore")))])
6506
6507 (define_insn "movsf_media_nofpu"
6508   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6509         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6510   "TARGET_SHMEDIA
6511    && (register_operand (operands[0], SFmode)
6512        || sh_register_operand (operands[1], SFmode))"
6513   "@
6514         add.l   %1, r63, %0
6515         #
6516         ld%M1.l %m1, %0
6517         st%M0.l %m0, %N1"
6518   [(set_attr "type" "arith_media,*,load_media,store_media")
6519    (set (attr "highpart")
6520         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6521                (const_string "user")]
6522               (const_string "ignore")))])
6523
6524 (define_split
6525   [(set (match_operand:SF 0 "arith_reg_dest" "")
6526         (match_operand:SF 1 "immediate_operand" ""))]
6527   "TARGET_SHMEDIA && reload_completed
6528    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6529   [(set (match_dup 3) (match_dup 2))]
6530   "
6531 {
6532   long values;
6533   REAL_VALUE_TYPE value;
6534
6535   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6536   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6537   operands[2] = GEN_INT (values);
6538
6539   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6540 }")
6541
6542 (define_insn "movsf_i"
6543   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6544         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6545   "TARGET_SH1
6546    && (! TARGET_SH2E
6547        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6548        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6549        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6550    && (arith_reg_operand (operands[0], SFmode)
6551        || arith_reg_operand (operands[1], SFmode))"
6552   "@
6553         mov     %1,%0
6554         mov     #0,%0
6555         mov.l   %1,%0
6556         mov.l   %1,%0
6557         mov.l   %1,%0
6558         lds     %1,%0
6559         sts     %1,%0"
6560   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6561
6562 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6563 ;; update_flow_info would not know where to put REG_EQUAL notes
6564 ;; when the destination changes mode.
6565 (define_insn "movsf_ie"
6566   [(set (match_operand:SF 0 "general_movdst_operand"
6567          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6568         (match_operand:SF 1 "general_movsrc_operand"
6569           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6570    (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"))
6571    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6572
6573   "TARGET_SH2E
6574    && (arith_reg_operand (operands[0], SFmode)
6575        || arith_reg_operand (operands[1], SFmode)
6576        || arith_reg_operand (operands[3], SImode)
6577        || (fpul_operand (operands[0], SFmode)
6578            && memory_operand (operands[1], SFmode)
6579            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6580        || (fpul_operand (operands[1], SFmode)
6581            && memory_operand (operands[0], SFmode)
6582            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6583   "@
6584         fmov    %1,%0
6585         mov     %1,%0
6586         fldi0   %0
6587         fldi1   %0
6588         #
6589         fmov.s  %1,%0
6590         fmov.s  %1,%0
6591         mov.l   %1,%0
6592         mov.l   %1,%0
6593         mov.l   %1,%0
6594         fsts    fpul,%0
6595         flds    %1,fpul
6596         lds.l   %1,%0
6597         #
6598         sts     %1,%0
6599         lds     %1,%0
6600         sts.l   %1,%0
6601         lds.l   %1,%0
6602         ! move optimized away"
6603   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6604    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6605    (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6606    (set_attr_alternative "length"
6607      [(const_int 2)
6608       (const_int 2)
6609       (const_int 2)
6610       (const_int 2)
6611       (const_int 4)
6612       (if_then_else
6613         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6614         (const_int 4) (const_int 2))
6615       (if_then_else
6616         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617         (const_int 4) (const_int 2))
6618       (const_int 2)
6619       (const_int 2)
6620       (const_int 2)
6621       (const_int 2)
6622       (const_int 2)
6623       (const_int 2)
6624       (const_int 4)
6625       (const_int 2)
6626       (const_int 2)
6627       (const_int 2)
6628       (const_int 2)
6629       (const_int 0)])
6630    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631                                            (const_string "single")
6632                                            (const_string "none")))])
6633
6634 (define_split
6635   [(set (match_operand:SF 0 "register_operand" "")
6636         (match_operand:SF 1 "register_operand" ""))
6637    (use (match_operand:PSI 2 "fpscr_operand" ""))
6638    (clobber (reg:SI FPUL_REG))]
6639   "TARGET_SH1"
6640   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641               (use (match_dup 2))
6642               (clobber (scratch:SI))])
6643    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644               (use (match_dup 2))
6645               (clobber (scratch:SI))])]
6646   "")
6647
6648 (define_expand "movsf"
6649   [(set (match_operand:SF 0 "general_movdst_operand" "")
6650         (match_operand:SF 1 "general_movsrc_operand" ""))]
6651   ""
6652   "
6653 {
6654   if (prepare_move_operands (operands, SFmode))
6655     DONE;
6656   if (TARGET_SHMEDIA)
6657     {
6658       if (TARGET_SHMEDIA_FPU)
6659         emit_insn (gen_movsf_media (operands[0], operands[1]));
6660       else
6661         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6662       DONE;
6663     }
6664   if (TARGET_SH2E)
6665     {
6666       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6667       DONE;
6668     }
6669 }")
6670
6671 (define_insn "mov_nop"
6672   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6673   "TARGET_SH2E"
6674   ""
6675   [(set_attr "length" "0")
6676    (set_attr "type" "nil")])
6677
6678 (define_expand "reload_insf__frn"
6679   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680                    (match_operand:SF 1 "immediate_operand" "FQ"))
6681               (use (reg:PSI FPSCR_REG))
6682               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6683   "TARGET_SH1"
6684   "")
6685
6686 (define_expand "reload_insi__i_fpul"
6687   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688                    (match_operand:SI 1 "immediate_operand" "i"))
6689               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6690   "TARGET_SH1"
6691   "")
6692
6693 (define_expand "ptabs"
6694   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6695   "TARGET_SHMEDIA"
6696   "
6697 {
6698   if (!TARGET_PT_FIXED)
6699     {
6700       rtx eq = operands[1];
6701
6702       /* ??? For canonical RTL we really should remove any CONST from EQ
6703          before wrapping it in the AND, and finally wrap the EQ into a
6704          const if is constant.  However, for reload we must expose the
6705          input register or symbolic constant, and we can't have
6706          different insn structures outside of the operands for different
6707          alternatives of the same pattern.  */
6708       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6709                        GEN_INT (3));
6710       operands[1]
6711         = (gen_rtx_IF_THEN_ELSE
6712             (PDImode,
6713              eq,
6714              gen_rtx_MEM (PDImode, operands[1]),
6715              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716                             PDImode, operands[1])));
6717     }
6718 }")
6719
6720 ;; expanded by ptabs expander.
6721 (define_insn "*extendsipdi_media"
6722   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6724                                                           "r,Csy")
6725                                       (const_int 3))
6726                               (const_int 3))
6727                           (mem:PDI (match_dup 1))
6728                           (sign_extend:PDI (match_dup 1))))]
6729   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6730   "@
6731         ptabs   %1, %0
6732         pt      %1, %0"
6733   [(set_attr "type"   "ptabs_media,pt_media")
6734    (set_attr "length" "4,*")])
6735
6736 (define_insn "*truncdipdi_media"
6737   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6739                                                           "r,Csy")
6740                                       (const_int 3))
6741                               (const_int 3))
6742                           (mem:PDI (match_dup 1))
6743                           (truncate:PDI (match_dup 1))))]
6744   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6745   "@
6746         ptabs   %1, %0
6747         pt      %1, %0"
6748   [(set_attr "type"   "ptabs_media,pt_media")
6749    (set_attr "length" "4,*")])
6750
6751 (define_insn "*movsi_y"
6752   [(set (match_operand:SI 0 "register_operand" "=y,y")
6753         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754    (clobber (match_scratch:SI 2 "=&z,r"))]
6755   "TARGET_SH2E
6756    && (reload_in_progress || reload_completed)"
6757   "#"
6758   [(set_attr "length" "4")
6759    (set_attr "type" "pcload,move")])
6760
6761 (define_split
6762   [(set (match_operand:SI 0 "register_operand" "")
6763         (match_operand:SI 1 "immediate_operand" ""))
6764    (clobber (match_operand:SI 2 "register_operand" ""))]
6765   "TARGET_SH1"
6766   [(set (match_dup 2) (match_dup 1))
6767    (set (match_dup 0) (match_dup 2))]
6768   "")
6769
6770 (define_split
6771   [(set (match_operand:SI 0 "register_operand" "")
6772         (match_operand:SI 1 "memory_operand" ""))
6773    (clobber (reg:SI R0_REG))]
6774   "TARGET_SH1"
6775   [(set (match_dup 0) (match_dup 1))]
6776   "")
6777 \f
6778 ;; ------------------------------------------------------------------------
6779 ;; Define the real conditional branch instructions.
6780 ;; ------------------------------------------------------------------------
6781
6782 (define_insn "branch_true"
6783   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784                            (label_ref (match_operand 0 "" ""))
6785                            (pc)))]
6786   "TARGET_SH1"
6787   "* return output_branch (1, insn, operands);"
6788   [(set_attr "type" "cbranch")])
6789
6790 (define_insn "branch_false"
6791   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792                            (label_ref (match_operand 0 "" ""))
6793                            (pc)))]
6794   "TARGET_SH1"
6795   "* return output_branch (0, insn, operands);"
6796   [(set_attr "type" "cbranch")])
6797
6798 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799 ;; which destination is too far away.
6800 ;; The const_int_operand is distinct for each branch target; it avoids
6801 ;; unwanted matches with redundant_insn.
6802 (define_insn "block_branch_redirect"
6803   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6804   "TARGET_SH1"
6805   ""
6806   [(set_attr "length" "0")])
6807
6808 ;; This one has the additional purpose to record a possible scratch register
6809 ;; for the following branch.
6810 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6811 ;; because the insn then might be deemed dead and deleted.  And we can't
6812 ;; make the use in the jump insn explicit because that would disable
6813 ;; delay slot scheduling from the target.
6814 (define_insn "indirect_jump_scratch"
6815   [(set (match_operand:SI 0 "register_operand" "=r")
6816         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6818   "TARGET_SH1"
6819   ""
6820   [(set_attr "length" "0")])
6821
6822 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823 ;; being pulled into the delay slot of a condbranch that has been made to
6824 ;; jump around the unconditional jump because it was out of range.
6825 (define_insn "stuff_delay_slot"
6826   [(set (pc)
6827         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6828    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6829   "TARGET_SH1"
6830   ""
6831   [(set_attr "length" "0")
6832    (set_attr "cond_delay_slot" "yes")])
6833 \f
6834 ;; Conditional branch insns
6835
6836 (define_expand "beq_media"
6837   [(set (pc)
6838         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6839                           (match_operand:DI 2 "arith_operand" "r,I06"))
6840                       (match_operand 0 "" "")
6841                       (pc)))]
6842   "TARGET_SHMEDIA"
6843   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6844
6845 (define_insn "*beq_media_i"
6846   [(set (pc)
6847         (if_then_else (match_operator 3 "equality_comparison_operator"
6848                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6849                          (match_operand:DI 2 "arith_operand" "r,I06")])
6850                       (match_operand 0 "target_operand" "b,b")
6851                       (pc)))]
6852   "TARGET_SHMEDIA"
6853   "@
6854         b%o3%'  %1, %2, %0%>
6855         b%o3i%' %1, %2, %0%>"
6856   [(set_attr "type" "cbranch_media")])
6857
6858 (define_insn "*beq_media_i32"
6859   [(set (pc)
6860         (if_then_else (match_operator 3 "equality_comparison_operator"
6861                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6862                          (match_operand:SI 2 "arith_operand" "r,I06")])
6863                       (match_operand 0 "target_operand" "b,b")
6864                       (pc)))]
6865   "TARGET_SHMEDIA"
6866   "@
6867         b%o3%'  %1, %2, %0%>
6868         b%o3i%' %1, %2, %0%>"
6869   [(set_attr "type" "cbranch_media")])
6870
6871 (define_expand "bne_media"
6872   [(set (pc)
6873         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6874                           (match_operand:DI 2 "arith_operand" "r,I06"))
6875                       (match_operand 0 "" "")
6876                       (pc)))]
6877   "TARGET_SHMEDIA"
6878   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6879
6880 (define_expand "bgt_media"
6881   [(set (pc)
6882         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6883                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6884                       (match_operand 0 "" "")
6885                       (pc)))]
6886   "TARGET_SHMEDIA"
6887   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6888
6889 (define_expand "bge_media"
6890   [(set (pc)
6891         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6892                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6893                       (match_operand 0 "" "")
6894                       (pc)))]
6895   "TARGET_SHMEDIA"
6896   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6897
6898 (define_expand "bgtu_media"
6899   [(set (pc)
6900         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6901                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6902                       (match_operand 0 "" "")
6903                       (pc)))]
6904   "TARGET_SHMEDIA"
6905   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6906
6907 (define_expand "bgeu_media"
6908   [(set (pc)
6909         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6910                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6911                       (match_operand 0 "" "")
6912                       (pc)))]
6913   "TARGET_SHMEDIA"
6914   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6915
6916 (define_insn "*bgt_media_i"
6917   [(set (pc)
6918         (if_then_else (match_operator 3 "greater_comparison_operator"
6919                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6920                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6921                       (match_operand 0 "target_operand" "b")
6922                       (pc)))]
6923   "TARGET_SHMEDIA"
6924   "b%o3%'       %N1, %N2, %0%>"
6925   [(set_attr "type" "cbranch_media")])
6926
6927 (define_insn "*bgt_media_i32"
6928   [(set (pc)
6929         (if_then_else (match_operator 3 "greater_comparison_operator"
6930                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6931                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6932                       (match_operand 0 "target_operand" "b")
6933                       (pc)))]
6934   "TARGET_SHMEDIA"
6935   "b%o3%'       %N1, %N2, %0%>"
6936   [(set_attr "type" "cbranch_media")])
6937
6938 ;; These are only needed to make invert_jump() happy - otherwise, jump
6939 ;; optimization will be silently disabled.
6940 (define_insn "*blt_media_i"
6941   [(set (pc)
6942         (if_then_else (match_operator 3 "less_comparison_operator"
6943                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6944                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6945                       (match_operand 0 "target_operand" "b")
6946                       (pc)))]
6947   "TARGET_SHMEDIA"
6948   "b%o3%'       %N2, %N1, %0%>"
6949   [(set_attr "type" "cbranch_media")])
6950
6951 (define_insn "*blt_media_i32"
6952   [(set (pc)
6953         (if_then_else (match_operator 3 "less_comparison_operator"
6954                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6955                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6956                       (match_operand 0 "target_operand" "b")
6957                       (pc)))]
6958   "TARGET_SHMEDIA"
6959   "b%o3%'       %N2, %N1, %0%>"
6960   [(set_attr "type" "cbranch_media")])
6961
6962 (define_expand "beq"
6963   [(set (pc)
6964         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6965                       (label_ref (match_operand 0 "" ""))
6966                       (pc)))]
6967   ""
6968   "
6969 {
6970   if (TARGET_SHMEDIA)
6971     {
6972       enum machine_mode mode = GET_MODE (sh_compare_op0);
6973
6974       if (mode != DImode && mode != SImode)
6975         {
6976           rtx tmp = gen_reg_rtx (DImode);
6977
6978           emit_insn (gen_seq (tmp));
6979           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6980           DONE;
6981         }
6982
6983       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6984       if (CONSTANT_P (sh_compare_op1)
6985           && (! satisfies_constraint_I06 (sh_compare_op1)))
6986         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6987       emit_jump_insn (gen_beq_media (operands[0],
6988                                      sh_compare_op0, sh_compare_op1));
6989       DONE;
6990     }
6991
6992   from_compare (operands, EQ);
6993 }")
6994
6995 (define_expand "bne"
6996   [(set (pc)
6997         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6998                       (label_ref (match_operand 0 "" ""))
6999                       (pc)))]
7000   ""
7001   "
7002 {
7003   if (TARGET_SHMEDIA)
7004     {
7005       enum machine_mode mode = GET_MODE (sh_compare_op0);
7006
7007       if (mode != DImode && mode != SImode)
7008         {
7009           rtx tmp = gen_reg_rtx (DImode);
7010
7011           emit_insn (gen_seq (tmp));
7012           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7013           DONE;
7014         }
7015
7016       sh_compare_op0 = force_reg (mode, sh_compare_op0);
7017       if (CONSTANT_P (sh_compare_op1)
7018           && (! satisfies_constraint_I06 (sh_compare_op1)))
7019         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7020       emit_jump_insn (gen_bne_media (operands[0],
7021                                      sh_compare_op0, sh_compare_op1));
7022       DONE;
7023     }
7024
7025   from_compare (operands, EQ);
7026 }")
7027
7028 (define_expand "bgt"
7029   [(set (pc)
7030         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7031                       (label_ref (match_operand 0 "" ""))
7032                       (pc)))]
7033   ""
7034   "
7035 {
7036   if (TARGET_SHMEDIA)
7037     {
7038       enum machine_mode mode = GET_MODE (sh_compare_op0);
7039
7040       if (mode != DImode && mode != SImode)
7041         {
7042           rtx tmp = gen_reg_rtx (DImode);
7043
7044           emit_insn (gen_sgt (tmp));
7045           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7046           DONE;
7047         }
7048
7049       if (sh_compare_op0 != const0_rtx)
7050         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7051       if (sh_compare_op1 != const0_rtx)
7052         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7053       emit_jump_insn (gen_bgt_media (operands[0],
7054                                      sh_compare_op0, sh_compare_op1));
7055       DONE;
7056     }
7057
7058   from_compare (operands, GT);
7059 }")
7060
7061 (define_expand "blt"
7062   [(set (pc)
7063         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7064                       (label_ref (match_operand 0 "" ""))
7065                       (pc)))]
7066   ""
7067   "
7068 {
7069   if (TARGET_SHMEDIA)
7070     {
7071       enum machine_mode mode = GET_MODE (sh_compare_op0);
7072
7073       if (mode != DImode && mode != SImode)
7074         {
7075           rtx tmp = gen_reg_rtx (DImode);
7076
7077           emit_insn (gen_slt (tmp));
7078           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7079           DONE;
7080         }
7081
7082       if (sh_compare_op0 != const0_rtx)
7083         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7084       if (sh_compare_op1 != const0_rtx)
7085         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7086       emit_jump_insn (gen_bgt_media (operands[0],
7087                                      sh_compare_op1, sh_compare_op0));
7088       DONE;
7089     }
7090
7091   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7092     {
7093       rtx tmp = sh_compare_op0;
7094       sh_compare_op0 = sh_compare_op1;
7095       sh_compare_op1 = tmp;
7096       emit_insn (gen_bgt (operands[0]));
7097       DONE;
7098     }
7099   from_compare (operands, GE);
7100 }")
7101
7102 (define_expand "ble"
7103   [(set (pc)
7104         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7105                       (label_ref (match_operand 0 "" ""))
7106                       (pc)))]
7107   ""
7108   "
7109 {
7110   if (TARGET_SHMEDIA)
7111     {
7112       enum machine_mode mode = GET_MODE (sh_compare_op0);
7113
7114       if (mode != DImode && mode != SImode)
7115         {
7116           rtx tmp = gen_reg_rtx (DImode);
7117
7118           emit_insn (gen_sle (tmp));
7119           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7120           DONE;
7121         }
7122
7123       if (sh_compare_op0 != const0_rtx)
7124         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7125       if (sh_compare_op1 != const0_rtx)
7126         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7127       emit_jump_insn (gen_bge_media (operands[0],
7128                                      sh_compare_op1, sh_compare_op0));
7129       DONE;
7130     }
7131
7132   if (TARGET_SH2E
7133       && TARGET_IEEE
7134       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7135     {
7136       rtx tmp = sh_compare_op0;
7137       sh_compare_op0 = sh_compare_op1;
7138       sh_compare_op1 = tmp;
7139       emit_insn (gen_bge (operands[0]));
7140       DONE;
7141     }
7142   from_compare (operands, GT);
7143 }")
7144
7145 (define_expand "bge"
7146   [(set (pc)
7147         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7148                       (label_ref (match_operand 0 "" ""))
7149                       (pc)))]
7150   ""
7151   "
7152 {
7153   if (TARGET_SHMEDIA)
7154     {
7155       enum machine_mode mode = GET_MODE (sh_compare_op0);
7156
7157       if (mode != DImode && mode != SImode)
7158         {
7159           rtx tmp = gen_reg_rtx (DImode);
7160
7161           emit_insn (gen_sge (tmp));
7162           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7163           DONE;
7164         }
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_bge_media (operands[0],
7171                                      sh_compare_op0, sh_compare_op1));
7172       DONE;
7173     }
7174
7175   if (TARGET_SH2E
7176       && ! TARGET_IEEE
7177       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7178     {
7179       rtx tmp = sh_compare_op0;
7180       sh_compare_op0 = sh_compare_op1;
7181       sh_compare_op1 = tmp;
7182       emit_insn (gen_ble (operands[0]));
7183       DONE;
7184     }
7185   from_compare (operands, GE);
7186 }")
7187
7188 (define_expand "bgtu"
7189   [(set (pc)
7190         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7191                       (label_ref (match_operand 0 "" ""))
7192                       (pc)))]
7193   ""
7194   "
7195 {
7196   if (TARGET_SHMEDIA)
7197     {
7198       enum machine_mode mode = GET_MODE (sh_compare_op0);
7199
7200       if (sh_compare_op0 != const0_rtx)
7201         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7202       if (sh_compare_op1 != const0_rtx)
7203         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7204       emit_jump_insn (gen_bgtu_media (operands[0],
7205                                       sh_compare_op0, sh_compare_op1));
7206       DONE;
7207     }
7208
7209   from_compare (operands, GTU);
7210 }")
7211
7212 (define_expand "bltu"
7213   [(set (pc)
7214         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7215                       (label_ref (match_operand 0 "" ""))
7216                       (pc)))]
7217   ""
7218   "
7219 {
7220   if (TARGET_SHMEDIA)
7221     {
7222       enum machine_mode mode = GET_MODE (sh_compare_op0);
7223
7224       if (sh_compare_op0 != const0_rtx)
7225         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7226       if (sh_compare_op1 != const0_rtx)
7227         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7228       emit_jump_insn (gen_bgtu_media (operands[0],
7229                                       sh_compare_op1, sh_compare_op0));
7230       DONE;
7231     }
7232
7233   from_compare (operands, GEU);
7234 }")
7235
7236 (define_expand "bgeu"
7237   [(set (pc)
7238         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7239                       (label_ref (match_operand 0 "" ""))
7240                       (pc)))]
7241   ""
7242   "
7243 {
7244   if (TARGET_SHMEDIA)
7245     {
7246       enum machine_mode mode = GET_MODE (sh_compare_op0);
7247
7248       if (sh_compare_op0 != const0_rtx)
7249         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7250       if (sh_compare_op1 != const0_rtx)
7251         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7252       emit_jump_insn (gen_bgeu_media (operands[0],
7253                                       sh_compare_op0, sh_compare_op1));
7254       DONE;
7255     }
7256
7257   from_compare (operands, GEU);
7258 }")
7259
7260 (define_expand "bleu"
7261   [(set (pc)
7262         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7263                       (label_ref (match_operand 0 "" ""))
7264                       (pc)))]
7265   ""
7266   "
7267 {
7268   if (TARGET_SHMEDIA)
7269     {
7270       enum machine_mode mode = GET_MODE (sh_compare_op0);
7271
7272       if (sh_compare_op0 != const0_rtx)
7273         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7274       if (sh_compare_op1 != const0_rtx)
7275         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7276       emit_jump_insn (gen_bgeu_media (operands[0],
7277                                       sh_compare_op1, sh_compare_op0));
7278       DONE;
7279     }
7280
7281   from_compare (operands, GTU);
7282 }")
7283
7284 (define_expand "bunordered"
7285   [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7286    (set (pc)
7287         (if_then_else (ne (match_dup 1) (const_int 0))
7288                       (match_operand 0 "" "")
7289                       (pc)))]
7290   "TARGET_SHMEDIA"
7291   "
7292 {
7293   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7294   operands[1] = gen_reg_rtx (SImode);
7295   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7296   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7297 }")
7298
7299 ;; combiner splitter for test-and-branch on single bit in register.  This
7300 ;; is endian dependent because the non-paradoxical subreg looks different
7301 ;; on big endian.
7302 (define_split
7303   [(set (pc)
7304         (if_then_else
7305           (match_operator 3 "equality_comparison_operator"
7306             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7307                                                       "extend_reg_operand" "")
7308                                                     0)
7309                                          (const_int 1)
7310                                          (match_operand 2
7311                                           "const_int_operand" "")) 0)
7312              (const_int 0)])
7313           (match_operand 0 "target_operand" "")
7314           (pc)))
7315    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7316   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7317   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7318    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7319
7320   "
7321 {
7322   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7323   operands[6] = (GET_CODE (operands[3]) == EQ
7324                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7325                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7326 }")
7327
7328 ; operand 0 is the loop count pseudo register
7329 ; operand 1 is the number of loop iterations or 0 if it is unknown
7330 ; operand 2 is the maximum number of loop iterations
7331 ; operand 3 is the number of levels of enclosed loops
7332 ; operand 4 is the label to jump to at the top of the loop
7333
7334 (define_expand "doloop_end"
7335   [(parallel [(set (pc) (if_then_else
7336                           (ne:SI (match_operand:SI 0 "" "")
7337                               (const_int 1))
7338                           (label_ref (match_operand 4 "" ""))
7339                           (pc)))
7340               (set (match_dup 0)
7341                    (plus:SI (match_dup 0) (const_int -1)))
7342               (clobber (reg:SI T_REG))])]
7343   "TARGET_SH2"
7344   "
7345 {
7346   if (GET_MODE (operands[0]) != SImode)
7347     FAIL;
7348 }
7349 ")
7350
7351 (define_insn_and_split "doloop_end_split"
7352   [(set (pc)
7353         (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7354                           (const_int 1))
7355                       (label_ref (match_operand 1 "" ""))
7356                       (pc)))
7357    (set (match_dup 0)
7358         (plus (match_dup 0) (const_int -1)))
7359    (clobber (reg:SI T_REG))]
7360   "TARGET_SH2"
7361   "#"
7362   ""
7363   [(parallel [(set (reg:SI T_REG)
7364                    (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7365                           (const_int 1)))
7366               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7367    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7368                            (label_ref (match_operand 1 "" ""))
7369                            (pc)))]
7370 ""
7371    [(set_attr "type" "cbranch")])
7372
7373 \f
7374 ;; ------------------------------------------------------------------------
7375 ;; Jump and linkage insns
7376 ;; ------------------------------------------------------------------------
7377
7378 (define_insn "jump_compact"
7379   [(set (pc)
7380         (label_ref (match_operand 0 "" "")))]
7381   "TARGET_SH1"
7382   "*
7383 {
7384   /* The length is 16 if the delay slot is unfilled.  */
7385   if (get_attr_length(insn) > 4)
7386     return output_far_jump(insn, operands[0]);
7387   else
7388     return   \"bra      %l0%#\";
7389 }"
7390   [(set_attr "type" "jump")
7391    (set_attr "needs_delay_slot" "yes")])
7392
7393 ;; ??? It would be much saner to explicitly use the scratch register
7394 ;; in the jump insn, and have indirect_jump_scratch only set it,
7395 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7396 ;; from the target then, as it uses simplejump_p.
7397 ;;(define_insn "jump_compact_far"
7398 ;;  [(set (pc)
7399 ;;      (label_ref (match_operand 0 "" "")))
7400 ;;   (use (match_operand 1 "register_operand" "r")]
7401 ;;  "TARGET_SH1"
7402 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7403 ;;  [(set_attr "type" "jump")
7404 ;;   (set_attr "needs_delay_slot" "yes")])
7405
7406 (define_insn "jump_media"
7407   [(set (pc)
7408         (match_operand 0 "target_operand" "b"))]
7409   "TARGET_SHMEDIA"
7410   "blink        %0, r63%>"
7411   [(set_attr "type" "jump_media")])
7412
7413 (define_expand "jump"
7414   [(set (pc)
7415         (label_ref (match_operand 0 "" "")))]
7416   ""
7417   "
7418 {
7419   if (TARGET_SH1)
7420     emit_jump_insn (gen_jump_compact (operands[0]));
7421   else if (TARGET_SHMEDIA)
7422     {
7423       if (reload_in_progress || reload_completed)
7424         FAIL;
7425       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7426                                                          operands[0])));
7427     }
7428   DONE;
7429 }")
7430
7431 (define_insn "force_mode_for_call"
7432   [(use (reg:PSI FPSCR_REG))]
7433   "TARGET_SHCOMPACT"
7434   ""
7435   [(set_attr "length" "0")
7436    (set (attr "fp_mode")
7437         (if_then_else (eq_attr "fpu_single" "yes")
7438                       (const_string "single") (const_string "double")))])
7439
7440 (define_insn "calli"
7441   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7442          (match_operand 1 "" ""))
7443    (use (reg:PSI FPSCR_REG))
7444    (clobber (reg:SI PR_REG))]
7445   "TARGET_SH1"
7446   "jsr  @%0%#"
7447   [(set_attr "type" "call")
7448    (set (attr "fp_mode")
7449         (if_then_else (eq_attr "fpu_single" "yes")
7450                       (const_string "single") (const_string "double")))
7451    (set_attr "needs_delay_slot" "yes")
7452    (set_attr "fp_set" "unknown")])
7453
7454 ;; This is a pc-rel call, using bsrf, for use with PIC.
7455
7456 (define_insn "calli_pcrel"
7457   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7458          (match_operand 1 "" ""))
7459    (use (reg:PSI FPSCR_REG))
7460    (use (reg:SI PIC_REG))
7461    (use (match_operand 2 "" ""))
7462    (clobber (reg:SI PR_REG))]
7463   "TARGET_SH2"
7464   "bsrf %0\\n%O2:%#"
7465   [(set_attr "type" "call")
7466    (set (attr "fp_mode")
7467         (if_then_else (eq_attr "fpu_single" "yes")
7468                       (const_string "single") (const_string "double")))
7469    (set_attr "needs_delay_slot" "yes")
7470    (set_attr "fp_set" "unknown")])
7471
7472 (define_insn_and_split "call_pcrel"
7473   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7474          (match_operand 1 "" ""))
7475    (use (reg:PSI FPSCR_REG))
7476    (use (reg:SI PIC_REG))
7477    (clobber (reg:SI PR_REG))
7478    (clobber (match_scratch:SI 2 "=r"))]
7479   "TARGET_SH2"
7480   "#"
7481   "reload_completed"
7482   [(const_int 0)]
7483   "
7484 {
7485   rtx lab = PATTERN (gen_call_site ());
7486
7487   if (SYMBOL_REF_LOCAL_P (operands[0]))
7488     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7489   else
7490     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7491   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7492   DONE;
7493 }"
7494   [(set_attr "type" "call")
7495    (set (attr "fp_mode")
7496         (if_then_else (eq_attr "fpu_single" "yes")
7497                       (const_string "single") (const_string "double")))
7498    (set_attr "needs_delay_slot" "yes")
7499    (set_attr "fp_set" "unknown")])
7500
7501 (define_insn "call_compact"
7502   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7503          (match_operand 1 "" ""))
7504    (match_operand 2 "immediate_operand" "n")
7505    (use (reg:SI R0_REG))
7506    (use (reg:SI R1_REG))
7507    (use (reg:PSI FPSCR_REG))
7508    (clobber (reg:SI PR_REG))]
7509   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7510   "jsr  @%0%#"
7511   [(set_attr "type" "call")
7512    (set (attr "fp_mode")
7513         (if_then_else (eq_attr "fpu_single" "yes")
7514                       (const_string "single") (const_string "double")))
7515    (set_attr "needs_delay_slot" "yes")])
7516
7517 (define_insn "call_compact_rettramp"
7518   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7519          (match_operand 1 "" ""))
7520    (match_operand 2 "immediate_operand" "n")
7521    (use (reg:SI R0_REG))
7522    (use (reg:SI R1_REG))
7523    (use (reg:PSI FPSCR_REG))
7524    (clobber (reg:SI R10_REG))
7525    (clobber (reg:SI PR_REG))]
7526   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7527   "jsr  @%0%#"
7528   [(set_attr "type" "call")
7529    (set (attr "fp_mode")
7530         (if_then_else (eq_attr "fpu_single" "yes")
7531                       (const_string "single") (const_string "double")))
7532    (set_attr "needs_delay_slot" "yes")])
7533
7534 (define_insn "call_media"
7535   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7536          (match_operand 1 "" ""))
7537    (clobber (reg:DI PR_MEDIA_REG))]
7538   "TARGET_SHMEDIA"
7539   "blink        %0, r18"
7540   [(set_attr "type" "jump_media")])
7541
7542 (define_insn "call_valuei"
7543   [(set (match_operand 0 "" "=rf")
7544         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7545               (match_operand 2 "" "")))
7546    (use (reg:PSI FPSCR_REG))
7547    (clobber (reg:SI PR_REG))]
7548   "TARGET_SH1"
7549   "jsr  @%1%#"
7550   [(set_attr "type" "call")
7551    (set (attr "fp_mode")
7552         (if_then_else (eq_attr "fpu_single" "yes")
7553                       (const_string "single") (const_string "double")))
7554    (set_attr "needs_delay_slot" "yes")
7555    (set_attr "fp_set" "unknown")])
7556
7557 (define_insn "call_valuei_pcrel"
7558   [(set (match_operand 0 "" "=rf")
7559         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7560               (match_operand 2 "" "")))
7561    (use (reg:PSI FPSCR_REG))
7562    (use (reg:SI PIC_REG))
7563    (use (match_operand 3 "" ""))
7564    (clobber (reg:SI PR_REG))]
7565   "TARGET_SH2"
7566   "bsrf %1\\n%O3:%#"
7567   [(set_attr "type" "call")
7568    (set (attr "fp_mode")
7569         (if_then_else (eq_attr "fpu_single" "yes")
7570                       (const_string "single") (const_string "double")))
7571    (set_attr "needs_delay_slot" "yes")
7572    (set_attr "fp_set" "unknown")])
7573
7574 (define_insn_and_split "call_value_pcrel"
7575   [(set (match_operand 0 "" "=rf")
7576         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7577               (match_operand 2 "" "")))
7578    (use (reg:PSI FPSCR_REG))
7579    (use (reg:SI PIC_REG))
7580    (clobber (reg:SI PR_REG))
7581    (clobber (match_scratch:SI 3 "=r"))]
7582   "TARGET_SH2"
7583   "#"
7584   "reload_completed"
7585   [(const_int 0)]
7586   "
7587 {
7588   rtx lab = PATTERN (gen_call_site ());
7589
7590   if (SYMBOL_REF_LOCAL_P (operands[1]))
7591     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7592   else
7593     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7594   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7595                                          operands[2], copy_rtx (lab)));
7596   DONE;
7597 }"
7598   [(set_attr "type" "call")
7599    (set (attr "fp_mode")
7600         (if_then_else (eq_attr "fpu_single" "yes")
7601                       (const_string "single") (const_string "double")))
7602    (set_attr "needs_delay_slot" "yes")
7603    (set_attr "fp_set" "unknown")])
7604
7605 (define_insn "call_value_compact"
7606   [(set (match_operand 0 "" "=rf")
7607         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7608               (match_operand 2 "" "")))
7609    (match_operand 3 "immediate_operand" "n")
7610    (use (reg:SI R0_REG))
7611    (use (reg:SI R1_REG))
7612    (use (reg:PSI FPSCR_REG))
7613    (clobber (reg:SI PR_REG))]
7614   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7615   "jsr  @%1%#"
7616   [(set_attr "type" "call")
7617    (set (attr "fp_mode")
7618         (if_then_else (eq_attr "fpu_single" "yes")
7619                       (const_string "single") (const_string "double")))
7620    (set_attr "needs_delay_slot" "yes")])
7621
7622 (define_insn "call_value_compact_rettramp"
7623   [(set (match_operand 0 "" "=rf")
7624         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7625               (match_operand 2 "" "")))
7626    (match_operand 3 "immediate_operand" "n")
7627    (use (reg:SI R0_REG))
7628    (use (reg:SI R1_REG))
7629    (use (reg:PSI FPSCR_REG))
7630    (clobber (reg:SI R10_REG))
7631    (clobber (reg:SI PR_REG))]
7632   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7633   "jsr  @%1%#"
7634   [(set_attr "type" "call")
7635    (set (attr "fp_mode")
7636         (if_then_else (eq_attr "fpu_single" "yes")
7637                       (const_string "single") (const_string "double")))
7638    (set_attr "needs_delay_slot" "yes")])
7639
7640 (define_insn "call_value_media"
7641   [(set (match_operand 0 "" "=rf")
7642         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7643               (match_operand 2 "" "")))
7644    (clobber (reg:DI PR_MEDIA_REG))]
7645   "TARGET_SHMEDIA"
7646   "blink        %1, r18"
7647   [(set_attr "type" "jump_media")])
7648
7649 (define_expand "call"
7650   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7651                             (match_operand 1 "" ""))
7652               (match_operand 2 "" "")
7653               (use (reg:PSI FPSCR_REG))
7654               (clobber (reg:SI PR_REG))])]
7655   ""
7656   "
7657 {
7658   if (TARGET_SHMEDIA)
7659     {
7660       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7661       emit_call_insn (gen_call_media (operands[0], operands[1]));
7662       DONE;
7663     }
7664   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7665     {
7666       rtx cookie_rtx = operands[2];
7667       long cookie = INTVAL (cookie_rtx);
7668       rtx func = XEXP (operands[0], 0);
7669       rtx r0, r1;
7670
7671       if (flag_pic)
7672         {
7673           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7674             {
7675               rtx reg = gen_reg_rtx (Pmode);
7676
7677               emit_insn (gen_symGOTPLT2reg (reg, func));
7678               func = reg;
7679             }
7680           else
7681             func = legitimize_pic_address (func, Pmode, 0);
7682         }
7683
7684       r0 = gen_rtx_REG (SImode, R0_REG);
7685       r1 = gen_rtx_REG (SImode, R1_REG);
7686
7687       /* Since such a call function may use all call-clobbered
7688          registers, we force a mode switch earlier, so that we don't
7689          run out of registers when adjusting fpscr for the call.  */
7690       emit_insn (gen_force_mode_for_call ());
7691
7692       operands[0]
7693         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7694                            SFUNC_GOT);
7695       operands[0] = force_reg (SImode, operands[0]);
7696
7697       emit_move_insn (r0, func);
7698       emit_move_insn (r1, cookie_rtx);
7699
7700       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7701         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7702                                                    operands[2]));
7703       else
7704         emit_call_insn (gen_call_compact (operands[0], operands[1],
7705                                           operands[2]));
7706
7707       DONE;
7708     }
7709   else if (TARGET_SHCOMPACT && flag_pic
7710            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7711            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7712     {
7713       rtx reg = gen_reg_rtx (Pmode);
7714
7715       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7716       XEXP (operands[0], 0) = reg;
7717     }
7718   if (flag_pic && TARGET_SH2
7719       && GET_CODE (operands[0]) == MEM
7720       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7721     {
7722       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7723       DONE;
7724     }
7725   else
7726   {
7727     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7728     operands[1] = operands[2];
7729   }
7730
7731   emit_call_insn (gen_calli (operands[0], operands[1]));
7732   DONE;
7733 }")
7734
7735 (define_insn "call_pop_compact"
7736   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7737          (match_operand 1 "" ""))
7738    (match_operand 2 "immediate_operand" "n")
7739    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7740                                  (match_operand 3 "immediate_operand" "n")))
7741    (use (reg:SI R0_REG))
7742    (use (reg:SI R1_REG))
7743    (use (reg:PSI FPSCR_REG))
7744    (clobber (reg:SI PR_REG))]
7745   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7746   "jsr  @%0%#"
7747   [(set_attr "type" "call")
7748    (set (attr "fp_mode")
7749         (if_then_else (eq_attr "fpu_single" "yes")
7750                       (const_string "single") (const_string "double")))
7751    (set_attr "needs_delay_slot" "yes")])
7752
7753 (define_insn "call_pop_compact_rettramp"
7754   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7755          (match_operand 1 "" ""))
7756    (match_operand 2 "immediate_operand" "n")
7757    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7758                                  (match_operand 3 "immediate_operand" "n")))
7759    (use (reg:SI R0_REG))
7760    (use (reg:SI R1_REG))
7761    (use (reg:PSI FPSCR_REG))
7762    (clobber (reg:SI R10_REG))
7763    (clobber (reg:SI PR_REG))]
7764   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7765   "jsr  @%0%#"
7766   [(set_attr "type" "call")
7767    (set (attr "fp_mode")
7768         (if_then_else (eq_attr "fpu_single" "yes")
7769                       (const_string "single") (const_string "double")))
7770    (set_attr "needs_delay_slot" "yes")])
7771
7772 (define_expand "call_pop"
7773   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7774                     (match_operand 1 "" ""))
7775              (match_operand 2 "" "")
7776              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7777                                            (match_operand 3 "" "")))])]
7778   "TARGET_SHCOMPACT"
7779   "
7780 {
7781   rtx cookie_rtx;
7782   long cookie;
7783   rtx func;
7784   rtx r0, r1;
7785
7786   gcc_assert (operands[2] && INTVAL (operands[2]));
7787   cookie_rtx = operands[2];
7788   cookie = INTVAL (cookie_rtx);
7789   func = XEXP (operands[0], 0);
7790
7791   if (flag_pic)
7792     {
7793       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7794         {
7795           rtx reg = gen_reg_rtx (Pmode);
7796           emit_insn (gen_symGOTPLT2reg (reg, func));
7797           func = reg;
7798         }
7799       else
7800         func = legitimize_pic_address (func, Pmode, 0);
7801     }
7802
7803   r0 = gen_rtx_REG (SImode, R0_REG);
7804   r1 = gen_rtx_REG (SImode, R1_REG);
7805
7806   /* Since such a call function may use all call-clobbered
7807      registers, we force a mode switch earlier, so that we don't
7808      run out of registers when adjusting fpscr for the call.  */
7809   emit_insn (gen_force_mode_for_call ());
7810
7811   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7812                                  SFUNC_GOT);
7813   operands[0] = force_reg (SImode, operands[0]);
7814
7815   emit_move_insn (r0, func);
7816   emit_move_insn (r1, cookie_rtx);
7817
7818   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7819     emit_call_insn (gen_call_pop_compact_rettramp
7820                      (operands[0], operands[1], operands[2], operands[3]));
7821   else
7822     emit_call_insn (gen_call_pop_compact
7823                      (operands[0], operands[1], operands[2], operands[3]));
7824
7825   DONE;
7826 }")
7827
7828 (define_expand "call_value"
7829   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7830                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7831                                  (match_operand 2 "" "")))
7832               (match_operand 3 "" "")
7833               (use (reg:PSI FPSCR_REG))
7834               (clobber (reg:SI PR_REG))])]
7835   ""
7836   "
7837 {
7838   if (TARGET_SHMEDIA)
7839     {
7840       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7841       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7842                                             operands[2]));
7843       DONE;
7844     }
7845   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7846     {
7847       rtx cookie_rtx = operands[3];
7848       long cookie = INTVAL (cookie_rtx);
7849       rtx func = XEXP (operands[1], 0);
7850       rtx r0, r1;
7851
7852       if (flag_pic)
7853         {
7854           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7855             {
7856               rtx reg = gen_reg_rtx (Pmode);
7857
7858               emit_insn (gen_symGOTPLT2reg (reg, func));
7859               func = reg;
7860             }
7861           else
7862             func = legitimize_pic_address (func, Pmode, 0);
7863         }
7864
7865       r0 = gen_rtx_REG (SImode, R0_REG);
7866       r1 = gen_rtx_REG (SImode, R1_REG);
7867
7868       /* Since such a call function may use all call-clobbered
7869          registers, we force a mode switch earlier, so that we don't
7870          run out of registers when adjusting fpscr for the call.  */
7871       emit_insn (gen_force_mode_for_call ());
7872
7873       operands[1]
7874         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7875                            SFUNC_GOT);
7876       operands[1] = force_reg (SImode, operands[1]);
7877
7878       emit_move_insn (r0, func);
7879       emit_move_insn (r1, cookie_rtx);
7880
7881       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7882         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7883                                                          operands[1],
7884                                                          operands[2],
7885                                                          operands[3]));
7886       else
7887         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7888                                                 operands[2], operands[3]));
7889
7890       DONE;
7891     }
7892   else if (TARGET_SHCOMPACT && flag_pic
7893            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7894            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7895     {
7896       rtx reg = gen_reg_rtx (Pmode);
7897
7898       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7899       XEXP (operands[1], 0) = reg;
7900     }
7901   if (flag_pic && TARGET_SH2
7902       && GET_CODE (operands[1]) == MEM
7903       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7904     {
7905       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7906                                             operands[2]));
7907       DONE;
7908     }
7909   else
7910     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7911
7912   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7913   DONE;
7914 }")
7915
7916 (define_insn "sibcalli"
7917   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7918          (match_operand 1 "" ""))
7919    (use (reg:PSI FPSCR_REG))
7920    (return)]
7921   "TARGET_SH1"
7922   "jmp  @%0%#"
7923   [(set_attr "needs_delay_slot" "yes")
7924    (set (attr "fp_mode")
7925         (if_then_else (eq_attr "fpu_single" "yes")
7926                       (const_string "single") (const_string "double")))
7927    (set_attr "type" "jump_ind")])
7928
7929 (define_insn "sibcalli_pcrel"
7930   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7931          (match_operand 1 "" ""))
7932    (use (match_operand 2 "" ""))
7933    (use (reg:PSI FPSCR_REG))
7934    (return)]
7935   "TARGET_SH2"
7936   "braf %0\\n%O2:%#"
7937   [(set_attr "needs_delay_slot" "yes")
7938    (set (attr "fp_mode")
7939         (if_then_else (eq_attr "fpu_single" "yes")
7940                       (const_string "single") (const_string "double")))
7941    (set_attr "type" "jump_ind")])
7942
7943 ;; This uses an unspec to describe that the symbol_ref is very close.
7944 (define_insn "sibcalli_thunk"
7945   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7946                              UNSPEC_THUNK))
7947          (match_operand 1 "" ""))
7948    (use (reg:PSI FPSCR_REG))
7949    (return)]
7950   "TARGET_SH1"
7951   "bra  %O0"
7952   [(set_attr "needs_delay_slot" "yes")
7953    (set (attr "fp_mode")
7954         (if_then_else (eq_attr "fpu_single" "yes")
7955                       (const_string "single") (const_string "double")))
7956    (set_attr "type" "jump")
7957    (set_attr "length" "2")])
7958
7959 (define_insn_and_split "sibcall_pcrel"
7960   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7961          (match_operand 1 "" ""))
7962    (use (reg:PSI FPSCR_REG))
7963    (clobber (match_scratch:SI 2 "=k"))
7964    (return)]
7965   "TARGET_SH2"
7966   "#"
7967   "reload_completed"
7968   [(const_int 0)]
7969   "
7970 {
7971   rtx lab = PATTERN (gen_call_site ());
7972   rtx call_insn;
7973
7974   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7975   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7976                                                   copy_rtx (lab)));
7977   SIBLING_CALL_P (call_insn) = 1;
7978   DONE;
7979 }"
7980   [(set_attr "needs_delay_slot" "yes")
7981    (set (attr "fp_mode")
7982         (if_then_else (eq_attr "fpu_single" "yes")
7983                       (const_string "single") (const_string "double")))
7984    (set_attr "type" "jump_ind")])
7985
7986 (define_insn "sibcall_compact"
7987   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7988          (match_operand 1 "" ""))
7989    (return)
7990    (use (match_operand:SI 2 "register_operand" "z,x"))
7991    (use (reg:SI R1_REG))
7992    (use (reg:PSI FPSCR_REG))
7993    ;; We want to make sure the `x' above will only match MACH_REG
7994    ;; because sibcall_epilogue may clobber MACL_REG.
7995    (clobber (reg:SI MACL_REG))]
7996   "TARGET_SHCOMPACT"
7997   "@
7998         jmp     @%0%#
7999         jmp     @%0\\n  sts     %2, r0"
8000   [(set_attr "needs_delay_slot" "yes,no")
8001    (set_attr "length" "2,4")
8002    (set (attr "fp_mode") (const_string "single"))
8003    (set_attr "type" "jump_ind")])
8004
8005 (define_insn "sibcall_media"
8006   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8007          (match_operand 1 "" ""))
8008    (use (reg:SI PR_MEDIA_REG))
8009    (return)]
8010   "TARGET_SHMEDIA"
8011   "blink        %0, r63"
8012   [(set_attr "type" "jump_media")])
8013
8014 (define_expand "sibcall"
8015   [(parallel
8016     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8017            (match_operand 1 "" ""))
8018      (match_operand 2 "" "")
8019      (use (reg:PSI FPSCR_REG))
8020      (return)])]
8021   ""
8022   "
8023 {
8024   if (TARGET_SHMEDIA)
8025     {
8026       operands[0] = shmedia_prepare_call_address (operands[0], 1);
8027       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8028       DONE;
8029     }
8030   else if (TARGET_SHCOMPACT && operands[2]
8031            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8032     {
8033       rtx cookie_rtx = operands[2];
8034       long cookie = INTVAL (cookie_rtx);
8035       rtx func = XEXP (operands[0], 0);
8036       rtx mach, r1;
8037
8038       if (flag_pic)
8039         {
8040           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8041             {
8042               rtx reg = gen_reg_rtx (Pmode);
8043
8044               emit_insn (gen_symGOT2reg (reg, func));
8045               func = reg;
8046             }
8047           else
8048             func = legitimize_pic_address (func, Pmode, 0);
8049         }
8050
8051       /* FIXME: if we could tell whether all argument registers are
8052          already taken, we could decide whether to force the use of
8053          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8054          simple way to tell.  We could use the CALL_COOKIE, but we
8055          can't currently tell a register used for regular argument
8056          passing from one that is unused.  If we leave it up to reload
8057          to decide which register to use, it seems to always choose
8058          R0_REG, which leaves no available registers in SIBCALL_REGS
8059          to hold the address of the trampoline.  */
8060       mach = gen_rtx_REG (SImode, MACH_REG);
8061       r1 = gen_rtx_REG (SImode, R1_REG);
8062
8063       /* Since such a call function may use all call-clobbered
8064          registers, we force a mode switch earlier, so that we don't
8065          run out of registers when adjusting fpscr for the call.  */
8066       emit_insn (gen_force_mode_for_call ());
8067
8068       operands[0]
8069         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8070                            SFUNC_GOT);
8071       operands[0] = force_reg (SImode, operands[0]);
8072
8073       /* We don't need a return trampoline, since the callee will
8074          return directly to the upper caller.  */
8075       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8076         {
8077           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8078           cookie_rtx = GEN_INT (cookie);
8079         }
8080
8081       emit_move_insn (mach, func);
8082       emit_move_insn (r1, cookie_rtx);
8083
8084       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8085       DONE;
8086     }
8087   else if (TARGET_SHCOMPACT && flag_pic
8088            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8089            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8090     {
8091       rtx reg = gen_reg_rtx (Pmode);
8092
8093       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8094       XEXP (operands[0], 0) = reg;
8095     }
8096   if (flag_pic && TARGET_SH2
8097       && GET_CODE (operands[0]) == MEM
8098       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8099       /* The PLT needs the PIC register, but the epilogue would have
8100          to restore it, so we can only use PC-relative PIC calls for
8101          static functions.  */
8102       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8103     {
8104       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8105       DONE;
8106     }
8107   else
8108     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8109
8110   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8111   DONE;
8112 }")
8113
8114 (define_insn "sibcall_valuei"
8115   [(set (match_operand 0 "" "=rf")
8116         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8117               (match_operand 2 "" "")))
8118    (use (reg:PSI FPSCR_REG))
8119    (return)]
8120   "TARGET_SH1"
8121   "jmp  @%1%#"
8122   [(set_attr "needs_delay_slot" "yes")
8123    (set (attr "fp_mode")
8124         (if_then_else (eq_attr "fpu_single" "yes")
8125                       (const_string "single") (const_string "double")))
8126    (set_attr "type" "jump_ind")])
8127
8128 (define_insn "sibcall_valuei_pcrel"
8129   [(set (match_operand 0 "" "=rf")
8130         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8131               (match_operand 2 "" "")))
8132    (use (match_operand 3 "" ""))
8133    (use (reg:PSI FPSCR_REG))
8134    (return)]
8135   "TARGET_SH2"
8136   "braf %1\\n%O3:%#"
8137   [(set_attr "needs_delay_slot" "yes")
8138    (set (attr "fp_mode")
8139         (if_then_else (eq_attr "fpu_single" "yes")
8140                       (const_string "single") (const_string "double")))
8141    (set_attr "type" "jump_ind")])
8142
8143 (define_insn_and_split "sibcall_value_pcrel"
8144   [(set (match_operand 0 "" "=rf")
8145         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8146               (match_operand 2 "" "")))
8147    (use (reg:PSI FPSCR_REG))
8148    (clobber (match_scratch:SI 3 "=k"))
8149    (return)]
8150   "TARGET_SH2"
8151   "#"
8152   "reload_completed"
8153   [(const_int 0)]
8154   "
8155 {
8156   rtx lab = PATTERN (gen_call_site ());
8157   rtx call_insn;
8158
8159   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8160   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8161                                                         operands[3],
8162                                                         operands[2],
8163                                                         copy_rtx (lab)));
8164   SIBLING_CALL_P (call_insn) = 1;
8165   DONE;
8166 }"
8167   [(set_attr "needs_delay_slot" "yes")
8168    (set (attr "fp_mode")
8169         (if_then_else (eq_attr "fpu_single" "yes")
8170                       (const_string "single") (const_string "double")))
8171    (set_attr "type" "jump_ind")])
8172
8173 (define_insn "sibcall_value_compact"
8174   [(set (match_operand 0 "" "=rf,rf")
8175         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8176               (match_operand 2 "" "")))
8177    (return)
8178    (use (match_operand:SI 3 "register_operand" "z,x"))
8179    (use (reg:SI R1_REG))
8180    (use (reg:PSI FPSCR_REG))
8181    ;; We want to make sure the `x' above will only match MACH_REG
8182    ;; because sibcall_epilogue may clobber MACL_REG.
8183    (clobber (reg:SI MACL_REG))]
8184   "TARGET_SHCOMPACT"
8185   "@
8186         jmp     @%1%#
8187         jmp     @%1\\n  sts     %3, r0"
8188   [(set_attr "needs_delay_slot" "yes,no")
8189    (set_attr "length" "2,4")
8190    (set (attr "fp_mode") (const_string "single"))
8191    (set_attr "type" "jump_ind")])
8192
8193 (define_insn "sibcall_value_media"
8194   [(set (match_operand 0 "" "=rf")
8195         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8196               (match_operand 2 "" "")))
8197    (use (reg:SI PR_MEDIA_REG))
8198    (return)]
8199   "TARGET_SHMEDIA"
8200   "blink        %1, r63"
8201   [(set_attr "type" "jump_media")])
8202
8203 (define_expand "sibcall_value"
8204   [(parallel
8205     [(set (match_operand 0 "arith_reg_operand" "")
8206           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8207                 (match_operand 2 "" "")))
8208      (match_operand 3 "" "")
8209      (use (reg:PSI FPSCR_REG))
8210      (return)])]
8211   ""
8212   "
8213 {
8214   if (TARGET_SHMEDIA)
8215     {
8216       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8217       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8218                                                operands[2]));
8219       DONE;
8220     }
8221   else if (TARGET_SHCOMPACT && operands[3]
8222            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8223     {
8224       rtx cookie_rtx = operands[3];
8225       long cookie = INTVAL (cookie_rtx);
8226       rtx func = XEXP (operands[1], 0);
8227       rtx mach, r1;
8228
8229       if (flag_pic)
8230         {
8231           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8232             {
8233               rtx reg = gen_reg_rtx (Pmode);
8234
8235               emit_insn (gen_symGOT2reg (reg, func));
8236               func = reg;
8237             }
8238           else
8239             func = legitimize_pic_address (func, Pmode, 0);
8240         }
8241
8242       /* FIXME: if we could tell whether all argument registers are
8243          already taken, we could decide whether to force the use of
8244          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8245          simple way to tell.  We could use the CALL_COOKIE, but we
8246          can't currently tell a register used for regular argument
8247          passing from one that is unused.  If we leave it up to reload
8248          to decide which register to use, it seems to always choose
8249          R0_REG, which leaves no available registers in SIBCALL_REGS
8250          to hold the address of the trampoline.  */
8251       mach = gen_rtx_REG (SImode, MACH_REG);
8252       r1 = gen_rtx_REG (SImode, R1_REG);
8253
8254       /* Since such a call function may use all call-clobbered
8255          registers, we force a mode switch earlier, so that we don't
8256          run out of registers when adjusting fpscr for the call.  */
8257       emit_insn (gen_force_mode_for_call ());
8258
8259       operands[1]
8260         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8261                            SFUNC_GOT);
8262       operands[1] = force_reg (SImode, operands[1]);
8263
8264       /* We don't need a return trampoline, since the callee will
8265          return directly to the upper caller.  */
8266       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8267         {
8268           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8269           cookie_rtx = GEN_INT (cookie);
8270         }
8271
8272       emit_move_insn (mach, func);
8273       emit_move_insn (r1, cookie_rtx);
8274
8275       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8276                                                  operands[2], mach));
8277       DONE;
8278     }
8279   else if (TARGET_SHCOMPACT && flag_pic
8280            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8281            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8282     {
8283       rtx reg = gen_reg_rtx (Pmode);
8284
8285       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8286       XEXP (operands[1], 0) = reg;
8287     }
8288   if (flag_pic && TARGET_SH2
8289       && GET_CODE (operands[1]) == MEM
8290       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8291       /* The PLT needs the PIC register, but the epilogue would have
8292          to restore it, so we can only use PC-relative PIC calls for
8293          static functions.  */
8294       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8295     {
8296       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8297                                                XEXP (operands[1], 0),
8298                                                operands[2]));
8299       DONE;
8300     }
8301   else
8302     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8303
8304   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8305   DONE;
8306 }")
8307
8308 (define_insn "call_value_pop_compact"
8309   [(set (match_operand 0 "" "=rf")
8310         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8311               (match_operand 2 "" "")))
8312    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8313                                  (match_operand 4 "immediate_operand" "n")))
8314    (match_operand 3 "immediate_operand" "n")
8315    (use (reg:SI R0_REG))
8316    (use (reg:SI R1_REG))
8317    (use (reg:PSI FPSCR_REG))
8318    (clobber (reg:SI PR_REG))]
8319   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8320   "jsr  @%1%#"
8321   [(set_attr "type" "call")
8322    (set (attr "fp_mode")
8323         (if_then_else (eq_attr "fpu_single" "yes")
8324                       (const_string "single") (const_string "double")))
8325    (set_attr "needs_delay_slot" "yes")])
8326
8327 (define_insn "call_value_pop_compact_rettramp"
8328   [(set (match_operand 0 "" "=rf")
8329         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8330               (match_operand 2 "" "")))
8331    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8332                                  (match_operand 4 "immediate_operand" "n")))
8333    (match_operand 3 "immediate_operand" "n")
8334    (use (reg:SI R0_REG))
8335    (use (reg:SI R1_REG))
8336    (use (reg:PSI FPSCR_REG))
8337    (clobber (reg:SI R10_REG))
8338    (clobber (reg:SI PR_REG))]
8339   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8340   "jsr  @%1%#"
8341   [(set_attr "type" "call")
8342    (set (attr "fp_mode")
8343         (if_then_else (eq_attr "fpu_single" "yes")
8344                       (const_string "single") (const_string "double")))
8345    (set_attr "needs_delay_slot" "yes")])
8346
8347 (define_expand "call_value_pop"
8348   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8349                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8350                                  (match_operand 2 "" "")))
8351               (match_operand 3 "" "")
8352               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8353                                             (match_operand 4 "" "")))])]
8354   "TARGET_SHCOMPACT"
8355   "
8356 {
8357   rtx cookie_rtx;
8358   long cookie;
8359   rtx func;
8360   rtx r0, r1;
8361
8362   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8363   cookie_rtx = operands[3];
8364   cookie = INTVAL (cookie_rtx);
8365   func = XEXP (operands[1], 0);
8366
8367   if (flag_pic)
8368     {
8369       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8370         {
8371           rtx reg = gen_reg_rtx (Pmode);
8372
8373           emit_insn (gen_symGOTPLT2reg (reg, func));
8374           func = reg;
8375         }
8376       else
8377         func = legitimize_pic_address (func, Pmode, 0);
8378     }
8379
8380   r0 = gen_rtx_REG (SImode, R0_REG);
8381   r1 = gen_rtx_REG (SImode, R1_REG);
8382
8383   /* Since such a call function may use all call-clobbered
8384      registers, we force a mode switch earlier, so that we don't
8385      run out of registers when adjusting fpscr for the call.  */
8386   emit_insn (gen_force_mode_for_call ());
8387
8388   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8389                                  SFUNC_GOT);
8390   operands[1] = force_reg (SImode, operands[1]);
8391
8392   emit_move_insn (r0, func);
8393   emit_move_insn (r1, cookie_rtx);
8394
8395   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8396     emit_call_insn (gen_call_value_pop_compact_rettramp
8397                         (operands[0], operands[1], operands[2],
8398                          operands[3], operands[4]));
8399   else
8400     emit_call_insn (gen_call_value_pop_compact
8401                         (operands[0], operands[1], operands[2],
8402                          operands[3], operands[4]));
8403
8404   DONE;
8405 }")
8406
8407 (define_expand "sibcall_epilogue"
8408   [(return)]
8409   ""
8410   "
8411 {
8412   sh_expand_epilogue (1);
8413   if (TARGET_SHCOMPACT)
8414     {
8415       rtx insn, set;
8416
8417       /* If epilogue clobbers r0, preserve it in macl.  */
8418       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8419         if ((set = single_set (insn))
8420             && GET_CODE (SET_DEST (set)) == REG
8421             && REGNO (SET_DEST (set)) == R0_REG)
8422           {
8423             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8424             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8425
8426             /* We can't tell at this point whether the sibcall is a
8427                sibcall_compact and, if it is, whether it uses r0 or
8428                mach as operand 2, so let the instructions that
8429                preserve r0 be optimized away if r0 turns out to be
8430                dead.  */
8431             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8432             emit_move_insn (r0, tmp);
8433             break;
8434           }
8435     }
8436   DONE;
8437 }")
8438
8439 (define_insn "indirect_jump_compact"
8440   [(set (pc)
8441         (match_operand:SI 0 "arith_reg_operand" "r"))]
8442   "TARGET_SH1"
8443   "jmp  @%0%#"
8444   [(set_attr "needs_delay_slot" "yes")
8445    (set_attr "type" "jump_ind")])
8446
8447 (define_expand "indirect_jump"
8448   [(set (pc)
8449         (match_operand 0 "register_operand" ""))]
8450   ""
8451   "
8452 {
8453   if (GET_MODE (operands[0]) != Pmode)
8454     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8455 }")
8456
8457 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8458 ;; which can be present in structured code from indirect jumps which can not
8459 ;; be present in structured code.  This allows -fprofile-arcs to work.
8460
8461 ;; For SH1 processors.
8462 (define_insn "casesi_jump_1"
8463   [(set (pc)
8464         (match_operand:SI 0 "register_operand" "r"))
8465    (use (label_ref (match_operand 1 "" "")))]
8466   "TARGET_SH1"
8467   "jmp  @%0%#"
8468   [(set_attr "needs_delay_slot" "yes")
8469    (set_attr "type" "jump_ind")])
8470
8471 ;; For all later processors.
8472 (define_insn "casesi_jump_2"
8473   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8474                       (label_ref (match_operand 1 "" ""))))
8475    (use (label_ref (match_operand 2 "" "")))]
8476   "TARGET_SH2
8477    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8478   "braf %0%#"
8479   [(set_attr "needs_delay_slot" "yes")
8480    (set_attr "type" "jump_ind")])
8481
8482 (define_insn "casesi_jump_media"
8483   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8484    (use (label_ref (match_operand 1 "" "")))]
8485   "TARGET_SHMEDIA"
8486   "blink        %0, r63"
8487   [(set_attr "type" "jump_media")])
8488
8489 ;; Call subroutine returning any type.
8490 ;; ??? This probably doesn't work.
8491
8492 (define_expand "untyped_call"
8493   [(parallel [(call (match_operand 0 "" "")
8494                     (const_int 0))
8495               (match_operand 1 "" "")
8496               (match_operand 2 "" "")])]
8497   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8498   "
8499 {
8500   int i;
8501
8502   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8503
8504   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8505     {
8506       rtx set = XVECEXP (operands[2], 0, i);
8507       emit_move_insn (SET_DEST (set), SET_SRC (set));
8508     }
8509
8510   /* The optimizer does not know that the call sets the function value
8511      registers we stored in the result block.  We avoid problems by
8512      claiming that all hard registers are used and clobbered at this
8513      point.  */
8514   emit_insn (gen_blockage ());
8515
8516   DONE;
8517 }")
8518 \f
8519 ;; ------------------------------------------------------------------------
8520 ;; Misc insns
8521 ;; ------------------------------------------------------------------------
8522
8523 (define_insn "dect"
8524   [(set (reg:SI T_REG)
8525         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8526    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8527   "TARGET_SH2"
8528   "dt   %0"
8529   [(set_attr "type" "arith")])
8530
8531 (define_insn "nop"
8532   [(const_int 0)]
8533   ""
8534   "nop")
8535
8536 ;; Load address of a label. This is only generated by the casesi expand,
8537 ;; and by machine_dependent_reorg (fixing up fp moves).
8538 ;; This must use unspec, because this only works for labels that are
8539 ;; within range,
8540
8541 (define_insn "mova"
8542   [(set (reg:SI R0_REG)
8543         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8544   "TARGET_SH1"
8545   "mova %O0,r0"
8546   [(set_attr "in_delay_slot" "no")
8547    (set_attr "type" "arith")])
8548
8549 ;; machine_dependent_reorg will make this a `mova'.
8550 (define_insn "mova_const"
8551   [(set (reg:SI R0_REG)
8552         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8553   "TARGET_SH1"
8554   "#"
8555   [(set_attr "in_delay_slot" "no")
8556    (set_attr "type" "arith")])
8557
8558 (define_expand "GOTaddr2picreg"
8559   [(set (reg:SI R0_REG)
8560         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8561                    UNSPEC_MOVA))
8562    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8563    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8564   "" "
8565 {
8566   if (TARGET_VXWORKS_RTP)
8567     {
8568       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8569       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8570       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8571       DONE;
8572     }
8573
8574   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8575   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8576
8577   if (TARGET_SHMEDIA)
8578     {
8579       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8580       rtx pic = operands[0];
8581       rtx lab = PATTERN (gen_call_site ());
8582       rtx insn, equiv;
8583
8584       equiv = operands[1];
8585       operands[1] = gen_rtx_MINUS (Pmode,
8586                                    operands[1],
8587                                    gen_rtx_CONST
8588                                    (Pmode,
8589                                     gen_rtx_MINUS (Pmode,
8590                                                    gen_rtx_CONST (Pmode,
8591                                                                   lab),
8592                                                    pc_rtx)));
8593       operands[1] = gen_sym2PIC (operands[1]);
8594       PUT_MODE (operands[1], Pmode);
8595
8596       if (Pmode == SImode)
8597         {
8598           emit_insn (gen_movsi_const (pic, operands[1]));
8599           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8600         }
8601       else
8602         {
8603           emit_insn (gen_movdi_const (pic, operands[1]));
8604           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8605         }
8606
8607       insn = emit_move_insn (operands[0], tr);
8608
8609       set_unique_reg_note (insn, REG_EQUAL, equiv);
8610
8611       DONE;
8612     }
8613 }
8614 ")
8615
8616 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8617 ;; PIC register.
8618
8619 (define_expand "vxworks_picreg"
8620   [(set (reg:SI PIC_REG)
8621         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8622    (set (reg:SI R0_REG)
8623         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8624    (set (reg:SI PIC_REG)
8625         (mem:SI (reg:SI PIC_REG)))
8626    (set (reg:SI PIC_REG)
8627         (mem:SI (plus:SI (reg:SI PIC_REG)
8628                          (reg:SI R0_REG))))]
8629   "TARGET_VXWORKS_RTP")
8630
8631 (define_insn "*ptb"
8632   [(set (match_operand 0 "target_reg_operand" "=b")
8633         (const (unspec [(match_operand 1 "" "Csy")]
8634                              UNSPEC_DATALABEL)))]
8635   "TARGET_SHMEDIA && flag_pic
8636    && satisfies_constraint_Csy (operands[1])"
8637   "ptb/u        datalabel %1, %0"
8638   [(set_attr "type" "ptabs_media")
8639    (set_attr "length" "*")])
8640
8641 (define_insn "ptrel_si"
8642   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8643         (plus:SI (match_operand:SI 1 "register_operand" "r")
8644               (pc)))
8645    (match_operand:SI 2 "" "")]
8646   "TARGET_SHMEDIA"
8647   "%O2: ptrel/u %1, %0"
8648   [(set_attr "type" "ptabs_media")])
8649
8650 (define_insn "ptrel_di"
8651   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8652         (plus:DI (match_operand:DI 1 "register_operand" "r")
8653               (pc)))
8654    (match_operand:DI 2 "" "")]
8655   "TARGET_SHMEDIA"
8656   "%O2: ptrel/u %1, %0"
8657   [(set_attr "type" "ptabs_media")])
8658
8659 (define_expand "builtin_setjmp_receiver"
8660   [(match_operand 0 "" "")]
8661   "flag_pic"
8662   "
8663 {
8664   emit_insn (gen_GOTaddr2picreg ());
8665   DONE;
8666 }")
8667
8668 (define_expand "call_site"
8669   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8670   "TARGET_SH1"
8671   "
8672 {
8673   static HOST_WIDE_INT i = 0;
8674   operands[0] = GEN_INT (i);
8675   i++;
8676 }")
8677
8678 (define_expand "sym_label2reg"
8679   [(set (match_operand:SI 0 "" "")
8680         (const:SI (minus:SI
8681                    (const:SI
8682                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8683                    (const:SI
8684                     (plus:SI
8685                      (match_operand:SI 2 "" "")
8686                      (const_int 2))))))]
8687   "TARGET_SH1" "")
8688
8689 (define_expand "symGOT_load"
8690   [(set (match_dup 2) (match_operand 1 "" ""))
8691    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8692    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8693   ""
8694   "
8695 {
8696   rtx insn, mem;
8697
8698   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8699   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8700
8701   if (TARGET_SHMEDIA)
8702     {
8703       rtx reg = operands[2];
8704
8705       if (Pmode == DImode)
8706         {      
8707           if (flag_pic > 1)
8708             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8709           else
8710             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8711         }
8712       else
8713         {
8714           if (flag_pic > 1)
8715             emit_insn (gen_movsi_const (reg, operands[1]));
8716           else
8717             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8718         }
8719     }
8720   else
8721     emit_move_insn (operands[2], operands[1]);
8722
8723   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8724                                              operands[2],
8725                                              gen_rtx_REG (Pmode, PIC_REG)));
8726
8727   /* When stack protector inserts codes after the result is set to
8728      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8729      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8730      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8731      matter because this is a rare situation.  */
8732   if (!TARGET_SHMEDIA
8733       && flag_stack_protect
8734       && GET_CODE (operands[1]) == CONST
8735       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8736       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8737       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8738                  \"__stack_chk_guard\") == 0)
8739     emit_insn (gen_blockage ());
8740
8741   /* N.B. This is not constant for a GOTPLT relocation.  */
8742   mem = gen_rtx_MEM (Pmode, operands[3]);
8743   MEM_NOTRAP_P (mem) = 1;
8744   /* ??? Should we have a special alias set for the GOT?  */
8745   insn = emit_move_insn (operands[0], mem);
8746
8747   set_unique_reg_note (insn, REG_EQUAL,
8748                        XVECEXP (XEXP (operands[1], 0), 0, 0));
8749
8750   DONE;
8751 }")
8752
8753 (define_expand "sym2GOT"
8754   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8755   ""
8756   "")
8757
8758 (define_expand "symGOT2reg"
8759   [(match_operand 0 "" "") (match_operand 1 "" "")]
8760   ""
8761   "
8762 {
8763   rtx gotsym, insn;
8764
8765   gotsym = gen_sym2GOT (operands[1]);
8766   PUT_MODE (gotsym, Pmode);
8767   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8768
8769   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8770
8771   DONE;
8772 }")
8773
8774 (define_expand "symGOTPLT2reg"
8775   [(match_operand 0 "" "") (match_operand 1 "" "")]
8776   ""
8777   "
8778 {
8779   rtx pltsym = gen_rtx_CONST (Pmode,
8780                               gen_rtx_UNSPEC (Pmode,
8781                                               gen_rtvec (1, operands[1]),
8782                                               UNSPEC_GOTPLT));
8783   emit_insn (gen_symGOT_load (operands[0], pltsym));
8784   DONE;
8785 }")
8786
8787 (define_expand "sym2GOTOFF"
8788   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8789   ""
8790   "")
8791
8792 (define_expand "symGOTOFF2reg"
8793   [(match_operand 0 "" "") (match_operand 1 "" "")]
8794   ""
8795   "
8796 {
8797   rtx gotoffsym, insn;
8798   rtx t = (!can_create_pseudo_p ()
8799            ? operands[0]
8800            : gen_reg_rtx (GET_MODE (operands[0])));
8801
8802   gotoffsym = gen_sym2GOTOFF (operands[1]);
8803   PUT_MODE (gotoffsym, Pmode);
8804   emit_move_insn (t, gotoffsym);
8805   insn = emit_move_insn (operands[0],
8806                          gen_rtx_PLUS (Pmode, t,
8807                                        gen_rtx_REG (Pmode, PIC_REG)));
8808
8809   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8810
8811   DONE;
8812 }")
8813
8814 (define_expand "symPLT_label2reg"
8815   [(set (match_operand:SI 0 "" "")
8816         (const:SI (minus:SI
8817                    (const:SI
8818                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8819                    (const:SI
8820                     (minus:SI
8821                      (const:SI (plus:SI
8822                                 (match_operand:SI 2 "" "")
8823                                 (const_int 2)))
8824                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8825    ;; Even though the PIC register is not really used by the call
8826    ;; sequence in which this is expanded, the PLT code assumes the PIC
8827    ;; register is set, so we must not skip its initialization.  Since
8828    ;; we only use this expand as part of calling sequences, and never
8829    ;; to take the address of a function, this is the best point to
8830    ;; insert the (use).  Using the PLT to take the address of a
8831    ;; function would be wrong, not only because the PLT entry could
8832    ;; then be called from a function that doesn't initialize the PIC
8833    ;; register to the proper GOT, but also because pointers to the
8834    ;; same function might not compare equal, should they be set by
8835    ;; different shared libraries.
8836    (use (reg:SI PIC_REG))]
8837   "TARGET_SH1"
8838   "")
8839
8840 (define_expand "sym2PIC"
8841   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8842   ""
8843   "")
8844
8845 ;; TLS code generation.
8846 ;; ??? this should be a define_insn_and_split
8847 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8848 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8849 ;; for details.
8850
8851 (define_insn "tls_global_dynamic"
8852   [(set (match_operand:SI 0 "register_operand" "=&z")
8853         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8854                                   UNSPEC_TLSGD))
8855               (const_int 0)))
8856    (use (reg:PSI FPSCR_REG))
8857    (use (reg:SI PIC_REG))
8858    (clobber (reg:SI PR_REG))
8859    (clobber (scratch:SI))]
8860   "TARGET_SH1"
8861   "*
8862 {
8863   return \"\\
8864 mov.l\\t1f,r4\\n\\
8865 \\tmova\\t2f,r0\\n\\
8866 \\tmov.l\\t2f,r1\\n\\
8867 \\tadd\\tr0,r1\\n\\
8868 \\tjsr\\t@r1\\n\\
8869 \\tadd\\tr12,r4\\n\\
8870 \\tbra\\t3f\\n\\
8871 \\tnop\\n\\
8872 \\t.align\\t2\\n\\
8873 1:\\t.long\\t%a1@TLSGD\\n\\
8874 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8875 3:\";
8876 }"
8877   [(set_attr "type" "tls_load")
8878    (set_attr "length" "26")])
8879
8880 (define_insn "tls_local_dynamic"
8881   [(set (match_operand:SI 0 "register_operand" "=&z")
8882         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8883                                   UNSPEC_TLSLDM))
8884               (const_int 0)))
8885    (use (reg:PSI FPSCR_REG))
8886    (use (reg:SI PIC_REG))
8887    (clobber (reg:SI PR_REG))
8888    (clobber (scratch:SI))]
8889   "TARGET_SH1"
8890   "*
8891 {
8892   return \"\\
8893 mov.l\\t1f,r4\\n\\
8894 \\tmova\\t2f,r0\\n\\
8895 \\tmov.l\\t2f,r1\\n\\
8896 \\tadd\\tr0,r1\\n\\
8897 \\tjsr\\t@r1\\n\\
8898 \\tadd\\tr12,r4\\n\\
8899 \\tbra\\t3f\\n\\
8900 \\tnop\\n\\
8901 \\t.align\\t2\\n\\
8902 1:\\t.long\\t%a1@TLSLDM\\n\\
8903 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8904 3:\";
8905 }"
8906   [(set_attr "type" "tls_load")
8907    (set_attr "length" "26")])
8908
8909 (define_expand "sym2DTPOFF"
8910   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8911   ""
8912   "")
8913
8914 (define_expand "symDTPOFF2reg"
8915   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8916   ""
8917   "
8918 {
8919   rtx dtpoffsym, insn;
8920   rtx t = (!can_create_pseudo_p ()
8921            ? operands[0]
8922            : gen_reg_rtx (GET_MODE (operands[0])));
8923
8924   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8925   PUT_MODE (dtpoffsym, Pmode);
8926   emit_move_insn (t, dtpoffsym);
8927   insn = emit_move_insn (operands[0],
8928                          gen_rtx_PLUS (Pmode, t, operands[2]));
8929   DONE;
8930 }")
8931
8932 (define_expand "sym2GOTTPOFF"
8933   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8934   ""
8935   "")
8936
8937 (define_insn "tls_initial_exec"
8938   [(set (match_operand:SI 0 "register_operand" "=&r")
8939         (unspec:SI [(match_operand:SI 1 "" "")]
8940                     UNSPEC_TLSIE))
8941    (use (reg:SI GBR_REG))
8942    (use (reg:SI PIC_REG))
8943    (clobber (reg:SI R0_REG))]
8944   ""
8945   "*
8946 {
8947   return \"\\
8948 mov.l\\t1f,r0\\n\\
8949 \\tstc\\tgbr,%0\\n\\
8950 \\tmov.l\\t@(r0,r12),r0\\n\\
8951 \\tbra\\t2f\\n\\
8952 \\tadd\\tr0,%0\\n\\
8953 \\t.align\\t2\\n\\
8954 1:\\t.long\\t%a1\\n\\
8955 2:\";
8956 }"
8957   [(set_attr "type" "tls_load")
8958    (set_attr "length" "16")])
8959
8960 (define_expand "sym2TPOFF"
8961   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8962   ""
8963   "")
8964
8965 (define_expand "symTPOFF2reg"
8966   [(match_operand 0 "" "") (match_operand 1 "" "")]
8967   ""
8968   "
8969 {
8970   rtx tpoffsym, insn;
8971
8972   tpoffsym = gen_sym2TPOFF (operands[1]);
8973   PUT_MODE (tpoffsym, Pmode);
8974   insn = emit_move_insn (operands[0], tpoffsym);
8975   DONE;
8976 }")
8977
8978 (define_insn "load_gbr"
8979   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8980    (use (reg:SI GBR_REG))]
8981   ""
8982   "stc  gbr,%0"
8983   [(set_attr "type" "tls_load")])
8984
8985 ;; case instruction for switch statements.
8986
8987 ;; Operand 0 is index
8988 ;; operand 1 is the minimum bound
8989 ;; operand 2 is the maximum bound - minimum bound + 1
8990 ;; operand 3 is CODE_LABEL for the table;
8991 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8992
8993 (define_expand "casesi"
8994   [(match_operand:SI 0 "arith_reg_operand" "")
8995    (match_operand:SI 1 "arith_reg_operand" "")
8996    (match_operand:SI 2 "arith_reg_operand" "")
8997    (match_operand 3 "" "") (match_operand 4 "" "")]
8998   ""
8999   "
9000 {
9001   rtx reg = gen_reg_rtx (SImode);
9002   rtx reg2 = gen_reg_rtx (SImode);
9003   if (TARGET_SHMEDIA)
9004     {
9005       rtx reg = gen_reg_rtx (DImode);
9006       rtx reg2 = gen_reg_rtx (DImode);
9007       rtx reg3 = gen_reg_rtx (Pmode);
9008       rtx reg4 = gen_reg_rtx (Pmode);
9009       rtx reg5 = gen_reg_rtx (Pmode);
9010       rtx load;
9011
9012       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9013       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9014       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9015
9016       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9017       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9018       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9019       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9020       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9021                                                (Pmode, operands[3])));
9022       /* Messy: can we subreg to clean this up? */
9023       if (Pmode == DImode)
9024         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9025       else
9026         load = gen_casesi_load_media (reg4,
9027                                       gen_rtx_SUBREG (DImode, reg3, 0),
9028                                       reg2, operands[3]);
9029       PUT_MODE (SET_SRC (load), Pmode);
9030       emit_insn (load);
9031       /* ??? The following add could be eliminated if we used ptrel.  */
9032       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9033       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9034       emit_barrier ();
9035       DONE;
9036     }
9037   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9038   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9039   /* If optimizing, casesi_worker depends on the mode of the instruction
9040      before label it 'uses' - operands[3].  */
9041   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9042                            reg));
9043   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9044   if (TARGET_SH2)
9045     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9046   else
9047     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9048   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9049      operands[3], but to lab.  We will fix this up in
9050      machine_dependent_reorg.  */
9051   emit_barrier ();
9052   DONE;
9053 }")
9054
9055 (define_expand "casesi_0"
9056   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9057    (set (match_dup 4) (minus:SI (match_dup 4)
9058                                 (match_operand:SI 1 "arith_operand" "")))
9059    (set (reg:SI T_REG)
9060         (gtu:SI (match_dup 4)
9061                 (match_operand:SI 2 "arith_reg_operand" "")))
9062    (set (pc)
9063         (if_then_else (ne (reg:SI T_REG)
9064                           (const_int 0))
9065                       (label_ref (match_operand 3 "" ""))
9066                       (pc)))]
9067   "TARGET_SH1"
9068   "")
9069
9070 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9071 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9072 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9073
9074 (define_insn "casesi_worker_0"
9075   [(set (match_operand:SI 0 "register_operand" "=r,r")
9076         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9077                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9078    (clobber (match_scratch:SI 3 "=X,1"))
9079    (clobber (match_scratch:SI 4 "=&z,z"))]
9080   "TARGET_SH1"
9081   "#")
9082
9083 (define_split
9084   [(set (match_operand:SI 0 "register_operand" "")
9085         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9086                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9087    (clobber (match_scratch:SI 3 ""))
9088    (clobber (match_scratch:SI 4 ""))]
9089   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9090   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9091    (parallel [(set (match_dup 0)
9092               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9093                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9094               (clobber (match_dup 3))])
9095    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9096   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9097
9098 (define_split
9099   [(set (match_operand:SI 0 "register_operand" "")
9100         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9101                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9102    (clobber (match_scratch:SI 3 ""))
9103    (clobber (match_scratch:SI 4 ""))]
9104   "TARGET_SH2 && reload_completed"
9105   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9106    (parallel [(set (match_dup 0)
9107               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9108                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9109               (clobber (match_dup 3))])]
9110   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9111
9112 (define_insn "casesi_worker_1"
9113   [(set (match_operand:SI 0 "register_operand" "=r,r")
9114         (unspec:SI [(reg:SI R0_REG)
9115                     (match_operand:SI 1 "register_operand" "0,r")
9116                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9117    (clobber (match_scratch:SI 3 "=X,1"))]
9118   "TARGET_SH1"
9119   "*
9120 {
9121   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9122
9123   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9124
9125   switch (GET_MODE (diff_vec))
9126     {
9127     case SImode:
9128       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9129     case HImode:
9130       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9131     case QImode:
9132       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9133         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9134       return \"mov.b    @(r0,%1),%0\";
9135     default:
9136       gcc_unreachable ();
9137     }
9138 }"
9139   [(set_attr "length" "4")])
9140
9141 (define_insn "casesi_worker_2"
9142   [(set (match_operand:SI 0 "register_operand" "=r,r")
9143         (unspec:SI [(reg:SI R0_REG)
9144                     (match_operand:SI 1 "register_operand" "0,r")
9145                     (label_ref (match_operand 2 "" ""))
9146                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9147    (clobber (match_operand:SI 4 "" "=X,1"))]
9148   "TARGET_SH2 && reload_completed && flag_pic"
9149   "*
9150 {
9151   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9152   const char *load;
9153
9154   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9155
9156   switch (GET_MODE (diff_vec))
9157     {
9158     case SImode:
9159       output_asm_insn (\"shll2    %1\", operands);
9160       load = \"mov.l    @(r0,%1),%0\"; break;
9161     case HImode:
9162       output_asm_insn (\"add    %1,%1\", operands);
9163       load = \"mov.w    @(r0,%1),%0\"; break;
9164     case QImode:
9165       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9166         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9167       else
9168         load = \"mov.b  @(r0,%1),%0\";
9169       break;
9170     default:
9171       gcc_unreachable ();
9172     }
9173   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9174   return load;
9175 }"
9176   [(set_attr "length" "8")])
9177
9178 (define_insn "casesi_shift_media"
9179   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9180         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9181                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9182                     UNSPEC_CASESI)))]
9183   "TARGET_SHMEDIA"
9184   "*
9185 {
9186   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9187
9188   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9189
9190   switch (GET_MODE (diff_vec))
9191     {
9192     case SImode:
9193       return \"shlli    %1, 2, %0\";
9194     case HImode:
9195       return \"shlli    %1, 1, %0\";
9196     case QImode:
9197       if (rtx_equal_p (operands[0], operands[1]))
9198         return \"\";
9199       return \"add      %1, r63, %0\";
9200     default:
9201       gcc_unreachable ();
9202     }
9203 }"
9204   [(set_attr "type" "arith_media")])
9205
9206 (define_insn "casesi_load_media"
9207   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9208         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9209                          (match_operand:DI 2 "arith_reg_operand" "r")
9210                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9211   "TARGET_SHMEDIA"
9212   "*
9213 {
9214   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9215
9216   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9217
9218   switch (GET_MODE (diff_vec))
9219     {
9220     case SImode:
9221       return \"ldx.l    %1, %2, %0\";
9222     case HImode:
9223 #if 0
9224       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9225         return \"ldx.uw %1, %2, %0\";
9226 #endif
9227       return \"ldx.w    %1, %2, %0\";
9228     case QImode:
9229       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9230         return \"ldx.ub %1, %2, %0\";
9231       return \"ldx.b    %1, %2, %0\";
9232     default:
9233       gcc_unreachable ();
9234     }
9235 }"
9236   [(set_attr "type" "load_media")])
9237
9238 (define_expand "return"
9239   [(return)]
9240   "reload_completed && ! sh_need_epilogue ()"
9241   "
9242 {
9243   if (TARGET_SHMEDIA)
9244     {
9245       emit_jump_insn (gen_return_media ());
9246       DONE;
9247     }
9248
9249   if (TARGET_SHCOMPACT
9250       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9251     {
9252       emit_jump_insn (gen_shcompact_return_tramp ());
9253       DONE;
9254     }
9255 }")
9256
9257 (define_insn "*return_i"
9258   [(return)]
9259   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9260                     && (current_function_args_info.call_cookie
9261                         & CALL_COOKIE_RET_TRAMP (1)))
9262    && reload_completed
9263    && lookup_attribute (\"trap_exit\",
9264                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9265   "%@   %#"
9266   [(set_attr "type" "return")
9267    (set_attr "needs_delay_slot" "yes")])
9268
9269 ;; trapa has no delay slot.
9270 (define_insn "*return_trapa"
9271   [(return)]
9272   "TARGET_SH1 && !TARGET_SHCOMPACT
9273    && reload_completed"
9274   "%@"
9275   [(set_attr "type" "return")])
9276
9277 (define_expand "shcompact_return_tramp"
9278   [(return)]
9279   "TARGET_SHCOMPACT
9280    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9281   "
9282 {
9283   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9284
9285   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9286   emit_jump_insn (gen_shcompact_return_tramp_i ());
9287   DONE;
9288 }")
9289
9290 (define_insn "shcompact_return_tramp_i"
9291   [(parallel [(return) (use (reg:SI R0_REG))])]
9292   "TARGET_SHCOMPACT
9293    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9294   "jmp  @r0%#"
9295   [(set_attr "type" "jump_ind")
9296    (set_attr "needs_delay_slot" "yes")])
9297
9298 (define_insn "return_media_i"
9299   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9300   "TARGET_SHMEDIA && reload_completed"
9301   "blink        %0, r63"
9302   [(set_attr "type" "jump_media")])
9303
9304 (define_insn "return_media_rte"
9305   [(return)]
9306   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9307   "rte"
9308   [(set_attr "type" "jump_media")])
9309
9310 (define_expand "return_media"
9311   [(return)]
9312   "TARGET_SHMEDIA && reload_completed"
9313   "
9314 {
9315   int tr_regno = sh_media_register_for_return ();
9316   rtx tr;
9317
9318   if (current_function_interrupt)
9319     {
9320       emit_jump_insn (gen_return_media_rte ());
9321       DONE;
9322     }
9323   if (tr_regno < 0)
9324     {
9325       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9326
9327       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9328       tr_regno = TR0_REG;
9329       tr = gen_rtx_REG (Pmode, tr_regno);
9330       emit_move_insn (tr, r18);
9331     }
9332   else
9333     tr = gen_rtx_REG (Pmode, tr_regno);
9334
9335   emit_jump_insn (gen_return_media_i (tr));
9336   DONE;
9337 }")
9338
9339 (define_insn "shcompact_preserve_incoming_args"
9340   [(set (match_operand:SI 0 "register_operand" "+r")
9341         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9342   "TARGET_SHCOMPACT"
9343   ""
9344   [(set_attr "length" "0")])
9345
9346 (define_insn "shcompact_incoming_args"
9347   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9348    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9349    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9350    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9351    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9352    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9353    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9354    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9355    (set (mem:BLK (reg:SI MACL_REG))
9356         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9357    (use (reg:SI R0_REG))
9358    (clobber (reg:SI R0_REG))
9359    (clobber (reg:SI MACL_REG))
9360    (clobber (reg:SI MACH_REG))
9361    (clobber (reg:SI PR_REG))]
9362   "TARGET_SHCOMPACT"
9363   "jsr  @r0%#"
9364   [(set_attr "needs_delay_slot" "yes")])
9365
9366 (define_insn "shmedia_save_restore_regs_compact"
9367   [(set (reg:SI SP_REG)
9368         (plus:SI (reg:SI SP_REG)
9369                  (match_operand:SI 0 "immediate_operand" "i")))
9370    (use (reg:SI R0_REG))
9371    (clobber (reg:SI PR_REG))]
9372   "TARGET_SHCOMPACT
9373    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9374        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9375   "jsr @r0%#"
9376   [(set_attr "needs_delay_slot" "yes")])
9377
9378 (define_expand "prologue"
9379   [(const_int 0)]
9380   ""
9381   "sh_expand_prologue (); DONE;")
9382
9383 (define_expand "epilogue"
9384   [(return)]
9385   ""
9386   "
9387 {
9388   sh_expand_epilogue (0);
9389   emit_jump_insn (gen_return ());
9390   DONE;
9391 }")
9392
9393 (define_expand "eh_return"
9394   [(use (match_operand 0 "register_operand" ""))]
9395   ""
9396 {
9397   rtx ra = operands[0];
9398
9399   if (TARGET_SHMEDIA64)
9400     emit_insn (gen_eh_set_ra_di (ra));
9401   else
9402     emit_insn (gen_eh_set_ra_si (ra));
9403
9404   DONE;
9405 })
9406
9407 ;; Clobber the return address on the stack.  We can't expand this
9408 ;; until we know where it will be put in the stack frame.
9409
9410 (define_insn "eh_set_ra_si"
9411   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9412       UNSPECV_EH_RETURN)
9413    (clobber (match_scratch:SI 1 "=&r"))]
9414   "! TARGET_SHMEDIA64"
9415   "#")
9416
9417 (define_insn "eh_set_ra_di"
9418   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9419       UNSPECV_EH_RETURN)
9420    (clobber (match_scratch:DI 1 "=&r"))]
9421   "TARGET_SHMEDIA64"
9422   "#")
9423
9424 (define_split
9425   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9426       UNSPECV_EH_RETURN)
9427    (clobber (match_scratch 1 ""))]
9428   "reload_completed"
9429   [(const_int 0)]
9430   "
9431 {
9432   sh_set_return_address (operands[0], operands[1]);
9433   DONE;
9434 }")
9435
9436 (define_insn "blockage"
9437   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9438   ""
9439   ""
9440   [(set_attr "length" "0")])
9441 \f
9442 ;; ------------------------------------------------------------------------
9443 ;; Scc instructions
9444 ;; ------------------------------------------------------------------------
9445
9446 (define_insn "movt"
9447   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9448         (eq:SI (reg:SI T_REG) (const_int 1)))]
9449   "TARGET_SH1"
9450   "movt %0"
9451   [(set_attr "type" "arith")])
9452
9453 (define_expand "seq"
9454   [(set (match_operand:SI 0 "arith_reg_dest" "")
9455         (match_dup 1))]
9456   ""
9457   "
9458 {
9459   if (TARGET_SHMEDIA)
9460     {
9461       rtx reg;
9462
9463       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9464       if (sh_compare_op1 != const0_rtx)
9465         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9466                                     ? GET_MODE (sh_compare_op0)
9467                                     : GET_MODE (sh_compare_op1),
9468                                     sh_compare_op1);
9469       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9470         {
9471           if (GET_MODE (operands[0]) != SImode)
9472             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9473
9474           switch (GET_MODE (sh_compare_op0))
9475             {
9476             case SImode:
9477               emit_insn (gen_cmpeqsi_media (operands[0],
9478                                               sh_compare_op0, sh_compare_op1));
9479               break;
9480
9481             case DImode:
9482               emit_insn (gen_cmpeqdi_media (operands[0],
9483                                               sh_compare_op0, sh_compare_op1));
9484               break;
9485
9486             case SFmode:
9487               if (! TARGET_SHMEDIA_FPU)
9488                 FAIL;
9489               emit_insn (gen_cmpeqsf_media (operands[0],
9490                                               sh_compare_op0, sh_compare_op1));
9491               break;
9492
9493             case DFmode:
9494               if (! TARGET_SHMEDIA_FPU)
9495                 FAIL;
9496               emit_insn (gen_cmpeqdf_media (operands[0],
9497                                               sh_compare_op0, sh_compare_op1));
9498               break;
9499
9500             default:
9501               FAIL;
9502             }
9503           DONE;
9504         }
9505
9506       reg = operands[0];
9507       if (GET_MODE (operands[0]) != SImode)
9508         reg = (!can_create_pseudo_p ()
9509                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9510                : gen_reg_rtx (SImode));
9511
9512       switch (GET_MODE (sh_compare_op0))
9513         {
9514         case SImode:
9515           emit_insn (gen_cmpeqsi_media (reg,
9516                                         sh_compare_op0, sh_compare_op1));
9517           break;
9518
9519         case DImode:
9520           emit_insn (gen_cmpeqdi_media (reg,
9521                                         sh_compare_op0, sh_compare_op1));
9522           break;
9523
9524         case SFmode:
9525           if (! TARGET_SHMEDIA_FPU)
9526             FAIL;
9527           emit_insn (gen_cmpeqsf_media (reg,
9528                                         sh_compare_op0, sh_compare_op1));
9529           break;
9530
9531         case DFmode:
9532           if (! TARGET_SHMEDIA_FPU)
9533             FAIL;
9534           emit_insn (gen_cmpeqdf_media (reg,
9535                                         sh_compare_op0, sh_compare_op1));
9536           break;
9537
9538         default:
9539           FAIL;
9540         }
9541
9542       if (GET_MODE (operands[0]) == DImode)
9543         emit_insn (gen_extendsidi2 (operands[0], reg));
9544
9545       DONE;
9546     }
9547   if (sh_expand_t_scc (EQ, operands[0]))
9548     DONE;
9549   if (! currently_expanding_to_rtl)
9550     FAIL;
9551   operands[1] = prepare_scc_operands (EQ);
9552 }")
9553
9554 (define_expand "slt"
9555   [(set (match_operand:SI 0 "arith_reg_operand" "")
9556         (match_dup 1))]
9557   ""
9558   "
9559 {
9560   if (TARGET_SHMEDIA)
9561     {
9562       rtx reg;
9563
9564       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9565       if (sh_compare_op1 != const0_rtx)
9566         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9567                                     ? GET_MODE (sh_compare_op0)
9568                                     : GET_MODE (sh_compare_op1),
9569                                     sh_compare_op1);
9570
9571       reg = operands[0];
9572       if (GET_MODE (operands[0]) != SImode)
9573         reg = (!can_create_pseudo_p ()
9574                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9575                : gen_reg_rtx (SImode));
9576
9577       switch (GET_MODE (sh_compare_op0))
9578         {
9579         case SImode:
9580           emit_insn (gen_cmpgtsi_media (reg,
9581                                         sh_compare_op1, sh_compare_op0));
9582           break;
9583
9584         case DImode:
9585           emit_insn (gen_cmpgtdi_media (reg,
9586                                         sh_compare_op1, sh_compare_op0));
9587           break;
9588
9589         case SFmode:
9590           if (! TARGET_SHMEDIA_FPU)
9591             FAIL;
9592           emit_insn (gen_cmpgtsf_media (reg,
9593                                         sh_compare_op1, sh_compare_op0));
9594           break;
9595
9596         case DFmode:
9597           if (! TARGET_SHMEDIA_FPU)
9598             FAIL;
9599           emit_insn (gen_cmpgtdf_media (reg,
9600                                         sh_compare_op1, sh_compare_op0));
9601           break;
9602
9603         default:
9604           FAIL;
9605         }
9606
9607       if (GET_MODE (operands[0]) == DImode)
9608         emit_insn (gen_extendsidi2 (operands[0], reg));
9609
9610       DONE;
9611     }
9612   if (! currently_expanding_to_rtl)
9613     FAIL;
9614   operands[1] = prepare_scc_operands (LT);
9615 }")
9616
9617 (define_expand "sle"
9618   [(match_operand:SI 0 "arith_reg_operand" "")]
9619   ""
9620   "
9621 {
9622   rtx tmp = sh_compare_op0;
9623
9624   if (TARGET_SHMEDIA)
9625     {
9626       rtx reg;
9627
9628       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9629       if (sh_compare_op1 != const0_rtx)
9630         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9631                                     ? GET_MODE (sh_compare_op0)
9632                                     : GET_MODE (sh_compare_op1),
9633                                     sh_compare_op1);
9634
9635       reg = operands[0];
9636       if (GET_MODE (operands[0]) != SImode)
9637         reg = (!can_create_pseudo_p ()
9638                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9639                : gen_reg_rtx (SImode));
9640
9641       switch (GET_MODE (sh_compare_op0))
9642         {
9643         case SImode:
9644           {
9645             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9646
9647             emit_insn (gen_cmpgtsi_media (tmp,
9648                                           sh_compare_op0, sh_compare_op1));
9649             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9650             break;
9651           }
9652
9653         case DImode:
9654           {
9655             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9656
9657             emit_insn (gen_cmpgtdi_media (tmp,
9658                                           sh_compare_op0, sh_compare_op1));
9659             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9660             break;
9661           }
9662
9663         case SFmode:
9664           if (! TARGET_SHMEDIA_FPU)
9665             FAIL;
9666           emit_insn (gen_cmpgesf_media (reg,
9667                                         sh_compare_op1, sh_compare_op0));
9668           break;
9669
9670         case DFmode:
9671           if (! TARGET_SHMEDIA_FPU)
9672             FAIL;
9673           emit_insn (gen_cmpgedf_media (reg,
9674                                         sh_compare_op1, sh_compare_op0));
9675           break;
9676
9677         default:
9678           FAIL;
9679         }
9680
9681       if (GET_MODE (operands[0]) == DImode)
9682         emit_insn (gen_extendsidi2 (operands[0], reg));
9683
9684       DONE;
9685     }
9686
9687   sh_compare_op0 = sh_compare_op1;
9688   sh_compare_op1 = tmp;
9689   emit_insn (gen_sge (operands[0]));
9690   DONE;
9691 }")
9692
9693 (define_expand "sgt"
9694   [(set (match_operand:SI 0 "arith_reg_operand" "")
9695         (match_dup 1))]
9696   ""
9697   "
9698 {
9699   if (TARGET_SHMEDIA)
9700     {
9701       rtx reg;
9702
9703       reg = operands[0];
9704       if (GET_MODE (operands[0]) != SImode)
9705         reg = (!can_create_pseudo_p () ?
9706                gen_rtx_SUBREG (SImode, operands[0], 0)
9707                : gen_reg_rtx (SImode));
9708       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9709       if (sh_compare_op1 != const0_rtx)
9710         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9711                                     ? GET_MODE (sh_compare_op0)
9712                                     : GET_MODE (sh_compare_op1),
9713                                     sh_compare_op1);
9714
9715       switch (GET_MODE (sh_compare_op0))
9716         {
9717         case SImode:
9718           emit_insn (gen_cmpgtsi_media (reg,
9719                                         sh_compare_op0, sh_compare_op1));
9720           break;
9721
9722         case DImode:
9723           emit_insn (gen_cmpgtdi_media (reg,
9724                                         sh_compare_op0, sh_compare_op1));
9725           break;
9726
9727         case SFmode:
9728           if (! TARGET_SHMEDIA_FPU)
9729             FAIL;
9730           emit_insn (gen_cmpgtsf_media (reg,
9731                                         sh_compare_op0, sh_compare_op1));
9732           break;
9733
9734         case DFmode:
9735           if (! TARGET_SHMEDIA_FPU)
9736             FAIL;
9737           emit_insn (gen_cmpgtdf_media (reg,
9738                                         sh_compare_op0, sh_compare_op1));
9739           break;
9740
9741         default:
9742           FAIL;
9743         }
9744
9745       if (GET_MODE (operands[0]) == DImode)
9746         emit_insn (gen_extendsidi2 (operands[0], reg));
9747
9748       DONE;
9749     }
9750   if (! currently_expanding_to_rtl)
9751     FAIL;
9752   operands[1] = prepare_scc_operands (GT);
9753 }")
9754
9755 (define_expand "sge"
9756   [(set (match_operand:SI 0 "arith_reg_operand" "")
9757         (match_dup 1))]
9758   ""
9759   "
9760 {
9761   if (TARGET_SHMEDIA)
9762     {
9763       rtx reg;
9764       enum machine_mode mode = GET_MODE (sh_compare_op0);
9765
9766       if ((mode) == VOIDmode)
9767         mode = GET_MODE (sh_compare_op1);
9768       reg = operands[0];
9769       if (GET_MODE (operands[0]) != SImode)
9770         reg = (!can_create_pseudo_p ()
9771                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9772                : gen_reg_rtx (SImode));
9773       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9774       if (sh_compare_op1 != const0_rtx)
9775         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9776
9777       switch (mode)
9778         {
9779         case SImode:
9780           {
9781             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9782
9783             emit_insn (gen_cmpgtsi_media (tmp,
9784                                           sh_compare_op1, sh_compare_op0));
9785             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9786             break;
9787           }
9788
9789         case DImode:
9790           {
9791             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9792
9793             emit_insn (gen_cmpgtdi_media (tmp,
9794                                           sh_compare_op1, sh_compare_op0));
9795             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9796             break;
9797           }
9798
9799         case SFmode:
9800           if (! TARGET_SHMEDIA_FPU)
9801             FAIL;
9802           emit_insn (gen_cmpgesf_media (reg,
9803                                         sh_compare_op0, sh_compare_op1));
9804           break;
9805
9806         case DFmode:
9807           if (! TARGET_SHMEDIA_FPU)
9808             FAIL;
9809           emit_insn (gen_cmpgedf_media (reg,
9810                                         sh_compare_op0, sh_compare_op1));
9811           break;
9812
9813         default:
9814           FAIL;
9815         }
9816
9817       if (GET_MODE (operands[0]) == DImode)
9818         emit_insn (gen_extendsidi2 (operands[0], reg));
9819
9820       DONE;
9821     }
9822
9823   if (! currently_expanding_to_rtl)
9824     FAIL;
9825   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9826     {
9827       if (TARGET_IEEE)
9828         {
9829           rtx lab = gen_label_rtx ();
9830           prepare_scc_operands (EQ);
9831           emit_jump_insn (gen_branch_true (lab));
9832           prepare_scc_operands (GT);
9833           emit_label (lab);
9834           emit_insn (gen_movt (operands[0]));
9835         }
9836       else
9837         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9838       DONE;
9839     }
9840   operands[1] = prepare_scc_operands (GE);
9841 }")
9842
9843 (define_expand "sgtu"
9844   [(set (match_operand:SI 0 "arith_reg_operand" "")
9845         (match_dup 1))]
9846   ""
9847   "
9848 {
9849   if (TARGET_SHMEDIA)
9850     {
9851       rtx reg;
9852
9853       reg = operands[0];
9854       if (GET_MODE (operands[0]) == DImode)
9855         reg = (!can_create_pseudo_p ()
9856                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9857                : gen_reg_rtx (SImode));
9858       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9859       if (sh_compare_op1 != const0_rtx)
9860         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9861                                     ? GET_MODE (sh_compare_op0)
9862                                     : GET_MODE (sh_compare_op1),
9863                                     sh_compare_op1);
9864
9865       emit_insn (gen_cmpgtudi_media (reg,
9866                                      sh_compare_op0, sh_compare_op1));
9867       if (GET_MODE (operands[0]) == DImode)
9868         emit_insn (gen_extendsidi2 (operands[0], reg));
9869
9870       DONE;
9871     }
9872   if (! currently_expanding_to_rtl)
9873     FAIL;
9874   operands[1] = prepare_scc_operands (GTU);
9875 }")
9876
9877 (define_expand "sltu"
9878   [(set (match_operand:SI 0 "arith_reg_operand" "")
9879         (match_dup 1))]
9880   ""
9881   "
9882 {
9883   if (TARGET_SHMEDIA)
9884     {
9885       rtx reg;
9886
9887       reg = operands[0];
9888       if (GET_MODE (operands[0]) == DImode)
9889         reg = (!can_create_pseudo_p ()
9890                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9891                : gen_reg_rtx (SImode));
9892       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9893       if (sh_compare_op1 != const0_rtx)
9894         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9895                                     ? GET_MODE (sh_compare_op0)
9896                                     : GET_MODE (sh_compare_op1),
9897                                     sh_compare_op1);
9898
9899       emit_insn (gen_cmpgtudi_media (reg,
9900                                      sh_compare_op1, sh_compare_op0));
9901       if (GET_MODE (operands[0]) == DImode)
9902         emit_insn (gen_extendsidi2 (operands[0], reg));
9903
9904       DONE;
9905     }
9906   if (! currently_expanding_to_rtl)
9907     FAIL;
9908   operands[1] = prepare_scc_operands (LTU);
9909 }")
9910
9911 (define_expand "sleu"
9912   [(set (match_operand:SI 0 "arith_reg_operand" "")
9913         (match_dup 1))]
9914   ""
9915   "
9916 {
9917   if (TARGET_SHMEDIA)
9918     {
9919       rtx tmp, reg;
9920
9921       reg = operands[0];
9922       if (GET_MODE (operands[0]) != SImode)
9923         reg = (!can_create_pseudo_p ()
9924                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9925                : gen_reg_rtx (SImode));
9926       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9927       if (sh_compare_op1 != const0_rtx)
9928         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9929                                     ? GET_MODE (sh_compare_op0)
9930                                     : GET_MODE (sh_compare_op1),
9931                                     sh_compare_op1);
9932
9933       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9934
9935       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9936       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9937       if (GET_MODE (operands[0]) == DImode)
9938         emit_insn (gen_extendsidi2 (operands[0], reg));
9939
9940       DONE;
9941     }
9942   if (! currently_expanding_to_rtl)
9943     FAIL;
9944   operands[1] = prepare_scc_operands (LEU);
9945 }")
9946
9947 (define_expand "sgeu"
9948   [(set (match_operand:SI 0 "arith_reg_operand" "")
9949         (match_dup 1))]
9950   ""
9951   "
9952 {
9953   if (TARGET_SHMEDIA)
9954     {
9955       rtx tmp, reg;
9956
9957       reg = operands[0];
9958       if (GET_MODE (operands[0]) != SImode)
9959         reg = (!can_create_pseudo_p ()
9960                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9961                : gen_reg_rtx (SImode));
9962       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9963       if (sh_compare_op1 != const0_rtx)
9964         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9965                                     ? GET_MODE (sh_compare_op0)
9966                                     : GET_MODE (sh_compare_op1),
9967                                     sh_compare_op1);
9968
9969       tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
9970
9971       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9972       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9973       if (GET_MODE (operands[0]) == DImode)
9974         emit_insn (gen_extendsidi2 (operands[0], reg));
9975
9976       DONE;
9977     }
9978
9979   if (! currently_expanding_to_rtl)
9980     FAIL;
9981   operands[1] = prepare_scc_operands (GEU);
9982 }")
9983
9984 ;; sne moves the complement of the T reg to DEST like this:
9985 ;;      cmp/eq ...
9986 ;;      mov    #-1,temp
9987 ;;      negc   temp,dest
9988 ;;   This is better than xoring compare result with 1 because it does
9989 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9990 ;;   loop.
9991
9992 (define_expand "sne"
9993   [(set (match_dup 2) (const_int -1))
9994    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9995                    (neg:SI (plus:SI (match_dup 1)
9996                                     (match_dup 2))))
9997               (set (reg:SI T_REG)
9998                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9999                           (const_int 0)))])]
10000   ""
10001   "
10002 {
10003   if (TARGET_SHMEDIA)
10004     {
10005       rtx tmp, reg;
10006
10007       reg = operands[0];
10008       if (GET_MODE (operands[0]) != SImode)
10009         reg = (!can_create_pseudo_p ()
10010                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10011                : gen_reg_rtx (SImode));
10012       if (! TARGET_SHMEDIA_FPU
10013           && GET_MODE (sh_compare_op0) != DImode
10014           && GET_MODE (sh_compare_op0) != SImode)
10015         FAIL;
10016
10017       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10018       if (sh_compare_op1 != const0_rtx)
10019         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10020                                     ? GET_MODE (sh_compare_op0)
10021                                     : GET_MODE (sh_compare_op1),
10022                                     sh_compare_op1);
10023
10024       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10025
10026       emit_insn (gen_seq (tmp));
10027       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10028       if (GET_MODE (operands[0]) == DImode)
10029         emit_insn (gen_extendsidi2 (operands[0], reg));
10030
10031       DONE;
10032     }
10033
10034   if (sh_expand_t_scc (NE, operands[0]))
10035     DONE;
10036   if (! currently_expanding_to_rtl)
10037     FAIL;
10038   operands[1] = prepare_scc_operands (EQ);
10039   operands[2] = gen_reg_rtx (SImode);
10040 }")
10041
10042 (define_expand "sunordered"
10043   [(set (match_operand:SI 0 "arith_reg_operand" "")
10044         (unordered:SI (match_dup 1) (match_dup 2)))]
10045   "TARGET_SHMEDIA_FPU"
10046   "
10047 {
10048   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10049   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10050 }")
10051
10052 ;; Use the same trick for FP sle / sge
10053
10054 ;; Apart from the constant use and the T setting, this is like movt,
10055 ;; except that it uses the logically negated value of T, i.e.
10056 ;; operand[0] := T ? 0 : 1.
10057 (define_expand "movnegt"
10058   [(set (match_dup 2) (const_int -1))
10059    (parallel [(set (match_operand 0 "" "")
10060                    (neg:SI (plus:SI (match_dup 1)
10061                                     (match_dup 2))))
10062               (set (reg:SI T_REG)
10063                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10064                           (const_int 0)))])]
10065   "TARGET_SH1"
10066   "operands[2] = gen_reg_rtx (SImode);")
10067
10068 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10069 ;; This prevents a regression that occurred when we switched from xor to
10070 ;; mov/neg for sne.
10071
10072 (define_split
10073   [(set (match_operand:SI 0 "arith_reg_dest" "")
10074         (plus:SI (reg:SI T_REG)
10075                  (const_int -1)))]
10076   "TARGET_SH1"
10077   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10078    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10079   "")
10080
10081 ;; -------------------------------------------------------------------------
10082 ;; Instructions to cope with inline literal tables
10083 ;; -------------------------------------------------------------------------
10084
10085 ; 2 byte integer in line
10086
10087 (define_insn "consttable_2"
10088  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10089                     (match_operand 1 "" "")]
10090                    UNSPECV_CONST2)]
10091  ""
10092  "*
10093 {
10094   if (operands[1] != const0_rtx)
10095     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10096   return \"\";
10097 }"
10098  [(set_attr "length" "2")
10099  (set_attr "in_delay_slot" "no")])
10100
10101 ; 4 byte integer in line
10102
10103 (define_insn "consttable_4"
10104  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10105                     (match_operand 1 "" "")]
10106                    UNSPECV_CONST4)]
10107  ""
10108  "*
10109 {
10110   if (operands[1] != const0_rtx)
10111     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10112   return \"\";
10113 }"
10114  [(set_attr "length" "4")
10115   (set_attr "in_delay_slot" "no")])
10116
10117 ; 8 byte integer in line
10118
10119 (define_insn "consttable_8"
10120  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10121                     (match_operand 1 "" "")]
10122                    UNSPECV_CONST8)]
10123  ""
10124  "*
10125 {
10126   if (operands[1] != const0_rtx)
10127     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10128   return \"\";
10129 }"
10130  [(set_attr "length" "8")
10131   (set_attr "in_delay_slot" "no")])
10132
10133 ; 4 byte floating point
10134
10135 (define_insn "consttable_sf"
10136  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10137                     (match_operand 1 "" "")]
10138                    UNSPECV_CONST4)]
10139  ""
10140  "*
10141 {
10142   if (operands[1] != const0_rtx)
10143     {
10144       REAL_VALUE_TYPE d;
10145       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10146       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10147     }
10148   return \"\";
10149 }"
10150  [(set_attr "length" "4")
10151   (set_attr "in_delay_slot" "no")])
10152
10153 ; 8 byte floating point
10154
10155 (define_insn "consttable_df"
10156  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10157                     (match_operand 1 "" "")]
10158                    UNSPECV_CONST8)]
10159  ""
10160  "*
10161 {
10162   if (operands[1] != const0_rtx)
10163     {
10164       REAL_VALUE_TYPE d;
10165       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10166       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10167     }
10168   return \"\";
10169 }"
10170  [(set_attr "length" "8")
10171   (set_attr "in_delay_slot" "no")])
10172
10173 ;; Alignment is needed for some constant tables; it may also be added for
10174 ;; Instructions at the start of loops, or after unconditional branches.
10175 ;; ??? We would get more accurate lengths if we did instruction
10176 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10177 ;; here is too conservative.
10178
10179 ; align to a two byte boundary
10180
10181 (define_expand "align_2"
10182  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10183  ""
10184  "")
10185
10186 ; align to a four byte boundary
10187 ;; align_4 and align_log are instructions for the starts of loops, or
10188 ;; after unconditional branches, which may take up extra room.
10189
10190 (define_expand "align_4"
10191  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10192  ""
10193  "")
10194
10195 ; align to a cache line boundary
10196
10197 (define_insn "align_log"
10198  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10199  ""
10200  ""
10201  [(set_attr "length" "0")
10202   (set_attr "in_delay_slot" "no")])
10203
10204 ; emitted at the end of the literal table, used to emit the
10205 ; 32bit branch labels if needed.
10206
10207 (define_insn "consttable_end"
10208   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10209   ""
10210   "* return output_jump_label_table ();"
10211   [(set_attr "in_delay_slot" "no")])
10212
10213 ; emitted at the end of the window in the literal table.
10214
10215 (define_insn "consttable_window_end"
10216   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10217   ""
10218   ""
10219   [(set_attr "length" "0")
10220    (set_attr "in_delay_slot" "no")])
10221
10222 ;; -------------------------------------------------------------------------
10223 ;; Misc
10224 ;; -------------------------------------------------------------------------
10225
10226 ;; String/block move insn.
10227
10228 (define_expand "movmemsi"
10229   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10230                    (mem:BLK (match_operand:BLK 1 "" "")))
10231               (use (match_operand:SI 2 "nonmemory_operand" ""))
10232               (use (match_operand:SI 3 "immediate_operand" ""))
10233               (clobber (reg:SI PR_REG))
10234               (clobber (reg:SI R4_REG))
10235               (clobber (reg:SI R5_REG))
10236               (clobber (reg:SI R0_REG))])]
10237   "TARGET_SH1 && ! TARGET_SH5"
10238   "
10239 {
10240   if(expand_block_move (operands))
10241      DONE;
10242   else FAIL;
10243 }")
10244
10245 (define_insn "block_move_real"
10246   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10247                    (mem:BLK (reg:SI R5_REG)))
10248               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10249               (clobber (reg:SI PR_REG))
10250               (clobber (reg:SI R0_REG))])]
10251   "TARGET_SH1 && ! TARGET_HARD_SH4"
10252   "jsr  @%0%#"
10253   [(set_attr "type" "sfunc")
10254    (set_attr "needs_delay_slot" "yes")])
10255
10256 (define_insn "block_lump_real"
10257   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10258                    (mem:BLK (reg:SI R5_REG)))
10259               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10260               (use (reg:SI R6_REG))
10261               (clobber (reg:SI PR_REG))
10262               (clobber (reg:SI T_REG))
10263               (clobber (reg:SI R4_REG))
10264               (clobber (reg:SI R5_REG))
10265               (clobber (reg:SI R6_REG))
10266               (clobber (reg:SI R0_REG))])]
10267   "TARGET_SH1 && ! TARGET_HARD_SH4"
10268   "jsr  @%0%#"
10269   [(set_attr "type" "sfunc")
10270    (set_attr "needs_delay_slot" "yes")])
10271
10272 (define_insn "block_move_real_i4"
10273   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10274                    (mem:BLK (reg:SI R5_REG)))
10275               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10276               (clobber (reg:SI PR_REG))
10277               (clobber (reg:SI R0_REG))
10278               (clobber (reg:SI R1_REG))
10279               (clobber (reg:SI R2_REG))])]
10280   "TARGET_HARD_SH4"
10281   "jsr  @%0%#"
10282   [(set_attr "type" "sfunc")
10283    (set_attr "needs_delay_slot" "yes")])
10284
10285 (define_insn "block_lump_real_i4"
10286   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10287                    (mem:BLK (reg:SI R5_REG)))
10288               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10289               (use (reg:SI R6_REG))
10290               (clobber (reg:SI PR_REG))
10291               (clobber (reg:SI T_REG))
10292               (clobber (reg:SI R4_REG))
10293               (clobber (reg:SI R5_REG))
10294               (clobber (reg:SI R6_REG))
10295               (clobber (reg:SI R0_REG))
10296               (clobber (reg:SI R1_REG))
10297               (clobber (reg:SI R2_REG))
10298               (clobber (reg:SI R3_REG))])]
10299   "TARGET_HARD_SH4"
10300   "jsr  @%0%#"
10301   [(set_attr "type" "sfunc")
10302    (set_attr "needs_delay_slot" "yes")])
10303 \f
10304 ;; -------------------------------------------------------------------------
10305 ;; Floating point instructions.
10306 ;; -------------------------------------------------------------------------
10307
10308 ;; ??? All patterns should have a type attribute.
10309
10310 (define_expand "movpsi"
10311   [(set (match_operand:PSI 0 "register_operand" "")
10312         (match_operand:PSI 1 "general_movsrc_operand" ""))]
10313   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10314   "")
10315
10316 ;; The c / m alternative is a fake to guide reload to load directly into
10317 ;; fpscr, since reload doesn't know how to use post-increment.
10318 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10319 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10320 ;; predicate after reload.
10321 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10322 ;; like a mac -> gpr move.
10323 (define_insn "fpu_switch"
10324   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10325         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10326   "TARGET_SH2E
10327    && (! reload_completed
10328        || true_regnum (operands[0]) != FPSCR_REG
10329        || GET_CODE (operands[1]) != MEM
10330        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10331   "@
10332         ! precision stays the same
10333         lds.l   %1,fpscr
10334         mov.l   %1,%0
10335         #
10336         lds     %1,fpscr
10337         mov     %1,%0
10338         mov.l   %1,%0
10339         sts     fpscr,%0
10340         sts.l   fpscr,%0"
10341   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10342    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10343
10344 (define_peephole2
10345   [(set (reg:PSI FPSCR_REG)
10346         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10347   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10348   [(const_int 0)]
10349 {
10350   rtx fpscr, mem, new_insn;
10351
10352   fpscr = SET_DEST (PATTERN (curr_insn));
10353   mem = SET_SRC (PATTERN (curr_insn));
10354   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10355
10356   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10357   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10358   DONE;
10359 })
10360
10361 (define_split
10362   [(set (reg:PSI FPSCR_REG)
10363         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10364   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10365    && (flag_peephole2 ? epilogue_completed : reload_completed)"
10366   [(const_int 0)]
10367 {
10368   rtx fpscr, mem, new_insn;
10369
10370   fpscr = SET_DEST (PATTERN (curr_insn));
10371   mem = SET_SRC (PATTERN (curr_insn));
10372   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10373
10374   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10375   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10376
10377   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10378     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10379   DONE;
10380 })
10381
10382 ;; ??? This uses the fp unit, but has no type indicating that.
10383 ;; If we did that, this would either give a bogus latency or introduce
10384 ;; a bogus FIFO constraint.
10385 ;; Since this insn is currently only used for prologues/epilogues,
10386 ;; it is probably best to claim no function unit, which matches the
10387 ;; current setting.
10388 (define_insn "toggle_sz"
10389   [(set (reg:PSI FPSCR_REG)
10390         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10391   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10392   "fschg"
10393   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10394
10395 ;; There's no way we can use it today, since optimize mode switching
10396 ;; doesn't enable us to know from which mode we're switching to the
10397 ;; mode it requests, to tell whether we can use a relative mode switch
10398 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10399 ;; memory).
10400 (define_insn "toggle_pr"
10401   [(set (reg:PSI FPSCR_REG)
10402         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10403   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10404   "fpchg"
10405   [(set_attr "type" "fpscr_toggle")])
10406
10407 (define_expand "addsf3"
10408   [(set (match_operand:SF 0 "arith_reg_operand" "")
10409         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10410                  (match_operand:SF 2 "arith_reg_operand" "")))]
10411   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10412   "
10413 {
10414   if (TARGET_SH2E)
10415     {
10416       expand_sf_binop (&gen_addsf3_i, operands);
10417       DONE;
10418     }
10419 }")
10420
10421 (define_insn "*addsf3_media"
10422   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10423         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10424                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10425   "TARGET_SHMEDIA_FPU"
10426   "fadd.s       %1, %2, %0"
10427   [(set_attr "type" "fparith_media")])
10428
10429 (define_insn_and_split "unary_sf_op"
10430   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10431         (vec_select:V2SF
10432          (vec_concat:V2SF
10433           (vec_select:SF
10434            (match_dup 0)
10435            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10436           (match_operator:SF 2 "unary_float_operator"
10437             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10438                             (parallel [(match_operand 4
10439                                         "const_int_operand" "n")]))]))
10440          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10441   "TARGET_SHMEDIA_FPU"
10442   "#"
10443   "TARGET_SHMEDIA_FPU && reload_completed"
10444   [(set (match_dup 5) (match_dup 6))]
10445   "
10446 {
10447   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10448   rtx op1 = gen_rtx_REG (SFmode,
10449                          (true_regnum (operands[1])
10450                           + (INTVAL (operands[4]) ^ endian)));
10451
10452   operands[7] = gen_rtx_REG (SFmode,
10453                              (true_regnum (operands[0])
10454                               + (INTVAL (operands[3]) ^ endian)));
10455   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10456 }"
10457   [(set_attr "type" "fparith_media")])
10458
10459 (define_insn_and_split "binary_sf_op0"
10460   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10461         (vec_concat:V2SF
10462           (match_operator:SF 3 "binary_float_operator"
10463             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10464                             (parallel [(const_int 0)]))
10465              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10466                             (parallel [(const_int 0)]))])
10467           (vec_select:SF
10468            (match_dup 0)
10469            (parallel [(const_int 1)]))))]
10470   "TARGET_SHMEDIA_FPU"
10471   "#"
10472   "&& reload_completed"
10473   [(set (match_dup 4) (match_dup 5))]
10474   "
10475 {
10476   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10477   rtx op1 = gen_rtx_REG (SFmode,
10478                          true_regnum (operands[1]) + endian);
10479   rtx op2 = gen_rtx_REG (SFmode,
10480                          true_regnum (operands[2]) + endian);
10481
10482   operands[4] = gen_rtx_REG (SFmode,
10483                              true_regnum (operands[0]) + endian);
10484   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10485 }"
10486   [(set_attr "type" "fparith_media")])
10487
10488 (define_insn_and_split "binary_sf_op1"
10489   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10490         (vec_concat:V2SF
10491           (vec_select:SF
10492            (match_dup 0)
10493            (parallel [(const_int 0)]))
10494           (match_operator:SF 3 "binary_float_operator"
10495             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10496                             (parallel [(const_int 1)]))
10497              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10498                             (parallel [(const_int 1)]))])))]
10499   "TARGET_SHMEDIA_FPU"
10500   "#"
10501   "&& reload_completed"
10502   [(set (match_dup 4) (match_dup 5))]
10503   "
10504 {
10505   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10506   rtx op1 = gen_rtx_REG (SFmode,
10507                          true_regnum (operands[1]) + (1 ^ endian));
10508   rtx op2 = gen_rtx_REG (SFmode,
10509                          true_regnum (operands[2]) + (1 ^ endian));
10510
10511   operands[4] = gen_rtx_REG (SFmode,
10512                              true_regnum (operands[0]) + (1 ^ endian));
10513   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10514 }"
10515   [(set_attr "type" "fparith_media")])
10516
10517 (define_insn "addsf3_i"
10518   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10519         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10520                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10521    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10522   "TARGET_SH2E"
10523   "fadd %2,%0"
10524   [(set_attr "type" "fp")
10525    (set_attr "fp_mode" "single")])
10526
10527 (define_expand "subsf3"
10528   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10529         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10530                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10531   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10532   "
10533 {
10534   if (TARGET_SH2E)
10535     {
10536       expand_sf_binop (&gen_subsf3_i, operands);
10537       DONE;
10538     }
10539 }")
10540
10541 (define_insn "*subsf3_media"
10542   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10543         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10544                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10545   "TARGET_SHMEDIA_FPU"
10546   "fsub.s       %1, %2, %0"
10547   [(set_attr "type" "fparith_media")])
10548
10549 (define_insn "subsf3_i"
10550   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10551         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10552                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10553    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10554   "TARGET_SH2E"
10555   "fsub %2,%0"
10556   [(set_attr "type" "fp")
10557    (set_attr "fp_mode" "single")])
10558
10559 (define_expand "mulsf3"
10560   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10561         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10562                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10563   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10564   "")
10565
10566 (define_insn "*mulsf3_media"
10567   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10568         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10569                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10570   "TARGET_SHMEDIA_FPU"
10571   "fmul.s       %1, %2, %0"
10572   [(set_attr "type" "fparith_media")])
10573
10574 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10575 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10576 ;; we start out with a mulsf pattern that does not depend on fpscr.
10577 ;; This is split after combine to introduce the dependency, in order to
10578 ;; get mode switching and scheduling right.
10579 (define_insn_and_split "mulsf3_ie"
10580   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10581         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10582                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10583   "TARGET_SH2E"
10584   "fmul %2,%0"
10585   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10586   [(const_int 0)]
10587   "
10588 {
10589   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10590              get_fpscr_rtx ()));
10591   DONE;
10592 }"
10593   [(set_attr "type" "fp")])
10594
10595 (define_insn "mulsf3_i4"
10596   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10597         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10598                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10599    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10600   "TARGET_SH2E"
10601   "fmul %2,%0"
10602   [(set_attr "type" "fp")
10603    (set_attr "fp_mode" "single")])
10604
10605 (define_insn "mac_media"
10606   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10607         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10608                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10609                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10610   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10611   "fmac.s %1, %2, %0"
10612   [(set_attr "type" "fparith_media")])
10613
10614 (define_insn "*macsf3"
10615   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10616         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10617                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10618                  (match_operand:SF 3 "arith_reg_operand" "0")))
10619    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10620   "TARGET_SH2E && TARGET_FMAC"
10621   "fmac fr0,%2,%0"
10622   [(set_attr "type" "fp")
10623    (set_attr "fp_mode" "single")])
10624
10625 (define_expand "divsf3"
10626   [(set (match_operand:SF 0 "arith_reg_operand" "")
10627         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10628                 (match_operand:SF 2 "arith_reg_operand" "")))]
10629   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10630   "
10631 {
10632   if (TARGET_SH2E)
10633     {
10634       expand_sf_binop (&gen_divsf3_i, operands);
10635       DONE;
10636     }
10637 }")
10638
10639 (define_insn "*divsf3_media"
10640   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10641         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10642                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10643   "TARGET_SHMEDIA_FPU"
10644   "fdiv.s       %1, %2, %0"
10645   [(set_attr "type" "fdiv_media")])
10646
10647 (define_insn "divsf3_i"
10648   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10649         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10650                  (match_operand:SF 2 "arith_reg_operand" "f")))
10651    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10652   "TARGET_SH2E"
10653   "fdiv %2,%0"
10654   [(set_attr "type" "fdiv")
10655    (set_attr "fp_mode" "single")])
10656
10657 (define_insn "floatdisf2"
10658   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10659         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10660   "TARGET_SHMEDIA_FPU"
10661   "float.qs %1, %0"
10662   [(set_attr "type" "fpconv_media")])
10663
10664 (define_expand "floatsisf2"
10665   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10666         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10667   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10668   "
10669 {
10670   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10671     {
10672       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10673       DONE;
10674     }
10675 }")
10676
10677 (define_insn "*floatsisf2_media"
10678   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10679         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10680   "TARGET_SHMEDIA_FPU"
10681   "float.ls     %1, %0"
10682   [(set_attr "type" "fpconv_media")])
10683
10684 (define_insn "floatsisf2_i4"
10685   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10686         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10687    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10688   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10689   "float        %1,%0"
10690   [(set_attr "type" "fp")
10691    (set_attr "fp_mode" "single")])
10692
10693 (define_insn "*floatsisf2_ie"
10694   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10695         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10696   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10697   "float        %1,%0"
10698   [(set_attr "type" "fp")])
10699
10700 (define_insn "fix_truncsfdi2"
10701   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10702         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10703   "TARGET_SHMEDIA_FPU"
10704   "ftrc.sq %1, %0"
10705   [(set_attr "type" "fpconv_media")])
10706
10707 (define_expand "fix_truncsfsi2"
10708   [(set (match_operand:SI 0 "fpul_operand" "=y")
10709         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10710   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10711   "
10712 {
10713   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10714     {
10715       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10716       DONE;
10717     }
10718 }")
10719
10720 (define_insn "*fix_truncsfsi2_media"
10721   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10722         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10723   "TARGET_SHMEDIA_FPU"
10724   "ftrc.sl      %1, %0"
10725   [(set_attr "type" "fpconv_media")])
10726
10727 (define_insn "fix_truncsfsi2_i4"
10728   [(set (match_operand:SI 0 "fpul_operand" "=y")
10729         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10730    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10731   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10732   "ftrc %1,%0"
10733   [(set_attr "type" "ftrc_s")
10734    (set_attr "fp_mode" "single")])
10735
10736 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10737 ;; fix_truncsfsi2_i4.
10738 ;; (define_insn "fix_truncsfsi2_i4_2"
10739 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10740 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10741 ;;   (use (reg:PSI FPSCR_REG))
10742 ;;   (clobber (reg:SI FPUL_REG))]
10743 ;;  "TARGET_SH4"
10744 ;;  "#"
10745 ;;  [(set_attr "length" "4")
10746 ;;   (set_attr "fp_mode" "single")])
10747
10748 ;;(define_split
10749 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10750 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10751 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10752 ;;   (clobber (reg:SI FPUL_REG))]
10753 ;;  "TARGET_SH4"
10754 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10755 ;;            (use (match_dup 2))])
10756 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10757
10758 (define_insn "*fixsfsi"
10759   [(set (match_operand:SI 0 "fpul_operand" "=y")
10760         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10761   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10762   "ftrc %1,%0"
10763   [(set_attr "type" "fp")])
10764
10765 (define_insn "cmpgtsf_t"
10766   [(set (reg:SI T_REG)
10767         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10768                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10769   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10770   "fcmp/gt      %1,%0"
10771   [(set_attr "type" "fp_cmp")
10772    (set_attr "fp_mode" "single")])
10773
10774 (define_insn "cmpeqsf_t"
10775   [(set (reg:SI T_REG)
10776         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10777                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10778   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10779   "fcmp/eq      %1,%0"
10780   [(set_attr "type" "fp_cmp")
10781    (set_attr "fp_mode" "single")])
10782
10783 (define_insn "ieee_ccmpeqsf_t"
10784   [(set (reg:SI T_REG)
10785         (ior:SI (reg:SI T_REG)
10786                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10787                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10788   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10789   "* return output_ieee_ccmpeq (insn, operands);"
10790   [(set_attr "length" "4")])
10791
10792
10793 (define_insn "cmpgtsf_t_i4"
10794   [(set (reg:SI T_REG)
10795         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10796                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10797    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10798   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10799   "fcmp/gt      %1,%0"
10800   [(set_attr "type" "fp_cmp")
10801    (set_attr "fp_mode" "single")])
10802
10803 (define_insn "cmpeqsf_t_i4"
10804   [(set (reg:SI T_REG)
10805         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10806                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10807    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10808   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10809   "fcmp/eq      %1,%0"
10810   [(set_attr "type" "fp_cmp")
10811    (set_attr "fp_mode" "single")])
10812
10813 (define_insn "*ieee_ccmpeqsf_t_4"
10814   [(set (reg:SI T_REG)
10815         (ior:SI (reg:SI T_REG)
10816                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10817                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10818    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10819   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10820   "* return output_ieee_ccmpeq (insn, operands);"
10821   [(set_attr "length" "4")
10822    (set_attr "fp_mode" "single")])
10823
10824 (define_insn "cmpeqsf_media"
10825   [(set (match_operand:SI 0 "register_operand" "=r")
10826         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10827                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10828   "TARGET_SHMEDIA_FPU"
10829   "fcmpeq.s     %1, %2, %0"
10830   [(set_attr "type" "fcmp_media")])
10831
10832 (define_insn "cmpgtsf_media"
10833   [(set (match_operand:SI 0 "register_operand" "=r")
10834         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10835                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10836   "TARGET_SHMEDIA_FPU"
10837   "fcmpgt.s     %1, %2, %0"
10838   [(set_attr "type" "fcmp_media")])
10839
10840 (define_insn "cmpgesf_media"
10841   [(set (match_operand:SI 0 "register_operand" "=r")
10842         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10843                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10844   "TARGET_SHMEDIA_FPU"
10845   "fcmpge.s     %1, %2, %0"
10846   [(set_attr "type" "fcmp_media")])
10847
10848 (define_insn "cmpunsf_media"
10849   [(set (match_operand:SI 0 "register_operand" "=r")
10850         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10851                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10852   "TARGET_SHMEDIA_FPU"
10853   "fcmpun.s     %1, %2, %0"
10854   [(set_attr "type" "fcmp_media")])
10855
10856 (define_expand "cmpsf"
10857   [(set (reg:SI T_REG)
10858         (compare (match_operand:SF 0 "arith_operand" "")
10859                  (match_operand:SF 1 "arith_operand" "")))]
10860   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10861   "
10862 {
10863   sh_compare_op0 = operands[0];
10864   sh_compare_op1 = operands[1];
10865   DONE;
10866 }")
10867
10868 (define_expand "negsf2"
10869   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10870         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10871   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10872   "
10873 {
10874   if (TARGET_SH2E)
10875     {
10876       expand_sf_unop (&gen_negsf2_i, operands);
10877       DONE;
10878     }
10879 }")
10880
10881 (define_insn "*negsf2_media"
10882   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10883         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10884   "TARGET_SHMEDIA_FPU"
10885   "fneg.s       %1, %0"
10886   [(set_attr "type" "fmove_media")])
10887
10888 (define_insn "negsf2_i"
10889   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10890         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10891    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10892   "TARGET_SH2E"
10893   "fneg %0"
10894   [(set_attr "type" "fmove")
10895    (set_attr "fp_mode" "single")])
10896
10897 (define_expand "sqrtsf2"
10898   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10899         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10900   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10901   "
10902 {
10903   if (TARGET_SH3E)
10904     {
10905       expand_sf_unop (&gen_sqrtsf2_i, operands);
10906       DONE;
10907     }
10908 }")
10909
10910 (define_insn "*sqrtsf2_media"
10911   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10912         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10913   "TARGET_SHMEDIA_FPU"
10914   "fsqrt.s      %1, %0"
10915   [(set_attr "type" "fdiv_media")])
10916
10917 (define_insn "sqrtsf2_i"
10918   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10919         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10920    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10921   "TARGET_SH3E"
10922   "fsqrt        %0"
10923   [(set_attr "type" "fdiv")
10924    (set_attr "fp_mode" "single")])
10925
10926 (define_insn "rsqrtsf2"
10927   [(set (match_operand:SF 0 "register_operand" "=f")
10928         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10929                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10930    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10931   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10932    && operands[1] == CONST1_RTX (SFmode)"
10933   "fsrra        %0"
10934   [(set_attr "type" "fsrra")
10935    (set_attr "fp_mode" "single")])
10936
10937 (define_insn "fsca"
10938   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10939         (vec_concat:V2SF
10940          (unspec:SF [(mult:SF
10941                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10942                       (match_operand:SF 2 "immediate_operand" "i"))
10943                     ] UNSPEC_FSINA)
10944          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10945                     ] UNSPEC_FCOSA)))
10946    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10947   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10948    && operands[2] == sh_fsca_int2sf ()"
10949   "fsca fpul,%d0"
10950   [(set_attr "type" "fsca")
10951    (set_attr "fp_mode" "single")])
10952
10953 (define_expand "sinsf2"
10954   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10955         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10956                    UNSPEC_FSINA))]
10957   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10958   "
10959 {
10960   rtx scaled = gen_reg_rtx (SFmode);
10961   rtx truncated = gen_reg_rtx (SImode);
10962   rtx fsca = gen_reg_rtx (V2SFmode);
10963   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10964
10965   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10966   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10967   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10968                           get_fpscr_rtx ()));
10969   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10970   DONE;
10971 }")
10972
10973 (define_expand "cossf2"
10974   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10975         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10976                    UNSPEC_FCOSA))]
10977   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10978   "
10979 {
10980   rtx scaled = gen_reg_rtx (SFmode);
10981   rtx truncated = gen_reg_rtx (SImode);
10982   rtx fsca = gen_reg_rtx (V2SFmode);
10983   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10984
10985   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10986   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10987   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10988                           get_fpscr_rtx ()));
10989   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10990   DONE;
10991 }")
10992
10993 (define_expand "sindf2"
10994   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10995         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10996                    UNSPEC_FSINA))]
10997   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10998   "
10999 {
11000   rtx scaled = gen_reg_rtx (DFmode);
11001   rtx truncated = gen_reg_rtx (SImode);
11002   rtx fsca = gen_reg_rtx (V2SFmode);
11003   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11004   rtx sfresult = gen_reg_rtx (SFmode);
11005
11006   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11007   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11008   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11009                           get_fpscr_rtx ()));
11010   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11011   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11012   DONE;
11013 }")
11014
11015 (define_expand "cosdf2"
11016   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11017         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11018                    UNSPEC_FCOSA))]
11019   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11020   "
11021 {
11022   rtx scaled = gen_reg_rtx (DFmode);
11023   rtx truncated = gen_reg_rtx (SImode);
11024   rtx fsca = gen_reg_rtx (V2SFmode);
11025   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11026   rtx sfresult = gen_reg_rtx (SFmode);
11027
11028   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11029   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11030   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11031                           get_fpscr_rtx ()));
11032   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11033   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11034   DONE;
11035 }")
11036
11037 (define_expand "abssf2"
11038   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11039         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11040   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11041   "
11042 {
11043   if (TARGET_SH2E)
11044     {
11045       expand_sf_unop (&gen_abssf2_i, operands);
11046       DONE;
11047     }
11048 }")
11049
11050 (define_insn "*abssf2_media"
11051   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11052         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11053   "TARGET_SHMEDIA_FPU"
11054   "fabs.s       %1, %0"
11055   [(set_attr "type" "fmove_media")])
11056
11057 (define_insn "abssf2_i"
11058   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11059         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11060    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11061   "TARGET_SH2E"
11062   "fabs %0"
11063   [(set_attr "type" "fmove")
11064    (set_attr "fp_mode" "single")])
11065
11066 (define_expand "adddf3"
11067   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11068         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11069                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11070   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11071   "
11072 {
11073   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11074     {
11075       expand_df_binop (&gen_adddf3_i, operands);
11076       DONE;
11077     }
11078 }")
11079
11080 (define_insn "*adddf3_media"
11081   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11082         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11083                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11084   "TARGET_SHMEDIA_FPU"
11085   "fadd.d       %1, %2, %0"
11086   [(set_attr "type" "dfparith_media")])
11087
11088 (define_insn "adddf3_i"
11089   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11090         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11091                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11092    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11093   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11094   "fadd %2,%0"
11095   [(set_attr "type" "dfp_arith")
11096    (set_attr "fp_mode" "double")])
11097
11098 (define_expand "subdf3"
11099   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11100         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11101                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11102   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11103   "
11104 {
11105   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11106     {
11107       expand_df_binop (&gen_subdf3_i, operands);
11108       DONE;
11109     }
11110 }")
11111
11112 (define_insn "*subdf3_media"
11113   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11114         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11115                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11116   "TARGET_SHMEDIA_FPU"
11117   "fsub.d       %1, %2, %0"
11118   [(set_attr "type" "dfparith_media")])
11119
11120 (define_insn "subdf3_i"
11121   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11122         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11123                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11124    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11125   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11126   "fsub %2,%0"
11127   [(set_attr "type" "dfp_arith")
11128    (set_attr "fp_mode" "double")])
11129
11130 (define_expand "muldf3"
11131   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11132         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11133                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11134   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11135   "
11136 {
11137   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11138     {
11139       expand_df_binop (&gen_muldf3_i, operands);
11140       DONE;
11141     }
11142 }")
11143
11144 (define_insn "*muldf3_media"
11145   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11146         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11147                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11148   "TARGET_SHMEDIA_FPU"
11149   "fmul.d       %1, %2, %0"
11150   [(set_attr "type" "dfmul_media")])
11151
11152 (define_insn "muldf3_i"
11153   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11154         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11155                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11156    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11157   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11158   "fmul %2,%0"
11159   [(set_attr "type" "dfp_mul")
11160    (set_attr "fp_mode" "double")])
11161
11162 (define_expand "divdf3"
11163   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11164         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11165                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11166   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11167   "
11168 {
11169   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11170     {
11171       expand_df_binop (&gen_divdf3_i, operands);
11172       DONE;
11173     }
11174 }")
11175
11176 (define_insn "*divdf3_media"
11177   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11178         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11179                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11180   "TARGET_SHMEDIA_FPU"
11181   "fdiv.d       %1, %2, %0"
11182   [(set_attr "type" "dfdiv_media")])
11183
11184 (define_insn "divdf3_i"
11185   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11186         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11187                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11188    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11189   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11190   "fdiv %2,%0"
11191   [(set_attr "type" "dfdiv")
11192    (set_attr "fp_mode" "double")])
11193
11194 (define_insn "floatdidf2"
11195   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11196         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11197   "TARGET_SHMEDIA_FPU"
11198   "float.qd     %1, %0"
11199   [(set_attr "type" "dfpconv_media")])
11200
11201 (define_expand "floatsidf2"
11202   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11203         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11204   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11205   "
11206 {
11207   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11208     {
11209       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11210                                       get_fpscr_rtx ()));
11211       DONE;
11212     }
11213 }")
11214
11215 (define_insn "*floatsidf2_media"
11216   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11217         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11218   "TARGET_SHMEDIA_FPU"
11219   "float.ld     %1, %0"
11220   [(set_attr "type" "dfpconv_media")])
11221
11222 (define_insn "floatsidf2_i"
11223   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11224         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11225    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11226   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11227   "float        %1,%0"
11228   [(set_attr "type" "dfp_conv")
11229    (set_attr "fp_mode" "double")])
11230
11231 (define_insn "fix_truncdfdi2"
11232   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11233         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11234   "TARGET_SHMEDIA_FPU"
11235   "ftrc.dq      %1, %0"
11236   [(set_attr "type" "dfpconv_media")])
11237
11238 (define_expand "fix_truncdfsi2"
11239   [(set (match_operand:SI 0 "fpul_operand" "")
11240         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11241   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11242   "
11243 {
11244   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11245     {
11246       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11247                                           get_fpscr_rtx ()));
11248       DONE;
11249     }
11250 }")
11251
11252 (define_insn "*fix_truncdfsi2_media"
11253   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11254         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11255   "TARGET_SHMEDIA_FPU"
11256   "ftrc.dl      %1, %0"
11257   [(set_attr "type" "dfpconv_media")])
11258
11259 (define_insn "fix_truncdfsi2_i"
11260   [(set (match_operand:SI 0 "fpul_operand" "=y")
11261         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11262    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11263   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11264   "ftrc %1,%0"
11265   [(set_attr "type" "dfp_conv")
11266    (set_attr "dfp_comp" "no")
11267    (set_attr "fp_mode" "double")])
11268
11269 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
11270 ;; fix_truncdfsi2_i.
11271 ;; (define_insn "fix_truncdfsi2_i4"
11272 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11273 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11274 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11275 ;;    (clobber (reg:SI FPUL_REG))]
11276 ;;   "TARGET_SH4"
11277 ;;   "#"
11278 ;;   [(set_attr "length" "4")
11279 ;;    (set_attr "fp_mode" "double")])
11280 ;;
11281 ;; (define_split
11282 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11283 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11284 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11285 ;;    (clobber (reg:SI FPUL_REG))]
11286 ;;   "TARGET_SH4"
11287 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11288 ;;            (use (match_dup 2))])
11289 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
11290
11291 (define_insn "cmpgtdf_t"
11292   [(set (reg:SI T_REG)
11293         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11294                (match_operand:DF 1 "arith_reg_operand" "f")))
11295    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11296   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11297   "fcmp/gt      %1,%0"
11298   [(set_attr "type" "dfp_cmp")
11299    (set_attr "fp_mode" "double")])
11300
11301 (define_insn "cmpeqdf_t"
11302   [(set (reg:SI T_REG)
11303         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11304                (match_operand:DF 1 "arith_reg_operand" "f")))
11305    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11306   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11307   "fcmp/eq      %1,%0"
11308   [(set_attr "type" "dfp_cmp")
11309    (set_attr "fp_mode" "double")])
11310
11311 (define_insn "*ieee_ccmpeqdf_t"
11312   [(set (reg:SI T_REG)
11313         (ior:SI (reg:SI T_REG)
11314                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11315                        (match_operand:DF 1 "arith_reg_operand" "f"))))
11316    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11317   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11318   "* return output_ieee_ccmpeq (insn, operands);"
11319   [(set_attr "length" "4")
11320    (set_attr "fp_mode" "double")])
11321
11322 (define_insn "cmpeqdf_media"
11323   [(set (match_operand:SI 0 "register_operand" "=r")
11324         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11325                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11326   "TARGET_SHMEDIA_FPU"
11327   "fcmpeq.d     %1,%2,%0"
11328   [(set_attr "type" "fcmp_media")])
11329
11330 (define_insn "cmpgtdf_media"
11331   [(set (match_operand:SI 0 "register_operand" "=r")
11332         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11333                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11334   "TARGET_SHMEDIA_FPU"
11335   "fcmpgt.d     %1,%2,%0"
11336   [(set_attr "type" "fcmp_media")])
11337
11338 (define_insn "cmpgedf_media"
11339   [(set (match_operand:SI 0 "register_operand" "=r")
11340         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11341                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11342   "TARGET_SHMEDIA_FPU"
11343   "fcmpge.d     %1,%2,%0"
11344   [(set_attr "type" "fcmp_media")])
11345
11346 (define_insn "cmpundf_media"
11347   [(set (match_operand:SI 0 "register_operand" "=r")
11348         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11349                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11350   "TARGET_SHMEDIA_FPU"
11351   "fcmpun.d     %1,%2,%0"
11352   [(set_attr "type" "fcmp_media")])
11353
11354 (define_expand "cmpdf"
11355   [(set (reg:SI T_REG)
11356         (compare (match_operand:DF 0 "arith_operand" "")
11357                  (match_operand:DF 1 "arith_operand" "")))]
11358   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11359   "
11360 {
11361   sh_compare_op0 = operands[0];
11362   sh_compare_op1 = operands[1];
11363   DONE;
11364 }")
11365
11366 (define_expand "negdf2"
11367   [(set (match_operand:DF 0 "arith_reg_operand" "")
11368         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11369   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11370   "
11371 {
11372   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11373     {
11374       expand_df_unop (&gen_negdf2_i, operands);
11375       DONE;
11376     }
11377 }")
11378
11379 (define_insn "*negdf2_media"
11380   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11381         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11382   "TARGET_SHMEDIA_FPU"
11383   "fneg.d       %1, %0"
11384   [(set_attr "type" "fmove_media")])
11385
11386 (define_insn "negdf2_i"
11387   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11388         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11389    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11390   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11391   "fneg %0"
11392   [(set_attr "type" "fmove")
11393    (set_attr "fp_mode" "double")])
11394
11395 (define_expand "sqrtdf2"
11396   [(set (match_operand:DF 0 "arith_reg_operand" "")
11397         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11398   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11399   "
11400 {
11401   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11402     {
11403       expand_df_unop (&gen_sqrtdf2_i, operands);
11404       DONE;
11405     }
11406 }")
11407
11408 (define_insn "*sqrtdf2_media"
11409   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11410         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11411   "TARGET_SHMEDIA_FPU"
11412   "fsqrt.d      %1, %0"
11413   [(set_attr "type" "dfdiv_media")])
11414
11415 (define_insn "sqrtdf2_i"
11416   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11417         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11418    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11419   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11420   "fsqrt        %0"
11421   [(set_attr "type" "dfdiv")
11422    (set_attr "fp_mode" "double")])
11423
11424 (define_expand "absdf2"
11425   [(set (match_operand:DF 0 "arith_reg_operand" "")
11426         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11427   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11428   "
11429 {
11430   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11431     {
11432       expand_df_unop (&gen_absdf2_i, operands);
11433       DONE;
11434     }
11435 }")
11436
11437 (define_insn "*absdf2_media"
11438   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11439         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11440   "TARGET_SHMEDIA_FPU"
11441   "fabs.d       %1, %0"
11442   [(set_attr "type" "fmove_media")])
11443
11444 (define_insn "absdf2_i"
11445   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11446         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11447    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11448   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11449   "fabs %0"
11450   [(set_attr "type" "fmove")
11451    (set_attr "fp_mode" "double")])
11452
11453 (define_expand "extendsfdf2"
11454   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11455         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11456   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11457   "
11458 {
11459   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11460     {
11461       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11462                                         get_fpscr_rtx ()));
11463       DONE;
11464     }
11465 }")
11466
11467 (define_insn "*extendsfdf2_media"
11468   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11469         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11470   "TARGET_SHMEDIA_FPU"
11471   "fcnv.sd      %1, %0"
11472   [(set_attr "type" "dfpconv_media")])
11473
11474 (define_insn "extendsfdf2_i4"
11475   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11476         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11477    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11478   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11479   "fcnvsd  %1,%0"
11480   [(set_attr "type" "fp")
11481    (set_attr "fp_mode" "double")])
11482
11483 (define_expand "truncdfsf2"
11484   [(set (match_operand:SF 0 "fpul_operand" "")
11485         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11486   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11487   "
11488 {
11489   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11490     {
11491       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11492                                        get_fpscr_rtx ()));
11493       DONE;
11494     }
11495 }")
11496
11497 (define_insn "*truncdfsf2_media"
11498   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11499         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11500   "TARGET_SHMEDIA_FPU"
11501   "fcnv.ds      %1, %0"
11502   [(set_attr "type" "dfpconv_media")])
11503
11504 (define_insn "truncdfsf2_i4"
11505   [(set (match_operand:SF 0 "fpul_operand" "=y")
11506         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11507    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11508   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11509   "fcnvds  %1,%0"
11510   [(set_attr "type" "fp")
11511    (set_attr "fp_mode" "double")])
11512 \f
11513 ;; Bit field extract patterns.  These give better code for packed bitfields,
11514 ;; because they allow auto-increment addresses to be generated.
11515
11516 (define_expand "insv"
11517   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11518                          (match_operand:SI 1 "immediate_operand" "")
11519                          (match_operand:SI 2 "immediate_operand" ""))
11520         (match_operand:SI 3 "general_operand" ""))]
11521   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11522   "
11523 {
11524   rtx addr_target, orig_address, shift_reg, qi_val;
11525   HOST_WIDE_INT bitsize, size, v = 0;
11526   rtx x = operands[3];
11527
11528   /* ??? expmed doesn't care for non-register predicates.  */
11529   if (! memory_operand (operands[0], VOIDmode)
11530       || ! immediate_operand (operands[1], VOIDmode)
11531       || ! immediate_operand (operands[2], VOIDmode)
11532       || ! general_operand (x, VOIDmode))
11533     FAIL;
11534   /* If this isn't a 16 / 24 / 32 bit field, or if
11535      it doesn't start on a byte boundary, then fail.  */
11536   bitsize = INTVAL (operands[1]);
11537   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11538       || (INTVAL (operands[2]) % 8) != 0)
11539     FAIL;
11540
11541   size = bitsize / 8;
11542   orig_address = XEXP (operands[0], 0);
11543   shift_reg = gen_reg_rtx (SImode);
11544   if (GET_CODE (x) == CONST_INT)
11545     {
11546       v = INTVAL (x);
11547       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11548     }
11549   else
11550     {
11551       emit_insn (gen_movsi (shift_reg, operands[3]));
11552       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11553     }
11554   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11555
11556   operands[0] = replace_equiv_address (operands[0], addr_target);
11557   emit_insn (gen_movqi (operands[0], qi_val));
11558
11559   while (size -= 1)
11560     {
11561       if (GET_CODE (x) == CONST_INT)
11562         qi_val
11563           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11564       else
11565         {
11566           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11567           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11568         }
11569       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11570       emit_insn (gen_movqi (operands[0], qi_val));
11571     }
11572
11573   DONE;
11574 }")
11575
11576 (define_insn "movua"
11577   [(set (match_operand:SI 0 "register_operand" "=z")
11578         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11579                    UNSPEC_MOVUA))]
11580   "TARGET_SH4A_ARCH"
11581   "movua.l      %1,%0"
11582   [(set_attr "type" "movua")])
11583
11584 ;; We shouldn't need this, but cse replaces increments with references
11585 ;; to other regs before flow has a chance to create post_inc
11586 ;; addressing modes, and only postreload's cse_move2add brings the
11587 ;; increments back to a usable form.
11588 (define_peephole2
11589   [(set (match_operand:SI 0 "register_operand" "")
11590         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11591                          (const_int 32) (const_int 0)))
11592    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11593   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11594   [(set (match_operand:SI 0 "register_operand" "")
11595         (sign_extract:SI (mem:SI (post_inc:SI
11596                                   (match_operand:SI 1 "register_operand" "")))
11597                          (const_int 32) (const_int 0)))]
11598   "")
11599
11600 (define_expand "extv"
11601   [(set (match_operand:SI 0 "register_operand" "")
11602         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11603                          (match_operand 2 "const_int_operand" "")
11604                          (match_operand 3 "const_int_operand" "")))]
11605   "TARGET_SH4A_ARCH"
11606 {
11607   if (TARGET_SH4A_ARCH
11608       && INTVAL (operands[2]) == 32
11609       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11610       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11611     {
11612       rtx src = adjust_address (operands[1], BLKmode, 0);
11613       set_mem_size (src, GEN_INT (4));
11614       emit_insn (gen_movua (operands[0], src));
11615       DONE;
11616     }
11617
11618   FAIL;
11619 })
11620
11621 (define_expand "extzv"
11622   [(set (match_operand:SI 0 "register_operand" "")
11623         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11624                          (match_operand 2 "const_int_operand" "")
11625                          (match_operand 3 "const_int_operand" "")))]
11626   "TARGET_SH4A_ARCH"
11627 {
11628   if (TARGET_SH4A_ARCH
11629       && INTVAL (operands[2]) == 32
11630       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11631       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11632     {
11633       rtx src = adjust_address (operands[1], BLKmode, 0);
11634       set_mem_size (src, GEN_INT (4));
11635       emit_insn (gen_movua (operands[0], src));
11636       DONE;
11637     }
11638
11639   FAIL;
11640 })
11641
11642 \f
11643 ;; -------------------------------------------------------------------------
11644 ;; Peepholes
11645 ;; -------------------------------------------------------------------------
11646
11647 ;; This matches cases where a stack pointer increment at the start of the
11648 ;; epilogue combines with a stack slot read loading the return value.
11649
11650 (define_peephole
11651   [(set (match_operand:SI 0 "arith_reg_operand" "")
11652         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11653    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11654   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11655   "mov.l        @%1+,%0")
11656
11657 ;; See the comment on the dt combiner pattern above.
11658
11659 (define_peephole
11660   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11661         (plus:SI (match_dup 0)
11662                  (const_int -1)))
11663    (set (reg:SI T_REG)
11664         (eq:SI (match_dup 0)
11665                (const_int 0)))]
11666   "TARGET_SH2"
11667   "dt   %0")
11668
11669 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11670 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11671 ;; reload when the constant is too large for a reg+offset address.
11672
11673 ;; ??? We would get much better code if this was done in reload.  This would
11674 ;; require modifying find_reloads_address to recognize that if the constant
11675 ;; is out-of-range for an immediate add, then we get better code by reloading
11676 ;; the constant into a register than by reloading the sum into a register,
11677 ;; since the former is one instruction shorter if the address does not need
11678 ;; to be offsettable.  Unfortunately this does not work, because there is
11679 ;; only one register, r0, that can be used as an index register.  This register
11680 ;; is also the function return value register.  So, if we try to force reload
11681 ;; to use double-reg addresses, then we end up with some instructions that
11682 ;; need to use r0 twice.  The only way to fix this is to change the calling
11683 ;; convention so that r0 is not used to return values.
11684
11685 (define_peephole
11686   [(set (match_operand:SI 0 "register_operand" "=r")
11687         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11688    (set (mem:SI (match_dup 0))
11689         (match_operand:SI 2 "general_movsrc_operand" ""))]
11690   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11691   "mov.l        %2,@(%0,%1)")
11692
11693 (define_peephole
11694   [(set (match_operand:SI 0 "register_operand" "=r")
11695         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11696    (set (match_operand:SI 2 "general_movdst_operand" "")
11697         (mem:SI (match_dup 0)))]
11698   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11699   "mov.l        @(%0,%1),%2")
11700
11701 (define_peephole
11702   [(set (match_operand:SI 0 "register_operand" "=r")
11703         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11704    (set (mem:HI (match_dup 0))
11705         (match_operand:HI 2 "general_movsrc_operand" ""))]
11706   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11707   "mov.w        %2,@(%0,%1)")
11708
11709 (define_peephole
11710   [(set (match_operand:SI 0 "register_operand" "=r")
11711         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11712    (set (match_operand:HI 2 "general_movdst_operand" "")
11713         (mem:HI (match_dup 0)))]
11714   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11715   "mov.w        @(%0,%1),%2")
11716
11717 (define_peephole
11718   [(set (match_operand:SI 0 "register_operand" "=r")
11719         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11720    (set (mem:QI (match_dup 0))
11721         (match_operand:QI 2 "general_movsrc_operand" ""))]
11722   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11723   "mov.b        %2,@(%0,%1)")
11724
11725 (define_peephole
11726   [(set (match_operand:SI 0 "register_operand" "=r")
11727         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11728    (set (match_operand:QI 2 "general_movdst_operand" "")
11729         (mem:QI (match_dup 0)))]
11730   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11731   "mov.b        @(%0,%1),%2")
11732
11733 (define_peephole
11734   [(set (match_operand:SI 0 "register_operand" "=r")
11735         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11736    (set (mem:SF (match_dup 0))
11737         (match_operand:SF 2 "general_movsrc_operand" ""))]
11738   "TARGET_SH1 && REGNO (operands[0]) == 0
11739    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11740        || (GET_CODE (operands[2]) == SUBREG
11741            && REGNO (SUBREG_REG (operands[2])) < 16))
11742    && reg_unused_after (operands[0], insn)"
11743   "mov.l        %2,@(%0,%1)")
11744
11745 (define_peephole
11746   [(set (match_operand:SI 0 "register_operand" "=r")
11747         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11748    (set (match_operand:SF 2 "general_movdst_operand" "")
11749
11750         (mem:SF (match_dup 0)))]
11751   "TARGET_SH1 && REGNO (operands[0]) == 0
11752    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11753        || (GET_CODE (operands[2]) == SUBREG
11754            && REGNO (SUBREG_REG (operands[2])) < 16))
11755    && reg_unused_after (operands[0], insn)"
11756   "mov.l        @(%0,%1),%2")
11757
11758 (define_peephole
11759   [(set (match_operand:SI 0 "register_operand" "=r")
11760         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11761    (set (mem:SF (match_dup 0))
11762         (match_operand:SF 2 "general_movsrc_operand" ""))]
11763   "TARGET_SH2E && REGNO (operands[0]) == 0
11764    && ((GET_CODE (operands[2]) == REG
11765         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11766        || (GET_CODE (operands[2]) == SUBREG
11767            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11768    && reg_unused_after (operands[0], insn)"
11769   "fmov{.s|}    %2,@(%0,%1)")
11770
11771 (define_peephole
11772   [(set (match_operand:SI 0 "register_operand" "=r")
11773         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11774    (set (match_operand:SF 2 "general_movdst_operand" "")
11775
11776         (mem:SF (match_dup 0)))]
11777   "TARGET_SH2E && REGNO (operands[0]) == 0
11778    && ((GET_CODE (operands[2]) == REG
11779         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11780        || (GET_CODE (operands[2]) == SUBREG
11781            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11782    && reg_unused_after (operands[0], insn)"
11783   "fmov{.s|}    @(%0,%1),%2")
11784
11785 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11786 (define_insn "sp_switch_1"
11787   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11788   "TARGET_SH1"
11789   "*
11790 {
11791   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11792   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11793   return \"mov r0,r15\";
11794 }"
11795   [(set_attr "length" "10")])
11796
11797 ;; Switch back to the original stack for interrupt functions with the
11798 ;; sp_switch attribute.  */
11799 (define_insn "sp_switch_2"
11800   [(const_int 2)]
11801   "TARGET_SH1"
11802   "mov.l @r15+,r15\;mov.l @r15+,r0"
11803   [(set_attr "length" "4")])
11804
11805 ;; Integer vector moves
11806
11807 (define_expand "movv8qi"
11808   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11809         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11810   "TARGET_SHMEDIA"
11811   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11812
11813 (define_insn "movv8qi_i"
11814   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11815         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11816   "TARGET_SHMEDIA
11817    && (register_operand (operands[0], V8QImode)
11818        || sh_register_operand (operands[1], V8QImode))"
11819   "@
11820         add     %1, r63, %0
11821         movi    %1, %0
11822         #
11823         ld%M1.q %m1, %0
11824         st%M0.q %m0, %N1"
11825   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11826    (set_attr "length" "4,4,16,4,4")])
11827
11828 (define_split
11829   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11830         (subreg:V8QI (const_int 0) 0))]
11831   "TARGET_SHMEDIA"
11832   [(set (match_dup 0)
11833         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11834                             (const_int 0) (const_int 0) (const_int 0)
11835                             (const_int 0) (const_int 0)]))])
11836
11837 (define_split
11838   [(set (match_operand 0 "arith_reg_dest" "")
11839         (match_operand 1 "sh_rep_vec" ""))]
11840   "TARGET_SHMEDIA && reload_completed
11841    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11842    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11843    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11844    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11845        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11846    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11847        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11848   [(set (match_dup 0) (match_dup 1))
11849    (match_dup 2)]
11850   "
11851 {
11852   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11853   rtx elt1 = XVECEXP (operands[1], 0, 1);
11854
11855   if (unit_size > 2)
11856     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11857   else
11858     {
11859       if (unit_size < 2)
11860         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11861       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11862     }
11863   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11864   operands[1] = XVECEXP (operands[1], 0, 0);
11865   if (unit_size < 2)
11866     {
11867       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11868         operands[1]
11869           = GEN_INT (TARGET_LITTLE_ENDIAN
11870                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11871                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11872       else
11873         {
11874           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11875           operands[1]
11876             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11877         }
11878     }
11879 }")
11880
11881 (define_split
11882   [(set (match_operand 0 "arith_reg_dest" "")
11883         (match_operand 1 "sh_const_vec" ""))]
11884   "TARGET_SHMEDIA && reload_completed
11885    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11886    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11887   [(set (match_dup 0) (match_dup 1))]
11888   "
11889 {
11890   rtx v = operands[1];
11891   enum machine_mode new_mode
11892     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11893
11894   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11895   operands[1]
11896     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11897 }")
11898
11899 (define_expand "movv2hi"
11900   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11901         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11902   "TARGET_SHMEDIA"
11903   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11904
11905 (define_insn "movv2hi_i"
11906   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11907         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11908   "TARGET_SHMEDIA
11909    && (register_operand (operands[0], V2HImode)
11910        || sh_register_operand (operands[1], V2HImode))"
11911   "@
11912         add.l   %1, r63, %0
11913         movi    %1, %0
11914         #
11915         ld%M1.l %m1, %0
11916         st%M0.l %m0, %N1"
11917   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11918    (set_attr "length" "4,4,16,4,4")
11919    (set (attr "highpart")
11920         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11921                (const_string "user")]
11922               (const_string "ignore")))])
11923
11924 (define_expand "movv4hi"
11925   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11926         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11927   "TARGET_SHMEDIA"
11928   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11929
11930 (define_insn "movv4hi_i"
11931   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11932         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11933   "TARGET_SHMEDIA
11934    && (register_operand (operands[0], V4HImode)
11935        || sh_register_operand (operands[1], V4HImode))"
11936   "@
11937         add     %1, r63, %0
11938         movi    %1, %0
11939         #
11940         ld%M1.q %m1, %0
11941         st%M0.q %m0, %N1"
11942   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11943    (set_attr "length" "4,4,16,4,4")
11944    (set_attr "highpart" "depend")])
11945
11946 (define_expand "movv2si"
11947   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11948         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11949   "TARGET_SHMEDIA"
11950   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11951
11952 (define_insn "movv2si_i"
11953   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11954         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11955   "TARGET_SHMEDIA
11956    && (register_operand (operands[0], V2SImode)
11957        || sh_register_operand (operands[1], V2SImode))"
11958   "@
11959         add     %1, r63, %0
11960         #
11961         #
11962         ld%M1.q %m1, %0
11963         st%M0.q %m0, %N1"
11964   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11965    (set_attr "length" "4,4,16,4,4")
11966    (set_attr "highpart" "depend")])
11967
11968 ;; Multimedia Intrinsics
11969
11970 (define_insn "absv2si2"
11971   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11972         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11973   "TARGET_SHMEDIA"
11974   "mabs.l       %1, %0"
11975   [(set_attr "type" "mcmp_media")
11976    (set_attr "highpart" "depend")])
11977
11978 (define_insn "absv4hi2"
11979   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11980         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11981   "TARGET_SHMEDIA"
11982   "mabs.w       %1, %0"
11983   [(set_attr "type" "mcmp_media")
11984    (set_attr "highpart" "depend")])
11985
11986 (define_insn "addv2si3"
11987   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11988         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11989                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11990   "TARGET_SHMEDIA"
11991   "madd.l       %1, %2, %0"
11992   [(set_attr "type" "arith_media")
11993    (set_attr "highpart" "depend")])
11994
11995 (define_insn "addv4hi3"
11996   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11997         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11998                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11999   "TARGET_SHMEDIA"
12000   "madd.w       %1, %2, %0"
12001   [(set_attr "type" "arith_media")
12002    (set_attr "highpart" "depend")])
12003
12004 (define_insn_and_split "addv2hi3"
12005   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12006         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12007                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12008   "TARGET_SHMEDIA"
12009   "#"
12010   "TARGET_SHMEDIA"
12011   [(const_int 0)]
12012   "
12013 {
12014   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12015   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12016   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12017   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12018   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12019
12020   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12021   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12022   DONE;
12023 }"
12024   [(set_attr "highpart" "must_split")])
12025
12026 (define_insn "ssaddv2si3"
12027   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12028         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12029                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12030   "TARGET_SHMEDIA"
12031   "madds.l      %1, %2, %0"
12032   [(set_attr "type" "mcmp_media")
12033    (set_attr "highpart" "depend")])
12034
12035 (define_insn "usaddv8qi3"
12036   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12037         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12038                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12039   "TARGET_SHMEDIA"
12040   "madds.ub     %1, %2, %0"
12041   [(set_attr "type" "mcmp_media")
12042    (set_attr "highpart" "depend")])
12043
12044 (define_insn "ssaddv4hi3"
12045   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12046         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12047                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12048   "TARGET_SHMEDIA"
12049   "madds.w      %1, %2, %0"
12050   [(set_attr "type" "mcmp_media")
12051    (set_attr "highpart" "depend")])
12052
12053 (define_insn "negcmpeqv8qi"
12054   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12055         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12056                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12057   "TARGET_SHMEDIA"
12058   "mcmpeq.b     %N1, %N2, %0"
12059   [(set_attr "type" "mcmp_media")
12060    (set_attr "highpart" "depend")])
12061
12062 (define_insn "negcmpeqv2si"
12063   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12064         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12065                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12066   "TARGET_SHMEDIA"
12067   "mcmpeq.l     %N1, %N2, %0"
12068   [(set_attr "type" "mcmp_media")
12069    (set_attr "highpart" "depend")])
12070
12071 (define_insn "negcmpeqv4hi"
12072   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12073         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12074                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12075   "TARGET_SHMEDIA"
12076   "mcmpeq.w     %N1, %N2, %0"
12077   [(set_attr "type" "mcmp_media")
12078    (set_attr "highpart" "depend")])
12079
12080 (define_insn "negcmpgtuv8qi"
12081   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12082         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12083                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12084   "TARGET_SHMEDIA"
12085   "mcmpgt.ub    %N1, %N2, %0"
12086   [(set_attr "type" "mcmp_media")
12087    (set_attr "highpart" "depend")])
12088
12089 (define_insn "negcmpgtv2si"
12090   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12091         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12092                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12093   "TARGET_SHMEDIA"
12094   "mcmpgt.l     %N1, %N2, %0"
12095   [(set_attr "type" "mcmp_media")
12096    (set_attr "highpart" "depend")])
12097
12098 (define_insn "negcmpgtv4hi"
12099   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12100         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12101                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12102   "TARGET_SHMEDIA"
12103   "mcmpgt.w     %N1, %N2, %0"
12104   [(set_attr "type" "mcmp_media")
12105    (set_attr "highpart" "depend")])
12106
12107 (define_insn "mcmv"
12108   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12109         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12110                         (match_operand:DI 2 "arith_reg_operand" "r"))
12111                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12112                         (not:DI (match_dup 2)))))]
12113   "TARGET_SHMEDIA"
12114   "mcmv %N1, %2, %0"
12115   [(set_attr "type" "arith_media")
12116    (set_attr "highpart" "depend")])
12117
12118 (define_insn "mcnvs_lw"
12119   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12120         (vec_concat:V4HI
12121          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12122          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12123   "TARGET_SHMEDIA"
12124   "mcnvs.lw     %N1, %N2, %0"
12125   [(set_attr "type" "mcmp_media")])
12126
12127 (define_insn "mcnvs_wb"
12128   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12129         (vec_concat:V8QI
12130          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12131          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12132   "TARGET_SHMEDIA"
12133   "mcnvs.wb     %N1, %N2, %0"
12134   [(set_attr "type" "mcmp_media")])
12135
12136 (define_insn "mcnvs_wub"
12137   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12138         (vec_concat:V8QI
12139          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12140          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12141   "TARGET_SHMEDIA"
12142   "mcnvs.wub    %N1, %N2, %0"
12143   [(set_attr "type" "mcmp_media")])
12144
12145 (define_insn "mextr_rl"
12146   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12147         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12148                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12149                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12150                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12151   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12152   "*
12153 {
12154   static char templ[21];
12155
12156   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12157            (int) INTVAL (operands[3]) >> 3);
12158   return templ;
12159 }"
12160   [(set_attr "type" "arith_media")])
12161
12162 (define_insn "*mextr_lr"
12163   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12164         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12165                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12166                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12167                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12168   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12169   "*
12170 {
12171   static char templ[21];
12172
12173   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12174            (int) INTVAL (operands[4]) >> 3);
12175   return templ;
12176 }"
12177   [(set_attr "type" "arith_media")])
12178
12179 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12180 ; vector then varies depending on endianness.
12181 (define_expand "mextr1"
12182   [(match_operand:DI 0 "arith_reg_dest" "")
12183    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12184    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12185   "TARGET_SHMEDIA"
12186   "
12187 {
12188   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12189                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12190   DONE;
12191 }")
12192
12193 (define_expand "mextr2"
12194   [(match_operand:DI 0 "arith_reg_dest" "")
12195    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12196    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12197   "TARGET_SHMEDIA"
12198   "
12199 {
12200   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12201                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12202   DONE;
12203 }")
12204
12205 (define_expand "mextr3"
12206   [(match_operand:DI 0 "arith_reg_dest" "")
12207    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12208    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12209   "TARGET_SHMEDIA"
12210   "
12211 {
12212   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12213                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12214   DONE;
12215 }")
12216
12217 (define_expand "mextr4"
12218   [(match_operand:DI 0 "arith_reg_dest" "")
12219    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12220    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12221   "TARGET_SHMEDIA"
12222   "
12223 {
12224   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12225                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12226   DONE;
12227 }")
12228
12229 (define_expand "mextr5"
12230   [(match_operand:DI 0 "arith_reg_dest" "")
12231    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12232    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12233   "TARGET_SHMEDIA"
12234   "
12235 {
12236   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12237                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12238   DONE;
12239 }")
12240
12241 (define_expand "mextr6"
12242   [(match_operand:DI 0 "arith_reg_dest" "")
12243    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12244    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12245   "TARGET_SHMEDIA"
12246   "
12247 {
12248   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12249                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12250   DONE;
12251 }")
12252
12253 (define_expand "mextr7"
12254   [(match_operand:DI 0 "arith_reg_dest" "")
12255    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12256    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12257   "TARGET_SHMEDIA"
12258   "
12259 {
12260   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12261                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12262   DONE;
12263 }")
12264
12265 (define_expand "mmacfx_wl"
12266   [(match_operand:V2SI 0 "arith_reg_dest" "")
12267    (match_operand:V2HI 1 "extend_reg_operand" "")
12268    (match_operand:V2HI 2 "extend_reg_operand" "")
12269    (match_operand:V2SI 3 "arith_reg_operand" "")]
12270   "TARGET_SHMEDIA"
12271   "
12272 {
12273   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12274                               operands[1], operands[2]));
12275   DONE;
12276 }")
12277
12278 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12279 ;; is depend
12280 (define_insn "mmacfx_wl_i"
12281   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12282         (ss_plus:V2SI
12283          (match_operand:V2SI 1 "arith_reg_operand" "0")
12284          (ss_truncate:V2SI
12285           (ashift:V2DI
12286            (sign_extend:V2DI
12287             (mult:V2SI
12288              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12289              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12290            (const_int 1)))))]
12291   "TARGET_SHMEDIA"
12292   "mmacfx.wl    %2, %3, %0"
12293   [(set_attr "type" "mac_media")
12294    (set_attr "highpart" "depend")])
12295
12296 (define_expand "mmacnfx_wl"
12297   [(match_operand:V2SI 0 "arith_reg_dest" "")
12298    (match_operand:V2HI 1 "extend_reg_operand" "")
12299    (match_operand:V2HI 2 "extend_reg_operand" "")
12300    (match_operand:V2SI 3 "arith_reg_operand" "")]
12301   "TARGET_SHMEDIA"
12302   "
12303 {
12304   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12305                                operands[1], operands[2]));
12306   DONE;
12307 }")
12308
12309 (define_insn "mmacnfx_wl_i"
12310   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12311         (ss_minus:V2SI
12312          (match_operand:V2SI 1 "arith_reg_operand" "0")
12313          (ss_truncate:V2SI
12314           (ashift:V2DI
12315            (sign_extend:V2DI
12316             (mult:V2SI
12317              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12318              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12319            (const_int 1)))))]
12320   "TARGET_SHMEDIA"
12321   "mmacnfx.wl   %2, %3, %0"
12322   [(set_attr "type" "mac_media")
12323    (set_attr "highpart" "depend")])
12324
12325 (define_insn "mulv2si3"
12326   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12327         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12328                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12329   "TARGET_SHMEDIA"
12330   "mmul.l       %1, %2, %0"
12331   [(set_attr "type" "d2mpy_media")
12332    (set_attr "highpart" "depend")])
12333
12334 (define_insn "mulv4hi3"
12335   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12336         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12337                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12338   "TARGET_SHMEDIA"
12339   "mmul.w       %1, %2, %0"
12340   [(set_attr "type" "dmpy_media")
12341    (set_attr "highpart" "depend")])
12342
12343 (define_insn "mmulfx_l"
12344   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12345         (ss_truncate:V2SI
12346          (ashiftrt:V2DI
12347           (mult:V2DI
12348            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12349            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12350           (const_int 31))))]
12351   "TARGET_SHMEDIA"
12352   "mmulfx.l     %1, %2, %0"
12353   [(set_attr "type" "d2mpy_media")
12354    (set_attr "highpart" "depend")])
12355
12356 (define_insn "mmulfx_w"
12357   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12358         (ss_truncate:V4HI
12359          (ashiftrt:V4SI
12360           (mult:V4SI
12361            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12362            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12363           (const_int 15))))]
12364   "TARGET_SHMEDIA"
12365   "mmulfx.w     %1, %2, %0"
12366   [(set_attr "type" "dmpy_media")
12367    (set_attr "highpart" "depend")])
12368
12369 (define_insn "mmulfxrp_w"
12370   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12371         (ss_truncate:V4HI
12372          (ashiftrt:V4SI
12373           (plus:V4SI
12374            (mult:V4SI
12375             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12376             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12377            (const_int 16384))
12378           (const_int 15))))]
12379   "TARGET_SHMEDIA"
12380   "mmulfxrp.w   %1, %2, %0"
12381   [(set_attr "type" "dmpy_media")
12382    (set_attr "highpart" "depend")])
12383
12384
12385 (define_expand "mmulhi_wl"
12386   [(match_operand:V2SI 0 "arith_reg_dest" "")
12387    (match_operand:V4HI 1 "arith_reg_operand" "")
12388    (match_operand:V4HI 2 "arith_reg_operand" "")]
12389   "TARGET_SHMEDIA"
12390   "
12391 {
12392   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12393              (operands[0], operands[1], operands[2]));
12394   DONE;
12395 }")
12396
12397 (define_expand "mmullo_wl"
12398   [(match_operand:V2SI 0 "arith_reg_dest" "")
12399    (match_operand:V4HI 1 "arith_reg_operand" "")
12400    (match_operand:V4HI 2 "arith_reg_operand" "")]
12401   "TARGET_SHMEDIA"
12402   "
12403 {
12404   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12405              (operands[0], operands[1], operands[2]));
12406   DONE;
12407 }")
12408
12409 (define_insn "mmul23_wl"
12410   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12411         (vec_select:V2SI
12412          (mult:V4SI
12413           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12414           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12415          (parallel [(const_int 2) (const_int 3)])))]
12416   "TARGET_SHMEDIA"
12417   "* return (TARGET_LITTLE_ENDIAN
12418              ? \"mmulhi.wl      %1, %2, %0\"
12419              : \"mmullo.wl      %1, %2, %0\");"
12420   [(set_attr "type" "dmpy_media")
12421    (set (attr "highpart")
12422         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12423          (const_string "user")))])
12424
12425 (define_insn "mmul01_wl"
12426   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12427         (vec_select:V2SI
12428          (mult:V4SI
12429           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12430           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12431          (parallel [(const_int 0) (const_int 1)])))]
12432   "TARGET_SHMEDIA"
12433   "* return (TARGET_LITTLE_ENDIAN
12434              ? \"mmullo.wl      %1, %2, %0\"
12435              : \"mmulhi.wl      %1, %2, %0\");"
12436   [(set_attr "type" "dmpy_media")
12437    (set (attr "highpart")
12438         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12439          (const_string "user")))])
12440
12441
12442 (define_expand "mmulsum_wq"
12443   [(match_operand:DI 0 "arith_reg_dest" "")
12444    (match_operand:V4HI 1 "arith_reg_operand" "")
12445    (match_operand:V4HI 2 "arith_reg_operand" "")
12446    (match_operand:DI 3 "arith_reg_operand" "")]
12447   "TARGET_SHMEDIA"
12448   "
12449 {
12450   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12451                                operands[1], operands[2]));
12452   DONE;
12453 }")
12454
12455 (define_insn "mmulsum_wq_i"
12456   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12457         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12458          (plus:DI
12459           (plus:DI
12460            (vec_select:DI
12461             (mult:V4DI
12462              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12463              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12464             (parallel [(const_int 0)]))
12465            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12466                                      (sign_extend:V4DI (match_dup 3)))
12467                           (parallel [(const_int 1)])))
12468           (plus:DI
12469            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12470                                      (sign_extend:V4DI (match_dup 3)))
12471                           (parallel [(const_int 2)]))
12472            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12473                                      (sign_extend:V4DI (match_dup 3)))
12474                           (parallel [(const_int 3)]))))))]
12475   "TARGET_SHMEDIA"
12476   "mmulsum.wq   %2, %3, %0"
12477   [(set_attr "type" "mac_media")])
12478
12479 (define_expand "mperm_w"
12480   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12481    (match_operand:V4HI 1 "arith_reg_operand" "r")
12482    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12483   "TARGET_SHMEDIA"
12484   "
12485 {
12486   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12487              (operands[0], operands[1], operands[2]));
12488   DONE;
12489 }")
12490
12491 ; This use of vec_select isn't exactly correct according to rtl.texi
12492 ; (because not constant), but it seems a straightforward extension.
12493 (define_insn "mperm_w_little"
12494   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12495         (vec_select:V4HI
12496          (match_operand:V4HI 1 "arith_reg_operand" "r")
12497          (parallel
12498           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12499                             (const_int 2) (const_int 0))
12500            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12501            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12502            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12503   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12504   "mperm.w      %1, %N2, %0"
12505   [(set_attr "type" "arith_media")])
12506
12507 (define_insn "mperm_w_big"
12508   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12509         (vec_select:V4HI
12510          (match_operand:V4HI 1 "arith_reg_operand" "r")
12511          (parallel
12512           [(zero_extract:QI (not:QI (match_operand:QI 2
12513                                      "extend_reg_or_0_operand" "rZ"))
12514                             (const_int 2) (const_int 0))
12515            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12516            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12517            (zero_extract:QI (not:QI (match_dup 2))
12518                             (const_int 2) (const_int 6))])))]
12519   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12520   "mperm.w      %1, %N2, %0"
12521   [(set_attr "type" "arith_media")])
12522
12523 (define_insn "mperm_w0"
12524   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12525         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12526                                           "trunc_hi_operand" "r"))))]
12527   "TARGET_SHMEDIA"
12528   "mperm.w      %1, r63, %0"
12529   [(set_attr "type" "arith_media")
12530    (set_attr "highpart" "ignore")])
12531
12532 (define_expand "msad_ubq"
12533   [(match_operand:DI 0 "arith_reg_dest" "")
12534    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12535    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12536    (match_operand:DI 3 "arith_reg_operand" "")]
12537   "TARGET_SHMEDIA"
12538   "
12539 {
12540   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12541                              operands[1], operands[2]));
12542   DONE;
12543 }")
12544
12545 (define_insn "msad_ubq_i"
12546   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12547         (plus:DI
12548          (plus:DI
12549           (plus:DI
12550            (plus:DI
12551             (match_operand:DI 1 "arith_reg_operand" "0")
12552             (abs:DI (vec_select:DI
12553                      (minus:V8DI
12554                       (zero_extend:V8DI
12555                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12556                       (zero_extend:V8DI
12557                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12558                      (parallel [(const_int 0)]))))
12559            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12560                                               (zero_extend:V8DI (match_dup 3)))
12561                                   (parallel [(const_int 1)]))))
12562           (plus:DI
12563            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12564                                               (zero_extend:V8DI (match_dup 3)))
12565                                   (parallel [(const_int 2)])))
12566            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12567                                               (zero_extend:V8DI (match_dup 3)))
12568                                   (parallel [(const_int 3)])))))
12569          (plus:DI
12570           (plus:DI
12571            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12572                                               (zero_extend:V8DI (match_dup 3)))
12573                                   (parallel [(const_int 4)])))
12574            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12575                                               (zero_extend:V8DI (match_dup 3)))
12576                                   (parallel [(const_int 5)]))))
12577           (plus:DI
12578            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12579                                               (zero_extend:V8DI (match_dup 3)))
12580                                   (parallel [(const_int 6)])))
12581            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12582                                               (zero_extend:V8DI (match_dup 3)))
12583                                   (parallel [(const_int 7)])))))))]
12584   "TARGET_SHMEDIA"
12585   "msad.ubq     %N2, %N3, %0"
12586   [(set_attr "type" "mac_media")])
12587
12588 (define_insn "mshalds_l"
12589   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12590         (ss_truncate:V2SI
12591          (ashift:V2DI
12592           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12593           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12594                   (const_int 31)))))]
12595   "TARGET_SHMEDIA"
12596   "mshalds.l    %1, %2, %0"
12597   [(set_attr "type" "mcmp_media")
12598    (set_attr "highpart" "depend")])
12599
12600 (define_insn "mshalds_w"
12601   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12602         (ss_truncate:V4HI
12603          (ashift:V4SI
12604           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12605           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12606                   (const_int 15)))))]
12607   "TARGET_SHMEDIA"
12608   "mshalds.w    %1, %2, %0"
12609   [(set_attr "type" "mcmp_media")
12610    (set_attr "highpart" "depend")])
12611
12612 (define_insn "ashrv2si3"
12613   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12614         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12615                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12616   "TARGET_SHMEDIA"
12617   "mshard.l     %1, %2, %0"
12618   [(set_attr "type" "arith_media")
12619    (set_attr "highpart" "depend")])
12620
12621 (define_insn "ashrv4hi3"
12622   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12623         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12624                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12625   "TARGET_SHMEDIA"
12626   "mshard.w     %1, %2, %0"
12627   [(set_attr "type" "arith_media")
12628    (set_attr "highpart" "depend")])
12629
12630 (define_insn "mshards_q"
12631   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12632         (ss_truncate:HI
12633          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12634                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12635   "TARGET_SHMEDIA"
12636   "mshards.q    %1, %N2, %0"
12637   [(set_attr "type" "mcmp_media")])
12638
12639 (define_expand "mshfhi_b"
12640   [(match_operand:V8QI 0 "arith_reg_dest" "")
12641    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12642    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12643   "TARGET_SHMEDIA"
12644   "
12645 {
12646   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12647              (operands[0], operands[1], operands[2]));
12648   DONE;
12649 }")
12650
12651 (define_expand "mshflo_b"
12652   [(match_operand:V8QI 0 "arith_reg_dest" "")
12653    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12654    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12655   "TARGET_SHMEDIA"
12656   "
12657 {
12658   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12659              (operands[0], operands[1], operands[2]));
12660   DONE;
12661 }")
12662
12663 (define_insn "mshf4_b"
12664   [(set
12665     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12666     (vec_select:V8QI
12667      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12668                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12669      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12670                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12671   "TARGET_SHMEDIA"
12672   "* return (TARGET_LITTLE_ENDIAN
12673              ? \"mshfhi.b       %N1, %N2, %0\"
12674              : \"mshflo.b       %N1, %N2, %0\");"
12675   [(set_attr "type" "arith_media")
12676    (set (attr "highpart")
12677         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12678          (const_string "user")))])
12679
12680 (define_insn "mshf0_b"
12681   [(set
12682     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12683     (vec_select:V8QI
12684      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12685                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12686      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12687                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12688   "TARGET_SHMEDIA"
12689   "* return (TARGET_LITTLE_ENDIAN
12690              ? \"mshflo.b       %N1, %N2, %0\"
12691              : \"mshfhi.b       %N1, %N2, %0\");"
12692   [(set_attr "type" "arith_media")
12693    (set (attr "highpart")
12694         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12695          (const_string "user")))])
12696
12697 (define_expand "mshfhi_l"
12698   [(match_operand:V2SI 0 "arith_reg_dest" "")
12699    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12700    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12701   "TARGET_SHMEDIA"
12702   "
12703 {
12704   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12705              (operands[0], operands[1], operands[2]));
12706   DONE;
12707 }")
12708
12709 (define_expand "mshflo_l"
12710   [(match_operand:V2SI 0 "arith_reg_dest" "")
12711    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12712    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12713   "TARGET_SHMEDIA"
12714   "
12715 {
12716   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12717              (operands[0], operands[1], operands[2]));
12718   DONE;
12719 }")
12720
12721 (define_insn "mshf4_l"
12722   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12723         (vec_select:V2SI
12724          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12725                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12726          (parallel [(const_int 1) (const_int 3)])))]
12727   "TARGET_SHMEDIA"
12728   "* return (TARGET_LITTLE_ENDIAN
12729              ? \"mshfhi.l       %N1, %N2, %0\"
12730              : \"mshflo.l       %N1, %N2, %0\");"
12731   [(set_attr "type" "arith_media")
12732    (set (attr "highpart")
12733         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12734          (const_string "user")))])
12735
12736 (define_insn "mshf0_l"
12737   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12738         (vec_select:V2SI
12739          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12740                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12741          (parallel [(const_int 0) (const_int 2)])))]
12742   "TARGET_SHMEDIA"
12743   "* return (TARGET_LITTLE_ENDIAN
12744              ? \"mshflo.l       %N1, %N2, %0\"
12745              : \"mshfhi.l       %N1, %N2, %0\");"
12746   [(set_attr "type" "arith_media")
12747    (set (attr "highpart")
12748         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12749          (const_string "user")))])
12750
12751 (define_expand "mshfhi_w"
12752   [(match_operand:V4HI 0 "arith_reg_dest" "")
12753    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12754    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12755   "TARGET_SHMEDIA"
12756   "
12757 {
12758   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12759              (operands[0], operands[1], operands[2]));
12760   DONE;
12761 }")
12762
12763 (define_expand "mshflo_w"
12764   [(match_operand:V4HI 0 "arith_reg_dest" "")
12765    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12766    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12767   "TARGET_SHMEDIA"
12768   "
12769 {
12770   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12771              (operands[0], operands[1], operands[2]));
12772   DONE;
12773 }")
12774
12775 (define_insn "mshf4_w"
12776   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12777         (vec_select:V4HI
12778          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12779                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12780          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12781   "TARGET_SHMEDIA"
12782   "* return (TARGET_LITTLE_ENDIAN
12783              ? \"mshfhi.w       %N1, %N2, %0\"
12784              : \"mshflo.w       %N1, %N2, %0\");"
12785   [(set_attr "type" "arith_media")
12786    (set (attr "highpart")
12787         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12788          (const_string "user")))])
12789
12790 (define_insn "mshf0_w"
12791   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12792         (vec_select:V4HI
12793          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12794                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12795          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12796   "TARGET_SHMEDIA"
12797   "* return (TARGET_LITTLE_ENDIAN
12798              ? \"mshflo.w       %N1, %N2, %0\"
12799              : \"mshfhi.w       %N1, %N2, %0\");"
12800   [(set_attr "type" "arith_media")
12801    (set (attr "highpart")
12802         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12803          (const_string "user")))])
12804
12805 (define_insn "mshflo_w_x"
12806   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12807         (vec_select:V4HI
12808          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12809                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12810          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12811   "TARGET_SHMEDIA"
12812   "mshflo.w     %N1, %N2, %0"
12813   [(set_attr "type" "arith_media")
12814    (set_attr "highpart" "ignore")])
12815
12816 /* These are useful to expand ANDs and as combiner patterns.  */
12817 (define_insn_and_split "mshfhi_l_di"
12818   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12819         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12820                              (const_int 32))
12821                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12822                         (const_int -4294967296))))]
12823   "TARGET_SHMEDIA"
12824   "@
12825         mshfhi.l        %N1, %N2, %0
12826         #"
12827   "TARGET_SHMEDIA && reload_completed
12828    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12829   [(set (match_dup 3) (match_dup 4))
12830    (set (match_dup 5) (match_dup 6))]
12831   "
12832 {
12833   operands[3] = gen_lowpart (SImode, operands[0]);
12834   operands[4] = gen_highpart (SImode, operands[1]);
12835   operands[5] = gen_highpart (SImode, operands[0]);
12836   operands[6] = gen_highpart (SImode, operands[2]);
12837 }"
12838   [(set_attr "type" "arith_media")])
12839
12840 (define_insn "*mshfhi_l_di_rev"
12841   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12842         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12843                         (const_int -4294967296))
12844                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12845                              (const_int 32))))]
12846   "TARGET_SHMEDIA"
12847   "mshfhi.l     %N2, %N1, %0"
12848   [(set_attr "type" "arith_media")])
12849
12850 (define_split
12851   [(set (match_operand:DI 0 "arith_reg_dest" "")
12852         (ior:DI (zero_extend:DI (match_operand:SI 1
12853                                               "extend_reg_or_0_operand" ""))
12854                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12855                         (const_int -4294967296))))
12856    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12857   "TARGET_SHMEDIA"
12858   [(const_int 0)]
12859   "
12860 {
12861   emit_insn (gen_ashldi3_media (operands[3],
12862                                 simplify_gen_subreg (DImode, operands[1],
12863                                                      SImode, 0),
12864                                 GEN_INT (32)));
12865   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12866   DONE;
12867 }")
12868
12869 (define_insn "mshflo_l_di"
12870   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12871         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12872                         (const_int 4294967295))
12873                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12874                            (const_int 32))))]
12875
12876   "TARGET_SHMEDIA"
12877   "mshflo.l     %N1, %N2, %0"
12878   [(set_attr "type" "arith_media")
12879    (set_attr "highpart" "ignore")])
12880
12881 (define_insn "*mshflo_l_di_rev"
12882   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12883         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12884                            (const_int 32))
12885                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12886                         (const_int 4294967295))))]
12887
12888   "TARGET_SHMEDIA"
12889   "mshflo.l     %N2, %N1, %0"
12890   [(set_attr "type" "arith_media")
12891    (set_attr "highpart" "ignore")])
12892
12893 ;; Combiner pattern for trampoline initialization.
12894 (define_insn_and_split "*double_shori"
12895   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12896         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12897                            (const_int 32))
12898                 (match_operand:DI 2 "const_int_operand" "n")))]
12899   "TARGET_SHMEDIA
12900    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12901   "#"
12902   "rtx_equal_p (operands[0], operands[1])"
12903   [(const_int 0)]
12904   "
12905 {
12906   HOST_WIDE_INT v = INTVAL (operands[2]);
12907
12908   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12909   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12910   DONE;
12911 }"
12912   [(set_attr "highpart" "ignore")])
12913
12914
12915 (define_insn "*mshflo_l_di_x"
12916   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12917         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12918                                  "rZ"))
12919                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12920                            (const_int 32))))]
12921
12922   "TARGET_SHMEDIA"
12923   "mshflo.l     %N1, %N2, %0"
12924   [(set_attr "type" "arith_media")
12925    (set_attr "highpart" "ignore")])
12926
12927 (define_insn_and_split "concat_v2sf"
12928   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12929 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12930         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12931                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12932
12933   "TARGET_SHMEDIA"
12934   "@
12935         mshflo.l        %N1, %N2, %0
12936         #
12937         #"
12938   "TARGET_SHMEDIA && reload_completed
12939    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12940   [(set (match_dup 3) (match_dup 1))
12941    (set (match_dup 4) (match_dup 2))]
12942   "
12943 {
12944   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12945   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12946 }"
12947   [(set_attr "type" "arith_media")
12948    (set_attr "highpart" "ignore")])
12949
12950 (define_insn "*mshflo_l_di_x_rev"
12951   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12952         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12953                            (const_int 32))
12954                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12955
12956   "TARGET_SHMEDIA"
12957   "mshflo.l     %N2, %N1, %0"
12958   [(set_attr "type" "arith_media")
12959    (set_attr "highpart" "ignore")])
12960
12961 (define_insn "ashlv2si3"
12962   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12963         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12964                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12965   "TARGET_SHMEDIA"
12966   "mshlld.l     %1, %2, %0"
12967   [(set_attr "type" "arith_media")
12968    (set_attr "highpart" "depend")])
12969
12970 (define_split
12971   [(set (match_operand 0 "any_register_operand" "")
12972         (match_operator 3 "shift_operator"
12973           [(match_operand 1 "any_register_operand" "")
12974            (match_operand 2 "shift_count_reg_operand" "")]))]
12975   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12976   [(set (match_dup 0) (match_dup 3))]
12977   "
12978 {
12979   rtx count = operands[2];
12980   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12981
12982   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12983          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12984          || GET_CODE (count) == TRUNCATE)
12985     count = XEXP (count, 0);
12986   inner_mode = GET_MODE (count);
12987   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12988                                subreg_lowpart_offset (outer_mode, inner_mode));
12989   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12990                                 operands[1], count);
12991 }")
12992
12993 (define_insn "ashlv4hi3"
12994   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12995         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12996                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12997   "TARGET_SHMEDIA"
12998   "mshlld.w     %1, %2, %0"
12999   [(set_attr "type" "arith_media")
13000    (set_attr "highpart" "depend")])
13001
13002 (define_insn "lshrv2si3"
13003   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13004         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13005                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13006   "TARGET_SHMEDIA"
13007   "mshlrd.l     %1, %2, %0"
13008   [(set_attr "type" "arith_media")
13009    (set_attr "highpart" "depend")])
13010
13011 (define_insn "lshrv4hi3"
13012   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13013         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13014                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13015   "TARGET_SHMEDIA"
13016   "mshlrd.w     %1, %2, %0"
13017   [(set_attr "type" "arith_media")
13018    (set_attr "highpart" "depend")])
13019
13020 (define_insn "subv2si3"
13021   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13022         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13023                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13024   "TARGET_SHMEDIA"
13025   "msub.l       %N1, %2, %0"
13026   [(set_attr "type" "arith_media")
13027    (set_attr "highpart" "depend")])
13028
13029 (define_insn "subv4hi3"
13030   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13031         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13032                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13033   "TARGET_SHMEDIA"
13034   "msub.w       %N1, %2, %0"
13035   [(set_attr "type" "arith_media")
13036    (set_attr "highpart" "depend")])
13037
13038 (define_insn_and_split "subv2hi3"
13039   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13040         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13041                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13042   "TARGET_SHMEDIA"
13043   "#"
13044   "TARGET_SHMEDIA"
13045   [(const_int 0)]
13046   "
13047 {
13048   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13049   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13050   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13051   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13052   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13053
13054   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13055   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13056   DONE;
13057 }"
13058   [(set_attr "highpart" "must_split")])
13059
13060 (define_insn "sssubv2si3"
13061   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13062         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13063                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13064   "TARGET_SHMEDIA"
13065   "msubs.l      %N1, %2, %0"
13066   [(set_attr "type" "mcmp_media")
13067    (set_attr "highpart" "depend")])
13068
13069 (define_insn "ussubv8qi3"
13070   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13071         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13072                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13073   "TARGET_SHMEDIA"
13074   "msubs.ub     %N1, %2, %0"
13075   [(set_attr "type" "mcmp_media")
13076    (set_attr "highpart" "depend")])
13077
13078 (define_insn "sssubv4hi3"
13079   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13080         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13081                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13082   "TARGET_SHMEDIA"
13083   "msubs.w      %N1, %2, %0"
13084   [(set_attr "type" "mcmp_media")
13085    (set_attr "highpart" "depend")])
13086
13087 ;; Floating Point Intrinsics
13088
13089 (define_insn "fcosa_s"
13090   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13091         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13092                    UNSPEC_FCOSA))]
13093   "TARGET_SHMEDIA"
13094   "fcosa.s      %1, %0"
13095   [(set_attr "type" "atrans_media")])
13096
13097 (define_insn "fsina_s"
13098   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13099         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13100                    UNSPEC_FSINA))]
13101   "TARGET_SHMEDIA"
13102   "fsina.s      %1, %0"
13103   [(set_attr "type" "atrans_media")])
13104
13105 (define_insn "fipr"
13106   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13107         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13108                                                     "fp_arith_reg_operand" "f")
13109                                                    (match_operand:V4SF 2
13110                                                     "fp_arith_reg_operand" "f"))
13111                                          (parallel [(const_int 0)]))
13112                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13113                                          (parallel [(const_int 1)])))
13114                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13115                                          (parallel [(const_int 2)]))
13116                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13117                                          (parallel [(const_int 3)])))))]
13118   "TARGET_SHMEDIA"
13119   "fipr.s       %1, %2, %0"
13120   [(set_attr "type" "fparith_media")])
13121
13122 (define_insn "fsrra_s"
13123   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13124         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13125                    UNSPEC_FSRRA))]
13126   "TARGET_SHMEDIA"
13127   "fsrra.s      %1, %0"
13128   [(set_attr "type" "atrans_media")])
13129
13130 (define_insn "ftrv"
13131   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13132         (plus:V4SF
13133          (plus:V4SF
13134           (mult:V4SF
13135            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13136                             (parallel [(const_int 0) (const_int 5)
13137                                        (const_int 10) (const_int 15)]))
13138            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13139           (mult:V4SF
13140            (vec_select:V4SF (match_dup 1)
13141                             (parallel [(const_int 4) (const_int 9)
13142                                        (const_int 14) (const_int 3)]))
13143            (vec_select:V4SF (match_dup 2)
13144                             (parallel [(const_int 1) (const_int 2)
13145                                        (const_int 3) (const_int 0)]))))
13146          (plus:V4SF
13147           (mult:V4SF
13148            (vec_select:V4SF (match_dup 1)
13149                             (parallel [(const_int 8) (const_int 13)
13150                                        (const_int 2) (const_int 7)]))
13151            (vec_select:V4SF (match_dup 2)
13152                             (parallel [(const_int 2) (const_int 3)
13153                                        (const_int 0) (const_int 1)])))
13154           (mult:V4SF
13155            (vec_select:V4SF (match_dup 1)
13156                             (parallel [(const_int 12) (const_int 1)
13157                                        (const_int 6) (const_int 11)]))
13158            (vec_select:V4SF (match_dup 2)
13159                             (parallel [(const_int 3) (const_int 0)
13160                                        (const_int 1) (const_int 2)]))))))]
13161   "TARGET_SHMEDIA"
13162   "ftrv.s %1, %2, %0"
13163   [(set_attr "type" "fparith_media")])
13164
13165 (define_insn "ldhi_l"
13166   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13167         (zero_extract:SI
13168          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13169                                   (const_int 3))
13170                           (const_int -3)))
13171          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13172          (const_int 0)))]
13173   "TARGET_SHMEDIA32"
13174   "ldhi.l       %U1, %0"
13175   [(set_attr "type" "load_media")])
13176
13177 (define_insn "ldhi_q"
13178   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13179         (zero_extract:DI
13180          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13181                                   (const_int 7))
13182                           (const_int -7)))
13183          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13184          (const_int 0)))]
13185   "TARGET_SHMEDIA32"
13186   "ldhi.q       %U1, %0"
13187   [(set_attr "type" "load_media")])
13188
13189 (define_insn_and_split "*ldhi_q_comb0"
13190   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13191         (zero_extract:DI
13192          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13193                                             "register_operand" "r")
13194                                            (match_operand:SI 2
13195                                             "ua_offset" "I06"))
13196                                   (const_int 7))
13197                           (const_int -7)))
13198          (plus:SI (and:SI (match_dup 1) (const_int 7))
13199                   (const_int 1))
13200          (const_int 0)))]
13201   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13202   "#"
13203   ""
13204   [(pc)]
13205   "emit_insn (gen_ldhi_q (operands[0],
13206                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13207    DONE;")
13208
13209
13210 (define_insn_and_split "*ldhi_q_comb1"
13211   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13212         (zero_extract:DI
13213          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13214                                             "register_operand" "r")
13215                                            (match_operand:SI 2
13216                                             "ua_offset" "I06"))
13217                                   (const_int 7))
13218                           (const_int -7)))
13219          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13220                                                    "ua_offset" "I06"))
13221                           (const_int 7))
13222                   (const_int 1))
13223          (const_int 0)))]
13224   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13225    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13226   "#"
13227   ""
13228   [(pc)]
13229   "emit_insn (gen_ldhi_q (operands[0],
13230                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13231    DONE;")
13232
13233
13234 (define_insn "ldlo_l"
13235   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13236         (zero_extract:SI
13237          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13238                          (const_int -4)))
13239          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13240          (and:SI (match_dup 1) (const_int 3))))]
13241   "TARGET_SHMEDIA32"
13242   "ldlo.l       %U1, %0"
13243   [(set_attr "type" "load_media")])
13244
13245 (define_insn "ldlo_q"
13246   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13247         (zero_extract:DI
13248          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13249                          (const_int -8)))
13250          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13251          (and:SI (match_dup 1) (const_int 7))))]
13252   "TARGET_SHMEDIA32"
13253   "ldlo.q       %U1, %0"
13254   [(set_attr "type" "load_media")])
13255
13256 (define_insn_and_split "*ldlo_q_comb0"
13257   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13258         (zero_extract:DI
13259          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13260                                   (match_operand:SI 2 "ua_offset" "I06"))
13261                          (const_int -8)))
13262          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13263          (and:SI (match_dup 1) (const_int 7))))]
13264   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13265   "#"
13266   ""
13267   [(pc)]
13268   "emit_insn (gen_ldlo_q (operands[0],
13269                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13270    DONE;")
13271
13272 (define_insn_and_split "*ldlo_q_comb1"
13273   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13274         (zero_extract:DI
13275          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13276                                   (match_operand:SI 2 "ua_offset" "I06"))
13277                          (const_int -8)))
13278          (minus:SI (const_int 8)
13279                    (and:SI (plus:SI (match_dup 1)
13280                                     (match_operand:SI 3 "ua_offset" "I06"))
13281                            (const_int 7)))
13282          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13283   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13284    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13285   "#"
13286   ""
13287   [(pc)]
13288   "emit_insn (gen_ldlo_q (operands[0],
13289                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13290    DONE;")
13291
13292 (define_insn "sthi_l"
13293   [(set (zero_extract:SI
13294          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13295                                   (const_int 3))
13296                           (const_int -3)))
13297          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13298          (const_int 0))
13299         (match_operand:SI 1 "arith_reg_operand" "r"))]
13300   "TARGET_SHMEDIA32"
13301   "sthi.l       %U0, %1"
13302   [(set_attr "type" "ustore_media")])
13303
13304 ;; All unaligned stores are considered to be 'narrow' because they typically
13305 ;; operate on less that a quadword, and when they operate on a full quadword,
13306 ;; the vanilla store high / store low sequence will cause a stall if not
13307 ;; scheduled apart.
13308 (define_insn "sthi_q"
13309   [(set (zero_extract:DI
13310          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13311                                   (const_int 7))
13312                           (const_int -7)))
13313          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13314          (const_int 0))
13315         (match_operand:DI 1 "arith_reg_operand" "r"))]
13316   "TARGET_SHMEDIA32"
13317   "sthi.q       %U0, %1"
13318   [(set_attr "type" "ustore_media")])
13319
13320 (define_insn_and_split "*sthi_q_comb0"
13321   [(set (zero_extract:DI
13322          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13323                                             "register_operand" "r")
13324                                            (match_operand:SI 1 "ua_offset"
13325                                             "I06"))
13326                                   (const_int 7))
13327                           (const_int -7)))
13328          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13329          (const_int 0))
13330         (match_operand:DI 2 "arith_reg_operand" "r"))]
13331   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13332   "#"
13333   ""
13334   [(pc)]
13335   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13336                           operands[2]));
13337    DONE;")
13338
13339 (define_insn_and_split "*sthi_q_comb1"
13340   [(set (zero_extract:DI
13341          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13342                                             "register_operand" "r")
13343                                            (match_operand:SI 1 "ua_offset"
13344                                             "I06"))
13345                                   (const_int 7))
13346                           (const_int -7)))
13347          (plus:SI (and:SI (plus:SI (match_dup 0)
13348                                    (match_operand:SI 2 "ua_offset" "I06"))
13349                           (const_int 7))
13350                   (const_int 1))
13351          (const_int 0))
13352         (match_operand:DI 3 "arith_reg_operand" "r"))]
13353   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13354    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13355   "#"
13356   ""
13357   [(pc)]
13358   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13359                           operands[3]));
13360    DONE;")
13361
13362 ;; This is highpart user because the address is used as full 64 bit.
13363 (define_insn "stlo_l"
13364   [(set (zero_extract:SI
13365          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13366                          (const_int -4)))
13367          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13368          (and:SI (match_dup 0) (const_int 3)))
13369         (match_operand:SI 1 "arith_reg_operand" "r"))]
13370   "TARGET_SHMEDIA32"
13371   "stlo.l       %U0, %1"
13372   [(set_attr "type" "ustore_media")])
13373
13374 (define_insn "stlo_q"
13375   [(set (zero_extract:DI
13376          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13377                          (const_int -8)))
13378          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13379          (and:SI (match_dup 0) (const_int 7)))
13380         (match_operand:DI 1 "arith_reg_operand" "r"))]
13381   "TARGET_SHMEDIA32"
13382   "stlo.q       %U0, %1"
13383   [(set_attr "type" "ustore_media")])
13384
13385 (define_insn_and_split "*stlo_q_comb0"
13386   [(set (zero_extract:DI
13387          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13388                                   (match_operand:SI 1 "ua_offset" "I06"))
13389                          (const_int -8)))
13390          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13391          (and:SI (match_dup 0) (const_int 7)))
13392         (match_operand:DI 2 "arith_reg_operand" "r"))]
13393   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13394   "#"
13395   ""
13396   [(pc)]
13397   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13398                           operands[2]));
13399    DONE;")
13400
13401 (define_insn_and_split "*stlo_q_comb1"
13402   [(set (zero_extract:DI
13403          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13404                                   (match_operand:SI 1 "ua_offset" "I06"))
13405                          (const_int -8)))
13406          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13407                                                   (match_operand:SI 2
13408                                                    "ua_offset" "I06"))
13409                                          (const_int 7)))
13410          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13411         (match_operand:DI 3 "arith_reg_operand" "r"))]
13412   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13413   "#"
13414   ""
13415   [(pc)]
13416   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13417                           operands[3]));
13418    DONE;")
13419
13420 (define_insn "ldhi_l64"
13421   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13422         (zero_extract:SI
13423          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13424                                   (const_int 3))
13425                           (const_int -3)))
13426          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13427          (const_int 0)))]
13428   "TARGET_SHMEDIA64"
13429   "ldhi.l       %U1, %0"
13430   [(set_attr "type" "load_media")])
13431
13432 (define_insn "ldhi_q64"
13433   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13434         (zero_extract:DI
13435          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13436                                   (const_int 7))
13437                           (const_int -7)))
13438          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13439          (const_int 0)))]
13440   "TARGET_SHMEDIA64"
13441   "ldhi.q       %U1, %0"
13442   [(set_attr "type" "load_media")])
13443
13444 (define_insn "ldlo_l64"
13445   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13446         (zero_extract:SI
13447          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13448                          (const_int -4)))
13449          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13450          (and:DI (match_dup 1) (const_int 3))))]
13451   "TARGET_SHMEDIA64"
13452   "ldlo.l       %U1, %0"
13453   [(set_attr "type" "load_media")])
13454
13455 (define_insn "ldlo_q64"
13456   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13457         (zero_extract:DI
13458          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13459                          (const_int -8)))
13460          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13461          (and:DI (match_dup 1) (const_int 7))))]
13462   "TARGET_SHMEDIA64"
13463   "ldlo.q       %U1, %0"
13464   [(set_attr "type" "load_media")])
13465
13466 (define_insn "sthi_l64"
13467   [(set (zero_extract:SI
13468          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13469                                   (const_int 3))
13470                           (const_int -3)))
13471          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13472          (const_int 0))
13473         (match_operand:SI 1 "arith_reg_operand" "r"))]
13474   "TARGET_SHMEDIA64"
13475   "sthi.l       %U0, %1"
13476   [(set_attr "type" "ustore_media")])
13477
13478 (define_insn "sthi_q64"
13479   [(set (zero_extract:DI
13480          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13481                                   (const_int 7))
13482                           (const_int -7)))
13483          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13484          (const_int 0))
13485         (match_operand:DI 1 "arith_reg_operand" "r"))]
13486   "TARGET_SHMEDIA64"
13487   "sthi.q       %U0, %1"
13488   [(set_attr "type" "ustore_media")])
13489
13490 (define_insn "stlo_l64"
13491   [(set (zero_extract:SI
13492          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13493                          (const_int -4)))
13494          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13495          (and:DI (match_dup 0) (const_int 3)))
13496         (match_operand:SI 1 "arith_reg_operand" "r"))]
13497   "TARGET_SHMEDIA64"
13498   "stlo.l       %U0, %1"
13499   [(set_attr "type" "ustore_media")])
13500
13501 (define_insn "stlo_q64"
13502   [(set (zero_extract:DI
13503          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13504                          (const_int -8)))
13505          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13506          (and:DI (match_dup 0) (const_int 7)))
13507         (match_operand:DI 1 "arith_reg_operand" "r"))]
13508   "TARGET_SHMEDIA64"
13509   "stlo.q       %U0, %1"
13510   [(set_attr "type" "ustore_media")])
13511
13512 (define_insn "nsb"
13513   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13514         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13515                    UNSPEC_NSB))]
13516   "TARGET_SHMEDIA"
13517   "nsb  %1, %0"
13518   [(set_attr "type" "arith_media")])
13519
13520 (define_insn "nsbsi"
13521   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13522         (zero_extend:SI
13523          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13524                     UNSPEC_NSB)))]
13525   "TARGET_SHMEDIA"
13526   "nsb  %1, %0"
13527   [(set_attr "type" "arith_media")])
13528
13529 (define_insn "nsbdi"
13530   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13531         (zero_extend:DI
13532          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13533                     UNSPEC_NSB)))]
13534   "TARGET_SHMEDIA"
13535   "nsb  %1, %0"
13536   [(set_attr "type" "arith_media")])
13537
13538 (define_expand "ffsdi2"
13539   [(set (match_operand:DI 0 "arith_reg_dest" "")
13540         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13541   "TARGET_SHMEDIA"
13542   "
13543 {
13544   rtx scratch = gen_reg_rtx (DImode);
13545   rtx last;
13546
13547   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13548   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13549   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13550   emit_insn (gen_nsbdi (scratch, scratch));
13551   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13552   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13553   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13554   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13555
13556   DONE;
13557 }")
13558
13559 (define_expand "ffssi2"
13560   [(set (match_operand:SI 0 "arith_reg_dest" "")
13561         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13562   "TARGET_SHMEDIA"
13563   "
13564 {
13565   rtx scratch = gen_reg_rtx (SImode);
13566   rtx discratch = gen_reg_rtx (DImode);
13567   rtx last;
13568
13569   emit_insn (gen_adddi3 (discratch,
13570                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13571                          constm1_rtx));
13572   emit_insn (gen_andcdi3 (discratch,
13573                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13574                           discratch));
13575   emit_insn (gen_nsbsi (scratch, discratch));
13576   last = emit_insn (gen_subsi3 (operands[0],
13577                                 force_reg (SImode, GEN_INT (63)), scratch));
13578   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13579
13580   DONE;
13581 }")
13582
13583 (define_insn "byterev"
13584   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13585         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13586                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13587                                     (const_int 4) (const_int 3) (const_int 2)
13588                                     (const_int 1) (const_int 0)])))]
13589   "TARGET_SHMEDIA"
13590   "byterev      %1, %0"
13591   [(set_attr "type" "arith_media")])
13592
13593 (define_insn "*prefetch_media"
13594   [(prefetch (match_operand:QI 0 "address_operand" "p")
13595              (match_operand:SI 1 "const_int_operand" "n")
13596              (match_operand:SI 2 "const_int_operand" "n"))]
13597   "TARGET_SHMEDIA"
13598   "*
13599 {
13600   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13601   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13602   return \"\";
13603 }"
13604   [(set_attr "type" "other")])
13605
13606 (define_insn "*prefetch_i4"
13607   [(prefetch (match_operand:SI 0 "register_operand" "r")
13608              (match_operand:SI 1 "const_int_operand" "n")
13609              (match_operand:SI 2 "const_int_operand" "n"))]
13610   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13611   "*
13612 {
13613   return \"pref @%0\";
13614 }"
13615   [(set_attr "type" "other")])
13616
13617 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13618 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13619 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13620 (define_expand "prefetch"
13621   [(prefetch (match_operand 0 "address_operand" "p")
13622              (match_operand:SI 1 "const_int_operand" "n")
13623              (match_operand:SI 2 "const_int_operand" "n"))]
13624   "(TARGET_HARD_SH4 || TARGET_SH5) && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP)"
13625   "
13626 {
13627   if (GET_MODE (operands[0]) != Pmode
13628       || GET_CODE (operands[1]) != CONST_INT
13629       || GET_CODE (operands[2]) != CONST_INT)
13630     FAIL;
13631   if (! TARGET_SHMEDIA)
13632     operands[0] = force_reg (Pmode, operands[0]);
13633 }")
13634
13635 (define_insn "alloco_i"
13636   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13637         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13638   "TARGET_SHMEDIA32"
13639   "*
13640 {
13641   rtx xops[2];
13642
13643   if (GET_CODE (operands[0]) == PLUS)
13644     {
13645       xops[0] = XEXP (operands[0], 0);
13646       xops[1] = XEXP (operands[0], 1);
13647     }
13648   else
13649     {
13650       xops[0] = operands[0];
13651       xops[1] = const0_rtx;
13652     }
13653   output_asm_insn (\"alloco   %0, %1\", xops);
13654   return \"\";
13655 }"
13656   [(set_attr "type" "other")])
13657
13658 (define_split
13659   [(set (match_operand 0 "any_register_operand" "")
13660         (match_operand 1 "" ""))]
13661   "TARGET_SHMEDIA && reload_completed"
13662   [(set (match_dup 0) (match_dup 1))]
13663   "
13664 {
13665   int n_changes = 0;
13666
13667   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13668   if (!n_changes)
13669     FAIL;
13670 }")
13671
13672 ; Stack Protector Patterns
13673
13674 (define_expand "stack_protect_set"
13675   [(set (match_operand 0 "memory_operand" "")
13676         (match_operand 1 "memory_operand" ""))]
13677   ""
13678 {
13679   if (TARGET_SHMEDIA)
13680     {
13681       if (TARGET_SHMEDIA64)
13682         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13683       else
13684         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13685     }
13686   else
13687     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13688
13689   DONE;
13690 })
13691
13692 (define_insn "stack_protect_set_si"
13693   [(set (match_operand:SI 0 "memory_operand" "=m")
13694         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13695    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13696   "!TARGET_SHMEDIA"
13697   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13698   [(set_attr "type" "other")
13699    (set_attr "length" "6")])
13700
13701 (define_insn "stack_protect_set_si_media"
13702   [(set (match_operand:SI 0 "memory_operand" "=m")
13703         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13704    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13705   "TARGET_SHMEDIA"
13706   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13707   [(set_attr "type" "other")
13708    (set_attr "length" "12")])
13709
13710 (define_insn "stack_protect_set_di_media"
13711   [(set (match_operand:DI 0 "memory_operand" "=m")
13712         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13713    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13714   "TARGET_SHMEDIA64"
13715   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13716   [(set_attr "type" "other")
13717    (set_attr "length" "12")])
13718
13719 (define_expand "stack_protect_test"
13720   [(match_operand 0 "memory_operand" "")
13721    (match_operand 1 "memory_operand" "")
13722    (match_operand 2 "" "")]
13723   ""
13724 {
13725   if (TARGET_SHMEDIA)
13726     {
13727       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13728
13729       if (TARGET_SHMEDIA64)
13730         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13731                                                     operands[1]));
13732       else
13733         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13734                                                     operands[1]));
13735
13736       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13737     }
13738   else
13739     {
13740       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13741       emit_jump_insn (gen_branch_true (operands[2]));
13742     }
13743
13744   DONE;
13745 })
13746
13747 (define_insn "stack_protect_test_si"
13748   [(set (reg:SI T_REG)
13749         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13750                     (match_operand:SI 1 "memory_operand" "m")]
13751                    UNSPEC_SP_TEST))
13752   (set (match_scratch:SI 2 "=&r") (const_int 0))
13753   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13754   "!TARGET_SHMEDIA"
13755   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13756   [(set_attr "type" "other")
13757    (set_attr "length" "10")])
13758
13759 (define_insn "stack_protect_test_si_media"
13760   [(set (match_operand:SI 0 "register_operand" "=&r")
13761         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13762                     (match_operand:SI 2 "memory_operand" "m")]
13763                    UNSPEC_SP_TEST))
13764   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13765   "TARGET_SHMEDIA"
13766   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13767   [(set_attr "type" "other")
13768    (set_attr "length" "16")])
13769
13770 (define_insn "stack_protect_test_di_media"
13771   [(set (match_operand:DI 0 "register_operand" "=&r")
13772         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13773                     (match_operand:DI 2 "memory_operand" "m")]
13774                    UNSPEC_SP_TEST))
13775   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13776   "TARGET_SHMEDIA64"
13777   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13778   [(set_attr "type" "other")
13779    (set_attr "length" "16")])