OSDN Git Service

* config/sh/linux.h (TARGET_DEFAULT): Add MASK_SOFT_ATOMIC.
[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, 2008, 2009, 2010, 2011
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_CHKADD        38)
154   (UNSPEC_SP_SET        40)
155   (UNSPEC_SP_TEST       41)
156   (UNSPEC_MOVUA         42)
157
158   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160   (UNSPEC_EXTRACT_S16   43)
161   (UNSPEC_EXTRACT_U16   44)
162
163   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164   (UNSPEC_SYMOFF        45)
165
166   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167   (UNSPEC_PCREL_SYMOFF  46)
168
169   ;; These are used with unspec_volatile.
170   (UNSPECV_BLOCKAGE     0)
171   (UNSPECV_ALIGN        1)
172   (UNSPECV_CONST2       2)
173   (UNSPECV_CONST4       4)
174   (UNSPECV_CONST8       6)
175   (UNSPECV_WINDOW_END   10)
176   (UNSPECV_CONST_END    11)
177   (UNSPECV_EH_RETURN    12)
178 ])
179
180 ;; -------------------------------------------------------------------------
181 ;; Attributes
182 ;; -------------------------------------------------------------------------
183
184 ;; Target CPU.
185
186 (define_attr "cpu"
187  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188   (const (symbol_ref "sh_cpu_attr")))
189
190 (define_attr "endian" "big,little"
191  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192                       (const_string "little") (const_string "big"))))
193
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197                          (const_string "yes") (const_string "no"))))
198
199 (define_attr "fmovd" "yes,no"
200   (const (if_then_else (symbol_ref "TARGET_FMOVD")
201                        (const_string "yes") (const_string "no"))))
202 ;; pipeline model
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
204   (const
205    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207          (const_string "sh1"))))
208
209 ;; cbranch      conditional branch instructions
210 ;; jump         unconditional jumps
211 ;; arith        ordinary arithmetic
212 ;; arith3       a compound insn that behaves similarly to a sequence of
213 ;;              three insns of type arith
214 ;; arith3b      like above, but might end with a redirected branch
215 ;; load         from memory
216 ;; load_si      Likewise, SImode variant for general register.
217 ;; fload        Likewise, but load to fp register.
218 ;; store        to memory
219 ;; fstore       floating point register to memory
220 ;; move         general purpose register to register
221 ;; movi8        8-bit immediate to general purpose register
222 ;; mt_group     other sh4 mt instructions
223 ;; fmove        register to register, floating point
224 ;; smpy         word precision integer multiply
225 ;; dmpy         longword or doublelongword precision integer multiply
226 ;; return       rts
227 ;; pload        load of pr reg, which can't be put into delay slot of rts
228 ;; prset        copy register to pr reg, ditto
229 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
230 ;; prget        copy pr to register, ditto
231 ;; pcload       pc relative load of constant value
232 ;; pcfload      Likewise, but load to fp register.
233 ;; pcload_si    Likewise, SImode variant for general register.
234 ;; rte          return from exception
235 ;; sfunc        special function call with known used registers
236 ;; call         function call
237 ;; fp           floating point
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv         floating point divide (or square root)
240 ;; gp_fpul      move from general purpose register to fpul
241 ;; fpul_gp      move from fpul to general purpose register
242 ;; mac_gp       move from mac[lh] to general purpose register
243 ;; gp_mac       move from general purpose register to mac[lh]
244 ;; mac_mem      move from mac[lh] to memory
245 ;; mem_mac      move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s       fix_truncsfsi2_i4
248 ;; dfdiv        double precision floating point divide (or square root)
249 ;; cwb          ic_invalidate_line_i
250 ;; movua        SH4a unaligned load
251 ;; fsrra        square root reciprocal approximate
252 ;; fsca         sine and cosine approximate
253 ;; tls_load     load TLS related address
254 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media    SHmedia compare instructions
257 ;; dfdiv_media  SHmedia double precision divide and square root
258 ;; dfmul_media  SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media   SHmedia longword multiply
262 ;; fcmp_media   SHmedia floating point compare instructions
263 ;; fdiv_media   SHmedia single precision divide and square root
264 ;; fload_media  SHmedia floating point register load instructions
265 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media  SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media   SHmedia unconditional branch instructions
272 ;; load_media   SHmedia general register load instructions
273 ;; pt_media     SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media  SHmedia ptabs instruction
275 ;; store_media  SHmedia general register store instructions
276 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media    SHmedia mac-style fixed point operations
278 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil          no-op move, will be deleted.
282
283 (define_attr "type"
284  "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"
285   (const_string "other"))
286
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
289 ;;
290 ;; mt_group      SH4 "mt" group instructions.
291 ;;
292 ;; ex_group      SH4 "ex" group instructions.
293 ;;
294 ;; ls_group      SH4 "ls" group instructions.
295 ;;
296
297 (define_attr "insn_class"
298   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302          (eq_attr "type" "cbranch,jump") (const_string "br_group")
303          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304            (const_string "fe_group")
305          (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")]
306         (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
310
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
312
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
314
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
318 ;; state.
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long.  Something in the
325 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
328 ; 2 bytes.
329
330 ;; The maximum range used for SImode constant pool entries is 1018.  A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table.  That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
342 ;;
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
345
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347 ;; inside an le.
348 (define_attr "short_cbranch_p" "no,yes"
349   (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
350          (const_string "no")
351          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352          (const_string "yes")
353          (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356          (const_string "yes")
357          ] (const_string "no")))
358
359 (define_attr "med_branch_p" "no,yes"
360   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361               (const_int 1988))
362          (const_string "yes")
363          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366               (const_int 8186))
367          (const_string "yes")
368          ] (const_string "no")))
369
370 (define_attr "med_cbranch_p" "no,yes"
371   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372               (const_int 1986))
373          (const_string "yes")
374          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377                (const_int 8184))
378          (const_string "yes")
379          ] (const_string "no")))
380
381 (define_attr "braf_branch_p" "no,yes"
382   (cond [(match_test "! TARGET_SH2")
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385               (const_int 20660))
386          (const_string "yes")
387          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390               (const_int 65530))
391          (const_string "yes")
392          ] (const_string "no")))
393
394 (define_attr "braf_cbranch_p" "no,yes"
395   (cond [(match_test "! TARGET_SH2")
396          (const_string "no")
397          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398               (const_int 20658))
399          (const_string "yes")
400          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401          (const_string "no")
402          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403               (const_int 65528))
404          (const_string "yes")
405          ] (const_string "no")))
406
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
413
414 ; All other instructions are two bytes long by default.
415
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419   (cond [(eq_attr "type" "cbranch")
420          (cond [(eq_attr "short_cbranch_p" "yes")
421                 (const_int 2)
422                 (eq_attr "med_cbranch_p" "yes")
423                 (const_int 6)
424                 (eq_attr "braf_cbranch_p" "yes")
425                 (const_int 12)
426 ;; ??? using pc is not computed transitively.
427                 (ne (match_dup 0) (match_dup 0))
428                 (const_int 14)
429                 (match_test "flag_pic")
430                 (const_int 24)
431                 ] (const_int 16))
432          (eq_attr "type" "jump")
433          (cond [(eq_attr "med_branch_p" "yes")
434                 (const_int 2)
435                 (and (match_test "prev_nonnote_insn (insn)")
436                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")                              (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")                             (symbol_ref "code_for_indirect_jump_scratch"))))
438                 (cond [(eq_attr "braf_branch_p" "yes")
439                        (const_int 6)
440                        (not (match_test "flag_pic"))
441                        (const_int 10)
442                        (match_test "TARGET_SH2")
443                        (const_int 10)] (const_int 18))
444                 (eq_attr "braf_branch_p" "yes")
445                 (const_int 10)
446 ;; ??? using pc is not computed transitively.
447                 (ne (match_dup 0) (match_dup 0))
448                 (const_int 12)
449                 (match_test "flag_pic")
450                 (const_int 22)
451                 ] (const_int 14))
452          (eq_attr "type" "pt_media")
453          (if_then_else (match_test "TARGET_SHMEDIA64")
454                        (const_int 20) (const_int 12))
455          (and (eq_attr "type" "jump_media")
456               (match_test "TARGET_SH5_CUT2_WORKAROUND"))
457          (const_int 8)
458          ] (if_then_else (match_test "TARGET_SHMEDIA")
459                          (const_int 4)
460                          (const_int 2))))
461
462 ;; DFA descriptions for the pipelines
463
464 (include "sh1.md")
465 (include "shmedia.md")
466 (include "sh4.md")
467
468 (include "predicates.md")
469 (include "constraints.md")
470
471 ;; Definitions for filling delay slots
472
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
474
475 (define_attr "banked" "yes,no" 
476         (cond [(match_test "sh_loads_bankedreg_p (insn)")
477                (const_string "yes")]
478               (const_string "no")))
479
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482         (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
483                (const_string "no")]
484               (const_string "yes")))
485
486 (define_attr "interrupt_function" "no,yes"
487   (const (symbol_ref "current_function_interrupt")))
488
489 (define_attr "in_delay_slot" "yes,no"
490   (cond [(eq_attr "type" "cbranch") (const_string "no")
491          (eq_attr "type" "pcload,pcload_si") (const_string "no")
492          (eq_attr "needs_delay_slot" "yes") (const_string "no")
493          (eq_attr "length" "2") (const_string "yes")
494          ] (const_string "no")))
495
496 (define_attr "cond_delay_slot" "yes,no"
497   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498          ] (const_string "no")))
499
500 (define_attr "is_sfunc" ""
501   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
502
503 (define_attr "is_mac_media" ""
504   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
505
506 (define_attr "branch_zero" "yes,no"
507   (cond [(eq_attr "type" "!cbranch") (const_string "no")
508          (ne (symbol_ref "(next_active_insn (insn)\
509                            == (prev_active_insn\
510                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511                           && get_attr_length (next_active_insn (insn)) == 2")
512              (const_int 0))
513          (const_string "yes")]
514         (const_string "no")))
515
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520         (const_string "no")))
521
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527          (const_string "yes")]
528         (const_string "no")))
529
530 (define_attr "any_int_load" "yes,no"
531   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532          (const_string "yes")]
533         (const_string "no")))
534
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536   (const_string "user"))
537
538 (define_delay
539   (eq_attr "needs_delay_slot" "yes")
540   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
541
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
546
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
549
550 (define_delay
551   (eq_attr "type" "return")
552   [(and (eq_attr "in_delay_slot" "yes")
553         (ior (and (eq_attr "interrupt_function" "no")
554                   (eq_attr "type" "!pload,prset"))
555              (and (eq_attr "interrupt_function" "yes")
556                   (ior
557                    (not (match_test "TARGET_SH3"))
558                    (eq_attr "hit_stack" "no")
559                    (eq_attr "banked" "no"))))) (nil) (nil)])
560
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
563
564 (define_delay
565   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566   [(and (eq_attr "in_delay_slot" "yes")
567         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
568
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
571
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
575
576 (define_delay
577   (and (eq_attr "type" "cbranch")
578        (match_test "TARGET_SH2"))
579   ;; SH2e has a hardware bug that pretty much prohibits the use of
580   ;; annuled delay slots.
581   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
583 \f
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
587
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group 
592 ;; instructions and thus will be executed in parallel.  On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
595
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits 
598 ;; and single bits.
599
600 (define_insn "tstsi_t"
601   [(set (reg:SI T_REG)
602         (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603                        (match_operand:SI 1 "logical_operand" "K08,r"))
604                (const_int 0)))]
605   "TARGET_SH1"
606   "tst  %1,%0"
607   [(set_attr "type" "mt_group")])
608
609 (define_insn "tsthi_t"
610   [(set (reg:SI T_REG)
611         (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612                                   (match_operand 1 "const_int_operand")) 0)
613                (const_int 0)))]
614   "TARGET_SH1
615    && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
616   "tst  %1,%0"
617   [(set_attr "type" "mt_group")])
618
619 (define_insn "tstqi_t"
620   [(set (reg:SI T_REG)
621         (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622                                   (match_operand 1 "const_int_operand")) 0)
623                (const_int 0)))]
624   "TARGET_SH1
625    && (CONST_OK_FOR_K08 (INTVAL (operands[1])) 
626        || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
627 {
628   operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
629   return "tst   %1,%0";
630 }
631   [(set_attr "type" "mt_group")])
632
633 ;; Test low QI subreg against zero.
634 ;; This avoids unecessary zero extension before the test.
635
636 (define_insn "tstqi_t_zero"
637   [(set (reg:SI T_REG)
638         (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
639   "TARGET_SH1"
640   "tst  #255,%0"
641   [(set_attr "type" "mt_group")])
642
643 ;; Extract LSB, negate and store in T bit.
644
645 (define_insn "tstsi_t_and_not"
646   [(set (reg:SI T_REG)
647          (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
648                  (const_int 1)))]
649   "TARGET_SH1"
650   "tst  #1,%0"
651   [(set_attr "type" "mt_group")])
652
653 ;; Extract contiguous bits and compare them against zero.
654
655 (define_insn "tstsi_t_zero_extract_eq"
656   [(set (reg:SI T_REG)
657         (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658                 (match_operand:SI 1 "const_int_operand")
659                 (match_operand:SI 2 "const_int_operand"))
660          (const_int 0)))]
661   "TARGET_SH1
662    && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
663 {
664   operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
665   return "tst   %1,%0";
666 }
667   [(set_attr "type" "mt_group")])
668
669 ;; This split is required when testing bits in a QI subreg.
670
671 (define_split
672   [(set (reg:SI T_REG)
673    (eq:SI (if_then_else:SI (zero_extract:SI
674                             (match_operand 0 "logical_operand" "")
675                             (match_operand 1 "const_int_operand")
676                             (match_operand 2 "const_int_operand"))
677                            (match_operand 3 "const_int_operand")
678                            (const_int 0))
679           (const_int 0)))]
680   "TARGET_SH1
681    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683   [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
684                               (const_int 0)))]
685   "
686 {
687   if (GET_MODE (operands[0]) == QImode)
688     operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
689 }")
690
691 ;; Extract single bit, negate and store it in the T bit.
692 ;; Not used for SH4A.
693
694 (define_insn "tstsi_t_zero_extract_xor"
695   [(set (reg:SI T_REG)
696         (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
697                           (match_operand:SI 3 "const_int_operand"))
698                          (match_operand:SI 1 "const_int_operand")
699                          (match_operand:SI 2 "const_int_operand")))]
700   "TARGET_SH1
701    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
702    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
703   "tst  %3,%0"
704   [(set_attr "type" "mt_group")])
705
706 ;; Extract single bit, negate and store it in the T bit.
707 ;; Used for SH4A little endian.
708
709 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
710   [(set (reg:SI T_REG)
711         (zero_extract:SI
712          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
713                             (match_operand:SI 3 "const_int_operand")) 0)
714          (match_operand:SI 1 "const_int_operand")
715          (match_operand:SI 2 "const_int_operand")))]
716   "TARGET_SH1 && TARGET_LITTLE_ENDIAN
717    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
718       == (INTVAL (operands[3]) & 255)
719    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
720 {
721   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
722   return "tst   %3,%0";
723 }
724   [(set_attr "type" "mt_group")])
725
726 ;; Extract single bit, negate and store it in the T bit.
727 ;; Used for SH4A big endian.
728
729 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
730   [(set (reg:SI T_REG)
731         (zero_extract:SI
732          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
733                             (match_operand:SI 3 "const_int_operand")) 3)
734          (match_operand:SI 1 "const_int_operand")
735          (match_operand:SI 2 "const_int_operand")))]
736   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
737    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
738       == (INTVAL (operands[3]) & 255)
739    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
740 {
741   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
742   return "tst   %3,%0";
743 }
744   [(set_attr "type" "mt_group")])
745
746 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
747 ;; That would still allow reload to create cmpi instructions, but would
748 ;; perhaps allow forcing the constant into a register when that is better.
749 ;; Probably should use r0 for mem/imm compares, but force constant into a
750 ;; register for pseudo/imm compares.
751
752 (define_insn "cmpeqsi_t"
753   [(set (reg:SI T_REG)
754         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
755                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
756   "TARGET_SH1"
757   "@
758         tst     %0,%0
759         cmp/eq  %1,%0
760         cmp/eq  %1,%0"
761    [(set_attr "type" "mt_group")])
762
763 (define_insn "cmpgtsi_t"
764   [(set (reg:SI T_REG)
765         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
766                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
767   "TARGET_SH1"
768   "@
769         cmp/gt  %1,%0
770         cmp/pl  %0"
771    [(set_attr "type" "mt_group")])
772
773 (define_insn "cmpgesi_t"
774   [(set (reg:SI T_REG)
775         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
777   "TARGET_SH1"
778   "@
779         cmp/ge  %1,%0
780         cmp/pz  %0"
781    [(set_attr "type" "mt_group")])
782
783 ;; -------------------------------------------------------------------------
784 ;; SImode compare and branch
785 ;; -------------------------------------------------------------------------
786
787 (define_expand "cbranchsi4"
788   [(set (pc)
789         (if_then_else (match_operator 0 "comparison_operator"
790                         [(match_operand:SI 1 "arith_operand" "")
791                          (match_operand:SI 2 "arith_operand" "")])
792                       (label_ref (match_operand 3 "" ""))
793                       (pc)))
794    (clobber (reg:SI T_REG))]
795   ""
796   "if (TARGET_SHMEDIA)
797       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
798                                              operands[2], operands[3]));
799    else if (TARGET_CBRANCHDI4)
800      expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
801    else
802      sh_emit_compare_and_branch (operands, SImode);
803    DONE;")
804
805 ;; -------------------------------------------------------------------------
806 ;; SImode unsigned integer comparisons
807 ;; -------------------------------------------------------------------------
808
809 (define_insn_and_split "cmpgeusi_t"
810   [(set (reg:SI T_REG)
811         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
812                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
813   "TARGET_SH1"
814   "cmp/hs       %1,%0"
815   "&& operands[1] == CONST0_RTX (SImode)"
816   [(pc)]
817   "
818 {
819   emit_insn (gen_sett ());
820   DONE;
821 }"
822    [(set_attr "type" "mt_group")])
823
824 (define_insn "cmpgtusi_t"
825   [(set (reg:SI T_REG)
826         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
827                 (match_operand:SI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH1"
829   "cmp/hi       %1,%0"
830    [(set_attr "type" "mt_group")])
831
832 \f
833 ;; -------------------------------------------------------------------------
834 ;; DImode compare and branch
835 ;; -------------------------------------------------------------------------
836
837
838 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
839 ;; Therefore, we aim to have a set of three branches that go straight to the
840 ;; destination, i.e. only one of them is taken at any one time.
841 ;; This mechanism should also be slightly better for the sh4-200.
842
843 (define_expand "cbranchdi4"
844   [(set (pc)
845         (if_then_else (match_operator 0 "comparison_operator"
846                         [(match_operand:DI 1 "arith_operand" "")
847                          (match_operand:DI 2 "arith_operand" "")])
848                       (label_ref (match_operand 3 "" ""))
849                       (pc)))
850    (clobber (match_dup 4))
851    (clobber (reg:SI T_REG))]
852   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
853   "
854 {
855   enum rtx_code comparison;
856
857   if (TARGET_SHMEDIA)
858     {
859       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
860                                              operands[2], operands[3]));
861       DONE;
862     }
863
864   else if (!TARGET_CBRANCHDI4)
865     {
866       sh_emit_compare_and_branch (operands, DImode);
867       DONE;
868     }
869
870   else
871     {
872       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
873         DONE;
874
875       comparison = prepare_cbranch_operands (operands, DImode,
876                                              LAST_AND_UNUSED_RTX_CODE);
877       if (comparison != GET_CODE (operands[0]))
878         operands[0]
879           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
880        operands[4] = gen_rtx_SCRATCH (SImode);
881     }
882 }")
883
884 (define_insn_and_split "cbranchdi4_i"
885   [(set (pc)
886         (if_then_else (match_operator 0 "comparison_operator"
887                         [(match_operand:DI 1 "arith_operand" "r,r")
888                          (match_operand:DI 2 "arith_operand" "rN,I08")])
889                       (label_ref (match_operand 3 "" ""))
890                       (pc)))
891    (clobber (match_scratch:SI 4 "=X,&r"))
892    (clobber (reg:SI T_REG))]
893   "TARGET_CBRANCHDI4"
894   "#"
895   "&& reload_completed"
896   [(pc)]
897   "
898 {
899   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
900     FAIL;
901   DONE;
902 }")
903
904 ;; -------------------------------------------------------------------------
905 ;; DImode signed integer comparisons
906 ;; -------------------------------------------------------------------------
907
908 (define_insn ""
909   [(set (reg:SI T_REG)
910         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
911                        (match_operand:DI 1 "arith_operand" "r"))
912                (const_int 0)))]
913   "TARGET_SH1"
914   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
915                                  insn, operands);"
916   [(set_attr "length" "6")
917    (set_attr "type" "arith3b")])
918
919 (define_insn "cmpeqdi_t"
920   [(set (reg:SI T_REG)
921         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
922                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
923   "TARGET_SH1"
924   "@
925         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
926         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
927   [(set_attr "length" "6")
928    (set_attr "type" "arith3b")])
929
930 (define_split
931   [(set (reg:SI T_REG)
932         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
933                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
934 ;; If we applied this split when not optimizing, it would only be
935 ;; applied during the machine-dependent reorg, when no new basic blocks
936 ;; may be created.
937   "TARGET_SH1 && reload_completed && optimize"
938   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
939    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
940                            (label_ref (match_dup 6))
941                            (pc)))
942    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
943    (match_dup 6)]
944   "
945 {
946   operands[2]
947     = gen_rtx_REG (SImode,
948                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
949   operands[3]
950     = (operands[1] == const0_rtx
951        ? const0_rtx
952        : gen_rtx_REG (SImode,
953                       true_regnum (operands[1])
954                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
955   operands[4] = gen_lowpart (SImode, operands[0]);
956   operands[5] = gen_lowpart (SImode, operands[1]);
957   operands[6] = gen_label_rtx ();
958 }")
959
960 (define_insn "cmpgtdi_t"
961   [(set (reg:SI T_REG)
962         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
963                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
964   "TARGET_SH2"
965   "@
966         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
967         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
968   [(set_attr "length" "8")
969    (set_attr "type" "arith3")])
970
971 (define_insn "cmpgedi_t"
972   [(set (reg:SI T_REG)
973         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
974                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
975   "TARGET_SH2"
976   "@
977         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
978         cmp/pz\\t%S0"
979   [(set_attr "length" "8,2")
980    (set_attr "type" "arith3,mt_group")])
981 \f
982 ;; -------------------------------------------------------------------------
983 ;; DImode unsigned integer comparisons
984 ;; -------------------------------------------------------------------------
985
986 (define_insn "cmpgeudi_t"
987   [(set (reg:SI T_REG)
988         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
989                 (match_operand:DI 1 "arith_reg_operand" "r")))]
990   "TARGET_SH2"
991   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
992   [(set_attr "length" "8")
993    (set_attr "type" "arith3")])
994
995 (define_insn "cmpgtudi_t"
996   [(set (reg:SI T_REG)
997         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
998                 (match_operand:DI 1 "arith_reg_operand" "r")))]
999   "TARGET_SH2"
1000   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
1001   [(set_attr "length" "8")
1002    (set_attr "type" "arith3")])
1003
1004 (define_insn "cmpeqsi_media"
1005   [(set (match_operand:SI 0 "register_operand" "=r")
1006         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1007                (match_operand:SI 2 "cmp_operand" "Nr")))]
1008   "TARGET_SHMEDIA"
1009   "cmpeq        %1, %N2, %0"
1010   [(set_attr "type" "cmp_media")])
1011
1012 (define_insn "cmpeqdi_media"
1013   [(set (match_operand:SI 0 "register_operand" "=r")
1014         (eq:SI (match_operand:DI 1 "register_operand" "%r")
1015                (match_operand:DI 2 "cmp_operand" "Nr")))]
1016   "TARGET_SHMEDIA"
1017   "cmpeq        %1, %N2, %0"
1018   [(set_attr "type" "cmp_media")])
1019
1020 (define_insn "cmpgtsi_media"
1021   [(set (match_operand:SI 0 "register_operand" "=r")
1022         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1023                (match_operand:SI 2 "cmp_operand" "rN")))]
1024   "TARGET_SHMEDIA"
1025   "cmpgt        %N1, %N2, %0"
1026   [(set_attr "type" "cmp_media")])
1027
1028 (define_insn "cmpgtdi_media"
1029   [(set (match_operand:SI 0 "register_operand" "=r")
1030         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1031                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1032   "TARGET_SHMEDIA"
1033   "cmpgt        %N1, %N2, %0"
1034   [(set_attr "type" "cmp_media")])
1035
1036 (define_insn "cmpgtusi_media"
1037   [(set (match_operand:SI 0 "register_operand" "=r")
1038         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1039                 (match_operand:SI 2 "cmp_operand" "rN")))]
1040   "TARGET_SHMEDIA"
1041   "cmpgtu       %N1, %N2, %0"
1042   [(set_attr "type" "cmp_media")])
1043
1044 (define_insn "cmpgtudi_media"
1045   [(set (match_operand:SI 0 "register_operand" "=r")
1046         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1047                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1048   "TARGET_SHMEDIA"
1049   "cmpgtu       %N1, %N2, %0"
1050   [(set_attr "type" "cmp_media")])
1051
1052 ; These two patterns are for combine.
1053 (define_insn "*cmpne0sisi_media"
1054   [(set (match_operand:SI 0 "register_operand" "=r")
1055         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1056   "TARGET_SHMEDIA"
1057   "cmpgtu       %1,r63,%0"
1058   [(set_attr "type" "cmp_media")])
1059
1060 ;; -------------------------------------------------------------------------
1061 ;; Conditional move instructions
1062 ;; -------------------------------------------------------------------------
1063
1064 ;; The insn names may seem reversed, but note that cmveq performs the move
1065 ;; if op1 == 0, and cmvne does it if op1 != 0.
1066
1067 (define_insn "movdicc_false"
1068   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1069         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1070                              (const_int 0))
1071          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1072          (match_operand:DI 3 "arith_reg_operand" "0")))]
1073   "TARGET_SHMEDIA"
1074   "cmveq        %1, %N2, %0"
1075   [(set_attr "type" "arith_media")])
1076
1077 (define_insn "movdicc_true"
1078   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1079         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1080                              (const_int 0))
1081          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1082          (match_operand:DI 3 "arith_reg_operand" "0")))]
1083   "TARGET_SHMEDIA"
1084   "cmvne        %1, %N2, %0"
1085   [(set_attr "type" "arith_media")])
1086
1087 (define_peephole2
1088   [(set (match_operand:DI 0 "arith_reg_dest" "")
1089         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1090                            [(match_operand:DI 1 "arith_reg_operand" "")
1091                             (const_int 0)])
1092          (match_operand:DI 2 "arith_reg_dest" "")
1093          (match_dup 0)))
1094    (set (match_dup 2) (match_dup 0))]
1095   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1096   [(set (match_dup 2)
1097         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1098   "
1099 {
1100   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1101                                 VOIDmode, operands[1], CONST0_RTX (DImode));
1102 }")
1103
1104 (define_peephole2
1105   [(set (match_operand:DI 0 "general_movdst_operand" "")
1106         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1107    (set (match_operand:DI 2 "arith_reg_dest" "")
1108         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1109                            [(match_operand:DI 3 "arith_reg_operand" "")
1110                             (const_int 0)])
1111          (match_dup 0)
1112          (match_dup 2)))]
1113   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1114   [(set (match_dup 2)
1115         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1116   "")
1117
1118 (define_expand "movdicc"
1119   [(set (match_operand:DI 0 "register_operand" "")
1120         (if_then_else:DI (match_operand 1 "comparison_operator" "")
1121                          (match_operand:DI 2 "register_operand" "")
1122                          (match_operand:DI 3 "register_operand" "")))]
1123   "TARGET_SHMEDIA"
1124   "
1125 {
1126   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1127       && GET_MODE (XEXP (operands[1], 0)) == DImode
1128       && XEXP (operands[1], 1) == const0_rtx)
1129     ;
1130   else
1131     {
1132       if (!can_create_pseudo_p ())
1133         FAIL;
1134
1135       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1136                                               GET_CODE (operands[1]),
1137                                               XEXP (operands[1], 0),
1138                                               XEXP (operands[1], 1));
1139       if (!operands[1])
1140         FAIL;
1141     }
1142 }")
1143
1144 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1145 ;; SImode to DImode.
1146 (define_insn "movsicc_false"
1147   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1148         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1149                           (const_int 0))
1150          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1151          (match_operand:SI 3 "arith_reg_operand" "0")))]
1152   "TARGET_SHMEDIA"
1153   "cmveq        %1, %N2, %0"
1154   [(set_attr "type" "arith_media")])
1155
1156 (define_insn "movsicc_true"
1157   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1158         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1159                           (const_int 0))
1160          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1161          (match_operand:SI 3 "arith_reg_operand" "0")))]
1162   "TARGET_SHMEDIA"
1163   "cmvne        %1, %N2, %0"
1164   [(set_attr "type" "arith_media")])
1165
1166 (define_peephole2
1167   [(set (match_operand:SI 0 "arith_reg_dest" "")
1168         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1169                            [(match_operand:SI 1 "arith_reg_operand" "")
1170                             (const_int 0)])
1171          (match_operand:SI 2 "arith_reg_dest" "")
1172          (match_dup 0)))
1173    (set (match_dup 2) (match_dup 0))]
1174   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1175   [(set (match_dup 2)
1176         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1177   "
1178 {
1179   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1180                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1181 }")
1182
1183 (define_peephole2
1184   [(set (match_operand:SI 0 "general_movdst_operand" "")
1185         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1186    (set (match_operand:SI 2 "arith_reg_dest" "")
1187         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1188                            [(match_operand:SI 3 "arith_reg_operand" "")
1189                             (const_int 0)])
1190          (match_dup 0)
1191          (match_dup 2)))]
1192   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1193    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1194   [(set (match_dup 2)
1195         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1196   "
1197 {
1198   replace_rtx (operands[4], operands[0], operands[1]);
1199 }")
1200
1201 (define_peephole2
1202   [(set (match_operand 0 "any_register_operand" "")
1203         (match_operand 1 "any_register_operand" ""))
1204    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1205    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1206   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1207     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1208    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1209    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1210    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1211    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1212    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1213    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1214    && (REGNO_REG_CLASS (REGNO (operands[0]))
1215        == REGNO_REG_CLASS (REGNO (operands[2])))
1216    && (REGNO_REG_CLASS (REGNO (operands[1]))
1217        == REGNO_REG_CLASS (REGNO (operands[0])))"
1218   [(set (match_dup 0) (match_dup 3))
1219    (set (match_dup 4) (match_dup 5))]
1220   "
1221 {
1222   rtx set1, set2, insn2;
1223   rtx replacements[4];
1224
1225   /* We want to replace occurrences of operands[0] with operands[1] and
1226      operands[2] with operands[0] in operands[4]/operands[5].
1227      Doing just two replace_rtx calls naively would result in the second
1228      replacement undoing all that the first did if operands[1] and operands[2]
1229      are identical, so we must do this simultaneously.  */
1230   replacements[0] = operands[0];
1231   replacements[1] = operands[1];
1232   replacements[2] = operands[2];
1233   replacements[3] = operands[0];
1234   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1235       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1236       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1237     FAIL;
1238
1239   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1240   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1241   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1242   /* The operands array is aliased to recog_data.operand, which gets
1243      clobbered by extract_insn, so finish with it now.  */
1244   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1245   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1246   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1247      always uses emit_insn.  */
1248   /* Check that we don't violate matching constraints or earlyclobbers.  */
1249   extract_insn (emit_insn (set1));
1250   if (! constrain_operands (1))
1251     goto failure;
1252   insn2 = emit (set2);
1253   if (GET_CODE (insn2) == BARRIER)
1254     goto failure;
1255   extract_insn (insn2);
1256   if (! constrain_operands (1))
1257     {
1258       rtx tmp;
1259     failure:
1260       tmp = replacements[0];
1261       replacements[0] = replacements[1];
1262       replacements[1] = tmp;
1263       tmp = replacements[2];
1264       replacements[2] = replacements[3];
1265       replacements[3] = tmp;
1266       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1267       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1268       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1269       FAIL;
1270     }
1271   DONE;
1272 }")
1273
1274 ;; The register allocator is rather clumsy in handling multi-way conditional
1275 ;; moves, so allow the combiner to make them, and we split them up after
1276 ;; reload.  */
1277 (define_insn_and_split "*movsicc_umin"
1278   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1279         (umin:SI (if_then_else:SI
1280                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1281                        (const_int 0))
1282                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1283                    (match_operand:SI 3 "register_operand" "0"))
1284                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1285    (clobber (match_scratch:SI 5 "=&r"))]
1286   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1287   "#"
1288   "TARGET_SHMEDIA && reload_completed"
1289   [(pc)]
1290   "
1291 {
1292   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1293                                 operands[3]));
1294   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1295   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1296                                 operands[0]));
1297   DONE;
1298 }")
1299
1300 (define_insn "*movsicc_t_false"
1301   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1302         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1303                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1304                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1305   "TARGET_PRETEND_CMOVE
1306    && (arith_reg_operand (operands[1], SImode)
1307        || (immediate_operand (operands[1], SImode)
1308            && satisfies_constraint_I08 (operands[1])))"
1309   "bt   0f\;mov %1,%0\\n0:"
1310   [(set_attr "type" "mt_group,arith") ;; poor approximation
1311    (set_attr "length" "4")])
1312
1313 (define_insn "*movsicc_t_true"
1314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1315         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1316                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1317                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1318   "TARGET_PRETEND_CMOVE
1319    && (arith_reg_operand (operands[1], SImode)
1320        || (immediate_operand (operands[1], SImode)
1321            && satisfies_constraint_I08 (operands[1])))"
1322   "bf   0f\;mov %1,%0\\n0:"
1323   [(set_attr "type" "mt_group,arith") ;; poor approximation
1324    (set_attr "length" "4")])
1325
1326 (define_expand "movsicc"
1327   [(set (match_operand:SI 0 "arith_reg_dest" "")
1328         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1329                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1330                          (match_operand:SI 3 "arith_reg_operand" "")))]
1331   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1332   "
1333 {
1334   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1335       && GET_MODE (XEXP (operands[1], 0)) == SImode
1336       && (TARGET_SHMEDIA
1337           || (REG_P (XEXP (operands[1], 0))
1338               && REGNO (XEXP (operands[1], 0)) == T_REG))
1339       && XEXP (operands[1], 1) == const0_rtx)
1340     ;
1341
1342   else if (TARGET_PRETEND_CMOVE)
1343     {
1344       enum rtx_code code = GET_CODE (operands[1]);
1345       enum rtx_code new_code = code;
1346       rtx op0 = XEXP (operands[1], 0);
1347       rtx op1 = XEXP (operands[1], 1);
1348
1349       if (! currently_expanding_to_rtl)
1350         FAIL;
1351       switch (code)
1352         {
1353         case LT: case LE: case LEU: case LTU:
1354           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1355             break;
1356         case NE:
1357           new_code = reverse_condition (code);
1358           break;
1359         case EQ: case GT: case GE: case GEU: case GTU:
1360           break;
1361         default:
1362           FAIL;
1363         }
1364       sh_emit_scc_to_t (new_code, op0, op1);
1365       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1366                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1367     }
1368   else
1369     {
1370       if (!can_create_pseudo_p ())
1371         FAIL;
1372
1373       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1374                                               GET_CODE (operands[1]),
1375                                               XEXP (operands[1], 0),
1376                                               XEXP (operands[1], 1));
1377       if (!operands[1])
1378         FAIL;
1379     }
1380 }")
1381
1382 (define_expand "movqicc"
1383   [(set (match_operand:QI 0 "register_operand" "")
1384         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1385                          (match_operand:QI 2 "register_operand" "")
1386                          (match_operand:QI 3 "register_operand" "")))]
1387   "TARGET_SHMEDIA"
1388   "
1389 {
1390   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1391   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1392   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1393   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1394   DONE;
1395 }")
1396 \f
1397 ;; -------------------------------------------------------------------------
1398 ;; Addition instructions
1399 ;; -------------------------------------------------------------------------
1400
1401 (define_expand "adddi3"
1402   [(set (match_operand:DI 0 "arith_reg_operand" "")
1403         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1404                  (match_operand:DI 2 "arith_operand" "")))]
1405   ""
1406   "
1407 {
1408   if (TARGET_SH1)
1409     {
1410       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1411         FAIL;
1412       operands[2] = force_reg (DImode, operands[2]);
1413       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1414       DONE;
1415     }
1416 }")
1417
1418 (define_insn "*adddi3_media"
1419   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
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     %1, %2, %0
1425         addi    %1, %2, %0"
1426   [(set_attr "type" "arith_media")])
1427
1428 (define_insn "*adddisi3_media"
1429   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1430         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1431                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1432   "TARGET_SHMEDIA"
1433   "@
1434         add.l   %1, %2, %0
1435         addi.l  %1, %2, %0"
1436   [(set_attr "type" "arith_media")
1437    (set_attr "highpart" "ignore")])
1438
1439 (define_insn "adddi3z_media"
1440   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1441         (zero_extend:DI
1442          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1443                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1444   "TARGET_SHMEDIA"
1445   "addz.l       %1, %N2, %0"
1446   [(set_attr "type" "arith_media")
1447    (set_attr "highpart" "ignore")])
1448
1449 (define_insn "adddi3_compact"
1450   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1451         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1452                  (match_operand:DI 2 "arith_reg_operand" "r")))
1453    (clobber (reg:SI T_REG))]
1454   "TARGET_SH1"
1455   "#"
1456   [(set_attr "length" "6")])
1457
1458 (define_split
1459   [(set (match_operand:DI 0 "arith_reg_dest" "")
1460         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1461                  (match_operand:DI 2 "arith_reg_operand" "")))
1462    (clobber (reg:SI T_REG))]
1463   "TARGET_SH1 && reload_completed"
1464   [(const_int 0)]
1465   "
1466 {
1467   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1468   high0 = gen_rtx_REG (SImode,
1469                        true_regnum (operands[0])
1470                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1471   high2 = gen_rtx_REG (SImode,
1472                        true_regnum (operands[2])
1473                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1474   emit_insn (gen_clrt ());
1475   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1476   emit_insn (gen_addc1 (high0, high0, high2));
1477   DONE;
1478 }")
1479
1480 (define_insn "addc"
1481   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1482         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1483                           (match_operand:SI 2 "arith_reg_operand" "r"))
1484                  (reg:SI T_REG)))
1485    (set (reg:SI T_REG)
1486         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1487   "TARGET_SH1"
1488   "addc %2,%0"
1489   [(set_attr "type" "arith")])
1490
1491 (define_insn "addc1"
1492   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1494                           (match_operand:SI 2 "arith_reg_operand" "r"))
1495                  (reg:SI T_REG)))
1496    (clobber (reg:SI T_REG))]
1497   "TARGET_SH1"
1498   "addc %2,%0"
1499   [(set_attr "type" "arith")])
1500
1501 (define_expand "addsi3"
1502   [(set (match_operand:SI 0 "arith_reg_operand" "")
1503         (plus:SI (match_operand:SI 1 "arith_operand" "")
1504                  (match_operand:SI 2 "arith_operand" "")))]
1505   ""
1506   "
1507 {
1508   if (TARGET_SHMEDIA)
1509     operands[1] = force_reg (SImode, operands[1]);
1510 }")
1511
1512 (define_insn "addsi3_media"
1513   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1514         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1515                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1516   "TARGET_SHMEDIA"
1517   "@
1518         add.l   %1, %2, %0
1519         addi.l  %1, %2, %0"
1520   [(set_attr "type" "arith_media")
1521    (set_attr "highpart" "ignore")])
1522
1523 (define_insn "addsidi3_media"
1524   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1525         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1526                                   "%r,r")
1527                                  (match_operand:SI 2 "arith_operand"
1528                                   "r,I10"))))]
1529   "TARGET_SHMEDIA"
1530   "@
1531         add.l   %1, %2, %0
1532         addi.l  %1, %2, %0"
1533   [(set_attr "type" "arith_media")
1534    (set_attr "highpart" "ignore")])
1535
1536 (define_insn "*addsi3_compact"
1537   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1538         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1539                  (match_operand:SI 2 "arith_operand" "rI08")))]
1540   "TARGET_SH1"
1541   "add  %2,%0"
1542   [(set_attr "type" "arith")])
1543
1544 ;; -------------------------------------------------------------------------
1545 ;; Subtraction instructions
1546 ;; -------------------------------------------------------------------------
1547
1548 (define_expand "subdi3"
1549   [(set (match_operand:DI 0 "arith_reg_operand" "")
1550         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1551                   (match_operand:DI 2 "arith_reg_operand" "")))]
1552   ""
1553   "
1554 {
1555   if (TARGET_SH1)
1556     {
1557       operands[1] = force_reg (DImode, operands[1]);
1558       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1559       DONE;
1560     }
1561 }")
1562
1563 (define_insn "*subdi3_media"
1564   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1565         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1566                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1567   "TARGET_SHMEDIA"
1568   "sub  %N1, %2, %0"
1569   [(set_attr "type" "arith_media")])
1570   
1571 (define_insn "subdisi3_media"
1572   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1573         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1574                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1575   "TARGET_SHMEDIA"
1576   "sub.l        %N1, %2, %0"
1577   [(set_attr "type" "arith_media")
1578    (set_attr "highpart" "ignore")])
1579
1580 (define_insn "subdi3_compact"
1581   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1582         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1583                  (match_operand:DI 2 "arith_reg_operand" "r")))
1584    (clobber (reg:SI T_REG))]
1585   "TARGET_SH1"
1586   "#"
1587   [(set_attr "length" "6")])
1588
1589 (define_split
1590   [(set (match_operand:DI 0 "arith_reg_dest" "")
1591         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1592                   (match_operand:DI 2 "arith_reg_operand" "")))
1593    (clobber (reg:SI T_REG))]
1594   "TARGET_SH1 && reload_completed"
1595   [(const_int 0)]
1596   "
1597 {
1598   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1599   high0 = gen_rtx_REG (SImode,
1600                        true_regnum (operands[0])
1601                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1602   high2 = gen_rtx_REG (SImode,
1603                        true_regnum (operands[2])
1604                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1605   emit_insn (gen_clrt ());
1606   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1607   emit_insn (gen_subc1 (high0, high0, high2));
1608   DONE;
1609 }")
1610
1611 (define_insn "subc"
1612   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1613         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1614                             (match_operand:SI 2 "arith_reg_operand" "r"))
1615                   (reg:SI T_REG)))
1616    (set (reg:SI T_REG)
1617         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1618                           (reg:SI T_REG))
1619                 (match_dup 1)))]
1620   "TARGET_SH1"
1621   "subc %2,%0"
1622   [(set_attr "type" "arith")])
1623
1624 (define_insn "subc1"
1625   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627                             (match_operand:SI 2 "arith_reg_operand" "r"))
1628                   (reg:SI T_REG)))
1629    (clobber (reg:SI T_REG))]
1630   "TARGET_SH1"
1631   "subc %2,%0"
1632   [(set_attr "type" "arith")])
1633
1634 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1635 ;; pattern for this case.  This helps multimedia applications that compute
1636 ;; the sum of absolute differences.
1637 (define_insn "mov_neg_si_t"
1638   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1639   "TARGET_SH1"
1640   "subc %0,%0"
1641   [(set_attr "type" "arith")])
1642
1643 (define_insn "*subsi3_internal"
1644   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1645         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1646                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1647   "TARGET_SH1"
1648   "sub  %2,%0"
1649   [(set_attr "type" "arith")])
1650
1651 (define_insn_and_split "*subsi3_media"
1652   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1653         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1654                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1655   "TARGET_SHMEDIA
1656    && (operands[1] != constm1_rtx
1657        || (GET_CODE (operands[2]) != TRUNCATE
1658            && GET_CODE (operands[2]) != SUBREG))"
1659   "sub.l        %N1, %2, %0"
1660   "operands[1] == constm1_rtx"
1661   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1662   ""
1663   [(set_attr "type" "arith_media")
1664    (set_attr "highpart" "ignore")])
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)) 0)))]
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
1676 (define_split
1677   [(set (match_operand:SI 0 "arith_reg_dest" "")
1678         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1679                                                        "general_extend_operand"
1680                                                        "") 0)) 3)))]
1681   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1682   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1683    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1684   "")
1685 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1686 ;; will sometimes save one instruction.  Otherwise we might get
1687 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1688 ;; are the same.
1689
1690 (define_expand "subsi3"
1691   [(set (match_operand:SI 0 "arith_reg_operand" "")
1692         (minus:SI (match_operand:SI 1 "arith_operand" "")
1693                   (match_operand:SI 2 "arith_reg_operand" "")))]
1694   ""
1695   "
1696 {
1697   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1698     {
1699       emit_insn (gen_negsi2 (operands[0], operands[2]));
1700       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1701       DONE;
1702     }
1703   if (TARGET_SHMEDIA)
1704     {
1705       if (!can_create_pseudo_p ()
1706           && ! arith_reg_or_0_operand (operands[1], SImode))
1707         FAIL;
1708       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1709         operands[1] = force_reg (SImode, operands[1]);
1710     }
1711 }")
1712 \f
1713 ;; -------------------------------------------------------------------------
1714 ;; Division instructions
1715 ;; -------------------------------------------------------------------------
1716
1717 ;; We take advantage of the library routines which don't clobber as many
1718 ;; registers as a normal function call would.
1719
1720 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1721 ;; also has an effect on the register that holds the address of the sfunc.
1722 ;; To make this work, we have an extra dummy insn that shows the use
1723 ;; of this register for reorg.
1724
1725 (define_insn "use_sfunc_addr"
1726   [(set (reg:SI PR_REG)
1727         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1728   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1729   ""
1730   [(set_attr "length" "0")])
1731
1732 (define_insn "udivsi3_sh2a"
1733   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1734         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1735                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1736   "TARGET_SH2A"
1737   "divu %2,%1"
1738   [(set_attr "type" "arith")
1739    (set_attr "in_delay_slot" "no")])
1740
1741 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1742 ;; hard register 0.  If we used hard register 0, then the next instruction
1743 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1744 ;; gets allocated to a stack slot that needs its address reloaded, then
1745 ;; there is nothing to prevent reload from using r0 to reload the address.
1746 ;; This reload would clobber the value in r0 we are trying to store.
1747 ;; If we let reload allocate r0, then this problem can never happen.
1748
1749 (define_insn "udivsi3_i1"
1750   [(set (match_operand:SI 0 "register_operand" "=z")
1751         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1752    (clobber (reg:SI T_REG))
1753    (clobber (reg:SI PR_REG))
1754    (clobber (reg:SI R4_REG))
1755    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1756   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1757   "jsr  @%1%#"
1758   [(set_attr "type" "sfunc")
1759    (set_attr "needs_delay_slot" "yes")])
1760
1761 ; Since shmedia-nofpu code could be linked against shcompact code, and
1762 ; the udivsi3 libcall has the same name, we must consider all registers
1763 ; clobbered that are in the union of the registers clobbered by the
1764 ; shmedia and the shcompact implementation.  Note, if the shcompact
1765 ; implementation actually used shcompact code, we'd need to clobber
1766 ; also r23 and fr23.
1767 (define_insn "udivsi3_i1_media"
1768   [(set (match_operand:SI 0 "register_operand" "=z")
1769         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1770    (clobber (reg:SI T_MEDIA_REG))
1771    (clobber (reg:SI PR_MEDIA_REG))
1772    (clobber (reg:SI R20_REG))
1773    (clobber (reg:SI R21_REG))
1774    (clobber (reg:SI R22_REG))
1775    (clobber (reg:DI TR0_REG))
1776    (clobber (reg:DI TR1_REG))
1777    (clobber (reg:DI TR2_REG))
1778    (use (match_operand 1 "target_reg_operand" "b"))]
1779   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1780   "blink        %1, r18"
1781   [(set_attr "type" "sfunc")
1782    (set_attr "needs_delay_slot" "yes")])
1783
1784 (define_expand "udivsi3_i4_media"
1785   [(set (match_dup 3)
1786         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1787    (set (match_dup 4)
1788         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1789    (set (match_dup 5) (float:DF (match_dup 3)))
1790    (set (match_dup 6) (float:DF (match_dup 4)))
1791    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1792    (set (match_dup 8) (fix:DI (match_dup 7)))
1793    (set (match_operand:SI 0 "register_operand" "")
1794         (truncate:SI (match_dup 8)))]
1795   "TARGET_SHMEDIA_FPU"
1796   "
1797 {
1798   operands[3] = gen_reg_rtx (DImode);
1799   operands[4] = gen_reg_rtx (DImode);
1800   operands[5] = gen_reg_rtx (DFmode);
1801   operands[6] = gen_reg_rtx (DFmode);
1802   operands[7] = gen_reg_rtx (DFmode);
1803   operands[8] = gen_reg_rtx (DImode);
1804 }")
1805
1806 (define_insn "udivsi3_i4"
1807   [(set (match_operand:SI 0 "register_operand" "=y")
1808         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809    (clobber (reg:SI T_REG))
1810    (clobber (reg:SI PR_REG))
1811    (clobber (reg:DF DR0_REG))
1812    (clobber (reg:DF DR2_REG))
1813    (clobber (reg:DF DR4_REG))
1814    (clobber (reg:SI R0_REG))
1815    (clobber (reg:SI R1_REG))
1816    (clobber (reg:SI R4_REG))
1817    (clobber (reg:SI R5_REG))
1818    (use (reg:PSI FPSCR_REG))
1819    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1820   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1821   "jsr  @%1%#"
1822   [(set_attr "type" "sfunc")
1823    (set_attr "fp_mode" "double")
1824    (set_attr "needs_delay_slot" "yes")])
1825
1826 (define_insn "udivsi3_i4_single"
1827   [(set (match_operand:SI 0 "register_operand" "=y")
1828         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829    (clobber (reg:SI T_REG))
1830    (clobber (reg:SI PR_REG))
1831    (clobber (reg:DF DR0_REG))
1832    (clobber (reg:DF DR2_REG))
1833    (clobber (reg:DF DR4_REG))
1834    (clobber (reg:SI R0_REG))
1835    (clobber (reg:SI R1_REG))
1836    (clobber (reg:SI R4_REG))
1837    (clobber (reg:SI R5_REG))
1838    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1839   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1840   "jsr  @%1%#"
1841   [(set_attr "type" "sfunc")
1842    (set_attr "needs_delay_slot" "yes")])
1843
1844 (define_insn "udivsi3_i4_int"
1845   [(set (match_operand:SI 0 "register_operand" "=z")
1846         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1847    (clobber (reg:SI T_REG))
1848    (clobber (reg:SI R1_REG))
1849    (clobber (reg:SI PR_REG))
1850    (clobber (reg:SI MACH_REG))
1851    (clobber (reg:SI MACL_REG))
1852    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1853   "TARGET_SH1"
1854   "jsr  @%1%#"
1855   [(set_attr "type" "sfunc")
1856    (set_attr "needs_delay_slot" "yes")])
1857
1858
1859 (define_expand "udivsi3"
1860   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1861    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1862    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1863    (parallel [(set (match_operand:SI 0 "register_operand" "")
1864                    (udiv:SI (reg:SI R4_REG)
1865                             (reg:SI R5_REG)))
1866               (clobber (reg:SI T_REG))
1867               (clobber (reg:SI PR_REG))
1868               (clobber (reg:SI R4_REG))
1869               (use (match_dup 3))])]
1870   ""
1871   "
1872 {
1873   rtx last;
1874
1875   operands[3] = gen_reg_rtx (Pmode);
1876   /* Emit the move of the address to a pseudo outside of the libcall.  */
1877   if (TARGET_DIVIDE_CALL_TABLE)
1878     {
1879       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1880          that causes problems when the divide code is supposed to come from a
1881          separate library.  Division by zero is undefined, so dividing 1 can be
1882          implemented by comparing with the divisor.  */
1883       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1884         {
1885           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1886           emit_insn (gen_cstoresi4 (operands[0], test,
1887                                     operands[1], operands[2]));
1888           DONE;
1889         }
1890       else if (operands[2] == const0_rtx)
1891         {
1892           emit_move_insn (operands[0], operands[2]);
1893           DONE;
1894         }
1895       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1896       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1897     }
1898   else if (TARGET_DIVIDE_CALL_FP)
1899     {
1900       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1901       if (TARGET_FPU_SINGLE)
1902         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1903       else
1904         last = gen_udivsi3_i4 (operands[0], operands[3]);
1905     }
1906   else if (TARGET_SHMEDIA_FPU)
1907     {
1908       operands[1] = force_reg (SImode, operands[1]);
1909       operands[2] = force_reg (SImode, operands[2]);
1910       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1911       DONE;
1912     }
1913   else if (TARGET_SH2A)
1914     {
1915       operands[1] = force_reg (SImode, operands[1]);
1916       operands[2] = force_reg (SImode, operands[2]);
1917       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1918       DONE;
1919     }
1920   else if (TARGET_SH5)
1921     {
1922       function_symbol (operands[3],
1923                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1924                        SFUNC_STATIC);
1925
1926       if (TARGET_SHMEDIA)
1927         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1928       else if (TARGET_FPU_ANY)
1929         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1930       else
1931         last = gen_udivsi3_i1 (operands[0], operands[3]);
1932     }
1933   else
1934     {
1935       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1936       last = gen_udivsi3_i1 (operands[0], operands[3]);
1937     }
1938   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1939   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1940   emit_insn (last);
1941   DONE;
1942 }")
1943
1944 (define_insn "divsi3_sh2a"
1945   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1946         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1947                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1948   "TARGET_SH2A"
1949   "divs %2,%1"
1950   [(set_attr "type" "arith")
1951    (set_attr "in_delay_slot" "no")])
1952
1953 (define_insn "divsi3_i1"
1954   [(set (match_operand:SI 0 "register_operand" "=z")
1955         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956    (clobber (reg:SI T_REG))
1957    (clobber (reg:SI PR_REG))
1958    (clobber (reg:SI R1_REG))
1959    (clobber (reg:SI R2_REG))
1960    (clobber (reg:SI R3_REG))
1961    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1963   "jsr  @%1%#"
1964   [(set_attr "type" "sfunc")
1965    (set_attr "needs_delay_slot" "yes")])
1966
1967 (define_insn "divsi3_i1_media"
1968   [(set (match_operand:SI 0 "register_operand" "=z")
1969         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970    (clobber (reg:SI T_MEDIA_REG))
1971    (clobber (reg:SI PR_MEDIA_REG))
1972    (clobber (reg:SI R1_REG))
1973    (clobber (reg:SI R20_REG))
1974    (clobber (reg:SI R21_REG))
1975    (clobber (reg:SI TR0_REG))
1976    (use (match_operand 1 "target_reg_operand" "b"))]
1977   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1978   "blink        %1, r18"
1979   [(set_attr "type" "sfunc")])
1980
1981 (define_insn "divsi3_media_2"
1982   [(set (match_operand:SI 0 "register_operand" "=z")
1983         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1984    (clobber (reg:SI T_MEDIA_REG))
1985    (clobber (reg:SI PR_MEDIA_REG))
1986    (clobber (reg:SI R1_REG))
1987    (clobber (reg:SI R21_REG))
1988    (clobber (reg:SI TR0_REG))
1989    (use (reg:SI R20_REG))
1990    (use (match_operand 1 "target_reg_operand" "b"))]
1991   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1992   "blink        %1, r18"
1993   [(set_attr "type" "sfunc")])
1994
1995 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1996 ;; hard reg clobbers and data dependencies that we need when we want
1997 ;; to rematerialize the division into a call.
1998 (define_insn_and_split "divsi_inv_call"
1999   [(set (match_operand:SI 0 "register_operand" "=r")
2000         (div:SI (match_operand:SI 1 "register_operand" "r")
2001                 (match_operand:SI 2 "register_operand" "r")))
2002    (clobber (reg:SI R4_REG))
2003    (clobber (reg:SI R5_REG))
2004    (clobber (reg:SI T_MEDIA_REG))
2005    (clobber (reg:SI PR_MEDIA_REG))
2006    (clobber (reg:SI R1_REG))
2007    (clobber (reg:SI R21_REG))
2008    (clobber (reg:SI TR0_REG))
2009    (clobber (reg:SI R20_REG))
2010    (use (match_operand:SI 3 "register_operand" "r"))]
2011   "TARGET_SHMEDIA"
2012   "#"
2013   "&& (high_life_started || reload_completed)"
2014   [(set (match_dup 0) (match_dup 3))]
2015   ""
2016   [(set_attr "highpart" "must_split")])
2017
2018 ;; This is the combiner pattern for -mdiv=inv:call .
2019 (define_insn_and_split "*divsi_inv_call_combine"
2020   [(set (match_operand:SI 0 "register_operand" "=z")
2021         (div:SI (match_operand:SI 1 "register_operand" "r")
2022                 (match_operand:SI 2 "register_operand" "r")))
2023    (clobber (reg:SI R4_REG))
2024    (clobber (reg:SI R5_REG))
2025    (clobber (reg:SI T_MEDIA_REG))
2026    (clobber (reg:SI PR_MEDIA_REG))
2027    (clobber (reg:SI R1_REG))
2028    (clobber (reg:SI R21_REG))
2029    (clobber (reg:SI TR0_REG))
2030    (clobber (reg:SI R20_REG))
2031    (use (unspec:SI [(match_dup 1)
2032                     (match_operand:SI 3 "" "")
2033                     (unspec:SI [(match_operand:SI 4 "" "")
2034                                 (match_dup 3)
2035                                 (match_operand:DI 5 "" "")]
2036                      UNSPEC_DIV_INV_M2)
2037                     (match_operand:DI 6 "" "")
2038                     (const_int 0)
2039                     (const_int 0)]
2040          UNSPEC_DIV_INV_M3))]
2041   "TARGET_SHMEDIA"
2042   "#"
2043   "&& (high_life_started || reload_completed)"
2044   [(pc)]
2045   "
2046 {
2047   const char *name = sh_divsi3_libfunc;
2048   enum sh_function_kind kind = SFUNC_GOT;
2049   rtx sym;
2050
2051   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2052   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2053   while (TARGET_DIVIDE_INV_CALL2)
2054     {
2055       rtx x = operands[3];
2056
2057       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2058         break;
2059       x = XVECEXP (x, 0, 0);
2060       name = \"__sdivsi3_2\";
2061       kind = SFUNC_STATIC;
2062       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2063       break;
2064     }
2065   sym = function_symbol (NULL, name, kind);
2066   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2067   DONE;
2068 }"
2069   [(set_attr "highpart" "must_split")])
2070
2071 (define_expand "divsi3_i4_media"
2072   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2073    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2074    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2075    (set (match_operand:SI 0 "register_operand" "=r")
2076         (fix:SI (match_dup 5)))]
2077   "TARGET_SHMEDIA_FPU"
2078   "
2079 {
2080   operands[3] = gen_reg_rtx (DFmode);
2081   operands[4] = gen_reg_rtx (DFmode);
2082   operands[5] = gen_reg_rtx (DFmode);
2083 }")
2084
2085 (define_insn "divsi3_i4"
2086   [(set (match_operand:SI 0 "register_operand" "=y")
2087         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2088    (clobber (reg:SI PR_REG))
2089    (clobber (reg:DF DR0_REG))
2090    (clobber (reg:DF DR2_REG))
2091    (use (reg:PSI FPSCR_REG))
2092    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2094   "jsr  @%1%#"
2095   [(set_attr "type" "sfunc")
2096    (set_attr "fp_mode" "double")
2097    (set_attr "needs_delay_slot" "yes")])
2098
2099 (define_insn "divsi3_i4_single"
2100   [(set (match_operand:SI 0 "register_operand" "=y")
2101         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2102    (clobber (reg:SI PR_REG))
2103    (clobber (reg:DF DR0_REG))
2104    (clobber (reg:DF DR2_REG))
2105    (clobber (reg:SI R2_REG))
2106    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2107   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2108   "jsr  @%1%#"
2109   [(set_attr "type" "sfunc")
2110    (set_attr "needs_delay_slot" "yes")])
2111
2112 (define_insn "divsi3_i4_int"
2113   [(set (match_operand:SI 0 "register_operand" "=z")
2114         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2115    (clobber (reg:SI T_REG))
2116    (clobber (reg:SI PR_REG))
2117    (clobber (reg:SI R1_REG))
2118    (clobber (reg:SI MACH_REG))
2119    (clobber (reg:SI MACL_REG))
2120    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2121   "TARGET_SH1"
2122   "jsr  @%1%#"
2123   [(set_attr "type" "sfunc")
2124    (set_attr "needs_delay_slot" "yes")])
2125
2126 (define_expand "divsi3"
2127   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2128    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2129    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2130    (parallel [(set (match_operand:SI 0 "register_operand" "")
2131                    (div:SI (reg:SI R4_REG)
2132                            (reg:SI R5_REG)))
2133               (clobber (reg:SI T_REG))
2134               (clobber (reg:SI PR_REG))
2135               (clobber (reg:SI R1_REG))
2136               (clobber (reg:SI R2_REG))
2137               (clobber (reg:SI R3_REG))
2138               (use (match_dup 3))])]
2139   ""
2140   "
2141 {
2142   rtx last;
2143
2144   operands[3] = gen_reg_rtx (Pmode);
2145   /* Emit the move of the address to a pseudo outside of the libcall.  */
2146   if (TARGET_DIVIDE_CALL_TABLE)
2147     {
2148       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2149       last = gen_divsi3_i4_int (operands[0], operands[3]);
2150     }
2151   else if (TARGET_DIVIDE_CALL_FP)
2152     {
2153       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2154       if (TARGET_FPU_SINGLE)
2155         last = gen_divsi3_i4_single (operands[0], operands[3]);
2156       else
2157         last = gen_divsi3_i4 (operands[0], operands[3]);
2158     }
2159   else if (TARGET_SH2A)
2160     {
2161       operands[1] = force_reg (SImode, operands[1]);
2162       operands[2] = force_reg (SImode, operands[2]);
2163       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2164       DONE;
2165     }
2166   else if (TARGET_DIVIDE_INV)
2167     {
2168       rtx dividend = operands[1];
2169       rtx divisor = operands[2];
2170       rtx tab_base;
2171       rtx nsb_res = gen_reg_rtx (DImode);
2172       rtx norm64 = gen_reg_rtx (DImode);
2173       rtx tab_ix = gen_reg_rtx (DImode);
2174       rtx norm32 = gen_reg_rtx (SImode);
2175       rtx i92 = force_reg (DImode, GEN_INT (92));
2176       rtx scratch0a = gen_reg_rtx (DImode);
2177       rtx scratch0b = gen_reg_rtx (DImode);
2178       rtx inv0 = gen_reg_rtx (SImode);
2179       rtx scratch1a = gen_reg_rtx (DImode);
2180       rtx scratch1b = gen_reg_rtx (DImode);
2181       rtx shift = gen_reg_rtx (DImode);
2182       rtx i2p27, i43;
2183       rtx inv1 = gen_reg_rtx (SImode);
2184       rtx scratch2a = gen_reg_rtx (DImode);
2185       rtx scratch2b = gen_reg_rtx (SImode);
2186       rtx inv2 = gen_reg_rtx (SImode);
2187       rtx scratch3a = gen_reg_rtx (DImode);
2188       rtx scratch3b = gen_reg_rtx (DImode);
2189       rtx scratch3c = gen_reg_rtx (DImode);
2190       rtx scratch3d = gen_reg_rtx (SImode);
2191       rtx scratch3e = gen_reg_rtx (DImode);
2192       rtx result = gen_reg_rtx (SImode);
2193
2194       if (! arith_reg_or_0_operand (dividend, SImode))
2195         dividend = force_reg (SImode, dividend);
2196       if (! arith_reg_operand (divisor, SImode))
2197         divisor = force_reg (SImode, divisor);
2198       if (flag_pic && Pmode != DImode)
2199         {
2200           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2201           tab_base = gen_datalabel_ref (tab_base);
2202           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2203         }
2204       else
2205         {
2206           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2207           tab_base = gen_datalabel_ref (tab_base);
2208           tab_base = force_reg (DImode, tab_base);
2209         }
2210       if (TARGET_DIVIDE_INV20U)
2211         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2212       else
2213         i2p27 = GEN_INT (0);
2214       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2215         i43 = force_reg (DImode, GEN_INT (43));
2216       else
2217         i43 = GEN_INT (0);
2218       emit_insn (gen_nsbdi (nsb_res,
2219                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2220       emit_insn (gen_ashldi3_media (norm64,
2221                                     gen_rtx_SUBREG (DImode, divisor, 0),
2222                                     nsb_res));
2223       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2224       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2225       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2226                                    inv0, scratch0a, scratch0b,
2227                                    scratch1a, scratch1b));
2228       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2229       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2230                                    scratch2a));
2231       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2232                                    i2p27, i43,
2233                                    scratch3a, scratch3b, scratch3c,
2234                                    scratch2a, scratch2b, scratch3d, scratch3e));
2235       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2236         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2237       else if (TARGET_DIVIDE_INV_FP)
2238         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2239                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2240                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2241                                      gen_reg_rtx (DFmode)));
2242       else
2243         emit_move_insn (operands[0], result);
2244       DONE;
2245     }
2246   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2247     {
2248       operands[1] = force_reg (SImode, operands[1]);
2249       operands[2] = force_reg (SImode, operands[2]);
2250       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2251       DONE;
2252     }
2253   else if (TARGET_SH5)
2254     {
2255       if (TARGET_DIVIDE_CALL2)
2256         {
2257           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2258           tab_base = gen_datalabel_ref (tab_base);
2259           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2260         }
2261       if (TARGET_FPU_ANY && TARGET_SH1)
2262         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2263       else if (TARGET_DIVIDE_CALL2)
2264         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2265       else
2266         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2267
2268       if (TARGET_SHMEDIA)
2269         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2270                 (operands[0], operands[3]));
2271       else if (TARGET_FPU_ANY)
2272         last = gen_divsi3_i4_single (operands[0], operands[3]);
2273       else
2274         last = gen_divsi3_i1 (operands[0], operands[3]);
2275     }
2276   else
2277     {
2278       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2279       last = gen_divsi3_i1 (operands[0], operands[3]);
2280     }
2281   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2282   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2283   emit_insn (last);
2284   DONE;
2285 }")
2286
2287 ;; operands: scratch, tab_base, tab_ix
2288 ;; These are unspecs because we could generate an indexed addressing mode
2289 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2290 ;; confuse reload.  See PR27117.
2291
2292 (define_insn "divsi_inv_qitable"
2293   [(set (match_operand:DI 0 "register_operand" "=r")
2294         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2295                                     (match_operand:DI 2 "register_operand" "r")]
2296                          UNSPEC_DIV_INV_TABLE)))]
2297   "TARGET_SHMEDIA"
2298   "@
2299         ldx.ub  %1, %2, %0"
2300   [(set_attr "type" "load_media")
2301    (set_attr "highpart" "user")])
2302
2303 ;; operands: scratch, tab_base, tab_ix
2304 (define_insn "divsi_inv_hitable"
2305   [(set (match_operand:DI 0 "register_operand" "=r")
2306         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2307                                     (match_operand:DI 2 "register_operand" "r")]
2308                          UNSPEC_DIV_INV_TABLE)))]
2309   "TARGET_SHMEDIA"
2310   "@
2311         ldx.w   %1, %2, %0"
2312   [(set_attr "type" "load_media")
2313    (set_attr "highpart" "user")])
2314
2315 ;; operands: inv0, tab_base, tab_ix, norm32
2316 ;; scratch equiv in sdivsi3_2: r19, r21
2317 (define_expand "divsi_inv_m0"
2318   [(set (match_operand:SI 0 "register_operand" "=r")
2319         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2320                     (match_operand:DI 2 "register_operand" "r")
2321                     (match_operand:SI 3 "register_operand" "r")]
2322          UNSPEC_DIV_INV_M0))
2323    (clobber (match_operand:DI 4 "register_operand" "=r"))
2324    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2325   "TARGET_SHMEDIA"
2326   "
2327 {
2328 /*
2329 tab_base: r20
2330 tab_ix: r21
2331 norm32: r25
2332  ldx.ub r20, r21, r19 // u0.8
2333  shlli r21, 1, r21
2334  muls.l r25, r19, r19 // s2.38
2335  ldx.w r20, r21, r21  // s2.14
2336  shari r19, 24, r19   // truncate to s2.14
2337  sub r21, r19, r19    // some 11 bit inverse in s1.14
2338 */
2339
2340   rtx inv0 = operands[0];
2341   rtx tab_base = operands[1];
2342   rtx tab_ix = operands[2];
2343   rtx norm32 = operands[3];
2344   rtx scratch0 = operands[4];
2345   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2346   rtx scratch1 = operands[5];
2347
2348   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2349   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2350   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2351   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2352   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2353   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2354   DONE;
2355 }")
2356
2357 ;; operands: inv1, tab_base, tab_ix, norm32
2358 (define_insn_and_split "divsi_inv_m1"
2359   [(set (match_operand:SI 0 "register_operand" "=r")
2360         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2361                     (match_operand:DI 2 "register_operand" "r")
2362                     (match_operand:SI 3 "register_operand" "r")]
2363          UNSPEC_DIV_INV_M1))
2364    (clobber (match_operand:SI 4 "register_operand" "=r"))
2365    (clobber (match_operand:DI 5 "register_operand" "=r"))
2366    (clobber (match_operand:DI 6 "register_operand" "=r"))
2367    (clobber (match_operand:DI 7 "register_operand" "=r"))
2368    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2369   "TARGET_SHMEDIA"
2370   "#"
2371   "&& !can_create_pseudo_p ()"
2372   [(pc)]
2373   "
2374 {
2375 /* inv0: r19
2376  muls.l r19, r19, r18 // u0.28
2377  muls.l r25, r18, r18 // s2.58
2378  shlli r19, 45, r0    // multiply by two and convert to s2.58
2379  sub r0, r18, r18
2380  shari r18, 28, r18   // some 18 bit inverse in s1.30
2381 */
2382
2383   rtx inv1 = operands[0];
2384   rtx tab_base = operands[1];
2385   rtx tab_ix = operands[2];
2386   rtx norm32 = operands[3];
2387   rtx inv0 = operands[4];
2388   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2389   rtx scratch0a = operands[5];
2390   rtx scratch0b = operands[6];
2391   rtx scratch0 = operands[7];
2392   rtx scratch1 = operands[8];
2393   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2394
2395   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2396                                scratch0a, scratch0b));
2397   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2398   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2399   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2400   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2401   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2402   DONE;
2403 }")
2404
2405 ;; operands: inv2, norm32, inv1, i92
2406 (define_insn_and_split "divsi_inv_m2"
2407   [(set (match_operand:SI 0 "register_operand" "=r")
2408         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2409                     (match_operand:SI 2 "register_operand" "r")
2410                     (match_operand:DI 3 "register_operand" "r")]
2411          UNSPEC_DIV_INV_M2))
2412    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2413   "TARGET_SHMEDIA"
2414   "#"
2415   "&& !can_create_pseudo_p ()"
2416   [(pc)]
2417   "
2418 {
2419 /*
2420  muls.l r18, r25, r0  // s2.60
2421  shari r0, 16, r0     // s-16.44
2422   sub
2423  muls.l r0, r18, r19  // s-16.74
2424  shari r19, 30, r19   // s-16.44
2425 */
2426   rtx inv2 = operands[0];
2427   rtx norm32 = operands[1];
2428   rtx inv1 = operands[2];
2429   rtx i92 = operands[3];
2430   rtx scratch0 = operands[4];
2431   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2432
2433   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2434   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2435   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2436   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2437   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2438   DONE;
2439 }")
2440
2441 (define_insn_and_split "divsi_inv_m3"
2442   [(set (match_operand:SI 0 "register_operand" "=r")
2443         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2444                     (match_operand:SI 2 "register_operand" "r")
2445                     (match_operand:SI 3 "register_operand" "r")
2446                     (match_operand:DI 4 "register_operand" "r")
2447                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2448                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2449          UNSPEC_DIV_INV_M3))
2450    (clobber (match_operand:DI 7 "register_operand" "=r"))
2451    (clobber (match_operand:DI 8 "register_operand" "=r"))
2452    (clobber (match_operand:DI 9 "register_operand" "=r"))
2453    (clobber (match_operand:DI 10 "register_operand" "=r"))
2454    (clobber (match_operand:SI 11 "register_operand" "=r"))
2455    (clobber (match_operand:SI 12 "register_operand" "=r"))
2456    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2457   "TARGET_SHMEDIA"
2458   "#"
2459   "&& !can_create_pseudo_p ()"
2460   [(pc)]
2461   "
2462 {
2463 /*
2464   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2465   r0: scratch0  r19: scratch1 r21: scratch2
2466
2467   muls.l r18, r4, r25 // s32.30
2468  muls.l r19, r4, r19  // s15.30
2469  shari r25, 63, r21
2470   shari r19, 14, r19  // s18.-14
2471  sub r25, r19, r0
2472  shard r0, r1, r0
2473  sub r0, r21, r0
2474 */
2475
2476   rtx result = operands[0];
2477   rtx dividend = operands[1];
2478   rtx inv1 = operands[2];
2479   rtx inv2 = operands[3];
2480   rtx shift = operands[4];
2481   rtx scratch0 = operands[7];
2482   rtx scratch1 = operands[8];
2483   rtx scratch2 = operands[9];
2484
2485   if (satisfies_constraint_N (dividend))
2486     {
2487       emit_move_insn (result, dividend);
2488       DONE;
2489     }
2490
2491   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2492   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2493   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2494   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2495   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2496   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2497   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2498   DONE;
2499 }")
2500
2501 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2502 ;; inv1: tab_base, tab_ix, norm32
2503 ;; inv2: norm32, inv1, i92
2504 (define_insn_and_split "divsi_inv_m1_3"
2505   [(set (match_operand:SI 0 "register_operand" "=r")
2506         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2507                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2508                                 (match_operand:DI 3 "register_operand" "r")
2509                                 (match_operand:SI 4 "register_operand" "r")]
2510                      UNSPEC_DIV_INV_M1)
2511                     (unspec:SI [(match_dup 4)
2512                                 (unspec:SI [(match_dup 2)
2513                                             (match_dup 3)
2514                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2515                                 (match_operand:SI 5 "" "")]
2516                      UNSPEC_DIV_INV_M2)
2517                     (match_operand:DI 6 "register_operand" "r")
2518                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2519                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2520          UNSPEC_DIV_INV_M3))
2521    (clobber (match_operand:DI 9 "register_operand" "=r"))
2522    (clobber (match_operand:DI 10 "register_operand" "=r"))
2523    (clobber (match_operand:DI 11 "register_operand" "=r"))
2524    (clobber (match_operand:DI 12 "register_operand" "=r"))
2525    (clobber (match_operand:SI 13 "register_operand" "=r"))
2526    (clobber (match_operand:SI 14 "register_operand" "=r"))
2527    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2528   "TARGET_SHMEDIA
2529    && (TARGET_DIVIDE_INV_MINLAT
2530        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2531   "#"
2532   "&& !can_create_pseudo_p ()"
2533   [(pc)]
2534   "
2535 {
2536   rtx result = operands[0];
2537   rtx dividend = operands[1];
2538   rtx tab_base = operands[2];
2539   rtx tab_ix = operands[3];
2540   rtx norm32 = operands[4];
2541   /* rtx i92 = operands[5]; */
2542   rtx shift = operands[6];
2543   rtx i2p27 = operands[7];
2544   rtx i43 = operands[8];
2545   rtx scratch0 = operands[9];
2546   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2547   rtx scratch1 = operands[10];
2548   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2549   rtx scratch2 = operands[11];
2550   rtx scratch3 = operands[12];
2551   rtx scratch4 = operands[13];
2552   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2553   rtx scratch5 = operands[14];
2554   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2555   rtx scratch6 = operands[15];
2556
2557   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2558                                scratch0, scratch1));
2559   /* inv0 == scratch4 */
2560   if (! TARGET_DIVIDE_INV20U)
2561     {
2562       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2563       i2p27 = scratch0;
2564       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2565     }
2566   else
2567     {
2568       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2569       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2570     }
2571   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2572   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2573   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2574   /* inv1 == scratch4 */
2575
2576   if (TARGET_DIVIDE_INV_MINLAT)
2577     {
2578       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2579       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2580       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2581       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2582       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2583       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2584       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2585       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2586       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2587       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2588       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2589     }
2590   else
2591     {
2592       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2593       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2594       emit_insn (gen_nsbdi (scratch6,
2595                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2596       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2597       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2598       emit_insn (gen_divsi_inv20 (scratch2,
2599                                   norm32, scratch4, dividend,
2600                                   scratch6, scratch3, i43,
2601                                   /* scratch0 may be shared with i2p27.  */
2602                                   scratch0, scratch1, scratch5,
2603                                   label, label, i2p27));
2604     }
2605   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2606   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2607   DONE;
2608 }")
2609
2610 (define_insn "divsi_inv20"
2611   [(set (match_operand:DI 0 "register_operand" "=&r")
2612         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2613                     (match_operand:SI 2 "register_operand" "r")
2614                     (match_operand:SI 3 "register_operand" "r")
2615                     (match_operand:DI 4 "register_operand" "r")
2616                     (match_operand:DI 5 "register_operand" "r")
2617                     (match_operand:DI 6 "register_operand" "r")
2618                     (match_operand:DI 12 "register_operand" "r")
2619                     (match_operand 10 "target_operand" "b")
2620                     (match_operand 11 "immediate_operand" "i")]
2621          UNSPEC_DIV_INV20))
2622    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2623    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2624    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2625   "TARGET_SHMEDIA
2626    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2627   "*
2628 {
2629 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2630              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2631              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2632              %10 label (tr), %11 label (imm)
2633
2634  muls.l inv1, norm32, scratch0  // s2.60
2635   muls.l inv1, dividend, result // s32.30
2636   xor i2p27, result_sign, round_scratch
2637  bge/u dividend_nsb, i43, tr.. (label)
2638  shari scratch0, 16, scratch0   // s-16.44
2639  muls.l sratch0_si, inv1, scratch0 // s-16.74
2640   sub result, round_scratch, result
2641   shari dividend, 14, scratch1   // s19.-14
2642  shari scratch0, 30, scratch0   // s-16.44
2643  muls.l scratch0, scratch1, round_scratch // s15.30
2644 label:
2645  sub result, round_scratch, result */
2646
2647   int likely = TARGET_DIVIDE_INV20L;
2648
2649   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2650   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2651   output_asm_insn (likely
2652                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2653                    : \"bge/u\t%4, %6, %10\", operands);
2654   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2655   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2656   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2657   return (likely
2658           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2659           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2660 }")
2661
2662 (define_insn_and_split "divsi_inv_fp"
2663   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2664         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2665                 (match_operand:SI 2 "register_operand" "rf")))
2666    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2667    (clobber (match_operand:SI 4 "register_operand" "=r"))
2668    (clobber (match_operand:SI 5 "register_operand" "=r"))
2669    (clobber (match_operand:DF 6 "register_operand" "=r"))
2670    (clobber (match_operand:DF 7 "register_operand" "=r"))
2671    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2672   "TARGET_SHMEDIA_FPU"
2673   "#"
2674   "&& (high_life_started || reload_completed)"
2675   [(set (match_dup 0) (match_dup 3))]
2676   ""
2677   [(set_attr "highpart" "must_split")])
2678
2679 ;; If a matching group of divide-by-inverse instructions is in the same
2680 ;; basic block after gcse & loop optimizations, we want to transform them
2681 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2682 (define_insn_and_split "*divsi_inv_fp_combine"
2683   [(set (match_operand:SI 0 "register_operand" "=f")
2684         (div:SI (match_operand:SI 1 "register_operand" "f")
2685                 (match_operand:SI 2 "register_operand" "f")))
2686    (use (unspec:SI [(match_dup 1)
2687                     (match_operand:SI 3 "" "")
2688                     (unspec:SI [(match_operand:SI 4 "" "")
2689                                 (match_dup 3)
2690                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2691                     (match_operand:DI 6 "" "")
2692                     (const_int 0)
2693                     (const_int 0)] UNSPEC_DIV_INV_M3))
2694    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2695    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2696    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2697    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2698    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2699   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2700   "#"
2701   "&& 1"
2702   [(set (match_dup 9) (float:DF (match_dup 1)))
2703    (set (match_dup 10) (float:DF (match_dup 2)))
2704    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2705    (set (match_dup 8)
2706         (fix:SI (match_dup 11)))
2707    (set (match_dup 0) (match_dup 8))]
2708   "
2709 {
2710   if (! fp_arith_reg_operand (operands[1], SImode))
2711     {
2712       emit_move_insn (operands[7], operands[1]);
2713       operands[1] = operands[7];
2714     }
2715   if (! fp_arith_reg_operand (operands[2], SImode))
2716     {
2717       emit_move_insn (operands[8], operands[2]);
2718       operands[2] = operands[8];
2719     }
2720 }"
2721   [(set_attr "highpart" "must_split")])
2722 \f
2723 ;; -------------------------------------------------------------------------
2724 ;; Multiplication instructions
2725 ;; -------------------------------------------------------------------------
2726
2727 (define_insn "umulhisi3_i"
2728   [(set (reg:SI MACL_REG)
2729         (mult:SI (zero_extend:SI
2730                   (match_operand:HI 0 "arith_reg_operand" "r"))
2731                  (zero_extend:SI
2732                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2733   "TARGET_SH1"
2734   "mulu.w       %1,%0"
2735   [(set_attr "type" "smpy")])
2736
2737 (define_insn "mulhisi3_i"
2738   [(set (reg:SI MACL_REG)
2739         (mult:SI (sign_extend:SI
2740                   (match_operand:HI 0 "arith_reg_operand" "r"))
2741                  (sign_extend:SI
2742                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2743   "TARGET_SH1"
2744   "muls.w       %1,%0"
2745   [(set_attr "type" "smpy")])
2746
2747 (define_expand "mulhisi3"
2748   [(set (reg:SI MACL_REG)
2749         (mult:SI (sign_extend:SI
2750                   (match_operand:HI 1 "arith_reg_operand" ""))
2751                  (sign_extend:SI
2752                   (match_operand:HI 2 "arith_reg_operand" ""))))
2753    (set (match_operand:SI 0 "arith_reg_operand" "")
2754         (reg:SI MACL_REG))]
2755   "TARGET_SH1"
2756   "
2757 {
2758   rtx insn, macl;
2759
2760   macl = gen_rtx_REG (SImode, MACL_REG);
2761   start_sequence ();
2762   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2763   insn = get_insns ();  
2764   end_sequence ();
2765   /* expand_binop can't find a suitable code in umul_widen_optab to
2766      make a REG_EQUAL note from, so make one here.
2767      See also smulsi3_highpart.
2768      ??? Alternatively, we could put this at the calling site of expand_binop,
2769      i.e. expand_expr.  */
2770   /* Use emit_libcall_block for loop invariant code motion and to make
2771      a REG_EQUAL note.  */
2772   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2773
2774   DONE;
2775 }")
2776
2777 (define_expand "umulhisi3"
2778   [(set (reg:SI MACL_REG)
2779         (mult:SI (zero_extend:SI
2780                   (match_operand:HI 1 "arith_reg_operand" ""))
2781                  (zero_extend:SI
2782                   (match_operand:HI 2 "arith_reg_operand" ""))))
2783    (set (match_operand:SI 0 "arith_reg_operand" "")
2784         (reg:SI MACL_REG))]
2785   "TARGET_SH1"
2786   "
2787 {
2788   rtx insn, macl;
2789
2790   macl = gen_rtx_REG (SImode, MACL_REG);
2791   start_sequence ();
2792   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2793   insn = get_insns ();  
2794   end_sequence ();
2795   /* expand_binop can't find a suitable code in umul_widen_optab to
2796      make a REG_EQUAL note from, so make one here.
2797      See also smulsi3_highpart.
2798      ??? Alternatively, we could put this at the calling site of expand_binop,
2799      i.e. expand_expr.  */
2800   /* Use emit_libcall_block for loop invariant code motion and to make
2801      a REG_EQUAL note.  */
2802   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2803
2804   DONE;
2805 }")
2806
2807 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2808 ;; a call to a routine which clobbers known registers.
2809
2810 (define_insn ""
2811   [(set (match_operand:SI 1 "register_operand" "=z")
2812         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2813    (clobber (reg:SI MACL_REG))
2814    (clobber (reg:SI T_REG))
2815    (clobber (reg:SI PR_REG))
2816    (clobber (reg:SI R3_REG))
2817    (clobber (reg:SI R2_REG))
2818    (clobber (reg:SI R1_REG))
2819    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2820   "TARGET_SH1"
2821   "jsr  @%0%#"
2822   [(set_attr "type" "sfunc")
2823    (set_attr "needs_delay_slot" "yes")])
2824
2825 (define_expand "mulsi3_call"
2826   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2827    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2828    (parallel[(set (match_operand:SI 0 "register_operand" "")
2829                   (mult:SI (reg:SI R4_REG)
2830                            (reg:SI R5_REG)))
2831              (clobber (reg:SI MACL_REG))
2832              (clobber (reg:SI T_REG))
2833              (clobber (reg:SI PR_REG))
2834              (clobber (reg:SI R3_REG))
2835              (clobber (reg:SI R2_REG))
2836              (clobber (reg:SI R1_REG))
2837              (use (match_operand:SI 3 "register_operand" ""))])]
2838   "TARGET_SH1"
2839   "")
2840
2841 (define_insn "mul_r"
2842   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2843         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2844                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2845   "TARGET_SH2A"
2846   "mulr %2,%0"
2847   [(set_attr "type" "dmpy")])
2848
2849 (define_insn "mul_l"
2850   [(set (reg:SI MACL_REG)
2851         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2852                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2853   "TARGET_SH2"
2854   "mul.l        %1,%0"
2855   [(set_attr "type" "dmpy")])
2856
2857 (define_expand "mulsi3"
2858   [(set (reg:SI MACL_REG)
2859         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2860                   (match_operand:SI 2 "arith_reg_operand" "")))
2861    (set (match_operand:SI 0 "arith_reg_operand" "")
2862         (reg:SI MACL_REG))]
2863   "TARGET_SH1"
2864   "
2865 {
2866   if (!TARGET_SH2)
2867     {
2868       /* The address must be set outside the libcall,
2869          since it goes into a pseudo.  */
2870       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2871       rtx addr = force_reg (SImode, sym);
2872       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2873                                    operands[2], addr);
2874       emit_insn (insns);
2875     }
2876   else
2877     {
2878       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2879
2880       emit_insn (gen_mul_l (operands[1], operands[2]));
2881       /* consec_sets_giv can only recognize the first insn that sets a
2882          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2883          note.  */
2884       emit_insn (gen_movsi_i ((operands[0]), macl));
2885     }
2886   DONE;
2887 }")
2888
2889 (define_insn "mulsidi3_i"
2890   [(set (reg:SI MACH_REG)
2891         (truncate:SI
2892          (lshiftrt:DI
2893           (mult:DI
2894            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2895            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2896           (const_int 32))))
2897    (set (reg:SI MACL_REG)
2898         (mult:SI (match_dup 0)
2899                  (match_dup 1)))]
2900   "TARGET_SH2"
2901   "dmuls.l      %1,%0"
2902   [(set_attr "type" "dmpy")])
2903
2904 (define_expand "mulsidi3"
2905   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2906         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2907                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2908   "TARGET_SH2 || TARGET_SHMEDIA"
2909   "
2910 {
2911   if (TARGET_SH2)
2912     {
2913        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2914                                         operands[2]));
2915        DONE;
2916     }
2917 }")
2918
2919 (define_insn "mulsidi3_media"
2920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2922                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2923   "TARGET_SHMEDIA"
2924   "muls.l       %1, %2, %0"
2925   [(set_attr "type" "dmpy_media")
2926    (set_attr "highpart" "ignore")])
2927
2928 (define_insn "mulsidi3_compact"
2929   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2930         (mult:DI
2931          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2932          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2933    (clobber (reg:SI MACH_REG))
2934    (clobber (reg:SI MACL_REG))]
2935   "TARGET_SH2"
2936   "#")
2937
2938 (define_split
2939   [(set (match_operand:DI 0 "arith_reg_dest" "")
2940         (mult:DI
2941          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2942          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2943    (clobber (reg:SI MACH_REG))
2944    (clobber (reg:SI MACL_REG))]
2945   "TARGET_SH2"
2946   [(const_int 0)]
2947   "
2948 {
2949   rtx low_dst = gen_lowpart (SImode, operands[0]);
2950   rtx high_dst = gen_highpart (SImode, operands[0]);
2951
2952   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2953
2954   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2955   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2956   /* We need something to tag the possible REG_EQUAL notes on to.  */
2957   emit_move_insn (operands[0], operands[0]);
2958   DONE;
2959 }")
2960
2961 (define_insn "umulsidi3_i"
2962   [(set (reg:SI MACH_REG)
2963         (truncate:SI
2964          (lshiftrt:DI
2965           (mult:DI
2966            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2967            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2968           (const_int 32))))
2969    (set (reg:SI MACL_REG)
2970         (mult:SI (match_dup 0)
2971                  (match_dup 1)))]
2972   "TARGET_SH2"
2973   "dmulu.l      %1,%0"
2974   [(set_attr "type" "dmpy")])
2975
2976 (define_expand "umulsidi3"
2977   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2978         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2979                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2980   "TARGET_SH2 || TARGET_SHMEDIA"
2981   "
2982 {
2983   if (TARGET_SH2)
2984     {
2985        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2986                                          operands[2]));
2987        DONE;
2988     }
2989 }")
2990
2991 (define_insn "umulsidi3_media"
2992   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2993         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2994                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2995   "TARGET_SHMEDIA"
2996   "mulu.l       %1, %2, %0"
2997   [(set_attr "type" "dmpy_media")
2998    (set_attr "highpart" "ignore")])
2999
3000 (define_insn "umulsidi3_compact"
3001   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3002         (mult:DI
3003          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3004          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3005    (clobber (reg:SI MACH_REG))
3006    (clobber (reg:SI MACL_REG))]
3007   "TARGET_SH2"
3008   "#")
3009
3010 (define_split
3011   [(set (match_operand:DI 0 "arith_reg_dest" "")
3012         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3013                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3014    (clobber (reg:SI MACH_REG))
3015    (clobber (reg:SI MACL_REG))]
3016   "TARGET_SH2"
3017   [(const_int 0)]
3018   "
3019 {
3020   rtx low_dst = gen_lowpart (SImode, operands[0]);
3021   rtx high_dst = gen_highpart (SImode, operands[0]);
3022
3023   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3024
3025   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3026   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3027   /* We need something to tag the possible REG_EQUAL notes on to.  */
3028   emit_move_insn (operands[0], operands[0]);
3029   DONE;
3030 }")
3031
3032 (define_insn "smulsi3_highpart_i"
3033   [(set (reg:SI MACH_REG)
3034         (truncate:SI
3035          (lshiftrt:DI
3036           (mult:DI
3037            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3038            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3039           (const_int 32))))
3040    (clobber (reg:SI MACL_REG))]
3041   "TARGET_SH2"
3042   "dmuls.l      %1,%0"
3043   [(set_attr "type" "dmpy")])
3044
3045 (define_expand "smulsi3_highpart"
3046   [(parallel
3047     [(set (reg:SI MACH_REG)
3048           (truncate:SI
3049            (lshiftrt:DI
3050             (mult:DI
3051              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3052              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3053             (const_int 32))))
3054     (clobber (reg:SI MACL_REG))])
3055    (set (match_operand:SI 0 "arith_reg_operand" "")
3056         (reg:SI MACH_REG))]
3057   "TARGET_SH2"
3058   "
3059 {
3060   rtx insn, mach;
3061
3062   mach = gen_rtx_REG (SImode, MACH_REG);
3063   start_sequence ();
3064   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3065   insn = get_insns ();  
3066   end_sequence ();
3067   /* expand_binop can't find a suitable code in mul_highpart_optab to
3068      make a REG_EQUAL note from, so make one here.
3069      See also {,u}mulhisi.
3070      ??? Alternatively, we could put this at the calling site of expand_binop,
3071      i.e. expand_mult_highpart.  */
3072   /* Use emit_libcall_block for loop invariant code motion and to make
3073      a REG_EQUAL note.  */
3074   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3075
3076   DONE;
3077 }")
3078
3079 (define_insn "umulsi3_highpart_i"
3080   [(set (reg:SI MACH_REG)
3081         (truncate:SI
3082          (lshiftrt:DI
3083           (mult:DI
3084            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3085            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3086           (const_int 32))))
3087    (clobber (reg:SI MACL_REG))]
3088   "TARGET_SH2"
3089   "dmulu.l      %1,%0"
3090   [(set_attr "type" "dmpy")])
3091
3092 (define_expand "umulsi3_highpart"
3093   [(parallel
3094     [(set (reg:SI MACH_REG)
3095           (truncate:SI
3096            (lshiftrt:DI
3097             (mult:DI
3098              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3099              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3100             (const_int 32))))
3101     (clobber (reg:SI MACL_REG))])
3102    (set (match_operand:SI 0 "arith_reg_operand" "")
3103         (reg:SI MACH_REG))]
3104   "TARGET_SH2"
3105   "
3106 {
3107   rtx insn, mach;
3108
3109   mach = gen_rtx_REG (SImode, MACH_REG);
3110   start_sequence ();
3111   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3112   insn = get_insns ();  
3113   end_sequence ();
3114   /* Use emit_libcall_block for loop invariant code motion and to make
3115      a REG_EQUAL note.  */
3116   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3117
3118   DONE;
3119 }")
3120
3121 (define_insn_and_split "muldi3"
3122   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3123         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3124                  (match_operand:DI 2 "arith_reg_operand" "r")))
3125    (clobber (match_scratch:DI 3 "=&r"))
3126    (clobber (match_scratch:DI 4 "=r"))]
3127   "TARGET_SHMEDIA"
3128   "#"
3129   "reload_completed"
3130   [(const_int 0)]
3131   "
3132 {
3133   rtx op3_v2si, op2_v2si;
3134
3135   op3_v2si = operands[3];
3136   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3137     {
3138       op3_v2si = XEXP (op3_v2si, 0);
3139       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3140     }
3141   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3142   op2_v2si = operands[2];
3143   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3144     {
3145       op2_v2si = XEXP (op2_v2si, 0);
3146       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3147     }
3148   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3149   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3150   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3151   emit_insn (gen_umulsidi3_media (operands[4],
3152                                  sh_gen_truncate (SImode, operands[1], 0),
3153                                  sh_gen_truncate (SImode, operands[2], 0)));
3154   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3155   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3156   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3157   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3158   DONE;
3159 }")
3160
3161 \f
3162 ;; -------------------------------------------------------------------------
3163 ;; Logical operations
3164 ;; -------------------------------------------------------------------------
3165
3166 (define_insn "*andsi3_compact"
3167   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3168         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3169                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3170   "TARGET_SH1"
3171   "and  %2,%0"
3172   [(set_attr "type" "arith")])
3173
3174 (define_insn "*andsi3_media"
3175   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3176         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3177                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3178   "TARGET_SHMEDIA"
3179   "@
3180         and     %1, %2, %0
3181         andi    %1, %2, %0"
3182   [(set_attr "type" "arith_media")])
3183
3184 (define_insn "*andsi3_bclr"
3185   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3187                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3188   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3189   "bclr\\t%W2,%0"
3190   [(set_attr "type" "arith")])
3191
3192 ;; If the constant is 255, then emit an extu.b instruction instead of an
3193 ;; and, since that will give better code.
3194
3195 (define_expand "andsi3"
3196   [(set (match_operand:SI 0 "arith_reg_operand" "")
3197         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3198                 (match_operand:SI 2 "logical_operand" "")))]
3199   ""
3200   "
3201 {
3202   if (TARGET_SH1
3203       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3204     {
3205       emit_insn (gen_zero_extendqisi2 (operands[0],
3206                                        gen_lowpart (QImode, operands[1])));
3207       DONE;
3208     }
3209 }")
3210
3211 (define_insn_and_split "anddi3"
3212   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3213         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3214                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3215   "TARGET_SHMEDIA"
3216   "@
3217         and     %1, %2, %0
3218         andi    %1, %2, %0
3219         #"
3220   "reload_completed
3221    && ! logical_operand (operands[2], DImode)"
3222   [(const_int 0)]
3223   "
3224 {
3225   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3226     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3227   else
3228     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3229   DONE;
3230 }"
3231   [(set_attr "type" "arith_media")])
3232
3233 (define_insn "andcsi3"
3234   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3235         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3236                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3237   "TARGET_SHMEDIA"
3238   "andc %1,%2,%0"
3239   [(set_attr "type" "arith_media")])
3240
3241 (define_insn "andcdi3"
3242   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3243         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3244                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3245   "TARGET_SHMEDIA"
3246   "andc %1,%2,%0"
3247   [(set_attr "type" "arith_media")])
3248
3249 (define_expand "iorsi3"
3250   [(set (match_operand:SI 0 "arith_reg_operand" "")
3251         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3252                 (match_operand:SI 2 "logical_operand" "")))]
3253   ""
3254   "")
3255
3256 (define_insn "*iorsi3_compact"
3257   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3258         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3259                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3260   "TARGET_SH1
3261    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3262   "or   %2,%0"
3263   [(set_attr "type" "arith")])
3264
3265 (define_insn "*iorsi3_media"
3266   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3267         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3268                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3269   "TARGET_SHMEDIA"
3270   "@
3271         or      %1, %2, %0
3272         ori     %1, %2, %0"
3273   [(set_attr "type" "arith_media")])
3274
3275 (define_insn "*iorsi3_bset"
3276   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3277         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3278         (match_operand:SI 2 "const_int_operand" "Pso")))]
3279   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3280   "bset\\t%V2,%0"
3281   [(set_attr "type" "arith")])
3282
3283 (define_insn "iordi3"
3284   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3285         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3286                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3287   "TARGET_SHMEDIA"
3288   "@
3289         or      %1, %2, %0
3290         ori     %1, %2, %0"
3291   [(set_attr "type" "arith_media")])
3292
3293 (define_insn_and_split "*logical_sidi3"
3294   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3296                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3297                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3298   "TARGET_SHMEDIA"
3299   "#"
3300   "&& reload_completed"
3301   [(set (match_dup 0) (match_dup 3))]
3302   "
3303 {
3304   operands[3]
3305     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3306                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3307                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3308 }")
3309
3310 (define_insn_and_split "*logical_sidisi3"
3311   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3312         (truncate:SI (sign_extend:DI
3313                         (match_operator:SI 3 "logical_operator"
3314                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3315                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3316   "TARGET_SHMEDIA"
3317   "#"
3318   "&& 1"
3319   [(set (match_dup 0) (match_dup 3))])
3320
3321 (define_insn_and_split "*logical_sidi3_2"
3322   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3323         (sign_extend:DI (truncate:SI (sign_extend:DI
3324                         (match_operator:SI 3 "logical_operator"
3325                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3326                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3327   "TARGET_SHMEDIA"
3328   "#"
3329   "&& 1"
3330   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3331
3332 (define_expand "xorsi3"
3333   [(set (match_operand:SI 0 "arith_reg_operand" "")
3334         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3335                 (match_operand:SI 2 "xor_operand" "")))]
3336   ""
3337   "")
3338
3339 (define_insn "*xorsi3_compact"
3340   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3341         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3342                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3343   "TARGET_SH1"
3344   "xor  %2,%0"
3345   [(set_attr "type" "arith")])
3346
3347 (define_insn "*xorsi3_media"
3348   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3349         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3350                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3351   "TARGET_SHMEDIA"
3352   "@
3353         xor     %1, %2, %0
3354         xori    %1, %2, %0"
3355   [(set_attr "type" "arith_media")])
3356
3357 ;; Store the complements of the T bit in a register.
3358 (define_insn "xorsi3_movrt"
3359   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3360         (xor:SI (reg:SI T_REG)
3361                 (const_int 1)))]
3362   "TARGET_SH2A"
3363   "movrt\\t%0"
3364   [(set_attr "type" "arith")])
3365
3366 (define_insn "xordi3"
3367   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3368         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3369                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3370   "TARGET_SHMEDIA"
3371   "@
3372         xor     %1, %2, %0
3373         xori    %1, %2, %0"
3374   [(set_attr "type" "arith_media")])
3375
3376 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3377 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3378 (define_split
3379   [(set (match_operand:DI 0 "arith_reg_dest" "")
3380         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3381                           [(match_operand 1 "any_register_operand" "")
3382                            (match_operand 2 "any_register_operand" "")])))]
3383   "TARGET_SHMEDIA"
3384   [(set (match_dup 5) (match_dup 4))
3385    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3386 "
3387 {
3388   enum machine_mode inmode = GET_MODE (operands[1]);
3389   int offset = 0;
3390
3391   if (GET_CODE (operands[0]) == SUBREG)
3392     {
3393       offset = SUBREG_BYTE (operands[0]);
3394       operands[0] = SUBREG_REG (operands[0]);
3395     }
3396   gcc_assert (REG_P (operands[0]));
3397   if (! TARGET_LITTLE_ENDIAN)
3398     offset += 8 - GET_MODE_SIZE (inmode);
3399   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3400 }")
3401 \f
3402 ;; -------------------------------------------------------------------------
3403 ;; Shifts and rotates
3404 ;; -------------------------------------------------------------------------
3405
3406 (define_expand "rotldi3"
3407   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3408         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3409                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3410   "TARGET_SHMEDIA"
3411   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3412
3413 (define_insn "rotldi3_mextr"
3414   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3415         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3416                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3417   "TARGET_SHMEDIA"
3418   "*
3419 {
3420   static char templ[16];
3421
3422   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3423            8 - (int) (INTVAL (operands[2]) >> 3));
3424   return templ;
3425 }"
3426   [(set_attr "type" "arith_media")])
3427
3428 (define_expand "rotrdi3"
3429   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3430         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3431                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3432   "TARGET_SHMEDIA"
3433   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3434
3435 (define_insn "rotrdi3_mextr"
3436   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3437         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3438                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3439   "TARGET_SHMEDIA"
3440   "*
3441 {
3442   static char templ[16];
3443
3444   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3445   return templ;
3446 }"
3447   [(set_attr "type" "arith_media")])
3448
3449 (define_split
3450   [(set (match_operand:DI 0 "arith_reg_dest" "")
3451         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3452                                          "ua_address_operand" "")))
3453                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3454                            (const_int 8))))
3455    (clobber (match_operand:DI 3 "register_operand" ""))]
3456   "TARGET_SHMEDIA"
3457   [(match_dup 4) (match_dup 5)]
3458   "
3459 {
3460   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3461                  (operands[3], operands[1]));
3462   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3463                               GEN_INT (56), GEN_INT (8));
3464 }")
3465
3466 (define_insn "rotlsi3_1"
3467   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3468         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3469                    (const_int 1)))
3470    (set (reg:SI T_REG)
3471         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3472   "TARGET_SH1"
3473   "rotl %0"
3474   [(set_attr "type" "arith")])
3475
3476 (define_insn "rotlsi3_31"
3477   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3478         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3479                    (const_int 31)))
3480    (clobber (reg:SI T_REG))]
3481   "TARGET_SH1"
3482   "rotr %0"
3483   [(set_attr "type" "arith")])
3484
3485 (define_insn "rotlsi3_16"
3486   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3487         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3488                    (const_int 16)))]
3489   "TARGET_SH1"
3490   "swap.w       %1,%0"
3491   [(set_attr "type" "arith")])
3492
3493 (define_expand "rotlsi3"
3494   [(set (match_operand:SI 0 "arith_reg_dest" "")
3495         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3496                    (match_operand:SI 2 "immediate_operand" "")))]
3497   "TARGET_SH1"
3498   "
3499 {
3500   static const char rot_tab[] = {
3501     000, 000, 000, 000, 000, 000, 010, 001,
3502     001, 001, 011, 013, 003, 003, 003, 003,
3503     003, 003, 003, 003, 003, 013, 012, 002,
3504     002, 002, 010, 000, 000, 000, 000, 000,
3505   };
3506
3507   int count, choice;
3508
3509   if (!CONST_INT_P (operands[2]))
3510     FAIL;
3511   count = INTVAL (operands[2]);
3512   choice = rot_tab[count];
3513   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3514     FAIL;
3515   choice &= 7;
3516   switch (choice)
3517     {
3518     case 0:
3519       emit_move_insn (operands[0], operands[1]);
3520       count -= (count & 16) * 2;
3521       break;
3522     case 3:
3523      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3524      count -= 16;
3525      break;
3526     case 1:
3527     case 2:
3528       {
3529         rtx parts[2];
3530         parts[0] = gen_reg_rtx (SImode);
3531         parts[1] = gen_reg_rtx (SImode);
3532         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3533         emit_move_insn (parts[choice-1], operands[1]);
3534         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3535         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3536         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3537         count = (count & ~16) - 8;
3538       }
3539     }
3540
3541   for (; count > 0; count--)
3542     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3543   for (; count < 0; count++)
3544     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3545
3546   DONE;
3547 }")
3548
3549 (define_insn "*rotlhi3_8"
3550   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3551         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3552                    (const_int 8)))]
3553   "TARGET_SH1"
3554   "swap.b       %1,%0"
3555   [(set_attr "type" "arith")])
3556
3557 (define_expand "rotlhi3"
3558   [(set (match_operand:HI 0 "arith_reg_operand" "")
3559         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3560                    (match_operand:HI 2 "immediate_operand" "")))]
3561   "TARGET_SH1"
3562   "
3563 {
3564   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3565     FAIL;
3566 }")
3567
3568 ;;
3569 ;; shift left
3570
3571 ;; This pattern is used by init_expmed for computing the costs of shift
3572 ;; insns.
3573
3574 (define_insn_and_split "ashlsi3_std"
3575   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3576         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3577                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3578    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3579   "(TARGET_SH3 || TARGET_SH2A)
3580    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3581   "@
3582    shld %2,%0
3583    add  %0,%0
3584    shll%O2      %0
3585    #"
3586   "(TARGET_SH3 || TARGET_SH2A)
3587    && reload_completed
3588    && CONST_INT_P (operands[2])
3589    && ! satisfies_constraint_P27 (operands[2])"
3590   [(set (match_dup 3) (match_dup 2))
3591    (parallel
3592     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3593      (clobber (match_dup 4))])]
3594   "operands[4] = gen_rtx_SCRATCH (SImode);"
3595   [(set_attr "length" "*,*,*,4")
3596    (set_attr "type" "dyn_shift,arith,arith,arith")])
3597
3598 (define_insn "ashlhi3_k"
3599   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3600         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3601                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3602   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3603   "@
3604         add     %0,%0
3605         shll%O2 %0"
3606   [(set_attr "type" "arith")])
3607
3608 (define_insn "ashlsi3_n"
3609   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3610         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3611                    (match_operand:SI 2 "const_int_operand" "n")))
3612    (clobber (reg:SI T_REG))]
3613   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3614   "#"
3615   [(set (attr "length")
3616         (cond [(match_test "shift_insns_rtx (insn)")
3617                (const_string "2")
3618                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3619                (const_string "4")
3620                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3621                (const_string "6")]
3622               (const_string "8")))
3623    (set_attr "type" "arith")])
3624
3625 (define_split
3626   [(set (match_operand:SI 0 "arith_reg_dest" "")
3627         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3628                    (match_operand:SI 2 "const_int_operand" "")))
3629    (clobber (reg:SI T_REG))]
3630   "TARGET_SH1 && reload_completed"
3631   [(use (reg:SI R0_REG))]
3632   "
3633 {
3634   gen_shifty_op (ASHIFT, operands);
3635   DONE;
3636 }")
3637
3638 (define_insn "ashlsi3_media"
3639   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3640         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3641                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3642   "TARGET_SHMEDIA"
3643   "@
3644         shlld.l %1, %2, %0
3645         shlli.l %1, %2, %0"
3646   [(set_attr "type" "arith_media")
3647    (set_attr "highpart" "ignore")])
3648
3649 (define_expand "ashlsi3"
3650   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3651                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3652                               (match_operand:SI 2 "nonmemory_operand" "")))
3653               (clobber (reg:SI T_REG))])]
3654   ""
3655   "
3656 {
3657   if (TARGET_SHMEDIA)
3658     {
3659       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3660       DONE;
3661     }
3662   if (CONST_INT_P (operands[2])
3663       && sh_dynamicalize_shift_p (operands[2]))
3664     operands[2] = force_reg (SImode, operands[2]);
3665   if (TARGET_SH3 || TARGET_SH2A)
3666     {
3667       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3668       DONE;
3669     }
3670   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3671     FAIL;
3672 }")
3673
3674 (define_insn "*ashlhi3_n"
3675   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3676         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3677                    (match_operand:HI 2 "const_int_operand" "n")))
3678    (clobber (reg:SI T_REG))]
3679   "TARGET_SH1"
3680   "#"
3681   [(set (attr "length")
3682         (cond [(match_test "shift_insns_rtx (insn)")
3683                (const_string "2")
3684                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3685                (const_string "4")]
3686               (const_string "6")))
3687    (set_attr "type" "arith")])
3688
3689 (define_expand "ashlhi3"
3690   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3691                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3692                               (match_operand:SI 2 "nonmemory_operand" "")))
3693               (clobber (reg:SI T_REG))])]
3694   "TARGET_SH1"
3695   "
3696 {
3697   if (!CONST_INT_P (operands[2]))
3698     FAIL;
3699   /* It may be possible to call gen_ashlhi3 directly with more generic
3700      operands.  Make sure operands[1] is a HImode register here.  */
3701   if (!arith_reg_operand (operands[1], HImode))
3702     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3703 }")
3704
3705 (define_split
3706   [(set (match_operand:HI 0 "arith_reg_dest" "")
3707         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3708                    (match_operand:HI 2 "const_int_operand" "")))
3709    (clobber (reg:SI T_REG))]
3710   "TARGET_SH1 && reload_completed"
3711   [(use (reg:SI R0_REG))]
3712   "
3713 {
3714   gen_shifty_hi_op (ASHIFT, operands);
3715   DONE;
3716 }")
3717
3718 ;
3719 ; arithmetic shift right
3720 ;
3721
3722 (define_insn "ashrsi3_k"
3723   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3724         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3725                      (match_operand:SI 2 "const_int_operand" "M")))
3726    (clobber (reg:SI T_REG))]
3727   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3728   "shar %0"
3729   [(set_attr "type" "arith")])
3730
3731 ;; We can't do HImode right shifts correctly unless we start out with an
3732 ;; explicit zero / sign extension; doing that would result in worse overall
3733 ;; code, so just let the machine independent code widen the mode.
3734 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3735
3736
3737 ;; ??? This should be a define expand.
3738
3739 (define_insn "ashrsi2_16"
3740   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3742                      (const_int 16)))]
3743   "TARGET_SH1"
3744   "#"
3745   [(set_attr "length" "4")])
3746
3747 (define_split
3748   [(set (match_operand:SI 0 "arith_reg_dest" "")
3749         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3750                      (const_int 16)))]
3751   "TARGET_SH1"
3752   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3753    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3754   "operands[2] = gen_lowpart (HImode, operands[0]);")
3755
3756 ;; ??? This should be a define expand.
3757
3758 (define_insn "ashrsi2_31"
3759   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3760         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3761                      (const_int 31)))
3762    (clobber (reg:SI T_REG))]
3763   "TARGET_SH1"
3764   "#"
3765   [(set_attr "length" "4")])
3766
3767 (define_split
3768   [(set (match_operand:SI 0 "arith_reg_dest" "")
3769         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3770                      (const_int 31)))
3771    (clobber (reg:SI T_REG))]
3772   "TARGET_SH1"
3773   [(const_int 0)]
3774   "
3775 {
3776   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3777   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3778   DONE;
3779 }")
3780
3781 (define_peephole2
3782   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3783    (set (reg:SI T_REG)
3784         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3785   "TARGET_SH1
3786    && peep2_reg_dead_p (2, operands[0])
3787    && peep2_reg_dead_p (2, operands[1])"
3788   [(const_int 0)]
3789   "
3790 {
3791   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3792   DONE;
3793 }")
3794
3795 (define_insn "ashlsi_c"
3796   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3797         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3798    (set (reg:SI T_REG)
3799         (lt:SI (match_dup 1) (const_int 0)))]
3800   "TARGET_SH1"
3801   "shll %0"
3802   [(set_attr "type" "arith")])
3803
3804 (define_insn "*ashlsi_c_void"
3805   [(set (reg:SI T_REG)
3806         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3807    (clobber (match_scratch:SI 1 "=0"))]
3808   "TARGET_SH1 && cse_not_expected"
3809   "shll %0"
3810   [(set_attr "type" "arith")])
3811
3812 (define_insn "ashrsi3_d"
3813   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3814         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3815                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3816   "TARGET_SH3 || TARGET_SH2A"
3817   "shad %2,%0"
3818   [(set_attr "type" "dyn_shift")])
3819
3820 (define_insn "ashrsi3_n"
3821   [(set (reg:SI R4_REG)
3822         (ashiftrt:SI (reg:SI R4_REG)
3823                      (match_operand:SI 0 "const_int_operand" "i")))
3824    (clobber (reg:SI T_REG))
3825    (clobber (reg:SI PR_REG))
3826    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3827   "TARGET_SH1"
3828   "jsr  @%1%#"
3829   [(set_attr "type" "sfunc")
3830    (set_attr "needs_delay_slot" "yes")])
3831
3832 (define_insn "ashrsi3_media"
3833   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3834         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3835                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3836   "TARGET_SHMEDIA"
3837   "@
3838         shard.l %1, %2, %0
3839         shari.l %1, %2, %0"
3840   [(set_attr "type" "arith_media")
3841    (set_attr "highpart" "ignore")])
3842
3843 (define_expand "ashrsi3"
3844   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3845                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3846                                 (match_operand:SI 2 "nonmemory_operand" "")))
3847               (clobber (reg:SI T_REG))])]
3848   ""
3849   "
3850 {
3851   if (TARGET_SHMEDIA)
3852     {
3853       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3854       DONE;
3855     }
3856   if (expand_ashiftrt (operands))
3857     DONE;
3858   else
3859     FAIL;
3860 }")
3861
3862 ;; logical shift right
3863
3864 (define_insn "lshrsi3_d"
3865   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3866         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3867                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3868   "TARGET_SH3 || TARGET_SH2A"
3869   "shld %2,%0"
3870   [(set_attr "type" "dyn_shift")])
3871
3872 ;;  Only the single bit shift clobbers the T bit.
3873
3874 (define_insn "lshrsi3_m"
3875   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3876         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3877                      (match_operand:SI 2 "const_int_operand" "M")))
3878    (clobber (reg:SI T_REG))]
3879   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3880   "shlr %0"
3881   [(set_attr "type" "arith")])
3882
3883 (define_insn "lshrsi3_k"
3884   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3885         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3886                      (match_operand:SI 2 "const_int_operand" "P27")))]
3887   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3888    && ! satisfies_constraint_M (operands[2])"
3889   "shlr%O2      %0"
3890   [(set_attr "type" "arith")])
3891
3892 (define_insn "lshrsi3_n"
3893   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3894         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3895                      (match_operand:SI 2 "const_int_operand" "n")))
3896    (clobber (reg:SI T_REG))]
3897   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3898   "#"
3899   [(set (attr "length")
3900         (cond [(match_test "shift_insns_rtx (insn)")
3901                (const_string "2")
3902                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3903                (const_string "4")
3904                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3905                (const_string "6")]
3906               (const_string "8")))
3907    (set_attr "type" "arith")])
3908
3909 (define_split
3910   [(set (match_operand:SI 0 "arith_reg_dest" "")
3911         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3912                      (match_operand:SI 2 "const_int_operand" "")))
3913    (clobber (reg:SI T_REG))]
3914   "TARGET_SH1 && reload_completed"
3915   [(use (reg:SI R0_REG))]
3916   "
3917 {
3918   gen_shifty_op (LSHIFTRT, operands);
3919   DONE;
3920 }")
3921
3922 (define_insn "lshrsi3_media"
3923   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3924         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3925                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3926   "TARGET_SHMEDIA"
3927   "@
3928         shlrd.l %1, %2, %0
3929         shlri.l %1, %2, %0"
3930   [(set_attr "type" "arith_media")
3931    (set_attr "highpart" "ignore")])
3932
3933 (define_expand "lshrsi3"
3934   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3935                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3936                                 (match_operand:SI 2 "nonmemory_operand" "")))
3937               (clobber (reg:SI T_REG))])]
3938   ""
3939   "
3940 {
3941   if (TARGET_SHMEDIA)
3942     {
3943       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3944       DONE;
3945     }
3946   if (CONST_INT_P (operands[2])
3947       && sh_dynamicalize_shift_p (operands[2]))
3948     operands[2] = force_reg (SImode, operands[2]);
3949   if ((TARGET_SH3 || TARGET_SH2A)
3950       && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3951     {
3952       rtx count = copy_to_mode_reg (SImode, operands[2]);
3953       emit_insn (gen_negsi2 (count, count));
3954       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3955       DONE;
3956     }
3957   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3958     FAIL;
3959 }")
3960
3961 ;; ??? This should be a define expand.
3962
3963 (define_insn "ashldi3_k"
3964   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3965         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3966                    (const_int 1)))
3967    (clobber (reg:SI T_REG))]
3968   "TARGET_SH1"
3969   "shll %R0\;rotcl      %S0"
3970   [(set_attr "length" "4")
3971    (set_attr "type" "arith")])
3972
3973 ;; Expander for DImode shift left with SImode operations.
3974
3975 (define_expand "ashldi3_std"
3976   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3977         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3978                    (match_operand:DI 2 "const_int_operand" "n")))]
3979   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3980   "
3981 {
3982   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3983   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3984   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3985   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3986   rtx dst = gen_reg_rtx (DImode);
3987   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3988   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3989   rtx tmp0, tmp1;
3990
3991   tmp0 = gen_reg_rtx (SImode);
3992   tmp1 = gen_reg_rtx (SImode);
3993   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3994   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3995   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3996   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3997   emit_move_insn (operands[0], dst);
3998   DONE;
3999 }")
4000
4001 (define_insn "ashldi3_media"
4002   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4003         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4004                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
4005   "TARGET_SHMEDIA"
4006   "@
4007         shlld   %1, %2, %0
4008         shlli   %1, %2, %0"
4009   [(set_attr "type" "arith_media")])
4010
4011 (define_insn "*ashldisi3_media"
4012   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4013         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4014                    (match_operand:DI 2 "const_int_operand" "n")))]
4015   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4016   "shlli.l      %1, %2, %0"
4017   [(set_attr "type" "arith_media")
4018    (set_attr "highpart" "ignore")])
4019
4020 (define_expand "ashldi3"
4021   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4022                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4023                               (match_operand:DI 2 "immediate_operand" "")))
4024               (clobber (reg:SI T_REG))])]
4025   ""
4026   "
4027 {
4028   if (TARGET_SHMEDIA)
4029     {
4030       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4031       DONE;
4032     }
4033   if (CONST_INT_P (operands[2])
4034       && INTVAL (operands[2]) == 1)
4035     {
4036       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4037       DONE;
4038     }
4039   else if (CONST_INT_P (operands[2])
4040       && INTVAL (operands[2]) < 32)
4041     {
4042       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4043       DONE;
4044     }
4045   else
4046     FAIL;
4047 }")
4048
4049 ;; ??? This should be a define expand.
4050
4051 (define_insn "lshrdi3_k"
4052   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4053         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4054                      (const_int 1)))
4055    (clobber (reg:SI T_REG))]
4056   "TARGET_SH1"
4057   "shlr %S0\;rotcr      %R0"
4058   [(set_attr "length" "4")
4059    (set_attr "type" "arith")])
4060
4061 (define_insn "lshrdi3_media"
4062   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4063         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4064                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4065   "TARGET_SHMEDIA
4066    && (arith_reg_dest (operands[0], DImode)
4067        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4068   "@
4069         shlrd   %1, %2, %0
4070         shlri   %1, %2, %0"
4071   [(set_attr "type" "arith_media")])
4072
4073 (define_insn "*lshrdisi3_media"
4074   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4075         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4076                      (match_operand:DI 2 "const_int_operand" "n")))]
4077   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4078   "shlri.l      %1, %2, %0"
4079   [(set_attr "type" "arith_media")
4080    (set_attr "highpart" "ignore")])
4081
4082 (define_expand "lshrdi3"
4083   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4084                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4085                                (match_operand:DI 2 "immediate_operand" "")))
4086              (clobber (reg:SI T_REG))])]
4087   ""
4088   "
4089 {
4090   if (TARGET_SHMEDIA)
4091     {
4092       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4093       DONE;
4094     }
4095   if (!CONST_INT_P (operands[2])
4096       || INTVAL (operands[2]) != 1)
4097     FAIL;
4098 }")
4099
4100 ;; ??? This should be a define expand.
4101
4102 (define_insn "ashrdi3_k"
4103   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4104         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4105                      (const_int 1)))
4106    (clobber (reg:SI T_REG))]
4107   "TARGET_SH1"
4108   "shar %S0\;rotcr      %R0"
4109   [(set_attr "length" "4")
4110    (set_attr "type" "arith")])
4111
4112 (define_insn "ashrdi3_media"
4113   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4114         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4115                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4116   "TARGET_SHMEDIA
4117    && (arith_reg_dest (operands[0], DImode)
4118        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4119   "@
4120         shard   %1, %2, %0
4121         shari   %1, %2, %0"
4122   [(set_attr "type" "arith_media")])
4123
4124 (define_insn "*ashrdisi3_media"
4125   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4126         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4127                      (match_operand:DI 2 "const_int_operand" "n")))]
4128   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4129   "shari.l      %1, %2, %0"
4130   [(set_attr "type" "arith_media")
4131    (set_attr "highpart" "ignore")])
4132
4133 (define_insn "ashrdisi3_media_high"
4134   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4135         (truncate:SI
4136            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4137                         (match_operand:DI 2 "const_int_operand" "n"))))]
4138   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4139   "shari        %1, %2, %0"
4140   [(set_attr "type" "arith_media")])
4141
4142 (define_insn "ashrdisi3_media_opaque"
4143   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4144         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4145                     (match_operand:DI 2 "const_int_operand" "n")]
4146          UNSPEC_ASHIFTRT))]
4147   "TARGET_SHMEDIA"
4148   "shari        %1, %2, %0"
4149   [(set_attr "type" "arith_media")])
4150
4151 (define_expand "ashrdi3"
4152   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4153                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4154                                 (match_operand:DI 2 "immediate_operand" "")))
4155               (clobber (reg:SI T_REG))])]
4156   ""
4157   "
4158 {
4159   if (TARGET_SHMEDIA)
4160     {
4161       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4162       DONE;
4163     }
4164   if (!CONST_INT_P (operands[2])
4165       || INTVAL (operands[2]) != 1)
4166     FAIL;
4167 }")
4168
4169 ;; combined left/right shift
4170
4171 (define_split
4172   [(set (match_operand:SI 0 "register_operand" "")
4173         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4174                            (match_operand:SI 2 "const_int_operand" ""))
4175                 (match_operand:SI 3 "const_int_operand" "")))]
4176   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4177   [(use (reg:SI R0_REG))]
4178   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4179    DONE;")
4180
4181 (define_split
4182   [(set (match_operand:SI 0 "register_operand" "")
4183         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4184                            (match_operand:SI 2 "const_int_operand" ""))
4185                 (match_operand:SI 3 "const_int_operand" "")))
4186    (clobber (reg:SI T_REG))]
4187   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4188   [(use (reg:SI R0_REG))]
4189   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4190    DONE;")
4191
4192 (define_insn ""
4193   [(set (match_operand:SI 0 "register_operand" "=r")
4194         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4195                            (match_operand:SI 2 "const_int_operand" "n"))
4196                 (match_operand:SI 3 "const_int_operand" "n")))
4197    (clobber (reg:SI T_REG))]
4198   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4199  "#"
4200   [(set (attr "length")
4201         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4202                (const_string "4")
4203                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4204                (const_string "6")
4205                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4206                (const_string "8")
4207                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4208                (const_string "10")
4209                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4210                (const_string "12")
4211                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4212                (const_string "14")
4213                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4214                (const_string "16")]
4215               (const_string "18")))
4216    (set_attr "type" "arith")])
4217
4218 (define_insn ""
4219   [(set (match_operand:SI 0 "register_operand" "=z")
4220         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4221                            (match_operand:SI 2 "const_int_operand" "n"))
4222                 (match_operand:SI 3 "const_int_operand" "n")))
4223    (clobber (reg:SI T_REG))]
4224   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4225  "#"
4226   [(set (attr "length")
4227         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4228                (const_string "4")
4229                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4230                (const_string "6")
4231                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4232                (const_string "8")]
4233               (const_string "10")))
4234    (set_attr "type" "arith")])
4235
4236 ;; shift left / and combination with a scratch register: The combine pass
4237 ;; does not accept the individual instructions, even though they are
4238 ;; cheap.  But it needs a precise description so that it is usable after
4239 ;; reload.
4240 (define_insn "and_shl_scratch"
4241   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4242         (lshiftrt:SI
4243          (ashift:SI
4244           (and:SI
4245            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4246                         (match_operand:SI 2 "const_int_operand" "N,n"))
4247            (match_operand:SI 3 "" "0,r"))
4248           (match_operand:SI 4 "const_int_operand" "n,n"))
4249          (match_operand:SI 5 "const_int_operand" "n,n")))
4250    (clobber (reg:SI T_REG))]
4251   "TARGET_SH1"
4252   "#"
4253   [(set (attr "length")
4254         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4255                (const_string "4")
4256                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4257                (const_string "6")
4258                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4259                (const_string "8")
4260                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4261                (const_string "10")]
4262               (const_string "12")))
4263    (set_attr "type" "arith")])
4264
4265 (define_split
4266   [(set (match_operand:SI 0 "register_operand" "")
4267         (lshiftrt:SI
4268          (ashift:SI
4269           (and:SI
4270            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4271                         (match_operand:SI 2 "const_int_operand" ""))
4272            (match_operand:SI 3 "register_operand" ""))
4273           (match_operand:SI 4 "const_int_operand" ""))
4274          (match_operand:SI 5 "const_int_operand" "")))
4275    (clobber (reg:SI T_REG))]
4276   "TARGET_SH1"
4277   [(use (reg:SI R0_REG))]
4278   "
4279 {
4280   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4281
4282   if (INTVAL (operands[2]))
4283     {
4284       gen_shifty_op (LSHIFTRT, operands);
4285     }
4286   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4287   operands[2] = operands[4];
4288   gen_shifty_op (ASHIFT, operands);
4289   if (INTVAL (operands[5]))
4290     {
4291       operands[2] = operands[5];
4292       gen_shifty_op (LSHIFTRT, operands);
4293     }
4294   DONE;
4295 }")
4296
4297 ;; signed left/right shift combination.
4298 (define_split
4299   [(set (match_operand:SI 0 "register_operand" "")
4300         (sign_extract:SI
4301          (ashift:SI (match_operand:SI 1 "register_operand" "")
4302                     (match_operand:SI 2 "const_int_operand" ""))
4303          (match_operand:SI 3 "const_int_operand" "")
4304          (const_int 0)))
4305    (clobber (reg:SI T_REG))]
4306   "TARGET_SH1"
4307   [(use (reg:SI R0_REG))]
4308   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4309    DONE;")
4310
4311 (define_insn "shl_sext_ext"
4312   [(set (match_operand:SI 0 "register_operand" "=r")
4313         (sign_extract:SI
4314          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4315                     (match_operand:SI 2 "const_int_operand" "n"))
4316          (match_operand:SI 3 "const_int_operand" "n")
4317          (const_int 0)))
4318    (clobber (reg:SI T_REG))]
4319   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4320   "#"
4321   [(set (attr "length")
4322         (cond [(match_test "shl_sext_length (insn)")
4323                (const_string "2")
4324                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4325                (const_string "4")
4326                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4327                (const_string "6")
4328                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4329                (const_string "8")
4330                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4331                (const_string "10")
4332                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4333                (const_string "12")
4334                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4335                (const_string "14")
4336                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4337                (const_string "16")]
4338               (const_string "18")))
4339     (set_attr "type" "arith")])
4340
4341 (define_insn "shl_sext_sub"
4342   [(set (match_operand:SI 0 "register_operand" "=z")
4343         (sign_extract:SI
4344          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4345                     (match_operand:SI 2 "const_int_operand" "n"))
4346          (match_operand:SI 3 "const_int_operand" "n")
4347          (const_int 0)))
4348    (clobber (reg:SI T_REG))]
4349   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4350   "#"
4351   [(set (attr "length")
4352         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4353                (const_string "6")
4354                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4355                (const_string "8")
4356                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4357                (const_string "10")
4358                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4359                (const_string "12")]
4360               (const_string "14")))
4361     (set_attr "type" "arith")])
4362
4363 ;; These patterns are found in expansions of DImode shifts by 16, and
4364 ;; allow the xtrct instruction to be generated from C source.
4365
4366 (define_insn "xtrct_left"
4367   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4368         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4369                            (const_int 16))
4370                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4371                              (const_int 16))))]
4372   "TARGET_SH1"
4373   "xtrct        %1,%0"
4374   [(set_attr "type" "arith")])
4375
4376 (define_insn "xtrct_right"
4377   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4378         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4379                              (const_int 16))
4380                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4381                            (const_int 16))))]
4382   "TARGET_SH1"
4383   "xtrct        %2,%0"
4384   [(set_attr "type" "arith")])
4385
4386 ;; -------------------------------------------------------------------------
4387 ;; Unary arithmetic
4388 ;; -------------------------------------------------------------------------
4389
4390 (define_insn "negc"
4391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4392         (neg:SI (plus:SI (reg:SI T_REG)
4393                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4394    (set (reg:SI T_REG)
4395         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4396                (const_int 0)))]
4397   "TARGET_SH1"
4398   "negc %1,%0"
4399   [(set_attr "type" "arith")])
4400
4401 (define_insn "*negdi_media"
4402   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4403         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4404   "TARGET_SHMEDIA"
4405   "sub  r63, %1, %0"
4406   [(set_attr "type" "arith_media")])
4407
4408
4409
4410 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4411 ;; combined.
4412 (define_expand "negdi2"
4413   [(set (match_operand:DI 0 "arith_reg_dest" "")
4414         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4415    (clobber (reg:SI T_REG))]
4416   ""
4417   "")
4418
4419 (define_insn_and_split "*negdi2"
4420   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4421         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4422   "TARGET_SH1"
4423   "#"
4424   "TARGET_SH1"
4425   [(const_int 0)]
4426   "
4427 {
4428   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4429   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4430
4431   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4432   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4433
4434   rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4435   rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4436
4437   emit_insn (gen_clrt ());
4438   emit_insn (gen_negc (low_dst, low_src));
4439   emit_insn (gen_negc (high_dst, high_src));
4440   DONE;
4441 }")
4442
4443 (define_insn "negsi2"
4444   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4445         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4446   "TARGET_SH1"
4447   "neg  %1,%0"
4448   [(set_attr "type" "arith")])
4449
4450 (define_insn "one_cmplsi2"
4451   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4452         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4453   "TARGET_SH1"
4454   "not  %1,%0"
4455   [(set_attr "type" "arith")])
4456
4457 (define_expand "one_cmpldi2"
4458   [(set (match_operand:DI 0 "arith_reg_dest" "")
4459         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4460                 (const_int -1)))]
4461   "TARGET_SHMEDIA" "")
4462
4463 (define_expand "abssi2"
4464   [(set (match_operand:SI 0 "arith_reg_dest" "")
4465         (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4466    (clobber (reg:SI T_REG))]
4467   ""
4468   "")
4469
4470 (define_insn_and_split "*abssi2"
4471   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4472         (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4473   "TARGET_SH1"
4474   "#"
4475   "TARGET_SH1"
4476   [(const_int 0)]
4477   "
4478 {
4479   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4480   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4481                  const1_rtx));
4482   DONE;
4483 }")
4484
4485 (define_insn_and_split "*negabssi2"
4486   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4487         (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4488   "TARGET_SH1"
4489   "#"
4490   "TARGET_SH1"
4491   [(const_int 0)]
4492   "
4493 {
4494   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4495   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4496                  const0_rtx));
4497   DONE;
4498 }")
4499
4500
4501 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4502 ;; This can be used as some kind of conditional execution, which is useful
4503 ;; for abs.
4504 ;; Actually the instruction scheduling should decide whether to use a
4505 ;; zero-offset branch or not for any generic case involving a single
4506 ;; instruction on SH4 202.
4507
4508 (define_insn_and_split "negsi_cond"
4509   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4510         (if_then_else:SI (eq:SI (reg:SI T_REG)
4511                           (match_operand:SI 3 "const_int_operand" "M,N"))
4512          (match_operand:SI 1 "arith_reg_operand" "0,0")
4513          (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4514   "TARGET_HARD_SH4"
4515   "@
4516         bt\\t0f\;neg\\t%2,%0\\n0:
4517         bf\\t0f\;neg\\t%2,%0\\n0:"
4518   "!TARGET_HARD_SH4"
4519   [(const_int 0)]
4520   "
4521 {
4522   rtx skip_neg_label = gen_label_rtx ();
4523
4524   emit_insn (gen_movsi (operands[0], operands[1]));
4525
4526   emit_jump_insn (INTVAL (operands[3])
4527                   ? gen_branch_true (skip_neg_label)
4528                   : gen_branch_false (skip_neg_label));
4529
4530   emit_label_after (skip_neg_label,
4531                     emit_insn (gen_negsi2 (operands[0], operands[1])));
4532   DONE;
4533 }"
4534   [(set_attr "type" "arith") ;; poor approximation
4535    (set_attr "length" "4")])
4536
4537 \f
4538 ;; -------------------------------------------------------------------------
4539 ;; Zero extension instructions
4540 ;; -------------------------------------------------------------------------
4541
4542 (define_insn "zero_extendsidi2"
4543   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4544         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4545   "TARGET_SHMEDIA"
4546   "addz.l       %1, r63, %0"
4547   [(set_attr "type" "arith_media")
4548    (set_attr "highpart" "extend")])
4549
4550 (define_insn "zero_extendhidi2"
4551   [(set (match_operand:DI 0 "register_operand" "=r,r")
4552         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4553   "TARGET_SHMEDIA"
4554   "@
4555         #
4556         ld%M1.uw        %m1, %0"
4557   [(set_attr "type" "*,load_media")
4558    (set (attr "highpart")
4559         (cond [(match_test "sh_contains_memref_p (insn)")
4560                (const_string "user")]
4561               (const_string "ignore")))])
4562
4563 (define_split
4564   [(set (match_operand:DI 0 "register_operand" "")
4565         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4566   "TARGET_SHMEDIA && reload_completed"
4567   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4568    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4569   "
4570 {
4571   if (GET_CODE (operands[1]) == TRUNCATE)
4572     operands[1] = XEXP (operands[1], 0);
4573 }")
4574
4575 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4576 ;; reload the entire truncate expression.
4577 (define_insn_and_split "*loaddi_trunc"
4578   [(set (match_operand 0 "any_register_operand" "=r")
4579         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4580   "TARGET_SHMEDIA && reload_completed"
4581   "#"
4582   "TARGET_SHMEDIA && reload_completed"
4583   [(set (match_dup 0) (match_dup 1))]
4584   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4585
4586 (define_insn "zero_extendqidi2"
4587   [(set (match_operand:DI 0 "register_operand" "=r,r")
4588         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4589   "TARGET_SHMEDIA"
4590   "@
4591         andi    %1, 255, %0
4592         ld%M1.ub        %m1, %0"
4593   [(set_attr "type" "arith_media,load_media")
4594    (set (attr "highpart")
4595         (cond [(match_test "sh_contains_memref_p (insn)")
4596                (const_string "user")]
4597               (const_string "ignore")))])
4598
4599 (define_expand "zero_extendhisi2"
4600   [(set (match_operand:SI 0 "arith_reg_operand" "")
4601         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4602   ""
4603   "
4604 {
4605   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4606     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4607 }")
4608
4609 (define_insn "*zero_extendhisi2_compact"
4610   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4611         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4612   "TARGET_SH1"
4613   "extu.w       %1,%0"
4614   [(set_attr "type" "arith")])
4615
4616 (define_insn "*zero_extendhisi2_media"
4617   [(set (match_operand:SI 0 "register_operand" "=r,r")
4618         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4619   "TARGET_SHMEDIA"
4620   "@
4621         #
4622         ld%M1.uw        %m1, %0"
4623   [(set_attr "type" "arith_media,load_media")
4624    (set (attr "highpart")
4625         (cond [(match_test "sh_contains_memref_p (insn)")
4626                (const_string "user")]
4627               (const_string "ignore")))])
4628
4629 (define_split
4630   [(set (match_operand:SI 0 "register_operand" "")
4631         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4632   "TARGET_SHMEDIA && reload_completed"
4633   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4634    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4635   "
4636 {
4637   rtx op1 = operands[1];
4638
4639   if (GET_CODE (op1) == TRUNCATE)
4640     op1 = XEXP (op1, 0);
4641   operands[2]
4642     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4643                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4644 }")
4645
4646 (define_expand "zero_extendqisi2"
4647   [(set (match_operand:SI 0 "arith_reg_operand" "")
4648         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4649   ""
4650   "
4651 {
4652   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4653     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4654 }")
4655
4656 (define_insn "*zero_extendqisi2_compact"
4657   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4658         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4659   "TARGET_SH1"
4660   "extu.b       %1,%0"
4661   [(set_attr "type" "arith")])
4662
4663 (define_insn "*zero_extendqisi2_media"
4664   [(set (match_operand:SI 0 "register_operand" "=r,r")
4665         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4666   "TARGET_SHMEDIA"
4667   "@
4668         andi    %1, 255, %0
4669         ld%M1.ub        %m1, %0"
4670   [(set_attr "type" "arith_media,load_media")
4671    (set (attr "highpart")
4672         (cond [(match_test "sh_contains_memref_p (insn)")
4673                (const_string "user")]
4674               (const_string "ignore")))])
4675
4676 (define_insn "zero_extendqihi2"
4677   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4678         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4679   "TARGET_SH1"
4680   "extu.b       %1,%0"
4681   [(set_attr "type" "arith")])
4682
4683 ;; -------------------------------------------------------------------------
4684 ;; Sign extension instructions
4685 ;; -------------------------------------------------------------------------
4686
4687 ;; ??? This should be a define expand.
4688 ;; ??? Or perhaps it should be dropped?
4689
4690 ;; convert_move generates good code for SH[1-4].
4691 (define_insn "extendsidi2"
4692   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4693         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4694   "TARGET_SHMEDIA"
4695   "@
4696         add.l   %1, r63, %0
4697         ld%M1.l %m1, %0
4698         fmov.sl %1, %0"
4699   [(set_attr "type" "arith_media,load_media,fpconv_media")
4700    (set (attr "highpart")
4701         (cond [(match_test "sh_contains_memref_p (insn)")
4702                (const_string "user")]
4703               (const_string "extend")))])
4704
4705 (define_insn "extendhidi2"
4706   [(set (match_operand:DI 0 "register_operand" "=r,r")
4707         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4708   "TARGET_SHMEDIA"
4709   "@
4710         #
4711         ld%M1.w %m1, %0"
4712   [(set_attr "type" "*,load_media")
4713    (set (attr "highpart")
4714         (cond [(match_test "sh_contains_memref_p (insn)")
4715                (const_string "user")]
4716               (const_string "ignore")))])
4717
4718 (define_split
4719   [(set (match_operand:DI 0 "register_operand" "")
4720         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4721   "TARGET_SHMEDIA && reload_completed"
4722   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4723    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4724   "
4725 {
4726   if (GET_CODE (operands[1]) == TRUNCATE)
4727     operands[1] = XEXP (operands[1], 0);
4728 }")
4729
4730 (define_insn "extendqidi2"
4731   [(set (match_operand:DI 0 "register_operand" "=r,r")
4732         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4733   "TARGET_SHMEDIA"
4734   "@
4735         #
4736         ld%M1.b %m1, %0"
4737   [(set_attr "type" "*,load_media")
4738    (set (attr "highpart")
4739         (cond [(match_test "sh_contains_memref_p (insn)")
4740                (const_string "user")]
4741               (const_string "ignore")))])
4742
4743 (define_split
4744   [(set (match_operand:DI 0 "register_operand" "")
4745         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4746   "TARGET_SHMEDIA && reload_completed"
4747   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4748    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4749   "
4750 {
4751   if (GET_CODE (operands[1]) == TRUNCATE)
4752     operands[1] = XEXP (operands[1], 0);
4753 }")
4754
4755 (define_expand "extendhisi2"
4756   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4757         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4758   ""
4759   "")
4760
4761 (define_insn "*extendhisi2_compact"
4762   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4763         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4764   "TARGET_SH1"
4765   "@
4766         exts.w  %1,%0
4767         mov.w   %1,%0"
4768   [(set_attr "type" "arith,load")])
4769
4770 (define_insn "*extendhisi2_media"
4771   [(set (match_operand:SI 0 "register_operand" "=r,r")
4772         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4773   "TARGET_SHMEDIA"
4774   "@
4775         #
4776         ld%M1.w %m1, %0"
4777   [(set_attr "type" "arith_media,load_media")
4778    (set (attr "highpart")
4779         (cond [(match_test "sh_contains_memref_p (insn)")
4780                (const_string "user")]
4781               (const_string "ignore")))])
4782
4783 (define_split
4784   [(set (match_operand:SI 0 "register_operand" "")
4785         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4786   "TARGET_SHMEDIA && reload_completed"
4787   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4788    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4789   "
4790 {
4791   rtx op1 = operands[1];
4792   if (GET_CODE (op1) == TRUNCATE)
4793     op1 = XEXP (op1, 0);
4794   operands[2]
4795     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4796                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4797 }")
4798
4799 (define_expand "extendqisi2"
4800   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4801         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4802   ""
4803   "")
4804
4805 (define_insn "*extendqisi2_compact"
4806   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4807         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4808   "TARGET_SH1"
4809   "@
4810         exts.b  %1,%0
4811         mov.b   %1,%0"
4812   [(set_attr "type" "arith,load")
4813    (set_attr_alternative "length"
4814      [(const_int 2)
4815        (if_then_else
4816         (match_test "TARGET_SH2A")
4817         (const_int 4) (const_int 2))])])
4818
4819 (define_insn "*extendqisi2_media"
4820   [(set (match_operand:SI 0 "register_operand" "=r,r")
4821         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4822   "TARGET_SHMEDIA"
4823   "@
4824         #
4825         ld%M1.b %m1, %0"
4826   [(set_attr "type" "arith_media,load_media")
4827    (set (attr "highpart")
4828         (cond [(match_test "sh_contains_memref_p (insn)")
4829                (const_string "user")]
4830               (const_string "ignore")))])
4831
4832 (define_split
4833   [(set (match_operand:SI 0 "register_operand" "")
4834         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4835   "TARGET_SHMEDIA && reload_completed"
4836   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4837    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4838    "
4839 {
4840   rtx op1 = operands[1];
4841   if (GET_CODE (op1) == TRUNCATE)
4842     op1 = XEXP (op1, 0);
4843   operands[2]
4844     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4845                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4846 }")
4847
4848 (define_insn "extendqihi2"
4849   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4850         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4851   "TARGET_SH1"
4852   "@
4853         exts.b  %1,%0
4854         mov.b   %1,%0"
4855   [(set_attr "type" "arith,load")
4856    (set_attr_alternative "length"
4857      [(const_int 2)
4858        (if_then_else
4859         (match_test "TARGET_SH2A")
4860         (const_int 4) (const_int 2))])])
4861
4862 /* It would seem useful to combine the truncXi patterns into the movXi
4863    patterns, but unary operators are ignored when matching constraints,
4864    so we need separate patterns.  */
4865 (define_insn "truncdisi2"
4866   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4867         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4868   "TARGET_SHMEDIA"
4869   "@
4870         add.l   %1, r63, %0
4871         st%M0.l %m0, %1
4872         fst%M0.s        %m0, %T1
4873         fmov.ls %1, %0
4874         fmov.sl %T1, %0
4875         fmov.s  %T1, %0"
4876   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4877    (set (attr "highpart")
4878         (cond [(match_test "sh_contains_memref_p (insn)")
4879                (const_string "user")]
4880               (const_string "extend")))])
4881
4882 (define_insn "truncdihi2"
4883   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4884         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4885   "TARGET_SHMEDIA"
4886   "@
4887         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4888         st%M0.w %m0, %1"
4889   [(set_attr "type"   "arith_media,store_media")
4890    (set_attr "length" "8,4")
4891    (set (attr "highpart")
4892         (cond [(match_test "sh_contains_memref_p (insn)")
4893                (const_string "user")]
4894               (const_string "extend")))])
4895
4896 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4897 ; Because we use zero extension, we can't provide signed QImode compares
4898 ; using a simple compare or conditional branch insn.
4899 (define_insn "truncdiqi2"
4900   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4901         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4902   "TARGET_SHMEDIA"
4903   "@
4904         andi    %1, 255, %0
4905         st%M0.b %m0, %1"
4906   [(set_attr "type"   "arith_media,store")
4907    (set (attr "highpart")
4908         (cond [(match_test "sh_contains_memref_p (insn)")
4909                (const_string "user")]
4910               (const_string "extend")))])
4911 ;; -------------------------------------------------------------------------
4912 ;; Move instructions
4913 ;; -------------------------------------------------------------------------
4914
4915 ;; define push and pop so it is easy for sh.c
4916 ;; We can't use push and pop on SHcompact because the stack must always
4917 ;; be 8-byte aligned.
4918
4919 (define_expand "push"
4920   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4921         (match_operand:SI 0 "register_operand" "r,l,x"))]
4922   "TARGET_SH1 && ! TARGET_SH5"
4923   "")
4924
4925 (define_expand "pop"
4926   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4927         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4928   "TARGET_SH1 && ! TARGET_SH5"
4929   "")
4930
4931 (define_expand "push_e"
4932   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4933                    (match_operand:SF 0 "" ""))
4934               (use (reg:PSI FPSCR_REG))
4935               (clobber (scratch:SI))])]
4936   "TARGET_SH1 && ! TARGET_SH5"
4937   "")
4938
4939 (define_insn "push_fpul"
4940   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4941   "TARGET_SH2E && ! TARGET_SH5"
4942   "sts.l        fpul,@-r15"
4943   [(set_attr "type" "fstore")
4944    (set_attr "late_fp_use" "yes")
4945    (set_attr "hit_stack" "yes")])
4946
4947 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4948 ;; so use that.
4949 (define_expand "push_4"
4950   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4951                    (match_operand:DF 0 "" ""))
4952               (use (reg:PSI FPSCR_REG))
4953               (clobber (scratch:SI))])]
4954   "TARGET_SH1 && ! TARGET_SH5"
4955   "")
4956
4957 (define_expand "pop_e"
4958   [(parallel [(set (match_operand:SF 0 "" "")
4959               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4960               (use (reg:PSI FPSCR_REG))
4961               (clobber (scratch:SI))])]
4962   "TARGET_SH1 && ! TARGET_SH5"
4963   "")
4964
4965 (define_insn "pop_fpul"
4966   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4967   "TARGET_SH2E && ! TARGET_SH5"
4968   "lds.l        @r15+,fpul"
4969   [(set_attr "type" "load")
4970    (set_attr "hit_stack" "yes")])
4971
4972 (define_expand "pop_4"
4973   [(parallel [(set (match_operand:DF 0 "" "")
4974                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4975               (use (reg:PSI FPSCR_REG))
4976               (clobber (scratch:SI))])]
4977   "TARGET_SH1 && ! TARGET_SH5"
4978   "")
4979
4980 (define_expand "push_fpscr"
4981   [(const_int 0)]
4982   "TARGET_SH2E"
4983   "
4984 {
4985   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4986                                                  gen_rtx_PRE_DEC (Pmode,
4987                                                           stack_pointer_rtx)),
4988                                         get_fpscr_rtx ()));
4989   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4990   DONE;
4991 }")
4992
4993 (define_expand "pop_fpscr"
4994   [(const_int 0)]
4995   "TARGET_SH2E"
4996   "
4997 {
4998   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4999                                         gen_frame_mem (PSImode,
5000                                                  gen_rtx_POST_INC (Pmode,
5001                                                           stack_pointer_rtx))));
5002   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5003   DONE;
5004 }")
5005
5006 ;; These two patterns can happen as the result of optimization, when
5007 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5008 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5009
5010 (define_insn "clrt"
5011   [(set (reg:SI T_REG) (const_int 0))]
5012   "TARGET_SH1"
5013   "clrt")
5014
5015 (define_insn "sett"
5016   [(set (reg:SI T_REG) (const_int 1))]
5017   "TARGET_SH1"
5018   "sett")
5019
5020 ;; Define additional pop for SH1 and SH2 so it does not get 
5021 ;; placed in the delay slot.
5022 (define_insn "*movsi_pop"
5023   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5024         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5025   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5026    && ! TARGET_SH3"
5027   "@
5028    mov.l   %1,%0
5029    lds.l   %1,%0
5030    lds.l   %1,%0"
5031   [(set_attr "type" "load_si,mem_mac,pload")
5032    (set_attr "length" "2,2,2")
5033    (set_attr "in_delay_slot" "no,no,no")])
5034
5035 ;; t/r must come after r/r, lest reload will try to reload stuff like
5036 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5037 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5038 (define_insn "movsi_i"
5039   [(set (match_operand:SI 0 "general_movdst_operand"
5040             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5041         (match_operand:SI 1 "general_movsrc_operand"
5042          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5043   "TARGET_SH1
5044    && ! TARGET_SH2E
5045    && ! TARGET_SH2A
5046    && (register_operand (operands[0], SImode)
5047        || register_operand (operands[1], SImode))"
5048   "@
5049         mov.l   %1,%0
5050         mov     %1,%0
5051         mov     %1,%0
5052         cmp/pl  %1
5053         mov.l   %1,%0
5054         sts     %1,%0
5055         sts     %1,%0
5056         movt    %0
5057         mov.l   %1,%0
5058         sts.l   %1,%0
5059         sts.l   %1,%0
5060         lds     %1,%0
5061         lds     %1,%0
5062         lds.l   %1,%0
5063         lds.l   %1,%0
5064         fake    %1,%0"
5065   [(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")
5066    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5067
5068 ;; t/r must come after r/r, lest reload will try to reload stuff like
5069 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5070 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5071 ;; will require a reload.
5072 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5073 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5074 (define_insn "movsi_ie"
5075   [(set (match_operand:SI 0 "general_movdst_operand"
5076             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5077         (match_operand:SI 1 "general_movsrc_operand"
5078          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5079   "(TARGET_SH2E || TARGET_SH2A)
5080    && (register_operand (operands[0], SImode)
5081        || register_operand (operands[1], SImode))"
5082   "@
5083         mov.l   %1,%0
5084         mov     %1,%0
5085         mov     %1,%0
5086         movi20  %1,%0
5087         movi20s %1,%0
5088         cmp/pl  %1
5089         mov.l   %1,%0
5090         sts     %1,%0
5091         sts     %1,%0
5092         movt    %0
5093         mov.l   %1,%0
5094         sts.l   %1,%0
5095         sts.l   %1,%0
5096         lds     %1,%0
5097         lds     %1,%0
5098         lds.l   %1,%0
5099         lds.l   %1,%0
5100         lds.l   %1,%0
5101         sts.l   %1,%0
5102         fake    %1,%0
5103         lds     %1,%0
5104         sts     %1,%0
5105         fsts    fpul,%0
5106         flds    %1,fpul
5107         fmov    %1,%0
5108         ! move optimized away"
5109   [(set_attr "type" "pcload_si,move,movi8,move,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")
5110    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5111    (set_attr_alternative "length"
5112      [(const_int 2)
5113       (const_int 2)
5114       (const_int 2)
5115       (const_int 4)
5116       (const_int 4)
5117       (const_int 2)
5118       (if_then_else
5119         (match_test "TARGET_SH2A")
5120         (const_int 4) (const_int 2))
5121       (const_int 2)
5122       (const_int 2)
5123       (const_int 2)
5124       (if_then_else
5125         (match_test "TARGET_SH2A")
5126         (const_int 4) (const_int 2))
5127       (const_int 2)
5128       (const_int 2)
5129       (const_int 2)
5130       (const_int 2)
5131       (const_int 2)
5132       (const_int 2)
5133       (const_int 2)
5134       (const_int 2)
5135       (const_int 2)
5136       (const_int 2)
5137       (const_int 2)
5138       (const_int 2)
5139       (const_int 2)
5140       (const_int 2)
5141       (const_int 0)])])
5142
5143 (define_insn "movsi_i_lowpart"
5144   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5145         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5146    "TARGET_SH1
5147     && (register_operand (operands[0], SImode)
5148         || register_operand (operands[1], SImode))"
5149   "@
5150         mov.l   %1,%0
5151         mov     %1,%0
5152         mov     %1,%0
5153         mov.l   %1,%0
5154         sts     %1,%0
5155         sts     %1,%0
5156         movt    %0
5157         mov.l   %1,%0
5158         fake    %1,%0"
5159   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5160
5161 (define_insn_and_split "load_ra"
5162   [(set (match_operand:SI 0 "general_movdst_operand" "")
5163         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5164   "TARGET_SH1"
5165   "#"
5166   "&& ! currently_expanding_to_rtl"
5167   [(set (match_dup 0) (match_dup 1))]
5168   "
5169 {
5170   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5171     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5172 }")
5173
5174 ;; The '?'s in the following constraints may not reflect the time taken
5175 ;; to perform the move. They are there to discourage the use of floating-
5176 ;; point registers for storing integer values.
5177 (define_insn "*movsi_media"
5178   [(set (match_operand:SI 0 "general_movdst_operand"
5179                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5180         (match_operand:SI 1 "general_movsrc_operand"
5181          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5182   "TARGET_SHMEDIA_FPU
5183    && (register_operand (operands[0], SImode)
5184        || sh_register_operand (operands[1], SImode)
5185        || GET_CODE (operands[1]) == TRUNCATE)"
5186   "@
5187         add.l   %1, r63, %0
5188         movi    %1, %0
5189         #
5190         ld%M1.l %m1, %0
5191         st%M0.l %m0, %N1
5192         fld%M1.s        %m1, %0
5193         fst%M0.s        %m0, %1
5194         fmov.ls %N1, %0
5195         fmov.sl %1, %0
5196         fmov.s  %1, %0
5197         ptabs   %1, %0
5198         gettr   %1, %0
5199         pt      %1, %0"
5200   [(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")
5201    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5202    (set (attr "highpart")
5203         (cond [(match_test "sh_contains_memref_p (insn)")
5204                (const_string "user")]
5205               (const_string "ignore")))])
5206
5207 (define_insn "*movsi_media_nofpu"
5208   [(set (match_operand:SI 0 "general_movdst_operand"
5209                 "=r,r,r,r,m,*b,r,*b")
5210         (match_operand:SI 1 "general_movsrc_operand"
5211          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5212   "TARGET_SHMEDIA
5213    && (register_operand (operands[0], SImode)
5214        || sh_register_operand (operands[1], SImode)
5215        || GET_CODE (operands[1]) == TRUNCATE)"
5216   "@
5217         add.l   %1, r63, %0
5218         movi    %1, %0
5219         #
5220         ld%M1.l %m1, %0
5221         st%M0.l %m0, %N1
5222         ptabs   %1, %0
5223         gettr   %1, %0
5224         pt      %1, %0"
5225   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5226    (set_attr "length" "4,4,8,4,4,4,4,12")
5227    (set (attr "highpart")
5228         (cond [(match_test "sh_contains_memref_p (insn)")
5229                (const_string "user")]
5230               (const_string "ignore")))])
5231
5232 (define_expand "movsi_const"
5233   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5234         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5235                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5236    (set (match_dup 0)
5237         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5238                 (const:SI (unspec:SI [(match_dup 1)
5239                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5240   "TARGET_SHMEDIA && reload_completed
5241    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5242   "
5243 {
5244   if (GET_CODE (operands[1]) == LABEL_REF
5245       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5246     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5247   else if (GOTOFF_P (operands[1]))
5248     {
5249       rtx unspec = XEXP (operands[1], 0);
5250
5251       if (! UNSPEC_GOTOFF_P (unspec))
5252         {
5253           unspec = XEXP (unspec, 0);
5254           if (! UNSPEC_GOTOFF_P (unspec))
5255             abort ();
5256         }
5257       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5258           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5259         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5260     }
5261 }")
5262
5263 (define_expand "movsi_const_16bit"
5264   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5265         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5266                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5267   "TARGET_SHMEDIA && flag_pic && reload_completed
5268    && GET_CODE (operands[1]) == SYMBOL_REF"
5269   "")
5270
5271 (define_split
5272   [(set (match_operand:SI 0 "arith_reg_dest" "")
5273         (match_operand:SI 1 "immediate_operand" ""))]
5274   "TARGET_SHMEDIA && reload_completed
5275    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5276   [(const_int 0)]
5277   "
5278 {
5279   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5280
5281   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5282
5283   DONE;
5284 }")
5285
5286 (define_split
5287   [(set (match_operand:SI 0 "register_operand" "")
5288         (match_operand:SI 1 "immediate_operand" ""))]
5289   "TARGET_SHMEDIA && reload_completed
5290    && ((CONST_INT_P (operands[1])
5291         && ! satisfies_constraint_I16 (operands[1]))
5292        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5293   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5294
5295 (define_expand "movsi"
5296   [(set (match_operand:SI 0 "general_movdst_operand" "")
5297         (match_operand:SI 1 "general_movsrc_operand" ""))]
5298   ""
5299   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5300
5301 (define_expand "ic_invalidate_line"
5302   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5303                                 (match_dup 1)] UNSPEC_ICACHE)
5304               (clobber (scratch:SI))])]
5305   "TARGET_HARD_SH4 || TARGET_SH5"
5306   "
5307 {
5308   if (TARGET_SHMEDIA)
5309     {
5310       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5311       DONE;
5312     }
5313   else if (TARGET_SHCOMPACT)
5314     {
5315       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5316       operands[1] = force_reg (Pmode, operands[1]);
5317       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5318       DONE;
5319     }
5320   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5321     {
5322       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5323       DONE;
5324     }
5325   operands[0] = force_reg (Pmode, operands[0]);
5326   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5327                                                                Pmode)));
5328 }")
5329
5330 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5331 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5332 ;; the requirement *1*00 for associative address writes.  The alignment of
5333 ;; %0 implies that its least significant bit is cleared,
5334 ;; thus we clear the V bit of a matching entry if there is one.
5335 (define_insn "ic_invalidate_line_i"
5336   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5337                      (match_operand:SI 1 "register_operand" "r")]
5338                      UNSPEC_ICACHE)
5339    (clobber (match_scratch:SI 2 "=&r"))]
5340   "TARGET_HARD_SH4"
5341   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5342   [(set_attr "length" "8")
5343    (set_attr "type" "cwb")])
5344
5345 (define_insn "ic_invalidate_line_sh4a"
5346   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5347                     UNSPEC_ICACHE)]
5348   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5349   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5350   [(set_attr "length" "16")
5351    (set_attr "type" "cwb")])
5352
5353 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5354 ;; an add in the code that calculates the address.
5355 (define_insn "ic_invalidate_line_media"
5356   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5357                     UNSPEC_ICACHE)]
5358   "TARGET_SHMEDIA"
5359   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5360   [(set_attr "length" "16")
5361    (set_attr "type" "invalidate_line_media")])
5362
5363 (define_insn "ic_invalidate_line_compact"
5364   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5365                      (match_operand:SI 1 "register_operand" "r")]
5366                     UNSPEC_ICACHE)
5367    (clobber (reg:SI PR_REG))]
5368   "TARGET_SHCOMPACT"
5369   "jsr @%1%#"
5370   [(set_attr "type" "sfunc")
5371    (set_attr "needs_delay_slot" "yes")])
5372
5373 (define_expand "initialize_trampoline"
5374   [(match_operand:SI 0 "" "")
5375    (match_operand:SI 1 "" "")
5376    (match_operand:SI 2 "" "")]
5377   "TARGET_SHCOMPACT"
5378   "
5379 {
5380   rtx sfun, tramp;
5381
5382   tramp = force_reg (Pmode, operands[0]);
5383   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5384                                             SFUNC_STATIC));
5385   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5386   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5387
5388   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5389   DONE;
5390 }")
5391
5392 (define_insn "initialize_trampoline_compact"
5393   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5394                      (match_operand:SI 1 "register_operand" "r")
5395                      (reg:SI R2_REG) (reg:SI R3_REG)]
5396                     UNSPEC_INIT_TRAMP)
5397
5398    (clobber (reg:SI PR_REG))]
5399   "TARGET_SHCOMPACT"
5400   "jsr @%1%#"
5401   [(set_attr "type" "sfunc")
5402    (set_attr "needs_delay_slot" "yes")])
5403
5404 (define_insn "movqi_i"
5405   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5406         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5407   "TARGET_SH1
5408    && (arith_reg_operand (operands[0], QImode)
5409        || arith_reg_operand (operands[1], QImode))"
5410   "@
5411         mov     %1,%0
5412         mov     %1,%0
5413         mov.b   %1,%0
5414         mov.b   %1,%0
5415         movt    %0
5416         sts     %1,%0
5417         lds     %1,%0"
5418  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5419   (set_attr_alternative "length"
5420      [(const_int 2)
5421       (const_int 2)
5422       (if_then_else
5423         (match_test "TARGET_SH2A")
5424         (const_int 4) (const_int 2))
5425       (if_then_else
5426         (match_test "TARGET_SH2A")
5427         (const_int 4) (const_int 2))
5428       (const_int 2)
5429       (const_int 2)
5430       (const_int 2)])])
5431
5432 (define_insn "*movqi_media"
5433   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5434         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5435   "TARGET_SHMEDIA
5436    && (arith_reg_operand (operands[0], QImode)
5437        || extend_reg_or_0_operand (operands[1], QImode))"
5438   "@
5439         add.l   %1, r63, %0
5440         movi    %1, %0
5441         ld%M1.ub        %m1, %0
5442         st%M0.b %m0, %N1"
5443   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5444    (set (attr "highpart")
5445         (cond [(match_test "sh_contains_memref_p (insn)")
5446                (const_string "user")]
5447               (const_string "ignore")))])
5448
5449 (define_expand "movqi"
5450   [(set (match_operand:QI 0 "general_operand" "")
5451         (match_operand:QI 1 "general_operand"  ""))]
5452   ""
5453   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5454
5455 (define_expand "reload_inqi"
5456   [(set (match_operand:SI 2 "" "=&r")
5457         (match_operand:QI 1 "inqhi_operand" ""))
5458    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5459         (truncate:QI (match_dup 3)))]
5460   "TARGET_SHMEDIA"
5461   "
5462 {
5463   rtx inner = XEXP (operands[1], 0);
5464   int regno = REGNO (inner);
5465
5466   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5467   operands[1] = gen_rtx_REG (SImode, regno);
5468   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5469 }")
5470
5471 /* When storing r0, we have to avoid reg+reg addressing.  */
5472 (define_insn "movhi_i"
5473   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5474         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5475   "TARGET_SH1
5476    && (arith_reg_operand (operands[0], HImode)
5477        || arith_reg_operand (operands[1], HImode))
5478    && (!MEM_P (operands[0])
5479        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5480        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5481        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5482   "@
5483         mov.w   %1,%0
5484         mov     %1,%0
5485         mov.w   %1,%0
5486         movt    %0
5487         mov.w   %1,%0
5488         sts     %1,%0
5489         lds     %1,%0
5490         fake    %1,%0"
5491   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5492
5493 (define_insn "*movhi_media"
5494   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5495         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5496   "TARGET_SHMEDIA
5497    && (arith_reg_operand (operands[0], HImode)
5498        || arith_reg_or_0_operand (operands[1], HImode))"
5499   "@
5500         add.l   %1, r63, %0
5501         movi    %1, %0
5502         #
5503         ld%M1.w %m1, %0
5504         st%M0.w %m0, %N1"
5505   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5506    (set (attr "highpart")
5507         (cond [(match_test "sh_contains_memref_p (insn)")
5508                (const_string "user")]
5509               (const_string "ignore")))])
5510
5511 (define_split
5512   [(set (match_operand:HI 0 "register_operand" "")
5513         (match_operand:HI 1 "immediate_operand" ""))]
5514   "TARGET_SHMEDIA && reload_completed
5515    && ! satisfies_constraint_I16 (operands[1])"
5516   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5517
5518 (define_expand "movhi"
5519   [(set (match_operand:HI 0 "general_movdst_operand" "")
5520         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5521   ""
5522   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5523
5524 (define_expand "reload_inhi"
5525   [(set (match_operand:SI 2 "" "=&r")
5526         (match_operand:HI 1 "inqhi_operand" ""))
5527    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5528         (truncate:HI (match_dup 3)))]
5529   "TARGET_SHMEDIA"
5530   "
5531 {
5532   rtx inner = XEXP (operands[1], 0);
5533   int regno = REGNO (inner);
5534
5535   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5536   operands[1] = gen_rtx_REG (SImode, regno);
5537   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5538 }")
5539
5540 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5541 ;; compiled with -m2 -ml -O3 -funroll-loops
5542 (define_insn "*movdi_i"
5543   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5544         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5545   "TARGET_SH1
5546    && (arith_reg_operand (operands[0], DImode)
5547        || arith_reg_operand (operands[1], DImode))"
5548   "* return output_movedouble (insn, operands, DImode);"
5549   [(set_attr "length" "4")
5550    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5551
5552 ;; If the output is a register and the input is memory or a register, we have
5553 ;; to be careful and see which word needs to be loaded first.
5554
5555 (define_split
5556   [(set (match_operand:DI 0 "general_movdst_operand" "")
5557         (match_operand:DI 1 "general_movsrc_operand" ""))]
5558   "TARGET_SH1 && reload_completed"
5559   [(set (match_dup 2) (match_dup 3))
5560    (set (match_dup 4) (match_dup 5))]
5561   "
5562 {
5563   int regno;
5564
5565   if ((MEM_P (operands[0])
5566        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5567       || (MEM_P (operands[1])
5568           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5569     FAIL;
5570
5571   switch (GET_CODE (operands[0]))
5572     {
5573     case REG:
5574       regno = REGNO (operands[0]);
5575       break;
5576     case SUBREG:
5577       regno = subreg_regno (operands[0]);
5578       break;
5579     case MEM:
5580       regno = -1;
5581       break;
5582     default:
5583       gcc_unreachable ();
5584     }
5585
5586   if (regno == -1
5587       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5588     {
5589       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5590       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5591       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5592       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5593     }
5594   else
5595     {
5596       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5597       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5598       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5599       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5600     }
5601
5602   if (operands[2] == 0 || operands[3] == 0
5603       || operands[4] == 0 || operands[5] == 0)
5604     FAIL;
5605 }")
5606
5607 ;; The '?'s in the following constraints may not reflect the time taken
5608 ;; to perform the move. They are there to discourage the use of floating-
5609 ;; point registers for storing integer values.
5610 (define_insn "*movdi_media"
5611   [(set (match_operand:DI 0 "general_movdst_operand"
5612                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5613         (match_operand:DI 1 "general_movsrc_operand"
5614          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5615   "TARGET_SHMEDIA_FPU
5616    && (register_operand (operands[0], DImode)
5617        || sh_register_operand (operands[1], DImode))"
5618   "@
5619         add     %1, r63, %0
5620         movi    %1, %0
5621         #
5622         ld%M1.q %m1, %0
5623         st%M0.q %m0, %N1
5624         fld%M1.d        %m1, %0
5625         fst%M0.d        %m0, %1
5626         fmov.qd %N1, %0
5627         fmov.dq %1, %0
5628         fmov.d  %1, %0
5629         ptabs   %1, %0
5630         gettr   %1, %0
5631         pt      %1, %0"
5632   [(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")
5633    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5634
5635 (define_insn "*movdi_media_nofpu"
5636   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5637         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5638   "TARGET_SHMEDIA
5639    && (register_operand (operands[0], DImode)
5640        || sh_register_operand (operands[1], DImode))"
5641   "@
5642         add     %1, r63, %0
5643         movi    %1, %0
5644         #
5645         ld%M1.q %m1, %0
5646         st%M0.q %m0, %N1
5647         ptabs   %1, %0
5648         gettr   %1, %0
5649         pt      %1, %0"
5650   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5651    (set_attr "length" "4,4,16,4,4,4,4,*")])
5652
5653 (define_insn "*movdi_media_I16"
5654   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5655         (match_operand:DI 1 "const_int_operand" "I16"))]
5656   "TARGET_SHMEDIA && reload_completed"
5657   "movi %1, %0"
5658   [(set_attr "type" "arith_media")
5659    (set_attr "length" "4")])
5660
5661 (define_split
5662   [(set (match_operand:DI 0 "arith_reg_dest" "")
5663         (match_operand:DI 1 "immediate_operand" ""))]
5664   "TARGET_SHMEDIA && reload_completed
5665    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5666   [(set (match_dup 0) (match_dup 1))]
5667   "
5668 {
5669   rtx insn;
5670
5671   if (TARGET_SHMEDIA64)
5672     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5673   else
5674     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5675
5676   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5677
5678   DONE;
5679 }")
5680
5681 (define_expand "movdi_const"
5682   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5683         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5684                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5685    (set (match_dup 0)
5686         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5687                 (const:DI (unspec:DI [(match_dup 1)
5688                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5689    (set (match_dup 0)
5690         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5691                 (const:DI (unspec:DI [(match_dup 1)
5692                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5693    (set (match_dup 0)
5694         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5695                 (const:DI (unspec:DI [(match_dup 1)
5696                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5697   "TARGET_SHMEDIA64 && reload_completed
5698    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5699   "
5700 {
5701   sh_mark_label (operands[1], 4);
5702 }")
5703
5704 (define_expand "movdi_const_32bit"
5705   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5706         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5707                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5708    (set (match_dup 0)
5709         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5710                 (const:DI (unspec:DI [(match_dup 1)
5711                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5712   "TARGET_SHMEDIA32 && reload_completed
5713    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5714   "
5715 {
5716   sh_mark_label (operands[1], 2);
5717 }")
5718
5719 (define_expand "movdi_const_16bit"
5720   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5721         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5722                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5723   "TARGET_SHMEDIA && flag_pic && reload_completed
5724    && GET_CODE (operands[1]) == SYMBOL_REF"
5725   "")
5726
5727 (define_split
5728   [(set (match_operand:DI 0 "ext_dest_operand" "")
5729         (match_operand:DI 1 "immediate_operand" ""))]
5730   "TARGET_SHMEDIA && reload_completed
5731    && CONST_INT_P (operands[1])
5732    && ! satisfies_constraint_I16 (operands[1])"
5733   [(set (match_dup 0) (match_dup 2))
5734    (match_dup 1)]
5735   "
5736 {
5737   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5738   unsigned HOST_WIDE_INT low = val;
5739   unsigned HOST_WIDE_INT high = val;
5740   unsigned HOST_WIDE_INT sign;
5741   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5742
5743   /* Zero-extend the 16 least-significant bits.  */
5744   low &= 0xffff;
5745
5746   /* Arithmetic shift right the word by 16 bits.  */
5747   high >>= 16;
5748   if (GET_CODE (operands[0]) == SUBREG
5749       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5750     {
5751       high &= 0xffff;
5752       high ^= 0x8000;
5753       high -= 0x8000;
5754     }
5755   else
5756     {
5757       sign = 1;
5758       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5759       high ^= sign;
5760       high -= sign;
5761     }
5762   do
5763     {
5764       /* If we can't generate the constant with a two-insn movi / shori
5765          sequence, try some other strategies.  */
5766       if (! CONST_OK_FOR_I16 (high))
5767         {
5768           /* Try constant load / left shift.  We know VAL != 0.  */
5769           val2 = val ^ (val-1);
5770           if (val2 > 0x1ffff)
5771             {
5772               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5773
5774               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5775                   || (! CONST_OK_FOR_I16 (high >> 16)
5776                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5777                 {
5778                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5779                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5780                                                    GEN_INT (trailing_zeroes));
5781                   break;
5782                 }
5783             }
5784           /* Try constant load / right shift.  */
5785           val2 = (val >> 15) + 1;
5786           if (val2 == (val2 & -val2))
5787             {
5788               int shift = 49 - exact_log2 (val2);
5789
5790               val2 = trunc_int_for_mode (val << shift, DImode);
5791               if (CONST_OK_FOR_I16 (val2))
5792                 {
5793                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5794                                                    GEN_INT (shift));
5795                   break;
5796                 }
5797             }
5798           /* Try mperm.w .  */
5799           val2 = val & 0xffff;
5800           if ((val >> 16 & 0xffff) == val2
5801               && (val >> 32 & 0xffff) == val2
5802               && (val >> 48 & 0xffff) == val2)
5803             {
5804               val2 = (HOST_WIDE_INT) val >> 48;
5805               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5806               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5807               break;
5808             }
5809           /* Try movi / mshflo.l  */
5810           val2 = (HOST_WIDE_INT) val >> 32;
5811           if (val2 == ((unsigned HOST_WIDE_INT)
5812                         trunc_int_for_mode (val, SImode)))
5813             {
5814               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5815                                              operands[0]);
5816               break;
5817             }
5818           /* Try movi / mshflo.l w/ r63.  */
5819           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5820           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5821             {
5822               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5823                                              const0_rtx);
5824               break;
5825             }
5826         }
5827       val2 = high;
5828       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5829     }
5830   while (0);
5831   operands[2] = GEN_INT (val2);
5832 }")
5833
5834 (define_split
5835   [(set (match_operand:DI 0 "ext_dest_operand" "")
5836         (match_operand:DI 1 "immediate_operand" ""))]
5837   "TARGET_SHMEDIA && reload_completed
5838    && GET_CODE (operands[1]) == CONST_DOUBLE"
5839   [(set (match_dup 0) (match_dup 2))
5840   (set (match_dup 0)
5841        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5842   "
5843 {
5844   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5845   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5846   unsigned HOST_WIDE_INT val = low;
5847   unsigned HOST_WIDE_INT sign;
5848
5849   /* Zero-extend the 16 least-significant bits.  */
5850   val &= 0xffff;
5851   operands[1] = GEN_INT (val);
5852
5853   /* Arithmetic shift right the double-word by 16 bits.  */
5854   low >>= 16;
5855   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5856   high >>= 16;
5857   sign = 1;
5858   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5859   high ^= sign;
5860   high -= sign;
5861
5862   /* This will only be true if high is a sign-extension of low, i.e.,
5863      it must be either 0 or (unsigned)-1, and be zero iff the
5864      most-significant bit of low is set.  */
5865   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5866     operands[2] = GEN_INT (low);
5867   else
5868     operands[2] = immed_double_const (low, high, DImode);
5869 }")
5870
5871 (define_insn "shori_media"
5872   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5873         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5874                            (const_int 16))
5875                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5876   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5877   "@
5878         shori   %u2, %0
5879         #"
5880   [(set_attr "type" "arith_media,*")])
5881
5882 (define_insn "*shori_media_si"
5883   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5884         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5885                            (const_int 16))
5886                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5887   "TARGET_SHMEDIA"
5888   "shori        %u2, %0")
5889
5890 (define_expand "movdi"
5891   [(set (match_operand:DI 0 "general_movdst_operand" "")
5892         (match_operand:DI 1 "general_movsrc_operand" ""))]
5893   ""
5894   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5895
5896 (define_insn "movdf_media"
5897   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5898         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5899   "TARGET_SHMEDIA_FPU
5900    && (register_operand (operands[0], DFmode)
5901        || sh_register_operand (operands[1], DFmode))"
5902   "@
5903         fmov.d  %1, %0
5904         fmov.qd %N1, %0
5905         fmov.dq %1, %0
5906         add     %1, r63, %0
5907         #
5908         fld%M1.d        %m1, %0
5909         fst%M0.d        %m0, %1
5910         ld%M1.q %m1, %0
5911         st%M0.q %m0, %N1"
5912   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5913
5914 (define_insn "movdf_media_nofpu"
5915   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5916         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5917   "TARGET_SHMEDIA
5918    && (register_operand (operands[0], DFmode)
5919        || sh_register_operand (operands[1], DFmode))"
5920   "@
5921         add     %1, r63, %0
5922         #
5923         ld%M1.q %m1, %0
5924         st%M0.q %m0, %N1"
5925   [(set_attr "type" "arith_media,*,load_media,store_media")])
5926
5927 (define_split
5928   [(set (match_operand:DF 0 "arith_reg_dest" "")
5929         (match_operand:DF 1 "immediate_operand" ""))]
5930   "TARGET_SHMEDIA && reload_completed"
5931   [(set (match_dup 3) (match_dup 2))]
5932   "
5933 {
5934   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5935   long values[2];
5936   REAL_VALUE_TYPE value;
5937
5938   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5939   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5940
5941   if (HOST_BITS_PER_WIDE_INT >= 64)
5942     operands[2] = immed_double_const ((unsigned long) values[endian]
5943                                       | ((HOST_WIDE_INT) values[1 - endian]
5944                                          << 32), 0, DImode);
5945   else
5946     {
5947       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5948       operands[2] = immed_double_const (values[endian], values[1 - endian],
5949                                         DImode);
5950     }
5951
5952   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5953 }")
5954
5955 ;; ??? This should be a define expand.
5956
5957 (define_insn "movdf_k"
5958   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5959         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5960   "TARGET_SH1
5961    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5962        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5963        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5964        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5965    && (arith_reg_operand (operands[0], DFmode)
5966        || arith_reg_operand (operands[1], DFmode))"
5967   "* return output_movedouble (insn, operands, DFmode);"
5968   [(set_attr "length" "4")
5969    (set_attr "type" "move,pcload,load,store")])
5970
5971 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5972 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5973 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5974 ;; the d/m/c/X alternative, which is split later into single-precision
5975 ;; instructions.  And when not optimizing, no splits are done before fixing
5976 ;; up pcloads, so we need usable length information for that.
5977 (define_insn "movdf_i4"
5978   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5979         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5980    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5981    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5982   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5983    && (arith_reg_operand (operands[0], DFmode)
5984        || arith_reg_operand (operands[1], DFmode))"
5985   {
5986     switch (which_alternative)
5987     {
5988     case 0:
5989       if (TARGET_FMOVD)
5990         return "fmov    %1,%0";
5991       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5992         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5993       else
5994         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5995     case 3:
5996     case 4:
5997       return "fmov.d    %1,%0";
5998     default:
5999       return "#";
6000     }
6001   }
6002   [(set_attr_alternative "length"
6003      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6004       (const_int 4)
6005       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6006       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6007       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6008       (const_int 4)
6009       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6010       ;; We can't use 4-byte push/pop on SHcompact, so we have to
6011       ;; increment or decrement r15 explicitly.
6012       (if_then_else
6013        (match_test "TARGET_SHCOMPACT")
6014        (const_int 10) (const_int 8))
6015       (if_then_else
6016        (match_test "TARGET_SHCOMPACT")
6017        (const_int 10) (const_int 8))])
6018    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6019    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6020    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6021                                            (const_string "double")
6022                                            (const_string "none")))])
6023
6024 ;; Moving DFmode between fp/general registers through memory
6025 ;; (the top of the stack) is faster than moving through fpul even for
6026 ;; little endian.  Because the type of an instruction is important for its
6027 ;; scheduling,  it is beneficial to split these operations, rather than
6028 ;; emitting them in one single chunk, even if this will expose a stack
6029 ;; use that will prevent scheduling of other stack accesses beyond this
6030 ;; instruction.
6031 (define_split
6032   [(set (match_operand:DF 0 "register_operand" "")
6033         (match_operand:DF 1 "register_operand" ""))
6034    (use (match_operand:PSI 2 "fpscr_operand" ""))
6035    (clobber (match_scratch:SI 3 "=X"))]
6036   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6037    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6038   [(const_int 0)]
6039   "
6040 {
6041   rtx insn, tos;
6042
6043   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6044     {
6045       emit_move_insn (stack_pointer_rtx,
6046                       plus_constant (stack_pointer_rtx, -8));
6047       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6048     }
6049   else
6050     tos = gen_tmp_stack_mem (DFmode,
6051                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6052   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6053   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6054     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6055   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6056     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6057   else
6058     tos = gen_tmp_stack_mem (DFmode,
6059                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6060   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6061   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6062     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6063   else
6064     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6065   DONE;
6066 }")
6067
6068 ;; local-alloc sometimes allocates scratch registers even when not required,
6069 ;; so we must be prepared to handle these.
6070
6071 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6072 (define_split
6073   [(set (match_operand:DF 0 "general_movdst_operand" "")
6074         (match_operand:DF 1 "general_movsrc_operand"  ""))
6075    (use (match_operand:PSI 2 "fpscr_operand" ""))
6076    (clobber (match_scratch:SI 3 ""))]
6077   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6078    && reload_completed
6079    && true_regnum (operands[0]) < 16
6080    && true_regnum (operands[1]) < 16"
6081   [(set (match_dup 0) (match_dup 1))]
6082   "
6083 {
6084   /* If this was a reg <-> mem operation with base + index reg addressing,
6085      we have to handle this in a special way.  */
6086   rtx mem = operands[0];
6087   int store_p = 1;
6088   if (! memory_operand (mem, DFmode))
6089     {
6090       mem = operands[1];
6091       store_p = 0;
6092     }
6093   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6094     mem = SUBREG_REG (mem);
6095   if (MEM_P (mem))
6096     {
6097       rtx addr = XEXP (mem, 0);
6098       if (GET_CODE (addr) == PLUS
6099           && REG_P (XEXP (addr, 0))
6100           && REG_P (XEXP (addr, 1)))
6101         {
6102           int offset;
6103           rtx reg0 = gen_rtx_REG (Pmode, 0);
6104           rtx regop = operands[store_p], word0 ,word1;
6105
6106           if (GET_CODE (regop) == SUBREG)
6107             alter_subreg (&regop);
6108           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6109             offset = 2;
6110           else
6111             offset = 4;
6112           mem = copy_rtx (mem);
6113           PUT_MODE (mem, SImode);
6114           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6115           alter_subreg (&word0);
6116           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6117           alter_subreg (&word1);
6118           if (store_p || ! refers_to_regno_p (REGNO (word0),
6119                                               REGNO (word0) + 1, addr, 0))
6120             {
6121               emit_insn (store_p
6122                          ? gen_movsi_ie (mem, word0)
6123                          : gen_movsi_ie (word0, mem));
6124               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6125               mem = copy_rtx (mem);
6126               emit_insn (store_p
6127                          ? gen_movsi_ie (mem, word1)
6128                          : gen_movsi_ie (word1, mem));
6129               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6130             }
6131           else
6132             {
6133               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6134               emit_insn (gen_movsi_ie (word1, mem));
6135               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6136               mem = copy_rtx (mem);
6137               emit_insn (gen_movsi_ie (word0, mem));
6138             }
6139           DONE;
6140         }
6141     }
6142 }")
6143
6144 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6145 (define_split
6146   [(set (match_operand:DF 0 "register_operand" "")
6147         (match_operand:DF 1 "memory_operand"  ""))
6148    (use (match_operand:PSI 2 "fpscr_operand" ""))
6149    (clobber (reg:SI R0_REG))]
6150   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6151   [(parallel [(set (match_dup 0) (match_dup 1))
6152               (use (match_dup 2))
6153               (clobber (scratch:SI))])]
6154   "")
6155
6156 (define_expand "reload_indf__frn"
6157   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6158                    (match_operand:DF 1 "immediate_operand" "FQ"))
6159               (use (reg:PSI FPSCR_REG))
6160               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6161   "TARGET_SH1"
6162   "")
6163
6164 (define_expand "reload_outdf__RnFRm"
6165   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6166                    (match_operand:DF 1 "register_operand" "af,r"))
6167               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6168   "TARGET_SH1"
6169   "")
6170
6171 ;; Simplify no-op moves.
6172 (define_split
6173   [(set (match_operand:SF 0 "register_operand" "")
6174         (match_operand:SF 1 "register_operand" ""))
6175    (use (match_operand:PSI 2 "fpscr_operand" ""))
6176    (clobber (match_scratch:SI 3 ""))]
6177   "TARGET_SH2E && reload_completed
6178    && true_regnum (operands[0]) == true_regnum (operands[1])"
6179   [(set (match_dup 0) (match_dup 0))]
6180   "")
6181
6182 ;; fmovd substitute post-reload splits
6183 (define_split
6184   [(set (match_operand:DF 0 "register_operand" "")
6185         (match_operand:DF 1 "register_operand" ""))
6186    (use (match_operand:PSI 2 "fpscr_operand" ""))
6187    (clobber (match_scratch:SI 3 ""))]
6188   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6189    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6190    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6191   [(const_int 0)]
6192   "
6193 {
6194   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6195   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6196                            gen_rtx_REG (SFmode, src), operands[2]));
6197   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6198                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6199   DONE;
6200 }")
6201
6202 (define_split
6203   [(set (match_operand:DF 0 "register_operand" "")
6204         (mem:DF (match_operand:SI 1 "register_operand" "")))
6205    (use (match_operand:PSI 2 "fpscr_operand" ""))
6206    (clobber (match_scratch:SI 3 ""))]
6207   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6208    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6209    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6210   [(const_int 0)]
6211   "
6212 {
6213   int regno = true_regnum (operands[0]);
6214   rtx insn;
6215   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6216   rtx mem2
6217     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6218   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6219                                            regno + !! TARGET_LITTLE_ENDIAN),
6220                                   mem2, operands[2]));
6221   add_reg_note (insn, REG_INC, operands[1]);
6222   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6223                                                regno + ! TARGET_LITTLE_ENDIAN),
6224                                   change_address (mem, SFmode, NULL_RTX),
6225                                   operands[2]));
6226   DONE;
6227 }")
6228
6229 (define_split
6230   [(set (match_operand:DF 0 "register_operand" "")
6231         (match_operand:DF 1 "memory_operand" ""))
6232    (use (match_operand:PSI 2 "fpscr_operand" ""))
6233    (clobber (match_scratch:SI 3 ""))]
6234   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6235    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6236   [(const_int 0)]
6237 {
6238   int regno = true_regnum (operands[0]);
6239   rtx addr, insn;
6240   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6241   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6242   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6243
6244   operands[1] = copy_rtx (mem2);
6245   addr = XEXP (mem2, 0);
6246
6247   switch (GET_CODE (addr))
6248     {
6249     case REG:
6250       /* This is complicated.  If the register is an arithmetic register
6251          we can just fall through to the REG+DISP case below.  Otherwise
6252          we have to use a combination of POST_INC and REG addressing...  */
6253       if (! arith_reg_operand (operands[1], SFmode))
6254         {
6255           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6256           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6257           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6258           
6259           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6260
6261           /* If we have modified the stack pointer, the value that we have
6262              read with post-increment might be modified by an interrupt,
6263              so write it back.  */
6264           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6265             emit_insn (gen_push_e (reg0));
6266           else
6267             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6268           break;
6269         }
6270       /* Fall through.  */
6271          
6272     case PLUS:
6273       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6274       operands[1] = copy_rtx (operands[1]);
6275       XEXP (operands[1], 0) = plus_constant (addr, 4);
6276       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6277       break;
6278       
6279     case POST_INC:
6280       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6281       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6282     
6283       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6284       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6285       break;
6286
6287     default:
6288       debug_rtx (addr);
6289       gcc_unreachable ();
6290     }
6291
6292   DONE;
6293 })
6294
6295 (define_split
6296   [(set (match_operand:DF 0 "memory_operand" "")
6297         (match_operand:DF 1 "register_operand" ""))
6298    (use (match_operand:PSI 2 "fpscr_operand" ""))
6299    (clobber (match_scratch:SI 3 ""))]
6300   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6301    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6302   [(const_int 0)]
6303 {
6304   int regno = true_regnum (operands[1]);
6305   rtx insn, addr;
6306   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6307   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6308
6309   operands[0] = copy_rtx (operands[0]);
6310   PUT_MODE (operands[0], SFmode);
6311   addr = XEXP (operands[0], 0);
6312
6313   switch (GET_CODE (addr))
6314     {
6315     case REG:
6316       /* This is complicated.  If the register is an arithmetic register
6317          we can just fall through to the REG+DISP case below.  Otherwise
6318          we have to use a combination of REG and PRE_DEC addressing...  */
6319       if (! arith_reg_operand (operands[0], SFmode))
6320         {
6321           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6322           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6323
6324           operands[0] = copy_rtx (operands[0]);
6325           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6326           
6327           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6328           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6329           break;
6330         }
6331       /* Fall through.  */
6332       
6333     case PLUS:
6334       /* Since REG+DISP addressing has already been decided upon by gcc
6335          we can rely upon it having chosen an arithmetic register as the
6336          register component of the address.  Just emit the lower numbered
6337          register first, to the lower address, then the higher numbered
6338          register to the higher address.  */
6339       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6340
6341       operands[0] = copy_rtx (operands[0]);
6342       XEXP (operands[0], 0) = plus_constant (addr, 4);
6343
6344       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6345       break;
6346       
6347     case PRE_DEC:
6348       /* This is easy.  Output the word to go to the higher address
6349          first (ie the word in the higher numbered register) then the
6350          word to go to the lower address.  */
6351
6352       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6353       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6354
6355       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6356       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6357       break;
6358       
6359     default:
6360       /* FAIL; */
6361       debug_rtx (addr);
6362       gcc_unreachable ();
6363     }
6364
6365   DONE;
6366 })
6367
6368 ;; If the output is a register and the input is memory or a register, we have
6369 ;; to be careful and see which word needs to be loaded first.
6370
6371 (define_split
6372   [(set (match_operand:DF 0 "general_movdst_operand" "")
6373         (match_operand:DF 1 "general_movsrc_operand" ""))]
6374   "TARGET_SH1 && reload_completed"
6375   [(set (match_dup 2) (match_dup 3))
6376    (set (match_dup 4) (match_dup 5))]
6377   "
6378 {
6379   int regno;
6380
6381   if ((MEM_P (operands[0])
6382        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6383       || (MEM_P (operands[1])
6384           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6385     FAIL;
6386
6387   switch (GET_CODE (operands[0]))
6388     {
6389     case REG:
6390       regno = REGNO (operands[0]);
6391       break;
6392     case SUBREG:
6393       regno = subreg_regno (operands[0]);
6394       break;
6395     case MEM:
6396       regno = -1;
6397       break;
6398     default:
6399       gcc_unreachable ();
6400     }
6401
6402   if (regno == -1
6403       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6404     {
6405       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6406       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6407       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6408       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6409     }
6410   else
6411     {
6412       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6413       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6414       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6415       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6416     }
6417
6418   if (operands[2] == 0 || operands[3] == 0
6419       || operands[4] == 0 || operands[5] == 0)
6420     FAIL;
6421 }")
6422
6423 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6424 ;; used only once, let combine add in the index again.
6425
6426 (define_split
6427   [(set (match_operand:SI 0 "register_operand" "")
6428         (match_operand:SI 1 "" ""))
6429    (clobber (match_operand 2 "register_operand" ""))]
6430   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6431    && ALLOW_INDEXED_ADDRESS"
6432   [(use (reg:SI R0_REG))]
6433   "
6434 {
6435   rtx addr, reg, const_int;
6436
6437   if (!MEM_P (operands[1]))
6438     FAIL;
6439   addr = XEXP (operands[1], 0);
6440   if (GET_CODE (addr) != PLUS)
6441     FAIL;
6442   reg = XEXP (addr, 0);
6443   const_int = XEXP (addr, 1);
6444   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6445          && CONST_INT_P (const_int)))
6446     FAIL;
6447   emit_move_insn (operands[2], const_int);
6448   emit_move_insn (operands[0],
6449                   change_address (operands[1], VOIDmode,
6450                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6451   DONE;
6452 }")
6453
6454 (define_split
6455   [(set (match_operand:SI 1 "" "")
6456         (match_operand:SI 0 "register_operand" ""))
6457    (clobber (match_operand 2 "register_operand" ""))]
6458   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6459    && ALLOW_INDEXED_ADDRESS"
6460   [(use (reg:SI R0_REG))]
6461   "
6462 {
6463   rtx addr, reg, const_int;
6464
6465   if (!MEM_P (operands[1]))
6466     FAIL;
6467   addr = XEXP (operands[1], 0);
6468   if (GET_CODE (addr) != PLUS)
6469     FAIL;
6470   reg = XEXP (addr, 0);
6471   const_int = XEXP (addr, 1);
6472   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6473          && CONST_INT_P (const_int)))
6474     FAIL;
6475   emit_move_insn (operands[2], const_int);
6476   emit_move_insn (change_address (operands[1], VOIDmode,
6477                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6478                   operands[0]);
6479   DONE;
6480 }")
6481
6482 (define_expand "movdf"
6483   [(set (match_operand:DF 0 "general_movdst_operand" "")
6484         (match_operand:DF 1 "general_movsrc_operand" ""))]
6485   ""
6486   "
6487 {
6488   if (prepare_move_operands (operands, DFmode)) DONE;
6489   if (TARGET_SHMEDIA)
6490     {
6491       if (TARGET_SHMEDIA_FPU)
6492         emit_insn (gen_movdf_media (operands[0], operands[1]));
6493       else
6494         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6495       DONE;
6496     }
6497   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6498     {
6499       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6500       DONE;
6501     }
6502 }")
6503
6504 ;;This is incompatible with the way gcc uses subregs.
6505 ;;(define_insn "movv2sf_i"
6506 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6507 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6508 ;;  "TARGET_SHMEDIA_FPU
6509 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6510 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6511 ;;  "@
6512 ;;      #
6513 ;;      fld%M1.p        %m1, %0
6514 ;;      fst%M0.p        %m0, %1"
6515 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6516
6517 (define_insn_and_split "movv2sf_i"
6518   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6519         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6520   "TARGET_SHMEDIA_FPU"
6521   "#"
6522   "TARGET_SHMEDIA_FPU && reload_completed"
6523   [(set (match_dup 0) (match_dup 1))]
6524   "
6525 {
6526   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6527   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6528 }")
6529
6530 (define_expand "movv2sf"
6531   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6532         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6533   "TARGET_SHMEDIA_FPU"
6534   "
6535 {
6536   if (prepare_move_operands (operands, V2SFmode))
6537     DONE;
6538 }")
6539
6540 (define_expand "addv2sf3"
6541   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6542    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6543    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6544   "TARGET_SHMEDIA_FPU"
6545   "
6546 {
6547   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6548   DONE;
6549 }")
6550
6551 (define_expand "subv2sf3"
6552   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6553    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6554    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6555   "TARGET_SHMEDIA_FPU"
6556   "
6557 {
6558   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6559   DONE;
6560 }")
6561
6562 (define_expand "mulv2sf3"
6563   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6564    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6565    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6566   "TARGET_SHMEDIA_FPU"
6567   "
6568 {
6569   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6570   DONE;
6571 }")
6572
6573 (define_expand "divv2sf3"
6574   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6575    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6576    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6577   "TARGET_SHMEDIA_FPU"
6578   "
6579 {
6580   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6581   DONE;
6582 }")
6583
6584 (define_insn_and_split "*movv4sf_i"
6585   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6586         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6587   "TARGET_SHMEDIA_FPU"
6588   "#"
6589   "&& reload_completed"
6590   [(const_int 0)]
6591   "
6592 {
6593   int i;
6594
6595   for (i = 0; i < 4/2; i++)
6596     {
6597       rtx x, y;
6598
6599       if (MEM_P (operands[0]))
6600         x = adjust_address (operands[0], V2SFmode,
6601                             i * GET_MODE_SIZE (V2SFmode));
6602       else
6603         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6604
6605       if (MEM_P (operands[1]))
6606         y = adjust_address (operands[1], V2SFmode,
6607                             i * GET_MODE_SIZE (V2SFmode));
6608       else
6609         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6610
6611       emit_insn (gen_movv2sf_i (x, y));
6612     }
6613
6614   DONE;
6615 }"
6616   [(set_attr "length" "8")])
6617
6618 (define_expand "movv4sf"
6619   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6620         (match_operand:V4SF 1 "general_operand" ""))]
6621   "TARGET_SHMEDIA_FPU"
6622   "
6623 {
6624   if (prepare_move_operands (operands, V4SFmode))
6625     DONE;
6626 }")
6627
6628 (define_insn_and_split "*movv16sf_i"
6629   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6630         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6631   "TARGET_SHMEDIA_FPU"
6632   "#"
6633   "&& reload_completed"
6634   [(const_int 0)]
6635   "
6636 {
6637   int i;
6638
6639   for (i = 0; i < 16/2; i++)
6640     {
6641       rtx x,y;
6642
6643       if (MEM_P (operands[0]))
6644         x = adjust_address (operands[0], V2SFmode,
6645                             i * GET_MODE_SIZE (V2SFmode));
6646       else
6647         {
6648           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6649           alter_subreg (&x);
6650         }
6651
6652       if (MEM_P (operands[1]))
6653         y = adjust_address (operands[1], V2SFmode,
6654                             i * GET_MODE_SIZE (V2SFmode));
6655       else
6656         {
6657           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6658           alter_subreg (&y);
6659         }
6660
6661       emit_insn (gen_movv2sf_i (x, y));
6662     }
6663
6664   DONE;
6665 }"
6666   [(set_attr "length" "32")])
6667
6668 (define_expand "movv16sf"
6669   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6670         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6671   "TARGET_SHMEDIA_FPU"
6672   "
6673 {
6674   if (prepare_move_operands (operands, V16SFmode))
6675     DONE;
6676 }")
6677
6678 (define_insn "movsf_media"
6679   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6680         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6681   "TARGET_SHMEDIA_FPU
6682    && (register_operand (operands[0], SFmode)
6683        || sh_register_operand (operands[1], SFmode))"
6684   "@
6685         fmov.s  %1, %0
6686         fmov.ls %N1, %0
6687         fmov.sl %1, %0
6688         add.l   %1, r63, %0
6689         #
6690         fld%M1.s        %m1, %0
6691         fst%M0.s        %m0, %1
6692         ld%M1.l %m1, %0
6693         st%M0.l %m0, %N1"
6694   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6695    (set (attr "highpart")
6696         (cond [(match_test "sh_contains_memref_p (insn)")
6697                (const_string "user")]
6698               (const_string "ignore")))])
6699
6700 (define_insn "movsf_media_nofpu"
6701   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6702         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6703   "TARGET_SHMEDIA
6704    && (register_operand (operands[0], SFmode)
6705        || sh_register_operand (operands[1], SFmode))"
6706   "@
6707         add.l   %1, r63, %0
6708         #
6709         ld%M1.l %m1, %0
6710         st%M0.l %m0, %N1"
6711   [(set_attr "type" "arith_media,*,load_media,store_media")
6712    (set (attr "highpart")
6713         (cond [(match_test "sh_contains_memref_p (insn)")
6714                (const_string "user")]
6715               (const_string "ignore")))])
6716
6717 (define_split
6718   [(set (match_operand:SF 0 "arith_reg_dest" "")
6719         (match_operand:SF 1 "immediate_operand" ""))]
6720   "TARGET_SHMEDIA && reload_completed
6721    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6722   [(set (match_dup 3) (match_dup 2))]
6723   "
6724 {
6725   long values;
6726   REAL_VALUE_TYPE value;
6727
6728   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6729   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6730   operands[2] = GEN_INT (values);
6731
6732   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6733 }")
6734
6735 (define_insn "movsf_i"
6736   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6737         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6738   "TARGET_SH1
6739    && (! TARGET_SH2E
6740        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6741        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6742        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6743    && (arith_reg_operand (operands[0], SFmode)
6744        || arith_reg_operand (operands[1], SFmode))"
6745   "@
6746         mov     %1,%0
6747         mov     #0,%0
6748         mov.l   %1,%0
6749         mov.l   %1,%0
6750         mov.l   %1,%0
6751         lds     %1,%0
6752         sts     %1,%0"
6753   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6754
6755 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6756 ;; update_flow_info would not know where to put REG_EQUAL notes
6757 ;; when the destination changes mode.
6758 (define_insn "movsf_ie"
6759   [(set (match_operand:SF 0 "general_movdst_operand"
6760          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6761         (match_operand:SF 1 "general_movsrc_operand"
6762           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6763    (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"))
6764    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6765
6766   "TARGET_SH2E
6767    && (arith_reg_operand (operands[0], SFmode)
6768        || arith_reg_operand (operands[1], SFmode)
6769        || arith_reg_operand (operands[3], SImode)
6770        || (fpul_operand (operands[0], SFmode)
6771            && memory_operand (operands[1], SFmode)
6772            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6773        || (fpul_operand (operands[1], SFmode)
6774            && memory_operand (operands[0], SFmode)
6775            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6776   "@
6777         fmov    %1,%0
6778         mov     %1,%0
6779         fldi0   %0
6780         fldi1   %0
6781         #
6782         fmov.s  %1,%0
6783         fmov.s  %1,%0
6784         mov.l   %1,%0
6785         mov.l   %1,%0
6786         mov.l   %1,%0
6787         fsts    fpul,%0
6788         flds    %1,fpul
6789         lds.l   %1,%0
6790         #
6791         sts     %1,%0
6792         lds     %1,%0
6793         sts.l   %1,%0
6794         lds.l   %1,%0
6795         ! move optimized away"
6796   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6797    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6798    (set_attr_alternative "length"
6799      [(const_int 2)
6800       (const_int 2)
6801       (const_int 2)
6802       (const_int 2)
6803       (const_int 4)
6804       (if_then_else
6805         (match_test "TARGET_SH2A")
6806         (const_int 4) (const_int 2))
6807       (if_then_else
6808         (match_test "TARGET_SH2A")
6809         (const_int 4) (const_int 2))
6810       (const_int 2)
6811       (if_then_else
6812         (match_test "TARGET_SH2A")
6813         (const_int 4) (const_int 2))
6814       (if_then_else
6815         (match_test "TARGET_SH2A")
6816         (const_int 4) (const_int 2))
6817       (const_int 2)
6818       (const_int 2)
6819       (const_int 2)
6820       (const_int 4)
6821       (const_int 2)
6822       (const_int 2)
6823       (const_int 2)
6824       (const_int 2)
6825       (const_int 0)])
6826    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6827                                            (const_string "single")
6828                                            (const_string "single")))])
6829
6830 (define_split
6831   [(set (match_operand:SF 0 "register_operand" "")
6832         (match_operand:SF 1 "register_operand" ""))
6833    (use (match_operand:PSI 2 "fpscr_operand" ""))
6834    (clobber (reg:SI FPUL_REG))]
6835   "TARGET_SH1"
6836   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6837               (use (match_dup 2))
6838               (clobber (scratch:SI))])
6839    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6840               (use (match_dup 2))
6841               (clobber (scratch:SI))])]
6842   "")
6843
6844 (define_expand "movsf"
6845   [(set (match_operand:SF 0 "general_movdst_operand" "")
6846         (match_operand:SF 1 "general_movsrc_operand" ""))]
6847   ""
6848   "
6849 {
6850   if (prepare_move_operands (operands, SFmode))
6851     DONE;
6852   if (TARGET_SHMEDIA)
6853     {
6854       if (TARGET_SHMEDIA_FPU)
6855         emit_insn (gen_movsf_media (operands[0], operands[1]));
6856       else
6857         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6858       DONE;
6859     }
6860   if (TARGET_SH2E)
6861     {
6862       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6863       DONE;
6864     }
6865 }")
6866
6867 (define_insn "mov_nop"
6868   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6869   "TARGET_SH2E"
6870   ""
6871   [(set_attr "length" "0")
6872    (set_attr "type" "nil")])
6873
6874 (define_expand "reload_insf__frn"
6875   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6876                    (match_operand:SF 1 "immediate_operand" "FQ"))
6877               (use (reg:PSI FPSCR_REG))
6878               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6879   "TARGET_SH1"
6880   "")
6881
6882 (define_expand "reload_insi__i_fpul"
6883   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6884                    (match_operand:SI 1 "immediate_operand" "i"))
6885               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6886   "TARGET_SH1"
6887   "")
6888
6889 (define_expand "ptabs"
6890   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6891   "TARGET_SHMEDIA"
6892   "
6893 {
6894   if (!TARGET_PT_FIXED)
6895     {
6896       rtx eq = operands[1];
6897
6898       /* ??? For canonical RTL we really should remove any CONST from EQ
6899          before wrapping it in the AND, and finally wrap the EQ into a
6900          const if is constant.  However, for reload we must expose the
6901          input register or symbolic constant, and we can't have
6902          different insn structures outside of the operands for different
6903          alternatives of the same pattern.  */
6904       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6905                        GEN_INT (3));
6906       operands[1]
6907         = (gen_rtx_IF_THEN_ELSE
6908             (PDImode,
6909              eq,
6910              gen_rtx_MEM (PDImode, operands[1]),
6911              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6912                             PDImode, operands[1])));
6913     }
6914 }")
6915
6916 ;; expanded by ptabs expander.
6917 (define_insn "*extendsipdi_media"
6918   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6919         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6920                                                           "r,Csy")
6921                                       (const_int 3))
6922                               (const_int 3))
6923                           (mem:PDI (match_dup 1))
6924                           (sign_extend:PDI (match_dup 1))))]
6925   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6926   "@
6927         ptabs   %1, %0
6928         pt      %1, %0"
6929   [(set_attr "type"   "ptabs_media,pt_media")
6930    (set_attr "length" "4,*")])
6931
6932 (define_insn "*truncdipdi_media"
6933   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6934         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6935                                                           "r,Csy")
6936                                       (const_int 3))
6937                               (const_int 3))
6938                           (mem:PDI (match_dup 1))
6939                           (truncate:PDI (match_dup 1))))]
6940   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6941   "@
6942         ptabs   %1, %0
6943         pt      %1, %0"
6944   [(set_attr "type"   "ptabs_media,pt_media")
6945    (set_attr "length" "4,*")])
6946
6947 (define_insn "*movsi_y"
6948   [(set (match_operand:SI 0 "register_operand" "=y,y")
6949         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6950    (clobber (match_scratch:SI 2 "=&z,r"))]
6951   "TARGET_SH2E
6952    && (reload_in_progress || reload_completed)"
6953   "#"
6954   [(set_attr "length" "4")
6955    (set_attr "type" "pcload,move")])
6956
6957 (define_split
6958   [(set (match_operand:SI 0 "register_operand" "")
6959         (match_operand:SI 1 "immediate_operand" ""))
6960    (clobber (match_operand:SI 2 "register_operand" ""))]
6961   "TARGET_SH1"
6962   [(set (match_dup 2) (match_dup 1))
6963    (set (match_dup 0) (match_dup 2))]
6964   "")
6965
6966 (define_split
6967   [(set (match_operand:SI 0 "register_operand" "")
6968         (match_operand:SI 1 "memory_operand" ""))
6969    (clobber (reg:SI R0_REG))]
6970   "TARGET_SH1"
6971   [(set (match_dup 0) (match_dup 1))]
6972   "")
6973 \f
6974 ;; ------------------------------------------------------------------------
6975 ;; Define the real conditional branch instructions.
6976 ;; ------------------------------------------------------------------------
6977
6978 (define_insn "branch_true"
6979   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6980                            (label_ref (match_operand 0 "" ""))
6981                            (pc)))]
6982   "TARGET_SH1"
6983   "* return output_branch (1, insn, operands);"
6984   [(set_attr "type" "cbranch")])
6985
6986 (define_insn "branch_false"
6987   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6988                            (label_ref (match_operand 0 "" ""))
6989                            (pc)))]
6990   "TARGET_SH1"
6991   "* return output_branch (0, insn, operands);"
6992   [(set_attr "type" "cbranch")])
6993
6994 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6995 ;; which destination is too far away.
6996 ;; The const_int_operand is distinct for each branch target; it avoids
6997 ;; unwanted matches with redundant_insn.
6998 (define_insn "block_branch_redirect"
6999   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7000   "TARGET_SH1"
7001   ""
7002   [(set_attr "length" "0")])
7003
7004 ;; This one has the additional purpose to record a possible scratch register
7005 ;; for the following branch.
7006 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7007 ;; because the insn then might be deemed dead and deleted.  And we can't
7008 ;; make the use in the jump insn explicit because that would disable
7009 ;; delay slot scheduling from the target.
7010 (define_insn "indirect_jump_scratch"
7011   [(set (match_operand:SI 0 "register_operand" "=r")
7012         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7013    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7014   "TARGET_SH1"
7015   ""
7016   [(set_attr "length" "0")])
7017
7018 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7019 ;; being pulled into the delay slot of a condbranch that has been made to
7020 ;; jump around the unconditional jump because it was out of range.
7021 (define_insn "stuff_delay_slot"
7022   [(set (pc)
7023         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7024                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7025   "TARGET_SH1"
7026   ""
7027   [(set_attr "length" "0")
7028    (set_attr "cond_delay_slot" "yes")])
7029 \f
7030 ;; Conditional branch insns
7031
7032 (define_expand "cbranchint4_media"
7033   [(set (pc)
7034         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7035                        [(match_operand 1 "" "")
7036                         (match_operand 2 "" "")])
7037                       (match_operand 3 "" "")
7038                       (pc)))]
7039   "TARGET_SHMEDIA"
7040   "
7041 {
7042   enum machine_mode mode = GET_MODE (operands[1]);
7043   if (mode == VOIDmode)
7044     mode = GET_MODE (operands[2]);
7045   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7046     {
7047       operands[1] = force_reg (mode, operands[1]);
7048       if (CONSTANT_P (operands[2])
7049           && (! satisfies_constraint_I06 (operands[2])))
7050         operands[2] = force_reg (mode, operands[2]);
7051     }
7052   else
7053     {
7054       if (operands[1] != const0_rtx)
7055         operands[1] = force_reg (mode, operands[1]);
7056       if (operands[2] != const0_rtx)
7057         operands[2] = force_reg (mode, operands[2]);
7058     }
7059   switch (GET_CODE (operands[0]))
7060     {
7061     case LEU:
7062     case LE:
7063     case LTU:
7064     case LT:
7065       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7066                                     VOIDmode, operands[2], operands[1]);
7067       operands[1] = XEXP (operands[0], 0);
7068       operands[2] = XEXP (operands[0], 1);
7069       break;
7070     default:
7071       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7072                                     VOIDmode, operands[1], operands[2]);
7073       break;
7074     }
7075   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7076 }")
7077
7078 (define_expand "cbranchfp4_media"
7079   [(set (pc)
7080         (if_then_else (match_operator 0 "sh_float_comparison_operator"
7081                        [(match_operand 1 "" "")
7082                         (match_operand 2 "" "")])
7083                       (match_operand 3 "" "")
7084                       (pc)))]
7085   "TARGET_SHMEDIA"
7086   "
7087 {
7088   rtx tmp = gen_reg_rtx (SImode);
7089   rtx cmp;
7090   if (GET_CODE (operands[0]) == NE)
7091     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7092   else
7093     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7094                           operands[1], operands[2]);
7095
7096   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7097
7098   if (GET_CODE (cmp) == GET_CODE (operands[0]))
7099     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7100   else
7101     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7102   operands[1] = tmp;
7103   operands[2] = const0_rtx;
7104   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7105 }")
7106
7107 (define_insn "*beq_media_i"
7108   [(set (pc)
7109         (if_then_else (match_operator 3 "equality_comparison_operator"
7110                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
7111                          (match_operand:DI 2 "arith_operand" "r,I06")])
7112                       (match_operand 0 "target_operand" "b,b")
7113                       (pc)))]
7114   "TARGET_SHMEDIA"
7115   "@
7116         b%o3%'  %1, %2, %0%>
7117         b%o3i%' %1, %2, %0%>"
7118   [(set_attr "type" "cbranch_media")])
7119
7120 (define_insn "*beq_media_i32"
7121   [(set (pc)
7122         (if_then_else (match_operator 3 "equality_comparison_operator"
7123                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
7124                          (match_operand:SI 2 "arith_operand" "r,I06")])
7125                       (match_operand 0 "target_operand" "b,b")
7126                       (pc)))]
7127   "TARGET_SHMEDIA"
7128   "@
7129         b%o3%'  %1, %2, %0%>
7130         b%o3i%' %1, %2, %0%>"
7131   [(set_attr "type" "cbranch_media")])
7132
7133 (define_insn "*bgt_media_i"
7134   [(set (pc)
7135         (if_then_else (match_operator 3 "greater_comparison_operator"
7136                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7137                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7138                       (match_operand 0 "target_operand" "b")
7139                       (pc)))]
7140   "TARGET_SHMEDIA"
7141   "b%o3%'       %N1, %N2, %0%>"
7142   [(set_attr "type" "cbranch_media")])
7143
7144 (define_insn "*bgt_media_i32"
7145   [(set (pc)
7146         (if_then_else (match_operator 3 "greater_comparison_operator"
7147                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7148                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7149                       (match_operand 0 "target_operand" "b")
7150                       (pc)))]
7151   "TARGET_SHMEDIA"
7152   "b%o3%'       %N1, %N2, %0%>"
7153   [(set_attr "type" "cbranch_media")])
7154
7155 ;; These are only needed to make invert_jump() happy - otherwise, jump
7156 ;; optimization will be silently disabled.
7157 (define_insn "*blt_media_i"
7158   [(set (pc)
7159         (if_then_else (match_operator 3 "less_comparison_operator"
7160                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7161                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7162                       (match_operand 0 "target_operand" "b")
7163                       (pc)))]
7164   "TARGET_SHMEDIA"
7165   "b%o3%'       %N2, %N1, %0%>"
7166   [(set_attr "type" "cbranch_media")])
7167
7168 (define_insn "*blt_media_i32"
7169   [(set (pc)
7170         (if_then_else (match_operator 3 "less_comparison_operator"
7171                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7172                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7173                       (match_operand 0 "target_operand" "b")
7174                       (pc)))]
7175   "TARGET_SHMEDIA"
7176   "b%o3%'       %N2, %N1, %0%>"
7177   [(set_attr "type" "cbranch_media")])
7178
7179 ;; combiner splitter for test-and-branch on single bit in register.  This
7180 ;; is endian dependent because the non-paradoxical subreg looks different
7181 ;; on big endian.
7182 (define_split
7183   [(set (pc)
7184         (if_then_else
7185           (match_operator 3 "equality_comparison_operator"
7186             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7187                                                       "extend_reg_operand" "")
7188                                                     0)
7189                                          (const_int 1)
7190                                          (match_operand 2
7191                                           "const_int_operand" "")) 0)
7192              (const_int 0)])
7193           (match_operand 0 "target_operand" "")
7194           (pc)))
7195    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7196   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7197   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7198    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7199
7200   "
7201 {
7202   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7203   operands[6] = (GET_CODE (operands[3]) == EQ
7204                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7205                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7206 }")
7207
7208 ; operand 0 is the loop count pseudo register
7209 ; operand 1 is the number of loop iterations or 0 if it is unknown
7210 ; operand 2 is the maximum number of loop iterations
7211 ; operand 3 is the number of levels of enclosed loops
7212 ; operand 4 is the label to jump to at the top of the loop
7213
7214 (define_expand "doloop_end"
7215   [(parallel [(set (pc) (if_then_else
7216                           (ne:SI (match_operand:SI 0 "" "")
7217                               (const_int 1))
7218                           (label_ref (match_operand 4 "" ""))
7219                           (pc)))
7220               (set (match_dup 0)
7221                    (plus:SI (match_dup 0) (const_int -1)))
7222               (clobber (reg:SI T_REG))])]
7223   "TARGET_SH2"
7224   "
7225 {
7226   if (GET_MODE (operands[0]) != SImode)
7227     FAIL;
7228 }
7229 ")
7230
7231 (define_insn_and_split "doloop_end_split"
7232   [(set (pc)
7233         (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7234                           (const_int 1))
7235                       (label_ref (match_operand 1 "" ""))
7236                       (pc)))
7237    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7238         (plus (match_dup 2) (const_int -1)))
7239    (clobber (reg:SI T_REG))]
7240   "TARGET_SH2"
7241   "#"
7242   ""
7243   [(parallel [(set (reg:SI T_REG)
7244                    (eq:SI (match_dup 2) (const_int 1)))
7245               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7246    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7247                            (label_ref (match_dup 1))
7248                            (pc)))]
7249 ""
7250    [(set_attr "type" "cbranch")])
7251
7252 \f
7253 ;; ------------------------------------------------------------------------
7254 ;; Jump and linkage insns
7255 ;; ------------------------------------------------------------------------
7256
7257 (define_insn "jump_compact"
7258   [(set (pc)
7259         (label_ref (match_operand 0 "" "")))]
7260   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7261   "*
7262 {
7263   /* The length is 16 if the delay slot is unfilled.  */
7264   if (get_attr_length(insn) > 4)
7265     return output_far_jump(insn, operands[0]);
7266   else
7267     return   \"bra      %l0%#\";
7268 }"
7269   [(set_attr "type" "jump")
7270    (set_attr "needs_delay_slot" "yes")])
7271
7272 ;; ??? It would be much saner to explicitly use the scratch register
7273 ;; in the jump insn, and have indirect_jump_scratch only set it,
7274 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7275 ;; from the target then, as it uses simplejump_p.
7276 ;;(define_insn "jump_compact_far"
7277 ;;  [(set (pc)
7278 ;;      (label_ref (match_operand 0 "" "")))
7279 ;;   (use (match_operand 1 "register_operand" "r")]
7280 ;;  "TARGET_SH1"
7281 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7282 ;;  [(set_attr "type" "jump")
7283 ;;   (set_attr "needs_delay_slot" "yes")])
7284
7285 (define_insn "jump_media"
7286   [(set (pc)
7287         (match_operand 0 "target_operand" "b"))]
7288   "TARGET_SHMEDIA"
7289   "blink        %0, r63%>"
7290   [(set_attr "type" "jump_media")])
7291
7292 (define_expand "jump"
7293   [(set (pc)
7294         (label_ref (match_operand 0 "" "")))]
7295   ""
7296   "
7297 {
7298   if (TARGET_SH1)
7299     emit_jump_insn (gen_jump_compact (operands[0]));
7300   else if (TARGET_SHMEDIA)
7301     {
7302       if (reload_in_progress || reload_completed)
7303         FAIL;
7304       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7305                                                          operands[0])));
7306     }
7307   DONE;
7308 }")
7309
7310 (define_insn "force_mode_for_call"
7311   [(use (reg:PSI FPSCR_REG))]
7312   "TARGET_SHCOMPACT"
7313   ""
7314   [(set_attr "length" "0")
7315    (set (attr "fp_mode")
7316         (if_then_else (eq_attr "fpu_single" "yes")
7317                       (const_string "single") (const_string "double")))])
7318
7319 (define_insn "calli"
7320   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7321          (match_operand 1 "" ""))
7322    (use (reg:PSI FPSCR_REG))
7323    (clobber (reg:SI PR_REG))]
7324   "TARGET_SH1"
7325   "*
7326    {
7327      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7328         return \"jsr/n\\t@%0\";
7329      else
7330         return \"jsr\\t@%0%#\";
7331    }"
7332
7333   [(set_attr "type" "call")
7334    (set (attr "fp_mode")
7335         (if_then_else (eq_attr "fpu_single" "yes")
7336                       (const_string "single") (const_string "double")))
7337    (set_attr "needs_delay_slot" "yes")
7338    (set_attr "fp_set" "unknown")])
7339
7340 ;; This is TBR relative jump instruction for SH2A architecture.
7341 ;; Its use is enabled assigning an attribute "function_vector"
7342 ;; and the vector number to a function during its declaration.
7343
7344 (define_insn "calli_tbr_rel"
7345   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7346          (match_operand 1 "" ""))
7347    (use (reg:PSI FPSCR_REG))
7348    (clobber (reg:SI PR_REG))]
7349   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7350   "*
7351 {
7352   unsigned HOST_WIDE_INT vect_num;
7353   vect_num = sh2a_get_function_vector_number (operands[0]);
7354   operands[2] = GEN_INT (vect_num * 4);
7355
7356   return \"jsr/n\\t@@(%O2,tbr)\";
7357 }"
7358   [(set_attr "type" "call")
7359    (set (attr "fp_mode")
7360         (if_then_else (eq_attr "fpu_single" "yes")
7361                       (const_string "single") (const_string "double")))
7362    (set_attr "needs_delay_slot" "no")
7363    (set_attr "fp_set" "unknown")])
7364
7365 ;; This is a pc-rel call, using bsrf, for use with PIC.
7366
7367 (define_insn "calli_pcrel"
7368   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7369          (match_operand 1 "" ""))
7370    (use (reg:PSI FPSCR_REG))
7371    (use (reg:SI PIC_REG))
7372    (use (match_operand 2 "" ""))
7373    (clobber (reg:SI PR_REG))]
7374   "TARGET_SH2"
7375   "bsrf %0\\n%O2:%#"
7376   [(set_attr "type" "call")
7377    (set (attr "fp_mode")
7378         (if_then_else (eq_attr "fpu_single" "yes")
7379                       (const_string "single") (const_string "double")))
7380    (set_attr "needs_delay_slot" "yes")
7381    (set_attr "fp_set" "unknown")])
7382
7383 (define_insn_and_split "call_pcrel"
7384   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7385          (match_operand 1 "" ""))
7386    (use (reg:PSI FPSCR_REG))
7387    (use (reg:SI PIC_REG))
7388    (clobber (reg:SI PR_REG))
7389    (clobber (match_scratch:SI 2 "=r"))]
7390   "TARGET_SH2"
7391   "#"
7392   "reload_completed"
7393   [(const_int 0)]
7394   "
7395 {
7396   rtx lab = PATTERN (gen_call_site ());
7397
7398   if (SYMBOL_REF_LOCAL_P (operands[0]))
7399     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7400   else
7401     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7402   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7403   DONE;
7404 }"
7405   [(set_attr "type" "call")
7406    (set (attr "fp_mode")
7407         (if_then_else (eq_attr "fpu_single" "yes")
7408                       (const_string "single") (const_string "double")))
7409    (set_attr "needs_delay_slot" "yes")
7410    (set_attr "fp_set" "unknown")])
7411
7412 (define_insn "call_compact"
7413   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7414          (match_operand 1 "" ""))
7415    (match_operand 2 "immediate_operand" "n")
7416    (use (reg:SI R0_REG))
7417    (use (reg:SI R1_REG))
7418    (use (reg:PSI FPSCR_REG))
7419    (clobber (reg:SI PR_REG))]
7420   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7421   "jsr  @%0%#"
7422   [(set_attr "type" "call")
7423    (set (attr "fp_mode")
7424         (if_then_else (eq_attr "fpu_single" "yes")
7425                       (const_string "single") (const_string "double")))
7426    (set_attr "needs_delay_slot" "yes")])
7427
7428 (define_insn "call_compact_rettramp"
7429   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7430          (match_operand 1 "" ""))
7431    (match_operand 2 "immediate_operand" "n")
7432    (use (reg:SI R0_REG))
7433    (use (reg:SI R1_REG))
7434    (use (reg:PSI FPSCR_REG))
7435    (clobber (reg:SI R10_REG))
7436    (clobber (reg:SI PR_REG))]
7437   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7438   "jsr  @%0%#"
7439   [(set_attr "type" "call")
7440    (set (attr "fp_mode")
7441         (if_then_else (eq_attr "fpu_single" "yes")
7442                       (const_string "single") (const_string "double")))
7443    (set_attr "needs_delay_slot" "yes")])
7444
7445 (define_insn "call_media"
7446   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7447          (match_operand 1 "" ""))
7448    (clobber (reg:DI PR_MEDIA_REG))]
7449   "TARGET_SHMEDIA"
7450   "blink        %0, r18"
7451   [(set_attr "type" "jump_media")])
7452
7453 (define_insn "call_valuei"
7454   [(set (match_operand 0 "" "=rf")
7455         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7456               (match_operand 2 "" "")))
7457    (use (reg:PSI FPSCR_REG))
7458    (clobber (reg:SI PR_REG))]
7459   "TARGET_SH1"
7460   "*
7461    {
7462      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7463         return \"jsr/n\\t@%1\";
7464      else
7465         return \"jsr\\t@%1%#\";
7466    }"
7467   [(set_attr "type" "call")
7468    (set (attr "fp_mode")
7469         (if_then_else (eq_attr "fpu_single" "yes")
7470                       (const_string "single") (const_string "double")))
7471    (set_attr "needs_delay_slot" "yes")
7472    (set_attr "fp_set" "unknown")])
7473
7474 ;; This is TBR relative jump instruction for SH2A architecture.
7475 ;; Its use is enabled assigning an attribute "function_vector"
7476 ;; and the vector number to a function during its declaration.
7477
7478 (define_insn "call_valuei_tbr_rel"
7479   [(set (match_operand 0 "" "=rf")
7480         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7481               (match_operand 2 "" "")))
7482    (use (reg:PSI FPSCR_REG))
7483    (clobber (reg:SI PR_REG))]
7484   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7485   "*
7486 {
7487   unsigned HOST_WIDE_INT vect_num;
7488   vect_num = sh2a_get_function_vector_number (operands[1]);
7489   operands[3] = GEN_INT (vect_num * 4);
7490
7491   return \"jsr/n\\t@@(%O3,tbr)\";
7492 }"
7493   [(set_attr "type" "call")
7494    (set (attr "fp_mode")
7495         (if_then_else (eq_attr "fpu_single" "yes")
7496                       (const_string "single") (const_string "double")))
7497    (set_attr "needs_delay_slot" "no")
7498    (set_attr "fp_set" "unknown")])
7499
7500 (define_insn "call_valuei_pcrel"
7501   [(set (match_operand 0 "" "=rf")
7502         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7503               (match_operand 2 "" "")))
7504    (use (reg:PSI FPSCR_REG))
7505    (use (reg:SI PIC_REG))
7506    (use (match_operand 3 "" ""))
7507    (clobber (reg:SI PR_REG))]
7508   "TARGET_SH2"
7509   "bsrf %1\\n%O3:%#"
7510   [(set_attr "type" "call")
7511    (set (attr "fp_mode")
7512         (if_then_else (eq_attr "fpu_single" "yes")
7513                       (const_string "single") (const_string "double")))
7514    (set_attr "needs_delay_slot" "yes")
7515    (set_attr "fp_set" "unknown")])
7516
7517 (define_insn_and_split "call_value_pcrel"
7518   [(set (match_operand 0 "" "=rf")
7519         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7520               (match_operand 2 "" "")))
7521    (use (reg:PSI FPSCR_REG))
7522    (use (reg:SI PIC_REG))
7523    (clobber (reg:SI PR_REG))
7524    (clobber (match_scratch:SI 3 "=r"))]
7525   "TARGET_SH2"
7526   "#"
7527   "reload_completed"
7528   [(const_int 0)]
7529   "
7530 {
7531   rtx lab = PATTERN (gen_call_site ());
7532
7533   if (SYMBOL_REF_LOCAL_P (operands[1]))
7534     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7535   else
7536     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7537   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7538                                          operands[2], copy_rtx (lab)));
7539   DONE;
7540 }"
7541   [(set_attr "type" "call")
7542    (set (attr "fp_mode")
7543         (if_then_else (eq_attr "fpu_single" "yes")
7544                       (const_string "single") (const_string "double")))
7545    (set_attr "needs_delay_slot" "yes")
7546    (set_attr "fp_set" "unknown")])
7547
7548 (define_insn "call_value_compact"
7549   [(set (match_operand 0 "" "=rf")
7550         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7551               (match_operand 2 "" "")))
7552    (match_operand 3 "immediate_operand" "n")
7553    (use (reg:SI R0_REG))
7554    (use (reg:SI R1_REG))
7555    (use (reg:PSI FPSCR_REG))
7556    (clobber (reg:SI PR_REG))]
7557   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7558   "jsr  @%1%#"
7559   [(set_attr "type" "call")
7560    (set (attr "fp_mode")
7561         (if_then_else (eq_attr "fpu_single" "yes")
7562                       (const_string "single") (const_string "double")))
7563    (set_attr "needs_delay_slot" "yes")])
7564
7565 (define_insn "call_value_compact_rettramp"
7566   [(set (match_operand 0 "" "=rf")
7567         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7568               (match_operand 2 "" "")))
7569    (match_operand 3 "immediate_operand" "n")
7570    (use (reg:SI R0_REG))
7571    (use (reg:SI R1_REG))
7572    (use (reg:PSI FPSCR_REG))
7573    (clobber (reg:SI R10_REG))
7574    (clobber (reg:SI PR_REG))]
7575   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7576   "jsr  @%1%#"
7577   [(set_attr "type" "call")
7578    (set (attr "fp_mode")
7579         (if_then_else (eq_attr "fpu_single" "yes")
7580                       (const_string "single") (const_string "double")))
7581    (set_attr "needs_delay_slot" "yes")])
7582
7583 (define_insn "call_value_media"
7584   [(set (match_operand 0 "" "=rf")
7585         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7586               (match_operand 2 "" "")))
7587    (clobber (reg:DI PR_MEDIA_REG))]
7588   "TARGET_SHMEDIA"
7589   "blink        %1, r18"
7590   [(set_attr "type" "jump_media")])
7591
7592 (define_expand "call"
7593   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7594                             (match_operand 1 "" ""))
7595               (match_operand 2 "" "")
7596               (use (reg:PSI FPSCR_REG))
7597               (clobber (reg:SI PR_REG))])]
7598   ""
7599   "
7600 {
7601   if (TARGET_SHMEDIA)
7602     {
7603       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7604       emit_call_insn (gen_call_media (operands[0], operands[1]));
7605       DONE;
7606     }
7607   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7608     {
7609       rtx cookie_rtx = operands[2];
7610       long cookie = INTVAL (cookie_rtx);
7611       rtx func = XEXP (operands[0], 0);
7612       rtx r0, r1;
7613
7614       if (flag_pic)
7615         {
7616           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7617             {
7618               rtx reg = gen_reg_rtx (Pmode);
7619
7620               emit_insn (gen_symGOTPLT2reg (reg, func));
7621               func = reg;
7622             }
7623           else
7624             func = legitimize_pic_address (func, Pmode, 0);
7625         }
7626
7627       r0 = gen_rtx_REG (SImode, R0_REG);
7628       r1 = gen_rtx_REG (SImode, R1_REG);
7629
7630       /* Since such a call function may use all call-clobbered
7631          registers, we force a mode switch earlier, so that we don't
7632          run out of registers when adjusting fpscr for the call.  */
7633       emit_insn (gen_force_mode_for_call ());
7634
7635       operands[0]
7636         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637                            SFUNC_GOT);
7638       operands[0] = force_reg (SImode, operands[0]);
7639
7640       emit_move_insn (r0, func);
7641       emit_move_insn (r1, cookie_rtx);
7642
7643       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7645                                                    operands[2]));
7646       else
7647         emit_call_insn (gen_call_compact (operands[0], operands[1],
7648                                           operands[2]));
7649
7650       DONE;
7651     }
7652   else if (TARGET_SHCOMPACT && flag_pic
7653            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7654            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7655     {
7656       rtx reg = gen_reg_rtx (Pmode);
7657
7658       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7659       XEXP (operands[0], 0) = reg;
7660     }
7661   if (!flag_pic && TARGET_SH2A
7662       && MEM_P (operands[0])
7663       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7664     {
7665       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7666         {
7667           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7668                                              operands[1]));
7669           DONE;
7670         }
7671     }
7672   if (flag_pic && TARGET_SH2
7673       && MEM_P (operands[0])
7674       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7675     {
7676       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7677       DONE;
7678     }
7679   else
7680   {
7681     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7682     operands[1] = operands[2];
7683   }
7684
7685   emit_call_insn (gen_calli (operands[0], operands[1]));
7686   DONE;
7687 }")
7688
7689 (define_insn "call_pop_compact"
7690   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7691          (match_operand 1 "" ""))
7692    (match_operand 2 "immediate_operand" "n")
7693    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7694                                  (match_operand 3 "immediate_operand" "n")))
7695    (use (reg:SI R0_REG))
7696    (use (reg:SI R1_REG))
7697    (use (reg:PSI FPSCR_REG))
7698    (clobber (reg:SI PR_REG))]
7699   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7700   "jsr  @%0%#"
7701   [(set_attr "type" "call")
7702    (set (attr "fp_mode")
7703         (if_then_else (eq_attr "fpu_single" "yes")
7704                       (const_string "single") (const_string "double")))
7705    (set_attr "needs_delay_slot" "yes")])
7706
7707 (define_insn "call_pop_compact_rettramp"
7708   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7709          (match_operand 1 "" ""))
7710    (match_operand 2 "immediate_operand" "n")
7711    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7712                                  (match_operand 3 "immediate_operand" "n")))
7713    (use (reg:SI R0_REG))
7714    (use (reg:SI R1_REG))
7715    (use (reg:PSI FPSCR_REG))
7716    (clobber (reg:SI R10_REG))
7717    (clobber (reg:SI PR_REG))]
7718   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7719   "jsr  @%0%#"
7720   [(set_attr "type" "call")
7721    (set (attr "fp_mode")
7722         (if_then_else (eq_attr "fpu_single" "yes")
7723                       (const_string "single") (const_string "double")))
7724    (set_attr "needs_delay_slot" "yes")])
7725
7726 (define_expand "call_pop"
7727   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7728                     (match_operand 1 "" ""))
7729              (match_operand 2 "" "")
7730              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7731                                            (match_operand 3 "" "")))])]
7732   "TARGET_SHCOMPACT"
7733   "
7734 {
7735   rtx cookie_rtx;
7736   long cookie;
7737   rtx func;
7738   rtx r0, r1;
7739
7740   gcc_assert (operands[2] && INTVAL (operands[2]));
7741   cookie_rtx = operands[2];
7742   cookie = INTVAL (cookie_rtx);
7743   func = XEXP (operands[0], 0);
7744
7745   if (flag_pic)
7746     {
7747       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7748         {
7749           rtx reg = gen_reg_rtx (Pmode);
7750           emit_insn (gen_symGOTPLT2reg (reg, func));
7751           func = reg;
7752         }
7753       else
7754         func = legitimize_pic_address (func, Pmode, 0);
7755     }
7756
7757   r0 = gen_rtx_REG (SImode, R0_REG);
7758   r1 = gen_rtx_REG (SImode, R1_REG);
7759
7760   /* Since such a call function may use all call-clobbered
7761      registers, we force a mode switch earlier, so that we don't
7762      run out of registers when adjusting fpscr for the call.  */
7763   emit_insn (gen_force_mode_for_call ());
7764
7765   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7766                                  SFUNC_GOT);
7767   operands[0] = force_reg (SImode, operands[0]);
7768
7769   emit_move_insn (r0, func);
7770   emit_move_insn (r1, cookie_rtx);
7771
7772   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7773     emit_call_insn (gen_call_pop_compact_rettramp
7774                      (operands[0], operands[1], operands[2], operands[3]));
7775   else
7776     emit_call_insn (gen_call_pop_compact
7777                      (operands[0], operands[1], operands[2], operands[3]));
7778
7779   DONE;
7780 }")
7781
7782 (define_expand "call_value"
7783   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7784                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7785                                  (match_operand 2 "" "")))
7786               (match_operand 3 "" "")
7787               (use (reg:PSI FPSCR_REG))
7788               (clobber (reg:SI PR_REG))])]
7789   ""
7790   "
7791 {
7792   if (TARGET_SHMEDIA)
7793     {
7794       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7795       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7796                                             operands[2]));
7797       DONE;
7798     }
7799   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7800     {
7801       rtx cookie_rtx = operands[3];
7802       long cookie = INTVAL (cookie_rtx);
7803       rtx func = XEXP (operands[1], 0);
7804       rtx r0, r1;
7805
7806       if (flag_pic)
7807         {
7808           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7809             {
7810               rtx reg = gen_reg_rtx (Pmode);
7811
7812               emit_insn (gen_symGOTPLT2reg (reg, func));
7813               func = reg;
7814             }
7815           else
7816             func = legitimize_pic_address (func, Pmode, 0);
7817         }
7818
7819       r0 = gen_rtx_REG (SImode, R0_REG);
7820       r1 = gen_rtx_REG (SImode, R1_REG);
7821
7822       /* Since such a call function may use all call-clobbered
7823          registers, we force a mode switch earlier, so that we don't
7824          run out of registers when adjusting fpscr for the call.  */
7825       emit_insn (gen_force_mode_for_call ());
7826
7827       operands[1]
7828         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7829                            SFUNC_GOT);
7830       operands[1] = force_reg (SImode, operands[1]);
7831
7832       emit_move_insn (r0, func);
7833       emit_move_insn (r1, cookie_rtx);
7834
7835       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7836         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7837                                                          operands[1],
7838                                                          operands[2],
7839                                                          operands[3]));
7840       else
7841         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7842                                                 operands[2], operands[3]));
7843
7844       DONE;
7845     }
7846   else if (TARGET_SHCOMPACT && flag_pic
7847            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7848            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7849     {
7850       rtx reg = gen_reg_rtx (Pmode);
7851
7852       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7853       XEXP (operands[1], 0) = reg;
7854     }
7855   if (!flag_pic && TARGET_SH2A
7856       && MEM_P (operands[1])
7857       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7858     {
7859       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7860         {
7861           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7862                                  XEXP (operands[1], 0), operands[2]));
7863           DONE;
7864         }
7865     }
7866   if (flag_pic && TARGET_SH2
7867       && MEM_P (operands[1])
7868       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7869     {
7870       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7871                                             operands[2]));
7872       DONE;
7873     }
7874   else
7875     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7876
7877   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7878   DONE;
7879 }")
7880
7881 (define_insn "sibcalli"
7882   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7883          (match_operand 1 "" ""))
7884    (use (reg:PSI FPSCR_REG))
7885    (return)]
7886   "TARGET_SH1"
7887   "jmp  @%0%#"
7888   [(set_attr "needs_delay_slot" "yes")
7889    (set (attr "fp_mode")
7890         (if_then_else (eq_attr "fpu_single" "yes")
7891                       (const_string "single") (const_string "double")))
7892    (set_attr "type" "jump_ind")])
7893
7894 (define_insn "sibcalli_pcrel"
7895   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7896          (match_operand 1 "" ""))
7897    (use (match_operand 2 "" ""))
7898    (use (reg:PSI FPSCR_REG))
7899    (return)]
7900   "TARGET_SH2"
7901   "braf %0\\n%O2:%#"
7902   [(set_attr "needs_delay_slot" "yes")
7903    (set (attr "fp_mode")
7904         (if_then_else (eq_attr "fpu_single" "yes")
7905                       (const_string "single") (const_string "double")))
7906    (set_attr "type" "jump_ind")])
7907
7908 ;; This uses an unspec to describe that the symbol_ref is very close.
7909 (define_insn "sibcalli_thunk"
7910   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7911                              UNSPEC_THUNK))
7912          (match_operand 1 "" ""))
7913    (use (reg:PSI FPSCR_REG))
7914    (return)]
7915   "TARGET_SH1"
7916   "bra  %O0"
7917   [(set_attr "needs_delay_slot" "yes")
7918    (set (attr "fp_mode")
7919         (if_then_else (eq_attr "fpu_single" "yes")
7920                       (const_string "single") (const_string "double")))
7921    (set_attr "type" "jump")
7922    (set_attr "length" "2")])
7923
7924 (define_insn_and_split "sibcall_pcrel"
7925   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7926          (match_operand 1 "" ""))
7927    (use (reg:PSI FPSCR_REG))
7928    (clobber (match_scratch:SI 2 "=k"))
7929    (return)]
7930   "TARGET_SH2"
7931   "#"
7932   "reload_completed"
7933   [(const_int 0)]
7934   "
7935 {
7936   rtx lab = PATTERN (gen_call_site ());
7937   rtx call_insn;
7938
7939   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7940   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7941                                                   copy_rtx (lab)));
7942   SIBLING_CALL_P (call_insn) = 1;
7943   DONE;
7944 }"
7945   [(set_attr "needs_delay_slot" "yes")
7946    (set (attr "fp_mode")
7947         (if_then_else (eq_attr "fpu_single" "yes")
7948                       (const_string "single") (const_string "double")))
7949    (set_attr "type" "jump_ind")])
7950
7951 (define_insn "sibcall_compact"
7952   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7953          (match_operand 1 "" ""))
7954    (return)
7955    (use (match_operand:SI 2 "register_operand" "z,x"))
7956    (use (reg:SI R1_REG))
7957    (use (reg:PSI FPSCR_REG))
7958    ;; We want to make sure the `x' above will only match MACH_REG
7959    ;; because sibcall_epilogue may clobber MACL_REG.
7960    (clobber (reg:SI MACL_REG))]
7961   "TARGET_SHCOMPACT"
7962   "@
7963         jmp     @%0%#
7964         jmp     @%0\\n  sts     %2, r0"
7965   [(set_attr "needs_delay_slot" "yes,no")
7966    (set_attr "length" "2,4")
7967    (set (attr "fp_mode") (const_string "single"))
7968    (set_attr "type" "jump_ind")])
7969
7970 (define_insn "sibcall_media"
7971   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7972          (match_operand 1 "" ""))
7973    (use (reg:SI PR_MEDIA_REG))
7974    (return)]
7975   "TARGET_SHMEDIA"
7976   "blink        %0, r63"
7977   [(set_attr "type" "jump_media")])
7978
7979 (define_expand "sibcall"
7980   [(parallel
7981     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7982            (match_operand 1 "" ""))
7983      (match_operand 2 "" "")
7984      (use (reg:PSI FPSCR_REG))
7985      (return)])]
7986   ""
7987   "
7988 {
7989   if (TARGET_SHMEDIA)
7990     {
7991       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7992       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7993       DONE;
7994     }
7995   else if (TARGET_SHCOMPACT && operands[2]
7996            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7997     {
7998       rtx cookie_rtx = operands[2];
7999       long cookie = INTVAL (cookie_rtx);
8000       rtx func = XEXP (operands[0], 0);
8001       rtx mach, r1;
8002
8003       if (flag_pic)
8004         {
8005           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8006             {
8007               rtx reg = gen_reg_rtx (Pmode);
8008
8009               emit_insn (gen_symGOT2reg (reg, func));
8010               func = reg;
8011             }
8012           else
8013             func = legitimize_pic_address (func, Pmode, 0);
8014         }
8015
8016       /* FIXME: if we could tell whether all argument registers are
8017          already taken, we could decide whether to force the use of
8018          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8019          simple way to tell.  We could use the CALL_COOKIE, but we
8020          can't currently tell a register used for regular argument
8021          passing from one that is unused.  If we leave it up to reload
8022          to decide which register to use, it seems to always choose
8023          R0_REG, which leaves no available registers in SIBCALL_REGS
8024          to hold the address of the trampoline.  */
8025       mach = gen_rtx_REG (SImode, MACH_REG);
8026       r1 = gen_rtx_REG (SImode, R1_REG);
8027
8028       /* Since such a call function may use all call-clobbered
8029          registers, we force a mode switch earlier, so that we don't
8030          run out of registers when adjusting fpscr for the call.  */
8031       emit_insn (gen_force_mode_for_call ());
8032
8033       operands[0]
8034         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8035                            SFUNC_GOT);
8036       operands[0] = force_reg (SImode, operands[0]);
8037
8038       /* We don't need a return trampoline, since the callee will
8039          return directly to the upper caller.  */
8040       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8041         {
8042           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8043           cookie_rtx = GEN_INT (cookie);
8044         }
8045
8046       emit_move_insn (mach, func);
8047       emit_move_insn (r1, cookie_rtx);
8048
8049       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8050       DONE;
8051     }
8052   else if (TARGET_SHCOMPACT && flag_pic
8053            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8054            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8055     {
8056       rtx reg = gen_reg_rtx (Pmode);
8057
8058       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8059       XEXP (operands[0], 0) = reg;
8060     }
8061   if (flag_pic && TARGET_SH2
8062       && MEM_P (operands[0])
8063       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8064       /* The PLT needs the PIC register, but the epilogue would have
8065          to restore it, so we can only use PC-relative PIC calls for
8066          static functions.  */
8067       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8068     {
8069       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8070       DONE;
8071     }
8072   else
8073     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8074
8075   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8076   DONE;
8077 }")
8078
8079 (define_insn "sibcall_valuei"
8080   [(set (match_operand 0 "" "=rf")
8081         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8082               (match_operand 2 "" "")))
8083    (use (reg:PSI FPSCR_REG))
8084    (return)]
8085   "TARGET_SH1"
8086   "jmp  @%1%#"
8087   [(set_attr "needs_delay_slot" "yes")
8088    (set (attr "fp_mode")
8089         (if_then_else (eq_attr "fpu_single" "yes")
8090                       (const_string "single") (const_string "double")))
8091    (set_attr "type" "jump_ind")])
8092
8093 (define_insn "sibcall_valuei_pcrel"
8094   [(set (match_operand 0 "" "=rf")
8095         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8096               (match_operand 2 "" "")))
8097    (use (match_operand 3 "" ""))
8098    (use (reg:PSI FPSCR_REG))
8099    (return)]
8100   "TARGET_SH2"
8101   "braf %1\\n%O3:%#"
8102   [(set_attr "needs_delay_slot" "yes")
8103    (set (attr "fp_mode")
8104         (if_then_else (eq_attr "fpu_single" "yes")
8105                       (const_string "single") (const_string "double")))
8106    (set_attr "type" "jump_ind")])
8107
8108 (define_insn_and_split "sibcall_value_pcrel"
8109   [(set (match_operand 0 "" "=rf")
8110         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8111               (match_operand 2 "" "")))
8112    (use (reg:PSI FPSCR_REG))
8113    (clobber (match_scratch:SI 3 "=k"))
8114    (return)]
8115   "TARGET_SH2"
8116   "#"
8117   "reload_completed"
8118   [(const_int 0)]
8119   "
8120 {
8121   rtx lab = PATTERN (gen_call_site ());
8122   rtx call_insn;
8123
8124   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8125   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8126                                                         operands[3],
8127                                                         operands[2],
8128                                                         copy_rtx (lab)));
8129   SIBLING_CALL_P (call_insn) = 1;
8130   DONE;
8131 }"
8132   [(set_attr "needs_delay_slot" "yes")
8133    (set (attr "fp_mode")
8134         (if_then_else (eq_attr "fpu_single" "yes")
8135                       (const_string "single") (const_string "double")))
8136    (set_attr "type" "jump_ind")])
8137
8138 (define_insn "sibcall_value_compact"
8139   [(set (match_operand 0 "" "=rf,rf")
8140         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8141               (match_operand 2 "" "")))
8142    (return)
8143    (use (match_operand:SI 3 "register_operand" "z,x"))
8144    (use (reg:SI R1_REG))
8145    (use (reg:PSI FPSCR_REG))
8146    ;; We want to make sure the `x' above will only match MACH_REG
8147    ;; because sibcall_epilogue may clobber MACL_REG.
8148    (clobber (reg:SI MACL_REG))]
8149   "TARGET_SHCOMPACT"
8150   "@
8151         jmp     @%1%#
8152         jmp     @%1\\n  sts     %3, r0"
8153   [(set_attr "needs_delay_slot" "yes,no")
8154    (set_attr "length" "2,4")
8155    (set (attr "fp_mode") (const_string "single"))
8156    (set_attr "type" "jump_ind")])
8157
8158 (define_insn "sibcall_value_media"
8159   [(set (match_operand 0 "" "=rf")
8160         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8161               (match_operand 2 "" "")))
8162    (use (reg:SI PR_MEDIA_REG))
8163    (return)]
8164   "TARGET_SHMEDIA"
8165   "blink        %1, r63"
8166   [(set_attr "type" "jump_media")])
8167
8168 (define_expand "sibcall_value"
8169   [(parallel
8170     [(set (match_operand 0 "arith_reg_operand" "")
8171           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8172                 (match_operand 2 "" "")))
8173      (match_operand 3 "" "")
8174      (use (reg:PSI FPSCR_REG))
8175      (return)])]
8176   ""
8177   "
8178 {
8179   if (TARGET_SHMEDIA)
8180     {
8181       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8182       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8183                                                operands[2]));
8184       DONE;
8185     }
8186   else if (TARGET_SHCOMPACT && operands[3]
8187            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8188     {
8189       rtx cookie_rtx = operands[3];
8190       long cookie = INTVAL (cookie_rtx);
8191       rtx func = XEXP (operands[1], 0);
8192       rtx mach, r1;
8193
8194       if (flag_pic)
8195         {
8196           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8197             {
8198               rtx reg = gen_reg_rtx (Pmode);
8199
8200               emit_insn (gen_symGOT2reg (reg, func));
8201               func = reg;
8202             }
8203           else
8204             func = legitimize_pic_address (func, Pmode, 0);
8205         }
8206
8207       /* FIXME: if we could tell whether all argument registers are
8208          already taken, we could decide whether to force the use of
8209          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8210          simple way to tell.  We could use the CALL_COOKIE, but we
8211          can't currently tell a register used for regular argument
8212          passing from one that is unused.  If we leave it up to reload
8213          to decide which register to use, it seems to always choose
8214          R0_REG, which leaves no available registers in SIBCALL_REGS
8215          to hold the address of the trampoline.  */
8216       mach = gen_rtx_REG (SImode, MACH_REG);
8217       r1 = gen_rtx_REG (SImode, R1_REG);
8218
8219       /* Since such a call function may use all call-clobbered
8220          registers, we force a mode switch earlier, so that we don't
8221          run out of registers when adjusting fpscr for the call.  */
8222       emit_insn (gen_force_mode_for_call ());
8223
8224       operands[1]
8225         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8226                            SFUNC_GOT);
8227       operands[1] = force_reg (SImode, operands[1]);
8228
8229       /* We don't need a return trampoline, since the callee will
8230          return directly to the upper caller.  */
8231       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8232         {
8233           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8234           cookie_rtx = GEN_INT (cookie);
8235         }
8236
8237       emit_move_insn (mach, func);
8238       emit_move_insn (r1, cookie_rtx);
8239
8240       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8241                                                  operands[2], mach));
8242       DONE;
8243     }
8244   else if (TARGET_SHCOMPACT && flag_pic
8245            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8246            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8247     {
8248       rtx reg = gen_reg_rtx (Pmode);
8249
8250       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8251       XEXP (operands[1], 0) = reg;
8252     }
8253   if (flag_pic && TARGET_SH2
8254       && MEM_P (operands[1])
8255       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8256       /* The PLT needs the PIC register, but the epilogue would have
8257          to restore it, so we can only use PC-relative PIC calls for
8258          static functions.  */
8259       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8260     {
8261       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8262                                                XEXP (operands[1], 0),
8263                                                operands[2]));
8264       DONE;
8265     }
8266   else
8267     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8268
8269   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8270   DONE;
8271 }")
8272
8273 (define_insn "call_value_pop_compact"
8274   [(set (match_operand 0 "" "=rf")
8275         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8276               (match_operand 2 "" "")))
8277    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8278                                  (match_operand 4 "immediate_operand" "n")))
8279    (match_operand 3 "immediate_operand" "n")
8280    (use (reg:SI R0_REG))
8281    (use (reg:SI R1_REG))
8282    (use (reg:PSI FPSCR_REG))
8283    (clobber (reg:SI PR_REG))]
8284   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8285   "jsr  @%1%#"
8286   [(set_attr "type" "call")
8287    (set (attr "fp_mode")
8288         (if_then_else (eq_attr "fpu_single" "yes")
8289                       (const_string "single") (const_string "double")))
8290    (set_attr "needs_delay_slot" "yes")])
8291
8292 (define_insn "call_value_pop_compact_rettramp"
8293   [(set (match_operand 0 "" "=rf")
8294         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8295               (match_operand 2 "" "")))
8296    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8297                                  (match_operand 4 "immediate_operand" "n")))
8298    (match_operand 3 "immediate_operand" "n")
8299    (use (reg:SI R0_REG))
8300    (use (reg:SI R1_REG))
8301    (use (reg:PSI FPSCR_REG))
8302    (clobber (reg:SI R10_REG))
8303    (clobber (reg:SI PR_REG))]
8304   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8305   "jsr  @%1%#"
8306   [(set_attr "type" "call")
8307    (set (attr "fp_mode")
8308         (if_then_else (eq_attr "fpu_single" "yes")
8309                       (const_string "single") (const_string "double")))
8310    (set_attr "needs_delay_slot" "yes")])
8311
8312 (define_expand "call_value_pop"
8313   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8314                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8315                                  (match_operand 2 "" "")))
8316               (match_operand 3 "" "")
8317               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8318                                             (match_operand 4 "" "")))])]
8319   "TARGET_SHCOMPACT"
8320   "
8321 {
8322   rtx cookie_rtx;
8323   long cookie;
8324   rtx func;
8325   rtx r0, r1;
8326
8327   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8328   cookie_rtx = operands[3];
8329   cookie = INTVAL (cookie_rtx);
8330   func = XEXP (operands[1], 0);
8331
8332   if (flag_pic)
8333     {
8334       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8335         {
8336           rtx reg = gen_reg_rtx (Pmode);
8337
8338           emit_insn (gen_symGOTPLT2reg (reg, func));
8339           func = reg;
8340         }
8341       else
8342         func = legitimize_pic_address (func, Pmode, 0);
8343     }
8344
8345   r0 = gen_rtx_REG (SImode, R0_REG);
8346   r1 = gen_rtx_REG (SImode, R1_REG);
8347
8348   /* Since such a call function may use all call-clobbered
8349      registers, we force a mode switch earlier, so that we don't
8350      run out of registers when adjusting fpscr for the call.  */
8351   emit_insn (gen_force_mode_for_call ());
8352
8353   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8354                                  SFUNC_GOT);
8355   operands[1] = force_reg (SImode, operands[1]);
8356
8357   emit_move_insn (r0, func);
8358   emit_move_insn (r1, cookie_rtx);
8359
8360   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8361     emit_call_insn (gen_call_value_pop_compact_rettramp
8362                         (operands[0], operands[1], operands[2],
8363                          operands[3], operands[4]));
8364   else
8365     emit_call_insn (gen_call_value_pop_compact
8366                         (operands[0], operands[1], operands[2],
8367                          operands[3], operands[4]));
8368
8369   DONE;
8370 }")
8371
8372 (define_expand "sibcall_epilogue"
8373   [(return)]
8374   ""
8375   "
8376 {
8377   sh_expand_epilogue (1);
8378   if (TARGET_SHCOMPACT)
8379     {
8380       rtx insn, set;
8381
8382       /* If epilogue clobbers r0, preserve it in macl.  */
8383       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8384         if ((set = single_set (insn))
8385             && REG_P (SET_DEST (set))
8386             && REGNO (SET_DEST (set)) == R0_REG)
8387           {
8388             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8389             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8390
8391             /* We can't tell at this point whether the sibcall is a
8392                sibcall_compact and, if it is, whether it uses r0 or
8393                mach as operand 2, so let the instructions that
8394                preserve r0 be optimized away if r0 turns out to be
8395                dead.  */
8396             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8397             emit_move_insn (r0, tmp);
8398             break;
8399           }
8400     }
8401   DONE;
8402 }")
8403
8404 (define_insn "indirect_jump_compact"
8405   [(set (pc)
8406         (match_operand:SI 0 "arith_reg_operand" "r"))]
8407   "TARGET_SH1"
8408   "jmp  @%0%#"
8409   [(set_attr "needs_delay_slot" "yes")
8410    (set_attr "type" "jump_ind")])
8411
8412 (define_expand "indirect_jump"
8413   [(set (pc)
8414         (match_operand 0 "register_operand" ""))]
8415   ""
8416   "
8417 {
8418   if (GET_MODE (operands[0]) != Pmode)
8419     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8420 }")
8421
8422 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8423 ;; which can be present in structured code from indirect jumps which can not
8424 ;; be present in structured code.  This allows -fprofile-arcs to work.
8425
8426 ;; For SH1 processors.
8427 (define_insn "casesi_jump_1"
8428   [(set (pc)
8429         (match_operand:SI 0 "register_operand" "r"))
8430    (use (label_ref (match_operand 1 "" "")))]
8431   "TARGET_SH1"
8432   "jmp  @%0%#"
8433   [(set_attr "needs_delay_slot" "yes")
8434    (set_attr "type" "jump_ind")])
8435
8436 ;; For all later processors.
8437 (define_insn "casesi_jump_2"
8438   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8439                       (label_ref (match_operand 1 "" ""))))
8440    (use (label_ref (match_operand 2 "" "")))]
8441   "TARGET_SH2
8442    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8443   "braf %0%#"
8444   [(set_attr "needs_delay_slot" "yes")
8445    (set_attr "type" "jump_ind")])
8446
8447 (define_insn "casesi_jump_media"
8448   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8449    (use (label_ref (match_operand 1 "" "")))]
8450   "TARGET_SHMEDIA"
8451   "blink        %0, r63"
8452   [(set_attr "type" "jump_media")])
8453
8454 ;; Call subroutine returning any type.
8455 ;; ??? This probably doesn't work.
8456
8457 (define_expand "untyped_call"
8458   [(parallel [(call (match_operand 0 "" "")
8459                     (const_int 0))
8460               (match_operand 1 "" "")
8461               (match_operand 2 "" "")])]
8462   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8463   "
8464 {
8465   int i;
8466
8467   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8468
8469   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8470     {
8471       rtx set = XVECEXP (operands[2], 0, i);
8472       emit_move_insn (SET_DEST (set), SET_SRC (set));
8473     }
8474
8475   /* The optimizer does not know that the call sets the function value
8476      registers we stored in the result block.  We avoid problems by
8477      claiming that all hard registers are used and clobbered at this
8478      point.  */
8479   emit_insn (gen_blockage ());
8480
8481   DONE;
8482 }")
8483 \f
8484 ;; ------------------------------------------------------------------------
8485 ;; Misc insns
8486 ;; ------------------------------------------------------------------------
8487
8488 (define_insn "dect"
8489   [(set (reg:SI T_REG)
8490         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8491    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8492         (plus:SI (match_dup 1) (const_int -1)))]
8493   "TARGET_SH2"
8494   "dt   %0"
8495   [(set_attr "type" "arith")])
8496
8497 (define_insn "nop"
8498   [(const_int 0)]
8499   ""
8500   "nop")
8501
8502 ;; Load address of a label. This is only generated by the casesi expand,
8503 ;; and by machine_dependent_reorg (fixing up fp moves).
8504 ;; This must use unspec, because this only works for labels that are
8505 ;; within range,
8506
8507 (define_insn "mova"
8508   [(set (reg:SI R0_REG)
8509         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8510   "TARGET_SH1"
8511   "mova %O0,r0"
8512   [(set_attr "in_delay_slot" "no")
8513    (set_attr "type" "arith")])
8514
8515 ;; machine_dependent_reorg will make this a `mova'.
8516 (define_insn "mova_const"
8517   [(set (reg:SI R0_REG)
8518         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8519   "TARGET_SH1"
8520   "#"
8521   [(set_attr "in_delay_slot" "no")
8522    (set_attr "type" "arith")])
8523
8524 (define_expand "GOTaddr2picreg"
8525   [(set (reg:SI R0_REG)
8526         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8527                    UNSPEC_MOVA))
8528    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8529    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8530   "" "
8531 {
8532   if (TARGET_VXWORKS_RTP)
8533     {
8534       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8535       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8536       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8537       DONE;
8538     }
8539
8540   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8541   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8542
8543   if (TARGET_SHMEDIA)
8544     {
8545       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8546       rtx pic = operands[0];
8547       rtx lab = PATTERN (gen_call_site ());
8548       rtx insn, equiv;
8549
8550       equiv = operands[1];
8551       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8552                                     UNSPEC_PCREL_SYMOFF);
8553       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8554
8555       if (Pmode == SImode)
8556         {
8557           emit_insn (gen_movsi_const (pic, operands[1]));
8558           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8559         }
8560       else
8561         {
8562           emit_insn (gen_movdi_const (pic, operands[1]));
8563           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8564         }
8565
8566       insn = emit_move_insn (operands[0], tr);
8567
8568       set_unique_reg_note (insn, REG_EQUAL, equiv);
8569
8570       DONE;
8571     }
8572 }
8573 ")
8574
8575 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8576 ;; PIC register.
8577
8578 (define_expand "vxworks_picreg"
8579   [(set (reg:SI PIC_REG)
8580         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8581    (set (reg:SI R0_REG)
8582         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8583    (set (reg:SI PIC_REG)
8584         (mem:SI (reg:SI PIC_REG)))
8585    (set (reg:SI PIC_REG)
8586         (mem:SI (plus:SI (reg:SI PIC_REG)
8587                          (reg:SI R0_REG))))]
8588   "TARGET_VXWORKS_RTP")
8589
8590 (define_insn "*ptb"
8591   [(set (match_operand 0 "target_reg_operand" "=b")
8592         (const (unspec [(match_operand 1 "" "Csy")]
8593                              UNSPEC_DATALABEL)))]
8594   "TARGET_SHMEDIA && flag_pic
8595    && satisfies_constraint_Csy (operands[1])"
8596   "ptb/u        datalabel %1, %0"
8597   [(set_attr "type" "ptabs_media")
8598    (set_attr "length" "*")])
8599
8600 (define_insn "ptrel_si"
8601   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8602         (plus:SI (match_operand:SI 1 "register_operand" "r")
8603               (pc)))
8604    (match_operand:SI 2 "" "")]
8605   "TARGET_SHMEDIA"
8606   "%O2: ptrel/u %1, %0"
8607   [(set_attr "type" "ptabs_media")])
8608
8609 (define_insn "ptrel_di"
8610   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8611         (plus:DI (match_operand:DI 1 "register_operand" "r")
8612               (pc)))
8613    (match_operand:DI 2 "" "")]
8614   "TARGET_SHMEDIA"
8615   "%O2: ptrel/u %1, %0"
8616   [(set_attr "type" "ptabs_media")])
8617
8618 (define_expand "builtin_setjmp_receiver"
8619   [(match_operand 0 "" "")]
8620   "flag_pic"
8621   "
8622 {
8623   emit_insn (gen_GOTaddr2picreg ());
8624   DONE;
8625 }")
8626
8627 (define_expand "call_site"
8628   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8629   "TARGET_SH1"
8630   "
8631 {
8632   static HOST_WIDE_INT i = 0;
8633   operands[0] = GEN_INT (i);
8634   i++;
8635 }")
8636
8637 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8638 ;; in symGOT_load expand.
8639
8640 (define_insn_and_split "chk_guard_add"
8641   [(set (match_operand:SI 0 "register_operand" "=&r")
8642         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8643                     (reg:SI PIC_REG)]
8644                    UNSPEC_CHKADD))]
8645   "TARGET_SH1"
8646   "#"
8647   "TARGET_SH1 && reload_completed"
8648   [(set (match_dup 0) (reg:SI PIC_REG))
8649    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8650   ""
8651   [(set_attr "type" "arith")])
8652
8653 (define_expand "sym_label2reg"
8654   [(set (match_operand:SI 0 "" "")
8655         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8656                               (const (plus:SI (match_operand:SI 2 "" "")
8657                                               (const_int 2)))]
8658                              UNSPEC_SYMOFF)))]
8659   "TARGET_SH1" "")
8660
8661 (define_expand "symGOT_load"
8662   [(set (match_dup 2) (match_operand 1 "" ""))
8663    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8664    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8665   ""
8666   "
8667 {
8668   rtx mem;
8669
8670   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8671   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8672
8673   if (TARGET_SHMEDIA)
8674     {
8675       rtx reg = operands[2];
8676
8677       if (Pmode == DImode)
8678         {      
8679           if (flag_pic > 1)
8680             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8681           else
8682             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8683         }
8684       else
8685         {
8686           if (flag_pic > 1)
8687             emit_insn (gen_movsi_const (reg, operands[1]));
8688           else
8689             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8690         }
8691     }
8692   else
8693     emit_move_insn (operands[2], operands[1]);
8694
8695   /* When stack protector inserts codes after the result is set to
8696      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8697      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8698      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8699      matter because this is a rare situation.  */
8700   if (!TARGET_SHMEDIA
8701       && flag_stack_protect
8702       && GET_CODE (operands[1]) == CONST
8703       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8704       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8705       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8706                  \"__stack_chk_guard\") == 0)
8707     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8708   else
8709     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8710                                                gen_rtx_REG (Pmode, PIC_REG)));
8711
8712   /* N.B. This is not constant for a GOTPLT relocation.  */
8713   mem = gen_rtx_MEM (Pmode, operands[3]);
8714   MEM_NOTRAP_P (mem) = 1;
8715   /* ??? Should we have a special alias set for the GOT?  */
8716   emit_move_insn (operands[0], mem);
8717
8718   DONE;
8719 }")
8720
8721 (define_expand "sym2GOT"
8722   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8723   ""
8724   "")
8725
8726 (define_expand "symGOT2reg"
8727   [(match_operand 0 "" "") (match_operand 1 "" "")]
8728   ""
8729   "
8730 {
8731   rtx gotsym, insn;
8732
8733   gotsym = gen_sym2GOT (operands[1]);
8734   PUT_MODE (gotsym, Pmode);
8735   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8736
8737   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8738
8739   DONE;
8740 }")
8741
8742 (define_expand "symGOTPLT2reg"
8743   [(match_operand 0 "" "") (match_operand 1 "" "")]
8744   ""
8745   "
8746 {
8747   rtx pltsym = gen_rtx_CONST (Pmode,
8748                               gen_rtx_UNSPEC (Pmode,
8749                                               gen_rtvec (1, operands[1]),
8750                                               UNSPEC_GOTPLT));
8751   emit_insn (gen_symGOT_load (operands[0], pltsym));
8752   DONE;
8753 }")
8754
8755 (define_expand "sym2GOTOFF"
8756   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8757   ""
8758   "")
8759
8760 (define_expand "symGOTOFF2reg"
8761   [(match_operand 0 "" "") (match_operand 1 "" "")]
8762   ""
8763   "
8764 {
8765   rtx gotoffsym, insn;
8766   rtx t = (!can_create_pseudo_p ()
8767            ? operands[0]
8768            : gen_reg_rtx (GET_MODE (operands[0])));
8769
8770   gotoffsym = gen_sym2GOTOFF (operands[1]);
8771   PUT_MODE (gotoffsym, Pmode);
8772   emit_move_insn (t, gotoffsym);
8773   insn = emit_move_insn (operands[0],
8774                          gen_rtx_PLUS (Pmode, t,
8775                                        gen_rtx_REG (Pmode, PIC_REG)));
8776
8777   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8778
8779   DONE;
8780 }")
8781
8782 (define_expand "symPLT_label2reg"
8783   [(set (match_operand:SI 0 "" "")
8784         (const:SI
8785          (unspec:SI
8786           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8787            (const:SI (plus:SI (match_operand:SI 2 "" "")
8788                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8789    ;; Even though the PIC register is not really used by the call
8790    ;; sequence in which this is expanded, the PLT code assumes the PIC
8791    ;; register is set, so we must not skip its initialization.  Since
8792    ;; we only use this expand as part of calling sequences, and never
8793    ;; to take the address of a function, this is the best point to
8794    ;; insert the (use).  Using the PLT to take the address of a
8795    ;; function would be wrong, not only because the PLT entry could
8796    ;; then be called from a function that doesn't initialize the PIC
8797    ;; register to the proper GOT, but also because pointers to the
8798    ;; same function might not compare equal, should they be set by
8799    ;; different shared libraries.
8800    (use (reg:SI PIC_REG))]
8801   "TARGET_SH1"
8802   "")
8803
8804 (define_expand "sym2PIC"
8805   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8806   ""
8807   "")
8808
8809 ;; TLS code generation.
8810 ;; ??? this should be a define_insn_and_split
8811 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8812 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8813 ;; for details.
8814
8815 (define_insn "tls_global_dynamic"
8816   [(set (match_operand:SI 0 "register_operand" "=&z")
8817         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8818                                   UNSPEC_TLSGD))
8819               (const_int 0)))
8820    (use (reg:PSI FPSCR_REG))
8821    (use (reg:SI PIC_REG))
8822    (clobber (reg:SI PR_REG))
8823    (clobber (scratch:SI))]
8824   "TARGET_SH1"
8825   "*
8826 {
8827   return \"\\
8828 mov.l\\t1f,r4\\n\\
8829 \\tmova\\t2f,r0\\n\\
8830 \\tmov.l\\t2f,r1\\n\\
8831 \\tadd\\tr0,r1\\n\\
8832 \\tjsr\\t@r1\\n\\
8833 \\tadd\\tr12,r4\\n\\
8834 \\tbra\\t3f\\n\\
8835 \\tnop\\n\\
8836 \\t.align\\t2\\n\\
8837 1:\\t.long\\t%a1@TLSGD\\n\\
8838 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8839 3:\";
8840 }"
8841   [(set_attr "type" "tls_load")
8842    (set_attr "length" "26")])
8843
8844 (define_insn "tls_local_dynamic"
8845   [(set (match_operand:SI 0 "register_operand" "=&z")
8846         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8847                                   UNSPEC_TLSLDM))
8848               (const_int 0)))
8849    (use (reg:PSI FPSCR_REG))
8850    (use (reg:SI PIC_REG))
8851    (clobber (reg:SI PR_REG))
8852    (clobber (scratch:SI))]
8853   "TARGET_SH1"
8854   "*
8855 {
8856   return \"\\
8857 mov.l\\t1f,r4\\n\\
8858 \\tmova\\t2f,r0\\n\\
8859 \\tmov.l\\t2f,r1\\n\\
8860 \\tadd\\tr0,r1\\n\\
8861 \\tjsr\\t@r1\\n\\
8862 \\tadd\\tr12,r4\\n\\
8863 \\tbra\\t3f\\n\\
8864 \\tnop\\n\\
8865 \\t.align\\t2\\n\\
8866 1:\\t.long\\t%a1@TLSLDM\\n\\
8867 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8868 3:\";
8869 }"
8870   [(set_attr "type" "tls_load")
8871    (set_attr "length" "26")])
8872
8873 (define_expand "sym2DTPOFF"
8874   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8875   ""
8876   "")
8877
8878 (define_expand "symDTPOFF2reg"
8879   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8880   ""
8881   "
8882 {
8883   rtx dtpoffsym;
8884   rtx t = (!can_create_pseudo_p ()
8885            ? operands[0]
8886            : gen_reg_rtx (GET_MODE (operands[0])));
8887
8888   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8889   PUT_MODE (dtpoffsym, Pmode);
8890   emit_move_insn (t, dtpoffsym);
8891   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8892   DONE;
8893 }")
8894
8895 (define_expand "sym2GOTTPOFF"
8896   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8897   ""
8898   "")
8899
8900 (define_insn "tls_initial_exec"
8901   [(set (match_operand:SI 0 "register_operand" "=&r")
8902         (unspec:SI [(match_operand:SI 1 "" "")]
8903                     UNSPEC_TLSIE))
8904    (use (reg:SI GBR_REG))
8905    (use (reg:SI PIC_REG))
8906    (clobber (reg:SI R0_REG))]
8907   ""
8908   "*
8909 {
8910   return \"\\
8911 mov.l\\t1f,r0\\n\\
8912 \\tstc\\tgbr,%0\\n\\
8913 \\tmov.l\\t@(r0,r12),r0\\n\\
8914 \\tbra\\t2f\\n\\
8915 \\tadd\\tr0,%0\\n\\
8916 \\t.align\\t2\\n\\
8917 1:\\t.long\\t%a1\\n\\
8918 2:\";
8919 }"
8920   [(set_attr "type" "tls_load")
8921    (set_attr "length" "16")])
8922
8923 (define_expand "sym2TPOFF"
8924   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8925   ""
8926   "")
8927
8928 (define_expand "symTPOFF2reg"
8929   [(match_operand 0 "" "") (match_operand 1 "" "")]
8930   ""
8931   "
8932 {
8933   rtx tpoffsym;
8934
8935   tpoffsym = gen_sym2TPOFF (operands[1]);
8936   PUT_MODE (tpoffsym, Pmode);
8937   emit_move_insn (operands[0], tpoffsym);
8938   DONE;
8939 }")
8940
8941 (define_insn "load_gbr"
8942   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8943    (use (reg:SI GBR_REG))]
8944   ""
8945   "stc  gbr,%0"
8946   [(set_attr "type" "tls_load")])
8947
8948 ;; case instruction for switch statements.
8949
8950 ;; Operand 0 is index
8951 ;; operand 1 is the minimum bound
8952 ;; operand 2 is the maximum bound - minimum bound + 1
8953 ;; operand 3 is CODE_LABEL for the table;
8954 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8955
8956 (define_expand "casesi"
8957   [(match_operand:SI 0 "arith_reg_operand" "")
8958    (match_operand:SI 1 "arith_reg_operand" "")
8959    (match_operand:SI 2 "arith_reg_operand" "")
8960    (match_operand 3 "" "") (match_operand 4 "" "")]
8961   ""
8962   "
8963 {
8964   rtx reg = gen_reg_rtx (SImode);
8965   rtx reg2 = gen_reg_rtx (SImode);
8966   if (TARGET_SHMEDIA)
8967     {
8968       rtx reg = gen_reg_rtx (DImode);
8969       rtx reg2 = gen_reg_rtx (DImode);
8970       rtx reg3 = gen_reg_rtx (Pmode);
8971       rtx reg4 = gen_reg_rtx (Pmode);
8972       rtx reg5 = gen_reg_rtx (Pmode);
8973       rtx load, test;
8974
8975       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8976       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8977       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8978
8979       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8980       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8981       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8982       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8983       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8984       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8985       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8986                                                (Pmode, operands[3])));
8987       /* Messy: can we subreg to clean this up? */
8988       if (Pmode == DImode)
8989         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8990       else
8991         load = gen_casesi_load_media (reg4,
8992                                       gen_rtx_SUBREG (DImode, reg3, 0),
8993                                       reg2, operands[3]);
8994       PUT_MODE (SET_SRC (load), Pmode);
8995       emit_insn (load);
8996       /* ??? The following add could be eliminated if we used ptrel.  */
8997       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8998       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8999       emit_barrier ();
9000       DONE;
9001     }
9002   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9003   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9004   /* If optimizing, casesi_worker depends on the mode of the instruction
9005      before label it 'uses' - operands[3].  */
9006   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9007                            reg));
9008   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9009   if (TARGET_SH2)
9010     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9011   else
9012     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9013   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9014      operands[3], but to lab.  We will fix this up in
9015      machine_dependent_reorg.  */
9016   emit_barrier ();
9017   DONE;
9018 }")
9019
9020 (define_expand "casesi_0"
9021   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9022    (set (match_dup 4) (minus:SI (match_dup 4)
9023                                 (match_operand:SI 1 "arith_operand" "")))
9024    (set (reg:SI T_REG)
9025         (gtu:SI (match_dup 4)
9026                 (match_operand:SI 2 "arith_reg_operand" "")))
9027    (set (pc)
9028         (if_then_else (ne (reg:SI T_REG)
9029                           (const_int 0))
9030                       (label_ref (match_operand 3 "" ""))
9031                       (pc)))]
9032   "TARGET_SH1"
9033   "")
9034
9035 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9036 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9037 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9038
9039 (define_insn "casesi_worker_0"
9040   [(set (match_operand:SI 0 "register_operand" "=r,r")
9041         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9042                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9043    (clobber (match_scratch:SI 3 "=X,1"))
9044    (clobber (match_scratch:SI 4 "=&z,z"))]
9045   "TARGET_SH1"
9046   "#")
9047
9048 (define_split
9049   [(set (match_operand:SI 0 "register_operand" "")
9050         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9051                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9052    (clobber (match_scratch:SI 3 ""))
9053    (clobber (match_scratch:SI 4 ""))]
9054   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9055   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9056    (parallel [(set (match_dup 0)
9057               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9058                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9059               (clobber (match_dup 3))])
9060    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9061   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9062
9063 (define_split
9064   [(set (match_operand:SI 0 "register_operand" "")
9065         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9066                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9067    (clobber (match_scratch:SI 3 ""))
9068    (clobber (match_scratch:SI 4 ""))]
9069   "TARGET_SH2 && reload_completed"
9070   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9071    (parallel [(set (match_dup 0)
9072               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9073                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9074               (clobber (match_dup 3))])]
9075   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9076
9077 (define_insn "casesi_worker_1"
9078   [(set (match_operand:SI 0 "register_operand" "=r,r")
9079         (unspec:SI [(reg:SI R0_REG)
9080                     (match_operand:SI 1 "register_operand" "0,r")
9081                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9082    (clobber (match_scratch:SI 3 "=X,1"))]
9083   "TARGET_SH1"
9084   "*
9085 {
9086   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9087
9088   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9089
9090   switch (GET_MODE (diff_vec))
9091     {
9092     case SImode:
9093       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9094     case HImode:
9095       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9096     case QImode:
9097       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9098         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9099       return \"mov.b    @(r0,%1),%0\";
9100     default:
9101       gcc_unreachable ();
9102     }
9103 }"
9104   [(set_attr "length" "4")])
9105
9106 (define_insn "casesi_worker_2"
9107   [(set (match_operand:SI 0 "register_operand" "=r,r")
9108         (unspec:SI [(reg:SI R0_REG)
9109                     (match_operand:SI 1 "register_operand" "0,r")
9110                     (label_ref (match_operand 2 "" ""))
9111                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9112    (clobber (match_operand:SI 4 "" "=X,1"))]
9113   "TARGET_SH2 && reload_completed && flag_pic"
9114   "*
9115 {
9116   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9117   const char *load;
9118
9119   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9120
9121   switch (GET_MODE (diff_vec))
9122     {
9123     case SImode:
9124       output_asm_insn (\"shll2    %1\", operands);
9125       load = \"mov.l    @(r0,%1),%0\"; break;
9126     case HImode:
9127       output_asm_insn (\"add    %1,%1\", operands);
9128       load = \"mov.w    @(r0,%1),%0\"; break;
9129     case QImode:
9130       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9131         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9132       else
9133         load = \"mov.b  @(r0,%1),%0\";
9134       break;
9135     default:
9136       gcc_unreachable ();
9137     }
9138   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9139   return load;
9140 }"
9141   [(set_attr "length" "8")])
9142
9143 (define_insn "casesi_shift_media"
9144   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9145         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9146                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9147                     UNSPEC_CASESI)))]
9148   "TARGET_SHMEDIA"
9149   "*
9150 {
9151   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9152
9153   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9154
9155   switch (GET_MODE (diff_vec))
9156     {
9157     case SImode:
9158       return \"shlli    %1, 2, %0\";
9159     case HImode:
9160       return \"shlli    %1, 1, %0\";
9161     case QImode:
9162       if (rtx_equal_p (operands[0], operands[1]))
9163         return \"\";
9164       return \"add      %1, r63, %0\";
9165     default:
9166       gcc_unreachable ();
9167     }
9168 }"
9169   [(set_attr "type" "arith_media")])
9170
9171 (define_insn "casesi_load_media"
9172   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9173         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9174                          (match_operand:DI 2 "arith_reg_operand" "r")
9175                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9176   "TARGET_SHMEDIA"
9177   "*
9178 {
9179   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9180
9181   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9182
9183   switch (GET_MODE (diff_vec))
9184     {
9185     case SImode:
9186       return \"ldx.l    %1, %2, %0\";
9187     case HImode:
9188 #if 0
9189       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9190         return \"ldx.uw %1, %2, %0\";
9191 #endif
9192       return \"ldx.w    %1, %2, %0\";
9193     case QImode:
9194       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9195         return \"ldx.ub %1, %2, %0\";
9196       return \"ldx.b    %1, %2, %0\";
9197     default:
9198       gcc_unreachable ();
9199     }
9200 }"
9201   [(set_attr "type" "load_media")])
9202
9203 (define_expand "return"
9204   [(return)]
9205   "reload_completed && ! sh_need_epilogue ()"
9206   "
9207 {
9208   if (TARGET_SHMEDIA)
9209     {
9210       emit_jump_insn (gen_return_media ());
9211       DONE;
9212     }
9213
9214   if (TARGET_SHCOMPACT
9215       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9216     {
9217       emit_jump_insn (gen_shcompact_return_tramp ());
9218       DONE;
9219     }
9220 }")
9221
9222 (define_insn "*return_i"
9223   [(return)]
9224   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9225                     && (crtl->args.info.call_cookie
9226                         & CALL_COOKIE_RET_TRAMP (1)))
9227    && reload_completed
9228    && lookup_attribute (\"trap_exit\",
9229                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9230   "*
9231   {
9232     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9233                         && !current_function_interrupt)
9234        return \"rts/n\";
9235     else
9236        return \"%@      %#\";
9237   }"
9238   [(set_attr "type" "return")
9239    (set_attr "needs_delay_slot" "yes")])
9240
9241 ;; trapa has no delay slot.
9242 (define_insn "*return_trapa"
9243   [(return)]
9244   "TARGET_SH1 && !TARGET_SHCOMPACT
9245    && reload_completed"
9246   "%@"
9247   [(set_attr "type" "return")])
9248
9249 (define_expand "shcompact_return_tramp"
9250   [(return)]
9251   "TARGET_SHCOMPACT
9252    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9253   "
9254 {
9255   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9256
9257   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9258   emit_jump_insn (gen_shcompact_return_tramp_i ());
9259   DONE;
9260 }")
9261
9262 (define_insn "shcompact_return_tramp_i"
9263   [(parallel [(return) (use (reg:SI R0_REG))])]
9264   "TARGET_SHCOMPACT
9265    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9266   "jmp  @r0%#"
9267   [(set_attr "type" "jump_ind")
9268    (set_attr "needs_delay_slot" "yes")])
9269
9270 (define_insn "return_media_i"
9271   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9272   "TARGET_SHMEDIA && reload_completed"
9273   "blink        %0, r63"
9274   [(set_attr "type" "jump_media")])
9275
9276 (define_insn "return_media_rte"
9277   [(return)]
9278   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9279   "rte"
9280   [(set_attr "type" "jump_media")])
9281
9282 (define_expand "return_media"
9283   [(return)]
9284   "TARGET_SHMEDIA && reload_completed"
9285   "
9286 {
9287   int tr_regno = sh_media_register_for_return ();
9288   rtx tr;
9289
9290   if (current_function_interrupt)
9291     {
9292       emit_jump_insn (gen_return_media_rte ());
9293       DONE;
9294     }
9295   if (tr_regno < 0)
9296     {
9297       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9298
9299       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9300       tr_regno = TR0_REG;
9301       tr = gen_rtx_REG (Pmode, tr_regno);
9302       emit_move_insn (tr, r18);
9303     }
9304   else
9305     tr = gen_rtx_REG (Pmode, tr_regno);
9306
9307   emit_jump_insn (gen_return_media_i (tr));
9308   DONE;
9309 }")
9310
9311 (define_insn "shcompact_preserve_incoming_args"
9312   [(set (match_operand:SI 0 "register_operand" "+r")
9313         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9314   "TARGET_SHCOMPACT"
9315   ""
9316   [(set_attr "length" "0")])
9317
9318 (define_insn "shcompact_incoming_args"
9319   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9320    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9321    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9322    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9323    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9324    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9325    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9326    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9327    (set (mem:BLK (reg:SI MACL_REG))
9328         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9329    (use (reg:SI R0_REG))
9330    (clobber (reg:SI R0_REG))
9331    (clobber (reg:SI MACL_REG))
9332    (clobber (reg:SI MACH_REG))
9333    (clobber (reg:SI PR_REG))]
9334   "TARGET_SHCOMPACT"
9335   "jsr  @r0%#"
9336   [(set_attr "needs_delay_slot" "yes")])
9337
9338 (define_insn "shmedia_save_restore_regs_compact"
9339   [(set (reg:SI SP_REG)
9340         (plus:SI (reg:SI SP_REG)
9341                  (match_operand:SI 0 "immediate_operand" "i")))
9342    (use (reg:SI R0_REG))
9343    (clobber (reg:SI PR_REG))]
9344   "TARGET_SHCOMPACT
9345    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9346        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9347   "jsr @r0%#"
9348   [(set_attr "needs_delay_slot" "yes")])
9349
9350 (define_expand "prologue"
9351   [(const_int 0)]
9352   ""
9353   "sh_expand_prologue (); DONE;")
9354
9355 (define_expand "epilogue"
9356   [(return)]
9357   ""
9358   "
9359 {
9360   sh_expand_epilogue (0);
9361   emit_jump_insn (gen_return ());
9362   DONE;
9363 }")
9364
9365 (define_expand "eh_return"
9366   [(use (match_operand 0 "register_operand" ""))]
9367   ""
9368 {
9369   rtx ra = operands[0];
9370
9371   if (TARGET_SHMEDIA64)
9372     emit_insn (gen_eh_set_ra_di (ra));
9373   else
9374     emit_insn (gen_eh_set_ra_si (ra));
9375
9376   DONE;
9377 })
9378
9379 ;; Clobber the return address on the stack.  We can't expand this
9380 ;; until we know where it will be put in the stack frame.
9381
9382 (define_insn "eh_set_ra_si"
9383   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9384       UNSPECV_EH_RETURN)
9385    (clobber (match_scratch:SI 1 "=&r"))]
9386   "! TARGET_SHMEDIA64"
9387   "#")
9388
9389 (define_insn "eh_set_ra_di"
9390   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9391       UNSPECV_EH_RETURN)
9392    (clobber (match_scratch:DI 1 "=&r"))]
9393   "TARGET_SHMEDIA64"
9394   "#")
9395
9396 (define_split
9397   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9398       UNSPECV_EH_RETURN)
9399    (clobber (match_scratch 1 ""))]
9400   "reload_completed"
9401   [(const_int 0)]
9402   "
9403 {
9404   sh_set_return_address (operands[0], operands[1]);
9405   DONE;
9406 }")
9407
9408 (define_insn "blockage"
9409   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9410   ""
9411   ""
9412   [(set_attr "length" "0")])
9413 \f
9414 ;; Define movml instructions for SH2A target.  Currently they are
9415 ;; used to push and pop all banked registers only.
9416
9417 (define_insn "movml_push_banked"
9418   [(set (match_operand:SI 0 "register_operand" "=r")
9419           (plus (match_dup 0) (const_int -32)))
9420    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9421    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9422    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9423    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9424    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9425    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9426    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9427    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9428   "TARGET_SH2A && REGNO (operands[0]) == 15"
9429   "movml.l\tr7,@-r15"
9430   [(set_attr "in_delay_slot" "no")])
9431
9432 (define_insn "movml_pop_banked"
9433   [(set (match_operand:SI 0 "register_operand" "=r")
9434           (plus (match_dup 0) (const_int 32)))
9435    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9436    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9437    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9438    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9439    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9440    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9441    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9442    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9443   "TARGET_SH2A && REGNO (operands[0]) == 15"
9444   "movml.l\t@r15+,r7"
9445   [(set_attr "in_delay_slot" "no")])
9446 \f
9447 ;; ------------------------------------------------------------------------
9448 ;; Scc instructions
9449 ;; ------------------------------------------------------------------------
9450
9451 (define_insn "movt"
9452   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9453         (eq:SI (reg:SI T_REG) (const_int 1)))]
9454   "TARGET_SH1"
9455   "movt %0"
9456   [(set_attr "type" "arith")])
9457
9458 (define_expand "cstore4_media"
9459   [(set (match_operand:SI 0 "register_operand" "=r")
9460         (match_operator:SI 1 "sh_float_comparison_operator"
9461          [(match_operand 2 "logical_operand" "")
9462           (match_operand 3 "cmp_operand" "")]))]
9463   "TARGET_SHMEDIA"
9464   "
9465 {
9466   enum machine_mode mode = GET_MODE (operands[2]);
9467   enum rtx_code code = GET_CODE (operands[1]);
9468   bool invert, swap;
9469   if (mode == VOIDmode)
9470     mode = GET_MODE (operands[3]);
9471   if (operands[2] == const0_rtx)
9472     {
9473       if (code == EQ || code == NE)
9474         operands[2] = operands[3], operands[3] = const0_rtx;
9475     }
9476   else
9477     operands[2] = force_reg (mode, operands[2]);
9478   if (operands[3] != const0_rtx)
9479     operands[3] = force_reg (mode, operands[3]);
9480
9481   switch (code)
9482     {
9483     case GEU:
9484     case GE:
9485       swap = invert = !FLOAT_MODE_P (mode);
9486       break;
9487
9488     case LEU:
9489     case LE:
9490       swap = FLOAT_MODE_P (mode), invert = !swap;
9491       break;
9492
9493     case LTU:
9494     case LT:
9495       swap = true, invert = false;
9496       break;
9497
9498     case GTU:
9499     case GT:
9500     case EQ:
9501     case UNORDERED:
9502       swap = invert = false;
9503       break;
9504
9505     case NE:
9506       swap = invert = true;
9507       break;
9508
9509     default:
9510       gcc_unreachable ();
9511   }
9512
9513   if (swap)
9514     {
9515       rtx tem = operands[2];
9516       operands[2] = operands[3];
9517       operands[3] = tem;
9518       code = swap_condition (code);
9519     }
9520
9521   if (invert)
9522     {
9523       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9524       code = reverse_condition (code);
9525       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9526       emit_insn (gen_cstore4_media (tem, operands[1],
9527                                     operands[2], operands[3]));
9528       code = EQ;
9529       operands[2] = tem;
9530       operands[3] = const0_rtx;
9531     }
9532
9533   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9534 }")
9535
9536 (define_expand "cstoresi4"
9537   [(set (match_operand:SI 0 "register_operand" "=r")
9538         (match_operator:SI 1 "comparison_operator"
9539          [(match_operand:SI 2 "cmpsi_operand" "")
9540           (match_operand:SI 3 "arith_operand" "")]))]
9541   "TARGET_SH1 || TARGET_SHMEDIA"
9542   "if (TARGET_SHMEDIA)
9543     {
9544       emit_insn (gen_cstore4_media (operands[0], operands[1],
9545                                     operands[2], operands[3]));
9546       DONE;
9547     }
9548
9549    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9550        && sh_expand_t_scc (operands))
9551      DONE;
9552
9553    if (! currently_expanding_to_rtl)
9554      FAIL;
9555    
9556    sh_emit_compare_and_set (operands, SImode);
9557    DONE;
9558 ")
9559
9560 (define_expand "cstoredi4"
9561   [(set (match_operand:SI 0 "register_operand" "=r")
9562         (match_operator:SI 1 "comparison_operator"
9563          [(match_operand:DI 2 "arith_operand" "")
9564           (match_operand:DI 3 "arith_operand" "")]))]
9565   "TARGET_SH2 || TARGET_SHMEDIA"
9566   "if (TARGET_SHMEDIA)
9567     {
9568       emit_insn (gen_cstore4_media (operands[0], operands[1],
9569                                     operands[2], operands[3]));
9570       DONE;
9571     }
9572
9573    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9574        && sh_expand_t_scc (operands))
9575      DONE;
9576
9577    if (! currently_expanding_to_rtl)
9578      FAIL;
9579    
9580    sh_emit_compare_and_set (operands, DImode);
9581    DONE;
9582 ")
9583
9584
9585
9586 ;; sne moves the complement of the T reg to DEST like this:
9587 ;;      cmp/eq ...
9588 ;;      mov    #-1,temp
9589 ;;      negc   temp,dest
9590 ;;   This is better than xoring compare result with 1 because it does
9591 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9592 ;;   loop.
9593
9594 (define_expand "movnegt"
9595   [(set (match_dup 1) (const_int -1))
9596    (parallel [(set (match_operand:SI 0 "" "")
9597                    (neg:SI (plus:SI (reg:SI T_REG)
9598                                     (match_dup 1))))
9599               (set (reg:SI T_REG)
9600                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9601                           (const_int 0)))])]
9602   ""
9603   "
9604 {
9605   operands[1] = gen_reg_rtx (SImode);
9606 }")
9607
9608
9609 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9610 ;; This prevents a regression that occurred when we switched from xor to
9611 ;; mov/neg for sne.
9612
9613 (define_split
9614   [(set (match_operand:SI 0 "arith_reg_dest" "")
9615         (plus:SI (reg:SI T_REG)
9616                  (const_int -1)))]
9617   "TARGET_SH1"
9618   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9619    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9620   "")
9621
9622 (define_expand "cstoresf4"
9623   [(set (match_operand:SI 0 "register_operand" "=r")
9624         (match_operator:SI 1 "sh_float_comparison_operator"
9625          [(match_operand:SF 2 "arith_operand" "")
9626           (match_operand:SF 3 "arith_operand" "")]))]
9627   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9628   "if (TARGET_SHMEDIA)
9629      {
9630        emit_insn (gen_cstore4_media (operands[0], operands[1],
9631                                      operands[2], operands[3]));
9632        DONE;
9633      }
9634
9635    if (! currently_expanding_to_rtl)
9636      FAIL;
9637    
9638    sh_emit_compare_and_set (operands, SFmode);
9639    DONE;
9640 ")
9641
9642 (define_expand "cstoredf4"
9643   [(set (match_operand:SI 0 "register_operand" "=r")
9644         (match_operator:SI 1 "sh_float_comparison_operator"
9645          [(match_operand:DF 2 "arith_operand" "")
9646           (match_operand:DF 3 "arith_operand" "")]))]
9647   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9648   "if (TARGET_SHMEDIA)
9649      {
9650        emit_insn (gen_cstore4_media (operands[0], operands[1],
9651                                      operands[2], operands[3]));
9652        DONE;
9653      }
9654
9655     if (! currently_expanding_to_rtl)
9656       FAIL;
9657    
9658    sh_emit_compare_and_set (operands, DFmode);
9659    DONE;
9660 ")
9661
9662
9663 ;; -------------------------------------------------------------------------
9664 ;; Instructions to cope with inline literal tables
9665 ;; -------------------------------------------------------------------------
9666
9667 ; 2 byte integer in line
9668
9669 (define_insn "consttable_2"
9670  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9671                     (match_operand 1 "" "")]
9672                    UNSPECV_CONST2)]
9673  ""
9674  "*
9675 {
9676   if (operands[1] != const0_rtx)
9677     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9678   return \"\";
9679 }"
9680  [(set_attr "length" "2")
9681  (set_attr "in_delay_slot" "no")])
9682
9683 ; 4 byte integer in line
9684
9685 (define_insn "consttable_4"
9686  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9687                     (match_operand 1 "" "")]
9688                    UNSPECV_CONST4)]
9689  ""
9690  "*
9691 {
9692   if (operands[1] != const0_rtx)
9693     {
9694       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9695       mark_symbol_refs_as_used (operands[0]);
9696     }
9697   return \"\";
9698 }"
9699  [(set_attr "length" "4")
9700   (set_attr "in_delay_slot" "no")])
9701
9702 ; 8 byte integer in line
9703
9704 (define_insn "consttable_8"
9705  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9706                     (match_operand 1 "" "")]
9707                    UNSPECV_CONST8)]
9708  ""
9709  "*
9710 {
9711   if (operands[1] != const0_rtx)
9712     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9713   return \"\";
9714 }"
9715  [(set_attr "length" "8")
9716   (set_attr "in_delay_slot" "no")])
9717
9718 ; 4 byte floating point
9719
9720 (define_insn "consttable_sf"
9721  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9722                     (match_operand 1 "" "")]
9723                    UNSPECV_CONST4)]
9724  ""
9725  "*
9726 {
9727   if (operands[1] != const0_rtx)
9728     {
9729       REAL_VALUE_TYPE d;
9730       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9731       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9732     }
9733   return \"\";
9734 }"
9735  [(set_attr "length" "4")
9736   (set_attr "in_delay_slot" "no")])
9737
9738 ; 8 byte floating point
9739
9740 (define_insn "consttable_df"
9741  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9742                     (match_operand 1 "" "")]
9743                    UNSPECV_CONST8)]
9744  ""
9745  "*
9746 {
9747   if (operands[1] != const0_rtx)
9748     {
9749       REAL_VALUE_TYPE d;
9750       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9751       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9752     }
9753   return \"\";
9754 }"
9755  [(set_attr "length" "8")
9756   (set_attr "in_delay_slot" "no")])
9757
9758 ;; Alignment is needed for some constant tables; it may also be added for
9759 ;; Instructions at the start of loops, or after unconditional branches.
9760 ;; ??? We would get more accurate lengths if we did instruction
9761 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9762 ;; here is too conservative.
9763
9764 ; align to a two byte boundary
9765
9766 (define_expand "align_2"
9767  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9768  ""
9769  "")
9770
9771 ; align to a four byte boundary
9772 ;; align_4 and align_log are instructions for the starts of loops, or
9773 ;; after unconditional branches, which may take up extra room.
9774
9775 (define_expand "align_4"
9776  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9777  ""
9778  "")
9779
9780 ; align to a cache line boundary
9781
9782 (define_insn "align_log"
9783  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9784  ""
9785  ""
9786  [(set_attr "length" "0")
9787   (set_attr "in_delay_slot" "no")])
9788
9789 ; emitted at the end of the literal table, used to emit the
9790 ; 32bit branch labels if needed.
9791
9792 (define_insn "consttable_end"
9793   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9794   ""
9795   "* return output_jump_label_table ();"
9796   [(set_attr "in_delay_slot" "no")])
9797
9798 ; emitted at the end of the window in the literal table.
9799
9800 (define_insn "consttable_window_end"
9801   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9802   ""
9803   ""
9804   [(set_attr "length" "0")
9805    (set_attr "in_delay_slot" "no")])
9806
9807 ;; -------------------------------------------------------------------------
9808 ;; Misc
9809 ;; -------------------------------------------------------------------------
9810
9811 ;; String/block move insn.
9812
9813 (define_expand "movmemsi"
9814   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9815                    (mem:BLK (match_operand:BLK 1 "" "")))
9816               (use (match_operand:SI 2 "nonmemory_operand" ""))
9817               (use (match_operand:SI 3 "immediate_operand" ""))
9818               (clobber (reg:SI PR_REG))
9819               (clobber (reg:SI R4_REG))
9820               (clobber (reg:SI R5_REG))
9821               (clobber (reg:SI R0_REG))])]
9822   "TARGET_SH1 && ! TARGET_SH5"
9823   "
9824 {
9825   if(expand_block_move (operands))
9826      DONE;
9827   else FAIL;
9828 }")
9829
9830 (define_insn "block_move_real"
9831   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9832                    (mem:BLK (reg:SI R5_REG)))
9833               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9834               (clobber (reg:SI PR_REG))
9835               (clobber (reg:SI R0_REG))])]
9836   "TARGET_SH1 && ! TARGET_HARD_SH4"
9837   "jsr  @%0%#"
9838   [(set_attr "type" "sfunc")
9839    (set_attr "needs_delay_slot" "yes")])
9840
9841 (define_insn "block_lump_real"
9842   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9843                    (mem:BLK (reg:SI R5_REG)))
9844               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9845               (use (reg:SI R6_REG))
9846               (clobber (reg:SI PR_REG))
9847               (clobber (reg:SI T_REG))
9848               (clobber (reg:SI R4_REG))
9849               (clobber (reg:SI R5_REG))
9850               (clobber (reg:SI R6_REG))
9851               (clobber (reg:SI R0_REG))])]
9852   "TARGET_SH1 && ! TARGET_HARD_SH4"
9853   "jsr  @%0%#"
9854   [(set_attr "type" "sfunc")
9855    (set_attr "needs_delay_slot" "yes")])
9856
9857 (define_insn "block_move_real_i4"
9858   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9859                    (mem:BLK (reg:SI R5_REG)))
9860               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9861               (clobber (reg:SI PR_REG))
9862               (clobber (reg:SI R0_REG))
9863               (clobber (reg:SI R1_REG))
9864               (clobber (reg:SI R2_REG))])]
9865   "TARGET_HARD_SH4"
9866   "jsr  @%0%#"
9867   [(set_attr "type" "sfunc")
9868    (set_attr "needs_delay_slot" "yes")])
9869
9870 (define_insn "block_lump_real_i4"
9871   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9872                    (mem:BLK (reg:SI R5_REG)))
9873               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9874               (use (reg:SI R6_REG))
9875               (clobber (reg:SI PR_REG))
9876               (clobber (reg:SI T_REG))
9877               (clobber (reg:SI R4_REG))
9878               (clobber (reg:SI R5_REG))
9879               (clobber (reg:SI R6_REG))
9880               (clobber (reg:SI R0_REG))
9881               (clobber (reg:SI R1_REG))
9882               (clobber (reg:SI R2_REG))
9883               (clobber (reg:SI R3_REG))])]
9884   "TARGET_HARD_SH4"
9885   "jsr  @%0%#"
9886   [(set_attr "type" "sfunc")
9887    (set_attr "needs_delay_slot" "yes")])
9888 \f
9889 ;; -------------------------------------------------------------------------
9890 ;; Floating point instructions.
9891 ;; -------------------------------------------------------------------------
9892
9893 ;; ??? All patterns should have a type attribute.
9894
9895 (define_expand "movpsi"
9896   [(set (match_operand:PSI 0 "register_operand" "")
9897         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9898   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9899   "")
9900
9901 ;; The c / m alternative is a fake to guide reload to load directly into
9902 ;; fpscr, since reload doesn't know how to use post-increment.
9903 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9904 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9905 ;; predicate after reload.
9906 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9907 ;; like a mac -> gpr move.
9908 (define_insn "fpu_switch"
9909   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9910         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9911   "TARGET_SH2E
9912    && (! reload_completed
9913        || true_regnum (operands[0]) != FPSCR_REG
9914        || !MEM_P (operands[1])
9915        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9916   "@
9917         ! precision stays the same
9918         lds.l   %1,fpscr
9919         mov.l   %1,%0
9920         #
9921         lds     %1,fpscr
9922         mov     %1,%0
9923         mov.l   %1,%0
9924         sts     fpscr,%0
9925         sts.l   fpscr,%0"
9926   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9927    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9928
9929 (define_peephole2
9930   [(set (reg:PSI FPSCR_REG)
9931         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9932   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9933   [(const_int 0)]
9934 {
9935   rtx fpscr, mem, new_insn;
9936
9937   fpscr = SET_DEST (PATTERN (curr_insn));
9938   mem = SET_SRC (PATTERN (curr_insn));
9939   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9940
9941   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9942   add_reg_note (new_insn, REG_INC, operands[0]);
9943   DONE;
9944 })
9945
9946 (define_split
9947   [(set (reg:PSI FPSCR_REG)
9948         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9949   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9950    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9951   [(const_int 0)]
9952 {
9953   rtx fpscr, mem, new_insn;
9954
9955   fpscr = SET_DEST (PATTERN (curr_insn));
9956   mem = SET_SRC (PATTERN (curr_insn));
9957   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9958
9959   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9960   add_reg_note (new_insn, REG_INC, operands[0]);
9961
9962   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9963     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9964   DONE;
9965 })
9966
9967 ;; ??? This uses the fp unit, but has no type indicating that.
9968 ;; If we did that, this would either give a bogus latency or introduce
9969 ;; a bogus FIFO constraint.
9970 ;; Since this insn is currently only used for prologues/epilogues,
9971 ;; it is probably best to claim no function unit, which matches the
9972 ;; current setting.
9973 (define_insn "toggle_sz"
9974   [(set (reg:PSI FPSCR_REG)
9975         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9976   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9977   "fschg"
9978   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9979
9980 ;; There's no way we can use it today, since optimize mode switching
9981 ;; doesn't enable us to know from which mode we're switching to the
9982 ;; mode it requests, to tell whether we can use a relative mode switch
9983 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9984 ;; memory).
9985 (define_insn "toggle_pr"
9986   [(set (reg:PSI FPSCR_REG)
9987         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9988   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9989   "fpchg"
9990   [(set_attr "type" "fpscr_toggle")])
9991
9992 (define_expand "addsf3"
9993   [(set (match_operand:SF 0 "arith_reg_operand" "")
9994         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9995                  (match_operand:SF 2 "arith_reg_operand" "")))]
9996   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9997   "
9998 {
9999   if (TARGET_SH2E)
10000     {
10001       expand_sf_binop (&gen_addsf3_i, operands);
10002       DONE;
10003     }
10004 }")
10005
10006 (define_insn "*addsf3_media"
10007   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10008         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10009                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10010   "TARGET_SHMEDIA_FPU"
10011   "fadd.s       %1, %2, %0"
10012   [(set_attr "type" "fparith_media")])
10013
10014 (define_insn_and_split "unary_sf_op"
10015   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10016         (vec_select:V2SF
10017          (vec_concat:V2SF
10018           (vec_select:SF
10019            (match_dup 0)
10020            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10021           (match_operator:SF 2 "unary_float_operator"
10022             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10023                             (parallel [(match_operand 4
10024                                         "const_int_operand" "n")]))]))
10025          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10026   "TARGET_SHMEDIA_FPU"
10027   "#"
10028   "TARGET_SHMEDIA_FPU && reload_completed"
10029   [(set (match_dup 5) (match_dup 6))]
10030   "
10031 {
10032   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10033   rtx op1 = gen_rtx_REG (SFmode,
10034                          (true_regnum (operands[1])
10035                           + (INTVAL (operands[4]) ^ endian)));
10036
10037   operands[7] = gen_rtx_REG (SFmode,
10038                              (true_regnum (operands[0])
10039                               + (INTVAL (operands[3]) ^ endian)));
10040   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10041 }"
10042   [(set_attr "type" "fparith_media")])
10043
10044 (define_insn_and_split "binary_sf_op0"
10045   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10046         (vec_concat:V2SF
10047           (match_operator:SF 3 "binary_float_operator"
10048             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10049                             (parallel [(const_int 0)]))
10050              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10051                             (parallel [(const_int 0)]))])
10052           (vec_select:SF
10053            (match_dup 0)
10054            (parallel [(const_int 1)]))))]
10055   "TARGET_SHMEDIA_FPU"
10056   "#"
10057   "&& reload_completed"
10058   [(set (match_dup 4) (match_dup 5))]
10059   "
10060 {
10061   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10062   rtx op1 = gen_rtx_REG (SFmode,
10063                          true_regnum (operands[1]) + endian);
10064   rtx op2 = gen_rtx_REG (SFmode,
10065                          true_regnum (operands[2]) + endian);
10066
10067   operands[4] = gen_rtx_REG (SFmode,
10068                              true_regnum (operands[0]) + endian);
10069   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10070 }"
10071   [(set_attr "type" "fparith_media")])
10072
10073 (define_insn_and_split "binary_sf_op1"
10074   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10075         (vec_concat:V2SF
10076           (vec_select:SF
10077            (match_dup 0)
10078            (parallel [(const_int 0)]))
10079           (match_operator:SF 3 "binary_float_operator"
10080             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10081                             (parallel [(const_int 1)]))
10082              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10083                             (parallel [(const_int 1)]))])))]
10084   "TARGET_SHMEDIA_FPU"
10085   "#"
10086   "&& reload_completed"
10087   [(set (match_dup 4) (match_dup 5))]
10088   "
10089 {
10090   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10091   rtx op1 = gen_rtx_REG (SFmode,
10092                          true_regnum (operands[1]) + (1 ^ endian));
10093   rtx op2 = gen_rtx_REG (SFmode,
10094                          true_regnum (operands[2]) + (1 ^ endian));
10095
10096   operands[4] = gen_rtx_REG (SFmode,
10097                              true_regnum (operands[0]) + (1 ^ endian));
10098   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10099 }"
10100   [(set_attr "type" "fparith_media")])
10101
10102 (define_insn "addsf3_i"
10103   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10104         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10105                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10106    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10107   "TARGET_SH2E"
10108   "fadd %2,%0"
10109   [(set_attr "type" "fp")
10110    (set_attr "fp_mode" "single")])
10111
10112 (define_expand "subsf3"
10113   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10114         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10115                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10116   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10117   "
10118 {
10119   if (TARGET_SH2E)
10120     {
10121       expand_sf_binop (&gen_subsf3_i, operands);
10122       DONE;
10123     }
10124 }")
10125
10126 (define_insn "*subsf3_media"
10127   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10128         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10129                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10130   "TARGET_SHMEDIA_FPU"
10131   "fsub.s       %1, %2, %0"
10132   [(set_attr "type" "fparith_media")])
10133
10134 (define_insn "subsf3_i"
10135   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10136         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10137                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10138    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10139   "TARGET_SH2E"
10140   "fsub %2,%0"
10141   [(set_attr "type" "fp")
10142    (set_attr "fp_mode" "single")])
10143
10144 (define_expand "mulsf3"
10145   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10146         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10147                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10148   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10149   "")
10150
10151 (define_insn "*mulsf3_media"
10152   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10153         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10154                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10155   "TARGET_SHMEDIA_FPU"
10156   "fmul.s       %1, %2, %0"
10157   [(set_attr "type" "fparith_media")])
10158
10159 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10160 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10161 ;; we start out with a mulsf pattern that does not depend on fpscr.
10162 ;; This is split after combine to introduce the dependency, in order to
10163 ;; get mode switching and scheduling right.
10164 (define_insn_and_split "mulsf3_ie"
10165   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10166         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10167                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10168   "TARGET_SH2E"
10169   "fmul %2,%0"
10170   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10171   [(const_int 0)]
10172   "
10173 {
10174   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10175              get_fpscr_rtx ()));
10176   DONE;
10177 }"
10178   [(set_attr "type" "fp")])
10179
10180 (define_insn "mulsf3_i4"
10181   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10182         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10183                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10184    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10185   "TARGET_SH2E"
10186   "fmul %2,%0"
10187   [(set_attr "type" "fp")
10188    (set_attr "fp_mode" "single")])
10189
10190 (define_insn "mac_media"
10191   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10192         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10193                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10194                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10195   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10196   "fmac.s %1, %2, %0"
10197   [(set_attr "type" "fparith_media")])
10198
10199 (define_insn "*macsf3"
10200   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10201         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10202                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10203                  (match_operand:SF 3 "arith_reg_operand" "0")))
10204    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10205   "TARGET_SH2E && TARGET_FMAC"
10206   "fmac fr0,%2,%0"
10207   [(set_attr "type" "fp")
10208    (set_attr "fp_mode" "single")])
10209
10210 (define_expand "divsf3"
10211   [(set (match_operand:SF 0 "arith_reg_operand" "")
10212         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10213                 (match_operand:SF 2 "arith_reg_operand" "")))]
10214   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10215   "
10216 {
10217   if (TARGET_SH2E)
10218     {
10219       expand_sf_binop (&gen_divsf3_i, operands);
10220       DONE;
10221     }
10222 }")
10223
10224 (define_insn "*divsf3_media"
10225   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10226         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10227                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10228   "TARGET_SHMEDIA_FPU"
10229   "fdiv.s       %1, %2, %0"
10230   [(set_attr "type" "fdiv_media")])
10231
10232 (define_insn "divsf3_i"
10233   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10234         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10235                  (match_operand:SF 2 "arith_reg_operand" "f")))
10236    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10237   "TARGET_SH2E"
10238   "fdiv %2,%0"
10239   [(set_attr "type" "fdiv")
10240    (set_attr "fp_mode" "single")])
10241
10242 (define_insn "floatdisf2"
10243   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10244         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10245   "TARGET_SHMEDIA_FPU"
10246   "float.qs %1, %0"
10247   [(set_attr "type" "fpconv_media")])
10248
10249 (define_expand "floatsisf2"
10250   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10251         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10252   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10253   "
10254 {
10255   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10256     {
10257       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10258       DONE;
10259     }
10260 }")
10261
10262 (define_insn "*floatsisf2_media"
10263   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10264         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10265   "TARGET_SHMEDIA_FPU"
10266   "float.ls     %1, %0"
10267   [(set_attr "type" "fpconv_media")])
10268
10269 (define_insn "floatsisf2_i4"
10270   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10271         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10272    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10273   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10274   "float        %1,%0"
10275   [(set_attr "type" "fp")
10276    (set_attr "fp_mode" "single")])
10277
10278 (define_insn "*floatsisf2_ie"
10279   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10280         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10281   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10282   "float        %1,%0"
10283   [(set_attr "type" "fp")])
10284
10285 (define_insn "fix_truncsfdi2"
10286   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10287         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10288   "TARGET_SHMEDIA_FPU"
10289   "ftrc.sq %1, %0"
10290   [(set_attr "type" "fpconv_media")])
10291
10292 (define_expand "fix_truncsfsi2"
10293   [(set (match_operand:SI 0 "fpul_operand" "=y")
10294         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10295   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10296   "
10297 {
10298   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10299     {
10300       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10301       DONE;
10302     }
10303 }")
10304
10305 (define_insn "*fix_truncsfsi2_media"
10306   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10307         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10308   "TARGET_SHMEDIA_FPU"
10309   "ftrc.sl      %1, %0"
10310   [(set_attr "type" "fpconv_media")])
10311
10312 (define_insn "fix_truncsfsi2_i4"
10313   [(set (match_operand:SI 0 "fpul_operand" "=y")
10314         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10315    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10316   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10317   "ftrc %1,%0"
10318   [(set_attr "type" "ftrc_s")
10319    (set_attr "fp_mode" "single")])
10320
10321 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10322 ;; fix_truncsfsi2_i4.
10323 ;; (define_insn "fix_truncsfsi2_i4_2"
10324 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10325 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10326 ;;   (use (reg:PSI FPSCR_REG))
10327 ;;   (clobber (reg:SI FPUL_REG))]
10328 ;;  "TARGET_SH4"
10329 ;;  "#"
10330 ;;  [(set_attr "length" "4")
10331 ;;   (set_attr "fp_mode" "single")])
10332
10333 ;;(define_split
10334 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10335 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10336 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10337 ;;   (clobber (reg:SI FPUL_REG))]
10338 ;;  "TARGET_SH4"
10339 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10340 ;;            (use (match_dup 2))])
10341 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10342
10343 (define_insn "*fixsfsi"
10344   [(set (match_operand:SI 0 "fpul_operand" "=y")
10345         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10346   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10347   "ftrc %1,%0"
10348   [(set_attr "type" "fp")])
10349
10350 (define_insn "cmpgtsf_t"
10351   [(set (reg:SI T_REG)
10352         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10353                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10354   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10355   "fcmp/gt      %1,%0"
10356   [(set_attr "type" "fp_cmp")
10357    (set_attr "fp_mode" "single")])
10358
10359 (define_insn "cmpeqsf_t"
10360   [(set (reg:SI T_REG)
10361         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10362                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10363   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10364   "fcmp/eq      %1,%0"
10365   [(set_attr "type" "fp_cmp")
10366    (set_attr "fp_mode" "single")])
10367
10368 (define_insn "ieee_ccmpeqsf_t"
10369   [(set (reg:SI T_REG)
10370         (ior:SI (reg:SI T_REG)
10371                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10372                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10373   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10374   "* return output_ieee_ccmpeq (insn, operands);"
10375   [(set_attr "length" "4")])
10376
10377
10378 (define_insn "cmpgtsf_t_i4"
10379   [(set (reg:SI T_REG)
10380         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10381                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10382    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10383   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10384   "fcmp/gt      %1,%0"
10385   [(set_attr "type" "fp_cmp")
10386    (set_attr "fp_mode" "single")])
10387
10388 (define_insn "cmpeqsf_t_i4"
10389   [(set (reg:SI T_REG)
10390         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10391                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10392    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10393   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10394   "fcmp/eq      %1,%0"
10395   [(set_attr "type" "fp_cmp")
10396    (set_attr "fp_mode" "single")])
10397
10398 (define_insn "*ieee_ccmpeqsf_t_4"
10399   [(set (reg:SI T_REG)
10400         (ior:SI (reg:SI T_REG)
10401                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10402                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10403    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10404   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10405   "* return output_ieee_ccmpeq (insn, operands);"
10406   [(set_attr "length" "4")
10407    (set_attr "fp_mode" "single")])
10408
10409 (define_insn "cmpeqsf_media"
10410   [(set (match_operand:SI 0 "register_operand" "=r")
10411         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10412                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10413   "TARGET_SHMEDIA_FPU"
10414   "fcmpeq.s     %1, %2, %0"
10415   [(set_attr "type" "fcmp_media")])
10416
10417 (define_insn "cmpgtsf_media"
10418   [(set (match_operand:SI 0 "register_operand" "=r")
10419         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10420                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10421   "TARGET_SHMEDIA_FPU"
10422   "fcmpgt.s     %1, %2, %0"
10423   [(set_attr "type" "fcmp_media")])
10424
10425 (define_insn "cmpgesf_media"
10426   [(set (match_operand:SI 0 "register_operand" "=r")
10427         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10428                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10429   "TARGET_SHMEDIA_FPU"
10430   "fcmpge.s     %1, %2, %0"
10431   [(set_attr "type" "fcmp_media")])
10432
10433 (define_insn "cmpunsf_media"
10434   [(set (match_operand:SI 0 "register_operand" "=r")
10435         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10436                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10437   "TARGET_SHMEDIA_FPU"
10438   "fcmpun.s     %1, %2, %0"
10439   [(set_attr "type" "fcmp_media")])
10440
10441 (define_expand "cbranchsf4"
10442   [(set (pc)
10443         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10444                        [(match_operand:SF 1 "arith_operand" "")
10445                         (match_operand:SF 2 "arith_operand" "")])
10446                       (match_operand 3 "" "")
10447                       (pc)))]
10448   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10449   "
10450 {
10451   if (TARGET_SHMEDIA)
10452     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10453                                           operands[3]));
10454   else
10455     sh_emit_compare_and_branch (operands, SFmode);
10456   DONE;
10457 }")
10458
10459 (define_expand "negsf2"
10460   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10461         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10462   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10463   "
10464 {
10465   if (TARGET_SH2E)
10466     {
10467       expand_sf_unop (&gen_negsf2_i, operands);
10468       DONE;
10469     }
10470 }")
10471
10472 (define_insn "*negsf2_media"
10473   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10474         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10475   "TARGET_SHMEDIA_FPU"
10476   "fneg.s       %1, %0"
10477   [(set_attr "type" "fmove_media")])
10478
10479 (define_insn "negsf2_i"
10480   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10481         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10482    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10483   "TARGET_SH2E"
10484   "fneg %0"
10485   [(set_attr "type" "fmove")
10486    (set_attr "fp_mode" "single")])
10487
10488 (define_expand "sqrtsf2"
10489   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10490         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10491   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10492   "
10493 {
10494   if (TARGET_SH3E)
10495     {
10496       expand_sf_unop (&gen_sqrtsf2_i, operands);
10497       DONE;
10498     }
10499 }")
10500
10501 (define_insn "*sqrtsf2_media"
10502   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10503         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10504   "TARGET_SHMEDIA_FPU"
10505   "fsqrt.s      %1, %0"
10506   [(set_attr "type" "fdiv_media")])
10507
10508 (define_insn "sqrtsf2_i"
10509   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10510         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10511    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10512   "TARGET_SH3E"
10513   "fsqrt        %0"
10514   [(set_attr "type" "fdiv")
10515    (set_attr "fp_mode" "single")])
10516
10517 (define_insn "rsqrtsf2"
10518   [(set (match_operand:SF 0 "register_operand" "=f")
10519         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10520                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10521    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10522   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10523    && operands[1] == CONST1_RTX (SFmode)"
10524   "fsrra        %0"
10525   [(set_attr "type" "fsrra")
10526    (set_attr "fp_mode" "single")])
10527
10528 (define_insn "fsca"
10529   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10530         (vec_concat:V2SF
10531          (unspec:SF [(mult:SF
10532                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10533                       (match_operand:SF 2 "immediate_operand" "i"))
10534                     ] UNSPEC_FSINA)
10535          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10536                     ] UNSPEC_FCOSA)))
10537    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10538   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10539    && operands[2] == sh_fsca_int2sf ()"
10540   "fsca fpul,%d0"
10541   [(set_attr "type" "fsca")
10542    (set_attr "fp_mode" "single")])
10543
10544 (define_expand "sinsf2"
10545   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10546         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10547                    UNSPEC_FSINA))]
10548   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10549   "
10550 {
10551   rtx scaled = gen_reg_rtx (SFmode);
10552   rtx truncated = gen_reg_rtx (SImode);
10553   rtx fsca = gen_reg_rtx (V2SFmode);
10554   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10555
10556   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10557   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10558   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10559                           get_fpscr_rtx ()));
10560   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10561   DONE;
10562 }")
10563
10564 (define_expand "cossf2"
10565   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10566         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10567                    UNSPEC_FCOSA))]
10568   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10569   "
10570 {
10571   rtx scaled = gen_reg_rtx (SFmode);
10572   rtx truncated = gen_reg_rtx (SImode);
10573   rtx fsca = gen_reg_rtx (V2SFmode);
10574   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10575
10576   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10577   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10578   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10579                           get_fpscr_rtx ()));
10580   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10581   DONE;
10582 }")
10583
10584 (define_expand "sindf2"
10585   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10586         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10587                    UNSPEC_FSINA))]
10588   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10589   "
10590 {
10591   rtx scaled = gen_reg_rtx (DFmode);
10592   rtx truncated = gen_reg_rtx (SImode);
10593   rtx fsca = gen_reg_rtx (V2SFmode);
10594   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10595   rtx sfresult = gen_reg_rtx (SFmode);
10596
10597   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10598   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10599   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10600                           get_fpscr_rtx ()));
10601   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10602   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10603   DONE;
10604 }")
10605
10606 (define_expand "cosdf2"
10607   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10608         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10609                    UNSPEC_FCOSA))]
10610   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10611   "
10612 {
10613   rtx scaled = gen_reg_rtx (DFmode);
10614   rtx truncated = gen_reg_rtx (SImode);
10615   rtx fsca = gen_reg_rtx (V2SFmode);
10616   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10617   rtx sfresult = gen_reg_rtx (SFmode);
10618
10619   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10620   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10621   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10622                           get_fpscr_rtx ()));
10623   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10624   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10625   DONE;
10626 }")
10627
10628 (define_expand "abssf2"
10629   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10630         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10631   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10632   "
10633 {
10634   if (TARGET_SH2E)
10635     {
10636       expand_sf_unop (&gen_abssf2_i, operands);
10637       DONE;
10638     }
10639 }")
10640
10641 (define_insn "*abssf2_media"
10642   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10643         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10644   "TARGET_SHMEDIA_FPU"
10645   "fabs.s       %1, %0"
10646   [(set_attr "type" "fmove_media")])
10647
10648 (define_insn "abssf2_i"
10649   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10650         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10651    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10652   "TARGET_SH2E"
10653   "fabs %0"
10654   [(set_attr "type" "fmove")
10655    (set_attr "fp_mode" "single")])
10656
10657 (define_expand "adddf3"
10658   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10659         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10660                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10661   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10662   "
10663 {
10664   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10665     {
10666       expand_df_binop (&gen_adddf3_i, operands);
10667       DONE;
10668     }
10669 }")
10670
10671 (define_insn "*adddf3_media"
10672   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10673         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10674                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10675   "TARGET_SHMEDIA_FPU"
10676   "fadd.d       %1, %2, %0"
10677   [(set_attr "type" "dfparith_media")])
10678
10679 (define_insn "adddf3_i"
10680   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10681         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10682                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10683    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10684   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10685   "fadd %2,%0"
10686   [(set_attr "type" "dfp_arith")
10687    (set_attr "fp_mode" "double")])
10688
10689 (define_expand "subdf3"
10690   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10691         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10692                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10693   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10694   "
10695 {
10696   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10697     {
10698       expand_df_binop (&gen_subdf3_i, operands);
10699       DONE;
10700     }
10701 }")
10702
10703 (define_insn "*subdf3_media"
10704   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10705         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10706                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10707   "TARGET_SHMEDIA_FPU"
10708   "fsub.d       %1, %2, %0"
10709   [(set_attr "type" "dfparith_media")])
10710
10711 (define_insn "subdf3_i"
10712   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10713         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10714                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10715    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10716   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10717   "fsub %2,%0"
10718   [(set_attr "type" "dfp_arith")
10719    (set_attr "fp_mode" "double")])
10720
10721 (define_expand "muldf3"
10722   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10723         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10724                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10725   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10726   "
10727 {
10728   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10729     {
10730       expand_df_binop (&gen_muldf3_i, operands);
10731       DONE;
10732     }
10733 }")
10734
10735 (define_insn "*muldf3_media"
10736   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10737         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10738                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10739   "TARGET_SHMEDIA_FPU"
10740   "fmul.d       %1, %2, %0"
10741   [(set_attr "type" "dfmul_media")])
10742
10743 (define_insn "muldf3_i"
10744   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10745         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10746                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10747    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10748   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10749   "fmul %2,%0"
10750   [(set_attr "type" "dfp_mul")
10751    (set_attr "fp_mode" "double")])
10752
10753 (define_expand "divdf3"
10754   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10755         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10756                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10757   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10758   "
10759 {
10760   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10761     {
10762       expand_df_binop (&gen_divdf3_i, operands);
10763       DONE;
10764     }
10765 }")
10766
10767 (define_insn "*divdf3_media"
10768   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10769         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10770                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10771   "TARGET_SHMEDIA_FPU"
10772   "fdiv.d       %1, %2, %0"
10773   [(set_attr "type" "dfdiv_media")])
10774
10775 (define_insn "divdf3_i"
10776   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10777         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10778                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10779    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10780   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10781   "fdiv %2,%0"
10782   [(set_attr "type" "dfdiv")
10783    (set_attr "fp_mode" "double")])
10784
10785 (define_insn "floatdidf2"
10786   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10787         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10788   "TARGET_SHMEDIA_FPU"
10789   "float.qd     %1, %0"
10790   [(set_attr "type" "dfpconv_media")])
10791
10792 (define_expand "floatsidf2"
10793   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10794         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10795   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10796   "
10797 {
10798   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10799     {
10800       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10801                                       get_fpscr_rtx ()));
10802       DONE;
10803     }
10804 }")
10805
10806 (define_insn "*floatsidf2_media"
10807   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10808         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10809   "TARGET_SHMEDIA_FPU"
10810   "float.ld     %1, %0"
10811   [(set_attr "type" "dfpconv_media")])
10812
10813 (define_insn "floatsidf2_i"
10814   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10815         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10816    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10817   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10818   "float        %1,%0"
10819   [(set_attr "type" "dfp_conv")
10820    (set_attr "fp_mode" "double")])
10821
10822 (define_insn "fix_truncdfdi2"
10823   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10824         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10825   "TARGET_SHMEDIA_FPU"
10826   "ftrc.dq      %1, %0"
10827   [(set_attr "type" "dfpconv_media")])
10828
10829 (define_expand "fix_truncdfsi2"
10830   [(set (match_operand:SI 0 "fpul_operand" "")
10831         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10832   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10833   "
10834 {
10835   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10836     {
10837       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10838                                           get_fpscr_rtx ()));
10839       DONE;
10840     }
10841 }")
10842
10843 (define_insn "*fix_truncdfsi2_media"
10844   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10845         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10846   "TARGET_SHMEDIA_FPU"
10847   "ftrc.dl      %1, %0"
10848   [(set_attr "type" "dfpconv_media")])
10849
10850 (define_insn "fix_truncdfsi2_i"
10851   [(set (match_operand:SI 0 "fpul_operand" "=y")
10852         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10853    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10854   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10855   "ftrc %1,%0"
10856   [(set_attr "type" "dfp_conv")
10857    (set_attr "dfp_comp" "no")
10858    (set_attr "fp_mode" "double")])
10859
10860 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10861 ;; fix_truncdfsi2_i.
10862 ;; (define_insn "fix_truncdfsi2_i4"
10863 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10864 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10865 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10866 ;;    (clobber (reg:SI FPUL_REG))]
10867 ;;   "TARGET_SH4"
10868 ;;   "#"
10869 ;;   [(set_attr "length" "4")
10870 ;;    (set_attr "fp_mode" "double")])
10871 ;;
10872 ;; (define_split
10873 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10874 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10875 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10876 ;;    (clobber (reg:SI FPUL_REG))]
10877 ;;   "TARGET_SH4"
10878 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10879 ;;            (use (match_dup 2))])
10880 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10881
10882 (define_insn "cmpgtdf_t"
10883   [(set (reg:SI T_REG)
10884         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10885                (match_operand:DF 1 "arith_reg_operand" "f")))
10886    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10887   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10888   "fcmp/gt      %1,%0"
10889   [(set_attr "type" "dfp_cmp")
10890    (set_attr "fp_mode" "double")])
10891
10892 (define_insn "cmpeqdf_t"
10893   [(set (reg:SI T_REG)
10894         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10895                (match_operand:DF 1 "arith_reg_operand" "f")))
10896    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10897   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10898   "fcmp/eq      %1,%0"
10899   [(set_attr "type" "dfp_cmp")
10900    (set_attr "fp_mode" "double")])
10901
10902 (define_insn "*ieee_ccmpeqdf_t"
10903   [(set (reg:SI T_REG)
10904         (ior:SI (reg:SI T_REG)
10905                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10906                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10907    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10908   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10909   "* return output_ieee_ccmpeq (insn, operands);"
10910   [(set_attr "length" "4")
10911    (set_attr "fp_mode" "double")])
10912
10913 (define_insn "cmpeqdf_media"
10914   [(set (match_operand:SI 0 "register_operand" "=r")
10915         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10916                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10917   "TARGET_SHMEDIA_FPU"
10918   "fcmpeq.d     %1,%2,%0"
10919   [(set_attr "type" "fcmp_media")])
10920
10921 (define_insn "cmpgtdf_media"
10922   [(set (match_operand:SI 0 "register_operand" "=r")
10923         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10924                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10925   "TARGET_SHMEDIA_FPU"
10926   "fcmpgt.d     %1,%2,%0"
10927   [(set_attr "type" "fcmp_media")])
10928
10929 (define_insn "cmpgedf_media"
10930   [(set (match_operand:SI 0 "register_operand" "=r")
10931         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10932                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10933   "TARGET_SHMEDIA_FPU"
10934   "fcmpge.d     %1,%2,%0"
10935   [(set_attr "type" "fcmp_media")])
10936
10937 (define_insn "cmpundf_media"
10938   [(set (match_operand:SI 0 "register_operand" "=r")
10939         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10940                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10941   "TARGET_SHMEDIA_FPU"
10942   "fcmpun.d     %1,%2,%0"
10943   [(set_attr "type" "fcmp_media")])
10944
10945 (define_expand "cbranchdf4"
10946   [(set (pc)
10947         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10948                        [(match_operand:DF 1 "arith_operand" "")
10949                         (match_operand:DF 2 "arith_operand" "")])
10950                       (match_operand 3 "" "")
10951                       (pc)))]
10952   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10953   "
10954 {
10955   if (TARGET_SHMEDIA)
10956     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10957                                           operands[3]));
10958   else
10959     sh_emit_compare_and_branch (operands, DFmode);
10960   DONE;
10961 }")
10962
10963
10964 (define_expand "negdf2"
10965   [(set (match_operand:DF 0 "arith_reg_operand" "")
10966         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10967   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10968   "
10969 {
10970   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10971     {
10972       expand_df_unop (&gen_negdf2_i, operands);
10973       DONE;
10974     }
10975 }")
10976
10977 (define_insn "*negdf2_media"
10978   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10979         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10980   "TARGET_SHMEDIA_FPU"
10981   "fneg.d       %1, %0"
10982   [(set_attr "type" "fmove_media")])
10983
10984 (define_insn "negdf2_i"
10985   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10986         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10987    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10988   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10989   "fneg %0"
10990   [(set_attr "type" "fmove")
10991    (set_attr "fp_mode" "double")])
10992
10993 (define_expand "sqrtdf2"
10994   [(set (match_operand:DF 0 "arith_reg_operand" "")
10995         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10996   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10997   "
10998 {
10999   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11000     {
11001       expand_df_unop (&gen_sqrtdf2_i, operands);
11002       DONE;
11003     }
11004 }")
11005
11006 (define_insn "*sqrtdf2_media"
11007   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11008         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11009   "TARGET_SHMEDIA_FPU"
11010   "fsqrt.d      %1, %0"
11011   [(set_attr "type" "dfdiv_media")])
11012
11013 (define_insn "sqrtdf2_i"
11014   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11015         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11016    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11017   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11018   "fsqrt        %0"
11019   [(set_attr "type" "dfdiv")
11020    (set_attr "fp_mode" "double")])
11021
11022 (define_expand "absdf2"
11023   [(set (match_operand:DF 0 "arith_reg_operand" "")
11024         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11025   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11026   "
11027 {
11028   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11029     {
11030       expand_df_unop (&gen_absdf2_i, operands);
11031       DONE;
11032     }
11033 }")
11034
11035 (define_insn "*absdf2_media"
11036   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11037         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11038   "TARGET_SHMEDIA_FPU"
11039   "fabs.d       %1, %0"
11040   [(set_attr "type" "fmove_media")])
11041
11042 (define_insn "absdf2_i"
11043   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11044         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11045    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11046   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11047   "fabs %0"
11048   [(set_attr "type" "fmove")
11049    (set_attr "fp_mode" "double")])
11050
11051 (define_expand "extendsfdf2"
11052   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11053         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11054   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11055   "
11056 {
11057   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11058     {
11059       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11060                                         get_fpscr_rtx ()));
11061       DONE;
11062     }
11063 }")
11064
11065 (define_insn "*extendsfdf2_media"
11066   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11067         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11068   "TARGET_SHMEDIA_FPU"
11069   "fcnv.sd      %1, %0"
11070   [(set_attr "type" "dfpconv_media")])
11071
11072 (define_insn "extendsfdf2_i4"
11073   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11074         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11075    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11076   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11077   "fcnvsd  %1,%0"
11078   [(set_attr "type" "fp")
11079    (set_attr "fp_mode" "double")])
11080
11081 (define_expand "truncdfsf2"
11082   [(set (match_operand:SF 0 "fpul_operand" "")
11083         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11084   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11085   "
11086 {
11087   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11088     {
11089       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11090                                        get_fpscr_rtx ()));
11091       DONE;
11092     }
11093 }")
11094
11095 (define_insn "*truncdfsf2_media"
11096   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11097         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11098   "TARGET_SHMEDIA_FPU"
11099   "fcnv.ds      %1, %0"
11100   [(set_attr "type" "dfpconv_media")])
11101
11102 (define_insn "truncdfsf2_i4"
11103   [(set (match_operand:SF 0 "fpul_operand" "=y")
11104         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11105    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11106   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11107   "fcnvds  %1,%0"
11108   [(set_attr "type" "fp")
11109    (set_attr "fp_mode" "double")])
11110 \f
11111 ;; Bit field extract patterns.  These give better code for packed bitfields,
11112 ;; because they allow auto-increment addresses to be generated.
11113
11114 (define_expand "insv"
11115   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11116                          (match_operand:SI 1 "immediate_operand" "")
11117                          (match_operand:SI 2 "immediate_operand" ""))
11118         (match_operand:SI 3 "general_operand" ""))]
11119   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11120   "
11121 {
11122   rtx addr_target, orig_address, shift_reg, qi_val;
11123   HOST_WIDE_INT bitsize, size, v = 0;
11124   rtx x = operands[3];
11125
11126   if (TARGET_SH2A && TARGET_BITOPS
11127       && (satisfies_constraint_Sbw (operands[0])
11128           || satisfies_constraint_Sbv (operands[0]))
11129       && satisfies_constraint_M (operands[1])
11130       && satisfies_constraint_K03 (operands[2]))
11131     {
11132       if (satisfies_constraint_N (operands[3]))
11133         {
11134           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11135           DONE;
11136         }
11137       else if (satisfies_constraint_M (operands[3]))
11138         {
11139           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11140           DONE;
11141         }
11142       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11143                 && satisfies_constraint_M (operands[1]))
11144         {
11145           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11146           DONE;
11147         }
11148       else if (REG_P (operands[3])
11149                && satisfies_constraint_M (operands[1]))
11150         {
11151           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11152           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11153           DONE;
11154         }
11155     }
11156   /* ??? expmed doesn't care for non-register predicates.  */
11157   if (! memory_operand (operands[0], VOIDmode)
11158       || ! immediate_operand (operands[1], VOIDmode)
11159       || ! immediate_operand (operands[2], VOIDmode)
11160       || ! general_operand (x, VOIDmode))
11161     FAIL;
11162   /* If this isn't a 16 / 24 / 32 bit field, or if
11163      it doesn't start on a byte boundary, then fail.  */
11164   bitsize = INTVAL (operands[1]);
11165   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11166       || (INTVAL (operands[2]) % 8) != 0)
11167     FAIL;
11168
11169   size = bitsize / 8;
11170   orig_address = XEXP (operands[0], 0);
11171   shift_reg = gen_reg_rtx (SImode);
11172   if (CONST_INT_P (x))
11173     {
11174       v = INTVAL (x);
11175       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11176     }
11177   else
11178     {
11179       emit_insn (gen_movsi (shift_reg, operands[3]));
11180       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11181     }
11182   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11183
11184   operands[0] = replace_equiv_address (operands[0], addr_target);
11185   emit_insn (gen_movqi (operands[0], qi_val));
11186
11187   while (size -= 1)
11188     {
11189       if (CONST_INT_P (x))
11190         qi_val
11191           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11192       else
11193         {
11194           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11195           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11196         }
11197       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11198       emit_insn (gen_movqi (operands[0], qi_val));
11199     }
11200
11201   DONE;
11202 }")
11203
11204 (define_insn "movua"
11205   [(set (match_operand:SI 0 "register_operand" "=z")
11206         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11207                    UNSPEC_MOVUA))]
11208   "TARGET_SH4A_ARCH"
11209   "movua.l      %1,%0"
11210   [(set_attr "type" "movua")])
11211
11212 ;; We shouldn't need this, but cse replaces increments with references
11213 ;; to other regs before flow has a chance to create post_inc
11214 ;; addressing modes, and only postreload's cse_move2add brings the
11215 ;; increments back to a usable form.
11216 (define_peephole2
11217   [(set (match_operand:SI 0 "register_operand" "")
11218         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11219                          (const_int 32) (const_int 0)))
11220    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11221   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11222   [(set (match_operand:SI 0 "register_operand" "")
11223         (sign_extract:SI (mem:SI (post_inc:SI
11224                                   (match_operand:SI 1 "register_operand" "")))
11225                          (const_int 32) (const_int 0)))]
11226   "")
11227
11228 (define_expand "extv"
11229   [(set (match_operand:SI 0 "register_operand" "")
11230         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11231                          (match_operand 2 "const_int_operand" "")
11232                          (match_operand 3 "const_int_operand" "")))]
11233   "TARGET_SH4A_ARCH || TARGET_SH2A"
11234 {
11235   if (TARGET_SH2A && TARGET_BITOPS
11236       && (satisfies_constraint_Sbw (operands[1])
11237           || satisfies_constraint_Sbv (operands[1]))
11238       && satisfies_constraint_M (operands[2])
11239       && satisfies_constraint_K03 (operands[3]))
11240    {
11241       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11242       if (REGNO (operands[0]) != T_REG)
11243         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11244       DONE;
11245    }
11246   if (TARGET_SH4A_ARCH
11247       && INTVAL (operands[2]) == 32
11248       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11249       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11250     {
11251       rtx src = adjust_address (operands[1], BLKmode, 0);
11252       set_mem_size (src, 4);
11253       emit_insn (gen_movua (operands[0], src));
11254       DONE;
11255     }
11256
11257   FAIL;
11258 })
11259
11260 (define_expand "extzv"
11261   [(set (match_operand:SI 0 "register_operand" "")
11262         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11263                          (match_operand 2 "const_int_operand" "")
11264                          (match_operand 3 "const_int_operand" "")))]
11265   "TARGET_SH4A_ARCH || TARGET_SH2A"
11266 {
11267   if (TARGET_SH2A && TARGET_BITOPS
11268       && (satisfies_constraint_Sbw (operands[1])
11269           || satisfies_constraint_Sbv (operands[1]))
11270       && satisfies_constraint_M (operands[2])
11271       && satisfies_constraint_K03 (operands[3]))
11272     {
11273       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11274       if (REGNO (operands[0]) != T_REG)
11275         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11276       DONE;
11277     }
11278   if (TARGET_SH4A_ARCH
11279       && INTVAL (operands[2]) == 32
11280       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11281       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11282     {
11283       rtx src = adjust_address (operands[1], BLKmode, 0);
11284       set_mem_size (src, 4);
11285       emit_insn (gen_movua (operands[0], src));
11286       DONE;
11287     }
11288
11289   FAIL;
11290 })
11291
11292 ;; SH2A instructions for bitwise operations.
11293
11294 ;; Clear a bit in a memory location.
11295 (define_insn "bclr_m2a"
11296   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11297         (and:QI
11298             (not:QI (ashift:QI (const_int 1)
11299                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11300             (match_dup 0)))]
11301   "TARGET_SH2A && TARGET_BITOPS"
11302   "@
11303         bclr.b\\t%1,%0
11304         bclr.b\\t%1,@(0,%t0)"
11305 [(set_attr "length" "4,4")])
11306
11307 (define_insn "bclrmem_m2a"
11308   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11309         (and:QI (match_dup 0)
11310                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11311   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11312   "@
11313         bclr.b\\t%W1,%0
11314         bclr.b\\t%W1,@(0,%t0)"
11315   [(set_attr "length" "4,4")])
11316
11317 ;; Set a bit in a memory location.
11318 (define_insn "bset_m2a"
11319   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11320         (ior:QI
11321             (ashift:QI (const_int 1)
11322                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11323             (match_dup 0)))]
11324   "TARGET_SH2A && TARGET_BITOPS"
11325   "@
11326         bset.b\\t%1,%0
11327         bset.b\\t%1,@(0,%t0)"
11328   [(set_attr "length" "4,4")])
11329
11330 (define_insn "bsetmem_m2a"
11331   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11332         (ior:QI (match_dup 0)
11333                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11334   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11335   "@
11336         bset.b\\t%V1,%0
11337         bset.b\\t%V1,@(0,%t0)"
11338   [(set_attr "length" "4,4")])
11339
11340 ;;; Transfer the contents of the T bit to a specified bit of memory.
11341 (define_insn "bst_m2a"
11342   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11343         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11344             (and:QI
11345                 (not:QI (ashift:QI (const_int 1)
11346                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11347                 (match_dup 0))
11348             (ior:QI
11349                 (ashift:QI (const_int 1) (match_dup 1))
11350                 (match_dup 0))))]
11351   "TARGET_SH2A && TARGET_BITOPS"
11352   "@
11353         bst.b\\t%1,%0
11354         bst.b\\t%1,@(0,%t0)"
11355   [(set_attr "length" "4")])
11356
11357 ;; Store a specified bit of memory in the T bit.
11358 (define_insn "bld_m2a"
11359   [(set (reg:SI T_REG)
11360         (zero_extract:SI
11361             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11362             (const_int 1)
11363             (match_operand 1 "const_int_operand" "K03,K03")))]
11364   "TARGET_SH2A && TARGET_BITOPS"
11365   "@
11366         bld.b\\t%1,%0
11367         bld.b\\t%1,@(0,%t0)"
11368   [(set_attr "length" "4,4")])
11369
11370 ;; Store a specified bit of memory in the T bit.
11371 (define_insn "bldsign_m2a"
11372   [(set (reg:SI T_REG)
11373         (sign_extract:SI
11374             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11375             (const_int 1)
11376             (match_operand 1 "const_int_operand" "K03,K03")))]
11377   "TARGET_SH2A && TARGET_BITOPS"
11378   "@
11379         bld.b\\t%1,%0
11380         bld.b\\t%1,@(0,%t0)"
11381   [(set_attr "length" "4,4")])
11382
11383 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11384 (define_insn "bld_reg"
11385   [(set (reg:SI T_REG)
11386         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11387                          (const_int 1)
11388                          (match_operand 1 "const_int_operand" "K03")))]
11389   "TARGET_SH2A"
11390   "bld\\t%1,%0")
11391
11392 (define_insn "*bld_regqi"
11393   [(set (reg:SI T_REG)
11394         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11395                          (const_int 1)
11396                          (match_operand 1 "const_int_operand" "K03")))]
11397   "TARGET_SH2A"
11398   "bld\\t%1,%0")
11399
11400 ;; Take logical and of a specified bit of memory with the T bit and
11401 ;; store its result in the T bit.
11402 (define_insn "band_m2a"
11403   [(set (reg:SI T_REG)
11404         (and:SI (reg:SI T_REG)
11405                 (zero_extract:SI
11406                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11407                     (const_int 1)
11408                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11409   "TARGET_SH2A && TARGET_BITOPS"
11410   "@
11411         band.b\\t%1,%0
11412         band.b\\t%1,@(0,%t0)"
11413   [(set_attr "length" "4,4")])
11414
11415 (define_insn "bandreg_m2a"
11416   [(set (match_operand:SI 0 "register_operand" "=r,r")
11417         (and:SI (zero_extract:SI
11418                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11419                     (const_int 1)
11420                     (match_operand 2 "const_int_operand" "K03,K03"))
11421                 (match_operand:SI 3 "register_operand" "r,r")))]
11422   "TARGET_SH2A && TARGET_BITOPS"
11423   "@
11424         band.b\\t%2,%1\;movt\\t%0
11425         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11426   [(set_attr "length" "6,6")])
11427
11428 ;; Take logical or of a specified bit of memory with the T bit and
11429 ;; store its result in the T bit.
11430 (define_insn "bor_m2a"
11431   [(set (reg:SI T_REG)
11432         (ior:SI (reg:SI T_REG)
11433                 (zero_extract:SI
11434                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11435                     (const_int 1)
11436                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11437   "TARGET_SH2A && TARGET_BITOPS"
11438   "@
11439         bor.b\\t%1,%0
11440         bor.b\\t%1,@(0,%t0)"
11441   [(set_attr "length" "4,4")])
11442
11443 (define_insn "borreg_m2a"
11444   [(set (match_operand:SI 0 "register_operand" "=r,r")
11445         (ior:SI (zero_extract:SI
11446                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11447                     (const_int 1)
11448                     (match_operand 2 "const_int_operand" "K03,K03"))
11449                 (match_operand:SI 3 "register_operand" "=r,r")))]
11450   "TARGET_SH2A && TARGET_BITOPS"
11451   "@
11452         bor.b\\t%2,%1\;movt\\t%0
11453         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11454   [(set_attr "length" "6,6")])
11455
11456 ;; Take exclusive or of a specified bit of memory with the T bit and
11457 ;; store its result in the T bit.
11458 (define_insn "bxor_m2a"
11459   [(set (reg:SI T_REG)
11460         (xor:SI (reg:SI T_REG)
11461                 (zero_extract:SI
11462                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11463                     (const_int 1)
11464                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11465   "TARGET_SH2A && TARGET_BITOPS"
11466   "@
11467         bxor.b\\t%1,%0
11468         bxor.b\\t%1,@(0,%t0)"
11469   [(set_attr "length" "4,4")])
11470
11471 (define_insn "bxorreg_m2a"
11472   [(set (match_operand:SI 0 "register_operand" "=r,r")
11473         (xor:SI (zero_extract:SI
11474                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11475                     (const_int 1)
11476                     (match_operand 2 "const_int_operand" "K03,K03"))
11477                 (match_operand:SI 3 "register_operand" "=r,r")))]
11478   "TARGET_SH2A && TARGET_BITOPS"
11479   "@
11480         bxor.b\\t%2,%1\;movt\\t%0
11481         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11482   [(set_attr "length" "6,6")])
11483
11484 \f
11485 ;; -------------------------------------------------------------------------
11486 ;; Peepholes
11487 ;; -------------------------------------------------------------------------
11488 ;; This matches cases where the bit in a memory location is set.
11489 (define_peephole2
11490   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11491         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11492    (set (match_dup 0)
11493         (ior:SI (match_dup 0)
11494         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11495    (set (match_dup 1)
11496         (match_operand 3 "arith_reg_operand" "r,r"))]
11497   "TARGET_SH2A && TARGET_BITOPS
11498    && satisfies_constraint_Pso (operands[2])
11499    && REGNO (operands[0]) == REGNO (operands[3])"
11500   [(set (match_dup 1)
11501         (ior:QI (match_dup 1)
11502                 (match_dup 2)))]
11503   "")
11504
11505 ;; This matches cases where the bit in a memory location is cleared.
11506 (define_peephole2
11507   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11508         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11509    (set (match_dup 0)
11510         (and:SI (match_dup 0)
11511         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11512    (set (match_dup 1)
11513         (match_operand 3 "arith_reg_operand" "r,r"))]
11514   "TARGET_SH2A && TARGET_BITOPS
11515    && satisfies_constraint_Psz (operands[2])
11516    && REGNO (operands[0]) == REGNO (operands[3])"
11517   [(set (match_dup 1)
11518         (and:QI (match_dup 1)
11519                 (match_dup 2)))]
11520   "")
11521
11522 ;; This matches cases where a stack pointer increment at the start of the
11523 ;; epilogue combines with a stack slot read loading the return value.
11524
11525 (define_peephole
11526   [(set (match_operand:SI 0 "arith_reg_operand" "")
11527         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11528    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11529   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11530   "mov.l        @%1+,%0")
11531
11532 ;; See the comment on the dt combiner pattern above.
11533
11534 (define_peephole
11535   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11536         (plus:SI (match_dup 0)
11537                  (const_int -1)))
11538    (set (reg:SI T_REG)
11539         (eq:SI (match_dup 0)
11540                (const_int 0)))]
11541   "TARGET_SH2"
11542   "dt   %0")
11543
11544 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11545 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11546 ;; reload when the constant is too large for a reg+offset address.
11547
11548 ;; ??? We would get much better code if this was done in reload.  This would
11549 ;; require modifying find_reloads_address to recognize that if the constant
11550 ;; is out-of-range for an immediate add, then we get better code by reloading
11551 ;; the constant into a register than by reloading the sum into a register,
11552 ;; since the former is one instruction shorter if the address does not need
11553 ;; to be offsettable.  Unfortunately this does not work, because there is
11554 ;; only one register, r0, that can be used as an index register.  This register
11555 ;; is also the function return value register.  So, if we try to force reload
11556 ;; to use double-reg addresses, then we end up with some instructions that
11557 ;; need to use r0 twice.  The only way to fix this is to change the calling
11558 ;; convention so that r0 is not used to return values.
11559
11560 (define_peephole
11561   [(set (match_operand:SI 0 "register_operand" "=r")
11562         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11563    (set (mem:SI (match_dup 0))
11564         (match_operand:SI 2 "general_movsrc_operand" ""))]
11565   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11566   "mov.l        %2,@(%0,%1)")
11567
11568 (define_peephole
11569   [(set (match_operand:SI 0 "register_operand" "=r")
11570         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11571    (set (match_operand:SI 2 "general_movdst_operand" "")
11572         (mem:SI (match_dup 0)))]
11573   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11574   "mov.l        @(%0,%1),%2")
11575
11576 (define_peephole
11577   [(set (match_operand:SI 0 "register_operand" "=r")
11578         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11579    (set (mem:HI (match_dup 0))
11580         (match_operand:HI 2 "general_movsrc_operand" ""))]
11581   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11582   "mov.w        %2,@(%0,%1)")
11583
11584 (define_peephole
11585   [(set (match_operand:SI 0 "register_operand" "=r")
11586         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11587    (set (match_operand:HI 2 "general_movdst_operand" "")
11588         (mem:HI (match_dup 0)))]
11589   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11590   "mov.w        @(%0,%1),%2")
11591
11592 (define_peephole
11593   [(set (match_operand:SI 0 "register_operand" "=r")
11594         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11595    (set (mem:QI (match_dup 0))
11596         (match_operand:QI 2 "general_movsrc_operand" ""))]
11597   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11598   "mov.b        %2,@(%0,%1)")
11599
11600 (define_peephole
11601   [(set (match_operand:SI 0 "register_operand" "=r")
11602         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11603    (set (match_operand:QI 2 "general_movdst_operand" "")
11604         (mem:QI (match_dup 0)))]
11605   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11606   "mov.b        @(%0,%1),%2")
11607
11608 (define_peephole
11609   [(set (match_operand:SI 0 "register_operand" "=r")
11610         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11611    (set (mem:SF (match_dup 0))
11612         (match_operand:SF 2 "general_movsrc_operand" ""))]
11613   "TARGET_SH1 && REGNO (operands[0]) == 0
11614    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11615        || (GET_CODE (operands[2]) == SUBREG
11616            && REGNO (SUBREG_REG (operands[2])) < 16))
11617    && reg_unused_after (operands[0], insn)"
11618   "mov.l        %2,@(%0,%1)")
11619
11620 (define_peephole
11621   [(set (match_operand:SI 0 "register_operand" "=r")
11622         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11623    (set (match_operand:SF 2 "general_movdst_operand" "")
11624
11625         (mem:SF (match_dup 0)))]
11626   "TARGET_SH1 && REGNO (operands[0]) == 0
11627    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11628        || (GET_CODE (operands[2]) == SUBREG
11629            && REGNO (SUBREG_REG (operands[2])) < 16))
11630    && reg_unused_after (operands[0], insn)"
11631   "mov.l        @(%0,%1),%2")
11632
11633 (define_peephole
11634   [(set (match_operand:SI 0 "register_operand" "=r")
11635         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11636    (set (mem:SF (match_dup 0))
11637         (match_operand:SF 2 "general_movsrc_operand" ""))]
11638   "TARGET_SH2E && REGNO (operands[0]) == 0
11639    && ((REG_P (operands[2])
11640         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11641        || (GET_CODE (operands[2]) == SUBREG
11642            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11643    && reg_unused_after (operands[0], insn)"
11644   "fmov{.s|}    %2,@(%0,%1)")
11645
11646 (define_peephole
11647   [(set (match_operand:SI 0 "register_operand" "=r")
11648         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11649    (set (match_operand:SF 2 "general_movdst_operand" "")
11650
11651         (mem:SF (match_dup 0)))]
11652   "TARGET_SH2E && REGNO (operands[0]) == 0
11653    && ((REG_P (operands[2])
11654         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11655        || (GET_CODE (operands[2]) == SUBREG
11656            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11657    && reg_unused_after (operands[0], insn)"
11658   "fmov{.s|}    @(%0,%1),%2")
11659
11660 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11661 (define_insn "sp_switch_1"
11662   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11663   "TARGET_SH1"
11664   "*
11665 {
11666   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11667   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11668   return \"mov r0,r15\";
11669 }"
11670   [(set_attr "length" "10")])
11671
11672 ;; Switch back to the original stack for interrupt functions with the
11673 ;; sp_switch attribute.  */
11674 (define_insn "sp_switch_2"
11675   [(const_int 2)]
11676   "TARGET_SH1"
11677   "mov.l @r15+,r15\;mov.l @r15+,r0"
11678   [(set_attr "length" "4")])
11679
11680 ;; Integer vector moves
11681
11682 (define_expand "movv8qi"
11683   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11684         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11685   "TARGET_SHMEDIA"
11686   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11687
11688 (define_insn "movv8qi_i"
11689   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11690         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11691   "TARGET_SHMEDIA
11692    && (register_operand (operands[0], V8QImode)
11693        || sh_register_operand (operands[1], V8QImode))"
11694   "@
11695         add     %1, r63, %0
11696         movi    %1, %0
11697         #
11698         ld%M1.q %m1, %0
11699         st%M0.q %m0, %N1"
11700   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11701    (set_attr "length" "4,4,16,4,4")])
11702
11703 (define_split
11704   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11705         (subreg:V8QI (const_int 0) 0))]
11706   "TARGET_SHMEDIA"
11707   [(set (match_dup 0)
11708         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11709                             (const_int 0) (const_int 0) (const_int 0)
11710                             (const_int 0) (const_int 0)]))])
11711
11712 (define_split
11713   [(set (match_operand 0 "arith_reg_dest" "")
11714         (match_operand 1 "sh_rep_vec" ""))]
11715   "TARGET_SHMEDIA && reload_completed
11716    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11717    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11718    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11719    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11720        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11721    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11722        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11723   [(set (match_dup 0) (match_dup 1))
11724    (match_dup 2)]
11725   "
11726 {
11727   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11728   rtx elt1 = XVECEXP (operands[1], 0, 1);
11729
11730   if (unit_size > 2)
11731     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11732   else
11733     {
11734       if (unit_size < 2)
11735         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11736       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11737     }
11738   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11739   operands[1] = XVECEXP (operands[1], 0, 0);
11740   if (unit_size < 2)
11741     {
11742       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11743         operands[1]
11744           = GEN_INT (TARGET_LITTLE_ENDIAN
11745                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11746                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11747       else
11748         {
11749           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11750           operands[1]
11751             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11752         }
11753     }
11754 }")
11755
11756 (define_split
11757   [(set (match_operand 0 "arith_reg_dest" "")
11758         (match_operand 1 "sh_const_vec" ""))]
11759   "TARGET_SHMEDIA && reload_completed
11760    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11761    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11762   [(set (match_dup 0) (match_dup 1))]
11763   "
11764 {
11765   rtx v = operands[1];
11766   enum machine_mode new_mode
11767     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11768
11769   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11770   operands[1]
11771     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11772 }")
11773
11774 (define_expand "movv2hi"
11775   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11776         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11777   "TARGET_SHMEDIA"
11778   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11779
11780 (define_insn "movv2hi_i"
11781   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11782         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11783   "TARGET_SHMEDIA
11784    && (register_operand (operands[0], V2HImode)
11785        || sh_register_operand (operands[1], V2HImode))"
11786   "@
11787         add.l   %1, r63, %0
11788         movi    %1, %0
11789         #
11790         ld%M1.l %m1, %0
11791         st%M0.l %m0, %N1"
11792   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11793    (set_attr "length" "4,4,16,4,4")
11794    (set (attr "highpart")
11795         (cond [(match_test "sh_contains_memref_p (insn)")
11796                (const_string "user")]
11797               (const_string "ignore")))])
11798
11799 (define_expand "movv4hi"
11800   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11801         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11802   "TARGET_SHMEDIA"
11803   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11804
11805 (define_insn "movv4hi_i"
11806   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11807         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11808   "TARGET_SHMEDIA
11809    && (register_operand (operands[0], V4HImode)
11810        || sh_register_operand (operands[1], V4HImode))"
11811   "@
11812         add     %1, r63, %0
11813         movi    %1, %0
11814         #
11815         ld%M1.q %m1, %0
11816         st%M0.q %m0, %N1"
11817   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11818    (set_attr "length" "4,4,16,4,4")
11819    (set_attr "highpart" "depend")])
11820
11821 (define_expand "movv2si"
11822   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11823         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11824   "TARGET_SHMEDIA"
11825   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11826
11827 (define_insn "movv2si_i"
11828   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11829         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11830   "TARGET_SHMEDIA
11831    && (register_operand (operands[0], V2SImode)
11832        || sh_register_operand (operands[1], V2SImode))"
11833   "@
11834         add     %1, r63, %0
11835         #
11836         #
11837         ld%M1.q %m1, %0
11838         st%M0.q %m0, %N1"
11839   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11840    (set_attr "length" "4,4,16,4,4")
11841    (set_attr "highpart" "depend")])
11842
11843 ;; Multimedia Intrinsics
11844
11845 (define_insn "absv2si2"
11846   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11847         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11848   "TARGET_SHMEDIA"
11849   "mabs.l       %1, %0"
11850   [(set_attr "type" "mcmp_media")
11851    (set_attr "highpart" "depend")])
11852
11853 (define_insn "absv4hi2"
11854   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11855         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11856   "TARGET_SHMEDIA"
11857   "mabs.w       %1, %0"
11858   [(set_attr "type" "mcmp_media")
11859    (set_attr "highpart" "depend")])
11860
11861 (define_insn "addv2si3"
11862   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11863         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11864                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11865   "TARGET_SHMEDIA"
11866   "madd.l       %1, %2, %0"
11867   [(set_attr "type" "arith_media")
11868    (set_attr "highpart" "depend")])
11869
11870 (define_insn "addv4hi3"
11871   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11872         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11873                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11874   "TARGET_SHMEDIA"
11875   "madd.w       %1, %2, %0"
11876   [(set_attr "type" "arith_media")
11877    (set_attr "highpart" "depend")])
11878
11879 (define_insn_and_split "addv2hi3"
11880   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11881         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11882                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11883   "TARGET_SHMEDIA"
11884   "#"
11885   "TARGET_SHMEDIA"
11886   [(const_int 0)]
11887   "
11888 {
11889   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11890   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11891   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11892   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11893   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11894
11895   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11896   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11897   DONE;
11898 }"
11899   [(set_attr "highpart" "must_split")])
11900
11901 (define_insn "ssaddv2si3"
11902   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11903         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11904                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11905   "TARGET_SHMEDIA"
11906   "madds.l      %1, %2, %0"
11907   [(set_attr "type" "mcmp_media")
11908    (set_attr "highpart" "depend")])
11909
11910 (define_insn "usaddv8qi3"
11911   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11912         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11913                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11914   "TARGET_SHMEDIA"
11915   "madds.ub     %1, %2, %0"
11916   [(set_attr "type" "mcmp_media")
11917    (set_attr "highpart" "depend")])
11918
11919 (define_insn "ssaddv4hi3"
11920   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11921         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11922                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11923   "TARGET_SHMEDIA"
11924   "madds.w      %1, %2, %0"
11925   [(set_attr "type" "mcmp_media")
11926    (set_attr "highpart" "depend")])
11927
11928 (define_insn "negcmpeqv8qi"
11929   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11930         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11931                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11932   "TARGET_SHMEDIA"
11933   "mcmpeq.b     %N1, %N2, %0"
11934   [(set_attr "type" "mcmp_media")
11935    (set_attr "highpart" "depend")])
11936
11937 (define_insn "negcmpeqv2si"
11938   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11939         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11940                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11941   "TARGET_SHMEDIA"
11942   "mcmpeq.l     %N1, %N2, %0"
11943   [(set_attr "type" "mcmp_media")
11944    (set_attr "highpart" "depend")])
11945
11946 (define_insn "negcmpeqv4hi"
11947   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11948         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11949                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11950   "TARGET_SHMEDIA"
11951   "mcmpeq.w     %N1, %N2, %0"
11952   [(set_attr "type" "mcmp_media")
11953    (set_attr "highpart" "depend")])
11954
11955 (define_insn "negcmpgtuv8qi"
11956   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11957         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11958                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11959   "TARGET_SHMEDIA"
11960   "mcmpgt.ub    %N1, %N2, %0"
11961   [(set_attr "type" "mcmp_media")
11962    (set_attr "highpart" "depend")])
11963
11964 (define_insn "negcmpgtv2si"
11965   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11966         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11967                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11968   "TARGET_SHMEDIA"
11969   "mcmpgt.l     %N1, %N2, %0"
11970   [(set_attr "type" "mcmp_media")
11971    (set_attr "highpart" "depend")])
11972
11973 (define_insn "negcmpgtv4hi"
11974   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11975         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11976                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11977   "TARGET_SHMEDIA"
11978   "mcmpgt.w     %N1, %N2, %0"
11979   [(set_attr "type" "mcmp_media")
11980    (set_attr "highpart" "depend")])
11981
11982 (define_insn "mcmv"
11983   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11984         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11985                         (match_operand:DI 2 "arith_reg_operand" "r"))
11986                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11987                         (not:DI (match_dup 2)))))]
11988   "TARGET_SHMEDIA"
11989   "mcmv %N1, %2, %0"
11990   [(set_attr "type" "arith_media")
11991    (set_attr "highpart" "depend")])
11992
11993 (define_insn "mcnvs_lw"
11994   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11995         (vec_concat:V4HI
11996          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11997          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11998   "TARGET_SHMEDIA"
11999   "mcnvs.lw     %N1, %N2, %0"
12000   [(set_attr "type" "mcmp_media")])
12001
12002 (define_insn "mcnvs_wb"
12003   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12004         (vec_concat:V8QI
12005          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12006          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12007   "TARGET_SHMEDIA"
12008   "mcnvs.wb     %N1, %N2, %0"
12009   [(set_attr "type" "mcmp_media")])
12010
12011 (define_insn "mcnvs_wub"
12012   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12013         (vec_concat:V8QI
12014          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12015          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12016   "TARGET_SHMEDIA"
12017   "mcnvs.wub    %N1, %N2, %0"
12018   [(set_attr "type" "mcmp_media")])
12019
12020 (define_insn "mextr_rl"
12021   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12022         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12023                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12024                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12025                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12026   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12027   "*
12028 {
12029   static char templ[21];
12030
12031   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12032            (int) INTVAL (operands[3]) >> 3);
12033   return templ;
12034 }"
12035   [(set_attr "type" "arith_media")])
12036
12037 (define_insn "*mextr_lr"
12038   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12039         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12040                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12041                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12042                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12043   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12044   "*
12045 {
12046   static char templ[21];
12047
12048   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12049            (int) INTVAL (operands[4]) >> 3);
12050   return templ;
12051 }"
12052   [(set_attr "type" "arith_media")])
12053
12054 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12055 ; vector then varies depending on endianness.
12056 (define_expand "mextr1"
12057   [(match_operand:DI 0 "arith_reg_dest" "")
12058    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12059    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12060   "TARGET_SHMEDIA"
12061   "
12062 {
12063   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12064                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12065   DONE;
12066 }")
12067
12068 (define_expand "mextr2"
12069   [(match_operand:DI 0 "arith_reg_dest" "")
12070    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12071    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12072   "TARGET_SHMEDIA"
12073   "
12074 {
12075   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12076                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12077   DONE;
12078 }")
12079
12080 (define_expand "mextr3"
12081   [(match_operand:DI 0 "arith_reg_dest" "")
12082    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12083    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12084   "TARGET_SHMEDIA"
12085   "
12086 {
12087   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12088                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12089   DONE;
12090 }")
12091
12092 (define_expand "mextr4"
12093   [(match_operand:DI 0 "arith_reg_dest" "")
12094    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12095    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12096   "TARGET_SHMEDIA"
12097   "
12098 {
12099   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12100                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12101   DONE;
12102 }")
12103
12104 (define_expand "mextr5"
12105   [(match_operand:DI 0 "arith_reg_dest" "")
12106    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12107    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12108   "TARGET_SHMEDIA"
12109   "
12110 {
12111   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12112                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12113   DONE;
12114 }")
12115
12116 (define_expand "mextr6"
12117   [(match_operand:DI 0 "arith_reg_dest" "")
12118    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12119    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12120   "TARGET_SHMEDIA"
12121   "
12122 {
12123   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12124                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12125   DONE;
12126 }")
12127
12128 (define_expand "mextr7"
12129   [(match_operand:DI 0 "arith_reg_dest" "")
12130    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12131    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12132   "TARGET_SHMEDIA"
12133   "
12134 {
12135   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12136                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12137   DONE;
12138 }")
12139
12140 (define_expand "mmacfx_wl"
12141   [(match_operand:V2SI 0 "arith_reg_dest" "")
12142    (match_operand:V2HI 1 "extend_reg_operand" "")
12143    (match_operand:V2HI 2 "extend_reg_operand" "")
12144    (match_operand:V2SI 3 "arith_reg_operand" "")]
12145   "TARGET_SHMEDIA"
12146   "
12147 {
12148   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12149                               operands[1], operands[2]));
12150   DONE;
12151 }")
12152
12153 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12154 ;; is depend
12155 (define_insn "mmacfx_wl_i"
12156   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12157         (ss_plus:V2SI
12158          (match_operand:V2SI 1 "arith_reg_operand" "0")
12159          (ss_truncate:V2SI
12160           (ashift:V2DI
12161            (sign_extend:V2DI
12162             (mult:V2SI
12163              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12164              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12165            (const_int 1)))))]
12166   "TARGET_SHMEDIA"
12167   "mmacfx.wl    %2, %3, %0"
12168   [(set_attr "type" "mac_media")
12169    (set_attr "highpart" "depend")])
12170
12171 (define_expand "mmacnfx_wl"
12172   [(match_operand:V2SI 0 "arith_reg_dest" "")
12173    (match_operand:V2HI 1 "extend_reg_operand" "")
12174    (match_operand:V2HI 2 "extend_reg_operand" "")
12175    (match_operand:V2SI 3 "arith_reg_operand" "")]
12176   "TARGET_SHMEDIA"
12177   "
12178 {
12179   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12180                                operands[1], operands[2]));
12181   DONE;
12182 }")
12183
12184 (define_insn "mmacnfx_wl_i"
12185   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12186         (ss_minus:V2SI
12187          (match_operand:V2SI 1 "arith_reg_operand" "0")
12188          (ss_truncate:V2SI
12189           (ashift:V2DI
12190            (sign_extend:V2DI
12191             (mult:V2SI
12192              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12193              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12194            (const_int 1)))))]
12195   "TARGET_SHMEDIA"
12196   "mmacnfx.wl   %2, %3, %0"
12197   [(set_attr "type" "mac_media")
12198    (set_attr "highpart" "depend")])
12199
12200 (define_insn "mulv2si3"
12201   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12202         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12203                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12204   "TARGET_SHMEDIA"
12205   "mmul.l       %1, %2, %0"
12206   [(set_attr "type" "d2mpy_media")
12207    (set_attr "highpart" "depend")])
12208
12209 (define_insn "mulv4hi3"
12210   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12211         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12212                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12213   "TARGET_SHMEDIA"
12214   "mmul.w       %1, %2, %0"
12215   [(set_attr "type" "dmpy_media")
12216    (set_attr "highpart" "depend")])
12217
12218 (define_insn "mmulfx_l"
12219   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12220         (ss_truncate:V2SI
12221          (ashiftrt:V2DI
12222           (mult:V2DI
12223            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12224            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12225           (const_int 31))))]
12226   "TARGET_SHMEDIA"
12227   "mmulfx.l     %1, %2, %0"
12228   [(set_attr "type" "d2mpy_media")
12229    (set_attr "highpart" "depend")])
12230
12231 (define_insn "mmulfx_w"
12232   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12233         (ss_truncate:V4HI
12234          (ashiftrt:V4SI
12235           (mult:V4SI
12236            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12237            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12238           (const_int 15))))]
12239   "TARGET_SHMEDIA"
12240   "mmulfx.w     %1, %2, %0"
12241   [(set_attr "type" "dmpy_media")
12242    (set_attr "highpart" "depend")])
12243
12244 (define_insn "mmulfxrp_w"
12245   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12246         (ss_truncate:V4HI
12247          (ashiftrt:V4SI
12248           (plus:V4SI
12249            (mult:V4SI
12250             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12251             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12252            (const_int 16384))
12253           (const_int 15))))]
12254   "TARGET_SHMEDIA"
12255   "mmulfxrp.w   %1, %2, %0"
12256   [(set_attr "type" "dmpy_media")
12257    (set_attr "highpart" "depend")])
12258
12259
12260 (define_expand "mmulhi_wl"
12261   [(match_operand:V2SI 0 "arith_reg_dest" "")
12262    (match_operand:V4HI 1 "arith_reg_operand" "")
12263    (match_operand:V4HI 2 "arith_reg_operand" "")]
12264   "TARGET_SHMEDIA"
12265   "
12266 {
12267   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12268              (operands[0], operands[1], operands[2]));
12269   DONE;
12270 }")
12271
12272 (define_expand "mmullo_wl"
12273   [(match_operand:V2SI 0 "arith_reg_dest" "")
12274    (match_operand:V4HI 1 "arith_reg_operand" "")
12275    (match_operand:V4HI 2 "arith_reg_operand" "")]
12276   "TARGET_SHMEDIA"
12277   "
12278 {
12279   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12280              (operands[0], operands[1], operands[2]));
12281   DONE;
12282 }")
12283
12284 (define_insn "mmul23_wl"
12285   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12286         (vec_select:V2SI
12287          (mult:V4SI
12288           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12289           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12290          (parallel [(const_int 2) (const_int 3)])))]
12291   "TARGET_SHMEDIA"
12292   "* return (TARGET_LITTLE_ENDIAN
12293              ? \"mmulhi.wl      %1, %2, %0\"
12294              : \"mmullo.wl      %1, %2, %0\");"
12295   [(set_attr "type" "dmpy_media")
12296    (set (attr "highpart")
12297         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12298          (const_string "user")))])
12299
12300 (define_insn "mmul01_wl"
12301   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12302         (vec_select:V2SI
12303          (mult:V4SI
12304           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12305           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12306          (parallel [(const_int 0) (const_int 1)])))]
12307   "TARGET_SHMEDIA"
12308   "* return (TARGET_LITTLE_ENDIAN
12309              ? \"mmullo.wl      %1, %2, %0\"
12310              : \"mmulhi.wl      %1, %2, %0\");"
12311   [(set_attr "type" "dmpy_media")
12312    (set (attr "highpart")
12313         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12314          (const_string "user")))])
12315
12316
12317 (define_expand "mmulsum_wq"
12318   [(match_operand:DI 0 "arith_reg_dest" "")
12319    (match_operand:V4HI 1 "arith_reg_operand" "")
12320    (match_operand:V4HI 2 "arith_reg_operand" "")
12321    (match_operand:DI 3 "arith_reg_operand" "")]
12322   "TARGET_SHMEDIA"
12323   "
12324 {
12325   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12326                                operands[1], operands[2]));
12327   DONE;
12328 }")
12329
12330 (define_insn "mmulsum_wq_i"
12331   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12332         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12333          (plus:DI
12334           (plus:DI
12335            (vec_select:DI
12336             (mult:V4DI
12337              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12338              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12339             (parallel [(const_int 0)]))
12340            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12341                                      (sign_extend:V4DI (match_dup 3)))
12342                           (parallel [(const_int 1)])))
12343           (plus:DI
12344            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12345                                      (sign_extend:V4DI (match_dup 3)))
12346                           (parallel [(const_int 2)]))
12347            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12348                                      (sign_extend:V4DI (match_dup 3)))
12349                           (parallel [(const_int 3)]))))))]
12350   "TARGET_SHMEDIA"
12351   "mmulsum.wq   %2, %3, %0"
12352   [(set_attr "type" "mac_media")])
12353
12354 (define_expand "mperm_w"
12355   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12356    (match_operand:V4HI 1 "arith_reg_operand" "r")
12357    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12358   "TARGET_SHMEDIA"
12359   "
12360 {
12361   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12362              (operands[0], operands[1], operands[2]));
12363   DONE;
12364 }")
12365
12366 ; This use of vec_select isn't exactly correct according to rtl.texi
12367 ; (because not constant), but it seems a straightforward extension.
12368 (define_insn "mperm_w_little"
12369   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12370         (vec_select:V4HI
12371          (match_operand:V4HI 1 "arith_reg_operand" "r")
12372          (parallel
12373           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12374                             (const_int 2) (const_int 0))
12375            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12376            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12377            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12378   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12379   "mperm.w      %1, %N2, %0"
12380   [(set_attr "type" "arith_media")])
12381
12382 (define_insn "mperm_w_big"
12383   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12384         (vec_select:V4HI
12385          (match_operand:V4HI 1 "arith_reg_operand" "r")
12386          (parallel
12387           [(zero_extract:QI (not:QI (match_operand:QI 2
12388                                      "extend_reg_or_0_operand" "rZ"))
12389                             (const_int 2) (const_int 0))
12390            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12391            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12392            (zero_extract:QI (not:QI (match_dup 2))
12393                             (const_int 2) (const_int 6))])))]
12394   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12395   "mperm.w      %1, %N2, %0"
12396   [(set_attr "type" "arith_media")])
12397
12398 (define_insn "mperm_w0"
12399   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12400         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12401                                           "trunc_hi_operand" "r"))))]
12402   "TARGET_SHMEDIA"
12403   "mperm.w      %1, r63, %0"
12404   [(set_attr "type" "arith_media")
12405    (set_attr "highpart" "ignore")])
12406
12407 (define_expand "msad_ubq"
12408   [(match_operand:DI 0 "arith_reg_dest" "")
12409    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12410    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12411    (match_operand:DI 3 "arith_reg_operand" "")]
12412   "TARGET_SHMEDIA"
12413   "
12414 {
12415   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12416                              operands[1], operands[2]));
12417   DONE;
12418 }")
12419
12420 (define_insn "msad_ubq_i"
12421   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12422         (plus:DI
12423          (plus:DI
12424           (plus:DI
12425            (plus:DI
12426             (match_operand:DI 1 "arith_reg_operand" "0")
12427             (abs:DI (vec_select:DI
12428                      (minus:V8DI
12429                       (zero_extend:V8DI
12430                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12431                       (zero_extend:V8DI
12432                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12433                      (parallel [(const_int 0)]))))
12434            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12435                                               (zero_extend:V8DI (match_dup 3)))
12436                                   (parallel [(const_int 1)]))))
12437           (plus:DI
12438            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12439                                               (zero_extend:V8DI (match_dup 3)))
12440                                   (parallel [(const_int 2)])))
12441            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12442                                               (zero_extend:V8DI (match_dup 3)))
12443                                   (parallel [(const_int 3)])))))
12444          (plus:DI
12445           (plus:DI
12446            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12447                                               (zero_extend:V8DI (match_dup 3)))
12448                                   (parallel [(const_int 4)])))
12449            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12450                                               (zero_extend:V8DI (match_dup 3)))
12451                                   (parallel [(const_int 5)]))))
12452           (plus:DI
12453            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12454                                               (zero_extend:V8DI (match_dup 3)))
12455                                   (parallel [(const_int 6)])))
12456            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12457                                               (zero_extend:V8DI (match_dup 3)))
12458                                   (parallel [(const_int 7)])))))))]
12459   "TARGET_SHMEDIA"
12460   "msad.ubq     %N2, %N3, %0"
12461   [(set_attr "type" "mac_media")])
12462
12463 (define_insn "mshalds_l"
12464   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12465         (ss_truncate:V2SI
12466          (ashift:V2DI
12467           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12468           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12469                   (const_int 31)))))]
12470   "TARGET_SHMEDIA"
12471   "mshalds.l    %1, %2, %0"
12472   [(set_attr "type" "mcmp_media")
12473    (set_attr "highpart" "depend")])
12474
12475 (define_insn "mshalds_w"
12476   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12477         (ss_truncate:V4HI
12478          (ashift:V4SI
12479           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12480           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12481                   (const_int 15)))))]
12482   "TARGET_SHMEDIA"
12483   "mshalds.w    %1, %2, %0"
12484   [(set_attr "type" "mcmp_media")
12485    (set_attr "highpart" "depend")])
12486
12487 (define_insn "ashrv2si3"
12488   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12489         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12490                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12491   "TARGET_SHMEDIA"
12492   "mshard.l     %1, %2, %0"
12493   [(set_attr "type" "arith_media")
12494    (set_attr "highpart" "depend")])
12495
12496 (define_insn "ashrv4hi3"
12497   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12498         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12499                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12500   "TARGET_SHMEDIA"
12501   "mshard.w     %1, %2, %0"
12502   [(set_attr "type" "arith_media")
12503    (set_attr "highpart" "depend")])
12504
12505 (define_insn "mshards_q"
12506   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12507         (ss_truncate:HI
12508          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12509                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12510   "TARGET_SHMEDIA"
12511   "mshards.q    %1, %N2, %0"
12512   [(set_attr "type" "mcmp_media")])
12513
12514 (define_expand "mshfhi_b"
12515   [(match_operand:V8QI 0 "arith_reg_dest" "")
12516    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12517    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12518   "TARGET_SHMEDIA"
12519   "
12520 {
12521   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12522              (operands[0], operands[1], operands[2]));
12523   DONE;
12524 }")
12525
12526 (define_expand "mshflo_b"
12527   [(match_operand:V8QI 0 "arith_reg_dest" "")
12528    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12529    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12530   "TARGET_SHMEDIA"
12531   "
12532 {
12533   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12534              (operands[0], operands[1], operands[2]));
12535   DONE;
12536 }")
12537
12538 (define_insn "mshf4_b"
12539   [(set
12540     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12541     (vec_select:V8QI
12542      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12543                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12544      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12545                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12546   "TARGET_SHMEDIA"
12547   "* return (TARGET_LITTLE_ENDIAN
12548              ? \"mshfhi.b       %N1, %N2, %0\"
12549              : \"mshflo.b       %N1, %N2, %0\");"
12550   [(set_attr "type" "arith_media")
12551    (set (attr "highpart")
12552         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12553          (const_string "user")))])
12554
12555 (define_insn "mshf0_b"
12556   [(set
12557     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12558     (vec_select:V8QI
12559      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12560                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12561      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12562                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12563   "TARGET_SHMEDIA"
12564   "* return (TARGET_LITTLE_ENDIAN
12565              ? \"mshflo.b       %N1, %N2, %0\"
12566              : \"mshfhi.b       %N1, %N2, %0\");"
12567   [(set_attr "type" "arith_media")
12568    (set (attr "highpart")
12569         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12570          (const_string "user")))])
12571
12572 (define_expand "mshfhi_l"
12573   [(match_operand:V2SI 0 "arith_reg_dest" "")
12574    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12575    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12576   "TARGET_SHMEDIA"
12577   "
12578 {
12579   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12580              (operands[0], operands[1], operands[2]));
12581   DONE;
12582 }")
12583
12584 (define_expand "mshflo_l"
12585   [(match_operand:V2SI 0 "arith_reg_dest" "")
12586    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12587    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12588   "TARGET_SHMEDIA"
12589   "
12590 {
12591   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12592              (operands[0], operands[1], operands[2]));
12593   DONE;
12594 }")
12595
12596 (define_insn "mshf4_l"
12597   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12598         (vec_select:V2SI
12599          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12600                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12601          (parallel [(const_int 1) (const_int 3)])))]
12602   "TARGET_SHMEDIA"
12603   "* return (TARGET_LITTLE_ENDIAN
12604              ? \"mshfhi.l       %N1, %N2, %0\"
12605              : \"mshflo.l       %N1, %N2, %0\");"
12606   [(set_attr "type" "arith_media")
12607    (set (attr "highpart")
12608         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12609          (const_string "user")))])
12610
12611 (define_insn "mshf0_l"
12612   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12613         (vec_select:V2SI
12614          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12615                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12616          (parallel [(const_int 0) (const_int 2)])))]
12617   "TARGET_SHMEDIA"
12618   "* return (TARGET_LITTLE_ENDIAN
12619              ? \"mshflo.l       %N1, %N2, %0\"
12620              : \"mshfhi.l       %N1, %N2, %0\");"
12621   [(set_attr "type" "arith_media")
12622    (set (attr "highpart")
12623         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12624          (const_string "user")))])
12625
12626 (define_expand "mshfhi_w"
12627   [(match_operand:V4HI 0 "arith_reg_dest" "")
12628    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12629    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12630   "TARGET_SHMEDIA"
12631   "
12632 {
12633   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12634              (operands[0], operands[1], operands[2]));
12635   DONE;
12636 }")
12637
12638 (define_expand "mshflo_w"
12639   [(match_operand:V4HI 0 "arith_reg_dest" "")
12640    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12641    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12642   "TARGET_SHMEDIA"
12643   "
12644 {
12645   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12646              (operands[0], operands[1], operands[2]));
12647   DONE;
12648 }")
12649
12650 (define_insn "mshf4_w"
12651   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12652         (vec_select:V4HI
12653          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12654                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12655          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12656   "TARGET_SHMEDIA"
12657   "* return (TARGET_LITTLE_ENDIAN
12658              ? \"mshfhi.w       %N1, %N2, %0\"
12659              : \"mshflo.w       %N1, %N2, %0\");"
12660   [(set_attr "type" "arith_media")
12661    (set (attr "highpart")
12662         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12663          (const_string "user")))])
12664
12665 (define_insn "mshf0_w"
12666   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12667         (vec_select:V4HI
12668          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12669                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12670          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12671   "TARGET_SHMEDIA"
12672   "* return (TARGET_LITTLE_ENDIAN
12673              ? \"mshflo.w       %N1, %N2, %0\"
12674              : \"mshfhi.w       %N1, %N2, %0\");"
12675   [(set_attr "type" "arith_media")
12676    (set (attr "highpart")
12677         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12678          (const_string "user")))])
12679
12680 (define_insn "mshflo_w_x"
12681   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12682         (vec_select:V4HI
12683          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12684                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12685          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12686   "TARGET_SHMEDIA"
12687   "mshflo.w     %N1, %N2, %0"
12688   [(set_attr "type" "arith_media")
12689    (set_attr "highpart" "ignore")])
12690
12691 /* These are useful to expand ANDs and as combiner patterns.  */
12692 (define_insn_and_split "mshfhi_l_di"
12693   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12694         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12695                              (const_int 32))
12696                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12697                         (const_int -4294967296))))]
12698   "TARGET_SHMEDIA"
12699   "@
12700         mshfhi.l        %N1, %N2, %0
12701         #"
12702   "TARGET_SHMEDIA && reload_completed
12703    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12704   [(set (match_dup 3) (match_dup 4))
12705    (set (match_dup 5) (match_dup 6))]
12706   "
12707 {
12708   operands[3] = gen_lowpart (SImode, operands[0]);
12709   operands[4] = gen_highpart (SImode, operands[1]);
12710   operands[5] = gen_highpart (SImode, operands[0]);
12711   operands[6] = gen_highpart (SImode, operands[2]);
12712 }"
12713   [(set_attr "type" "arith_media")])
12714
12715 (define_insn "*mshfhi_l_di_rev"
12716   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12717         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12718                         (const_int -4294967296))
12719                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12720                              (const_int 32))))]
12721   "TARGET_SHMEDIA"
12722   "mshfhi.l     %N2, %N1, %0"
12723   [(set_attr "type" "arith_media")])
12724
12725 (define_split
12726   [(set (match_operand:DI 0 "arith_reg_dest" "")
12727         (ior:DI (zero_extend:DI (match_operand:SI 1
12728                                               "extend_reg_or_0_operand" ""))
12729                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12730                         (const_int -4294967296))))
12731    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12732   "TARGET_SHMEDIA"
12733   [(const_int 0)]
12734   "
12735 {
12736   emit_insn (gen_ashldi3_media (operands[3],
12737                                 simplify_gen_subreg (DImode, operands[1],
12738                                                      SImode, 0),
12739                                 GEN_INT (32)));
12740   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12741   DONE;
12742 }")
12743
12744 (define_insn "mshflo_l_di"
12745   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12746         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12747                         (const_int 4294967295))
12748                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12749                            (const_int 32))))]
12750
12751   "TARGET_SHMEDIA"
12752   "mshflo.l     %N1, %N2, %0"
12753   [(set_attr "type" "arith_media")
12754    (set_attr "highpart" "ignore")])
12755
12756 (define_insn "*mshflo_l_di_rev"
12757   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12758         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12759                            (const_int 32))
12760                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12761                         (const_int 4294967295))))]
12762
12763   "TARGET_SHMEDIA"
12764   "mshflo.l     %N2, %N1, %0"
12765   [(set_attr "type" "arith_media")
12766    (set_attr "highpart" "ignore")])
12767
12768 ;; Combiner pattern for trampoline initialization.
12769 (define_insn_and_split "*double_shori"
12770   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12771         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12772                            (const_int 32))
12773                 (match_operand:DI 2 "const_int_operand" "n")))]
12774   "TARGET_SHMEDIA
12775    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12776   "#"
12777   "rtx_equal_p (operands[0], operands[1])"
12778   [(const_int 0)]
12779   "
12780 {
12781   HOST_WIDE_INT v = INTVAL (operands[2]);
12782
12783   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12784   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12785   DONE;
12786 }"
12787   [(set_attr "highpart" "ignore")])
12788
12789
12790 (define_insn "*mshflo_l_di_x"
12791   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12792         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12793                                  "rZ"))
12794                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12795                            (const_int 32))))]
12796
12797   "TARGET_SHMEDIA"
12798   "mshflo.l     %N1, %N2, %0"
12799   [(set_attr "type" "arith_media")
12800    (set_attr "highpart" "ignore")])
12801
12802 (define_insn_and_split "concat_v2sf"
12803   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12804 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12805         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12806                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12807
12808   "TARGET_SHMEDIA"
12809   "@
12810         mshflo.l        %N1, %N2, %0
12811         #
12812         #"
12813   "TARGET_SHMEDIA && reload_completed
12814    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12815   [(set (match_dup 3) (match_dup 1))
12816    (set (match_dup 4) (match_dup 2))]
12817   "
12818 {
12819   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12820   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12821 }"
12822   [(set_attr "type" "arith_media")
12823    (set_attr "highpart" "ignore")])
12824
12825 (define_insn "*mshflo_l_di_x_rev"
12826   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12827         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12828                            (const_int 32))
12829                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12830
12831   "TARGET_SHMEDIA"
12832   "mshflo.l     %N2, %N1, %0"
12833   [(set_attr "type" "arith_media")
12834    (set_attr "highpart" "ignore")])
12835
12836 (define_insn "ashlv2si3"
12837   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12838         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12839                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12840   "TARGET_SHMEDIA"
12841   "mshlld.l     %1, %2, %0"
12842   [(set_attr "type" "arith_media")
12843    (set_attr "highpart" "depend")])
12844
12845 (define_split
12846   [(set (match_operand 0 "any_register_operand" "")
12847         (match_operator 3 "shift_operator"
12848           [(match_operand 1 "any_register_operand" "")
12849            (match_operand 2 "shift_count_reg_operand" "")]))]
12850   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12851   [(set (match_dup 0) (match_dup 3))]
12852   "
12853 {
12854   rtx count = operands[2];
12855   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12856
12857   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12858          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12859          || GET_CODE (count) == TRUNCATE)
12860     count = XEXP (count, 0);
12861   inner_mode = GET_MODE (count);
12862   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12863                                subreg_lowpart_offset (outer_mode, inner_mode));
12864   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12865                                 operands[1], count);
12866 }")
12867
12868 (define_insn "ashlv4hi3"
12869   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12870         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12871                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12872   "TARGET_SHMEDIA"
12873   "mshlld.w     %1, %2, %0"
12874   [(set_attr "type" "arith_media")
12875    (set_attr "highpart" "depend")])
12876
12877 (define_insn "lshrv2si3"
12878   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12879         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12880                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12881   "TARGET_SHMEDIA"
12882   "mshlrd.l     %1, %2, %0"
12883   [(set_attr "type" "arith_media")
12884    (set_attr "highpart" "depend")])
12885
12886 (define_insn "lshrv4hi3"
12887   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12888         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12889                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12890   "TARGET_SHMEDIA"
12891   "mshlrd.w     %1, %2, %0"
12892   [(set_attr "type" "arith_media")
12893    (set_attr "highpart" "depend")])
12894
12895 (define_insn "subv2si3"
12896   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12897         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12898                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12899   "TARGET_SHMEDIA"
12900   "msub.l       %N1, %2, %0"
12901   [(set_attr "type" "arith_media")
12902    (set_attr "highpart" "depend")])
12903
12904 (define_insn "subv4hi3"
12905   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12906         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12907                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12908   "TARGET_SHMEDIA"
12909   "msub.w       %N1, %2, %0"
12910   [(set_attr "type" "arith_media")
12911    (set_attr "highpart" "depend")])
12912
12913 (define_insn_and_split "subv2hi3"
12914   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12915         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12916                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12917   "TARGET_SHMEDIA"
12918   "#"
12919   "TARGET_SHMEDIA"
12920   [(const_int 0)]
12921   "
12922 {
12923   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12924   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12925   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12926   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12927   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12928
12929   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12930   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12931   DONE;
12932 }"
12933   [(set_attr "highpart" "must_split")])
12934
12935 (define_insn "sssubv2si3"
12936   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12937         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12938                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12939   "TARGET_SHMEDIA"
12940   "msubs.l      %N1, %2, %0"
12941   [(set_attr "type" "mcmp_media")
12942    (set_attr "highpart" "depend")])
12943
12944 (define_insn "ussubv8qi3"
12945   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12946         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12947                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12948   "TARGET_SHMEDIA"
12949   "msubs.ub     %N1, %2, %0"
12950   [(set_attr "type" "mcmp_media")
12951    (set_attr "highpart" "depend")])
12952
12953 (define_insn "sssubv4hi3"
12954   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12955         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12956                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12957   "TARGET_SHMEDIA"
12958   "msubs.w      %N1, %2, %0"
12959   [(set_attr "type" "mcmp_media")
12960    (set_attr "highpart" "depend")])
12961
12962 ;; Floating Point Intrinsics
12963
12964 (define_insn "fcosa_s"
12965   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12966         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12967                    UNSPEC_FCOSA))]
12968   "TARGET_SHMEDIA"
12969   "fcosa.s      %1, %0"
12970   [(set_attr "type" "atrans_media")])
12971
12972 (define_insn "fsina_s"
12973   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12974         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12975                    UNSPEC_FSINA))]
12976   "TARGET_SHMEDIA"
12977   "fsina.s      %1, %0"
12978   [(set_attr "type" "atrans_media")])
12979
12980 (define_insn "fipr"
12981   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12982         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12983                                                     "fp_arith_reg_operand" "f")
12984                                                    (match_operand:V4SF 2
12985                                                     "fp_arith_reg_operand" "f"))
12986                                          (parallel [(const_int 0)]))
12987                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12988                                          (parallel [(const_int 1)])))
12989                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12990                                          (parallel [(const_int 2)]))
12991                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12992                                          (parallel [(const_int 3)])))))]
12993   "TARGET_SHMEDIA"
12994   "fipr.s       %1, %2, %0"
12995   [(set_attr "type" "fparith_media")])
12996
12997 (define_insn "fsrra_s"
12998   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12999         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13000                    UNSPEC_FSRRA))]
13001   "TARGET_SHMEDIA"
13002   "fsrra.s      %1, %0"
13003   [(set_attr "type" "atrans_media")])
13004
13005 (define_insn "ftrv"
13006   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13007         (plus:V4SF
13008          (plus:V4SF
13009           (mult:V4SF
13010            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13011                             (parallel [(const_int 0) (const_int 5)
13012                                        (const_int 10) (const_int 15)]))
13013            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13014           (mult:V4SF
13015            (vec_select:V4SF (match_dup 1)
13016                             (parallel [(const_int 4) (const_int 9)
13017                                        (const_int 14) (const_int 3)]))
13018            (vec_select:V4SF (match_dup 2)
13019                             (parallel [(const_int 1) (const_int 2)
13020                                        (const_int 3) (const_int 0)]))))
13021          (plus:V4SF
13022           (mult:V4SF
13023            (vec_select:V4SF (match_dup 1)
13024                             (parallel [(const_int 8) (const_int 13)
13025                                        (const_int 2) (const_int 7)]))
13026            (vec_select:V4SF (match_dup 2)
13027                             (parallel [(const_int 2) (const_int 3)
13028                                        (const_int 0) (const_int 1)])))
13029           (mult:V4SF
13030            (vec_select:V4SF (match_dup 1)
13031                             (parallel [(const_int 12) (const_int 1)
13032                                        (const_int 6) (const_int 11)]))
13033            (vec_select:V4SF (match_dup 2)
13034                             (parallel [(const_int 3) (const_int 0)
13035                                        (const_int 1) (const_int 2)]))))))]
13036   "TARGET_SHMEDIA"
13037   "ftrv.s %1, %2, %0"
13038   [(set_attr "type" "fparith_media")])
13039
13040 (define_insn "ldhi_l"
13041   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13042         (zero_extract:SI
13043          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13044                                   (const_int 3))
13045                           (const_int -3)))
13046          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13047          (const_int 0)))]
13048   "TARGET_SHMEDIA32"
13049   "ldhi.l       %U1, %0"
13050   [(set_attr "type" "load_media")])
13051
13052 (define_insn "ldhi_q"
13053   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13054         (zero_extract:DI
13055          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13056                                   (const_int 7))
13057                           (const_int -7)))
13058          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13059          (const_int 0)))]
13060   "TARGET_SHMEDIA32"
13061   "ldhi.q       %U1, %0"
13062   [(set_attr "type" "load_media")])
13063
13064 (define_insn_and_split "*ldhi_q_comb0"
13065   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13066         (zero_extract:DI
13067          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13068                                             "register_operand" "r")
13069                                            (match_operand:SI 2
13070                                             "ua_offset" "I06"))
13071                                   (const_int 7))
13072                           (const_int -7)))
13073          (plus:SI (and:SI (match_dup 1) (const_int 7))
13074                   (const_int 1))
13075          (const_int 0)))]
13076   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13077   "#"
13078   ""
13079   [(pc)]
13080   "emit_insn (gen_ldhi_q (operands[0],
13081                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13082    DONE;")
13083
13084
13085 (define_insn_and_split "*ldhi_q_comb1"
13086   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13087         (zero_extract:DI
13088          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13089                                             "register_operand" "r")
13090                                            (match_operand:SI 2
13091                                             "ua_offset" "I06"))
13092                                   (const_int 7))
13093                           (const_int -7)))
13094          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13095                                                    "ua_offset" "I06"))
13096                           (const_int 7))
13097                   (const_int 1))
13098          (const_int 0)))]
13099   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13100    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13101   "#"
13102   ""
13103   [(pc)]
13104   "emit_insn (gen_ldhi_q (operands[0],
13105                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13106    DONE;")
13107
13108
13109 (define_insn "ldlo_l"
13110   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13111         (zero_extract:SI
13112          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13113                          (const_int -4)))
13114          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13115          (and:SI (match_dup 1) (const_int 3))))]
13116   "TARGET_SHMEDIA32"
13117   "ldlo.l       %U1, %0"
13118   [(set_attr "type" "load_media")])
13119
13120 (define_insn "ldlo_q"
13121   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13122         (zero_extract:DI
13123          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13124                          (const_int -8)))
13125          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13126          (and:SI (match_dup 1) (const_int 7))))]
13127   "TARGET_SHMEDIA32"
13128   "ldlo.q       %U1, %0"
13129   [(set_attr "type" "load_media")])
13130
13131 (define_insn_and_split "*ldlo_q_comb0"
13132   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13133         (zero_extract:DI
13134          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13135                                   (match_operand:SI 2 "ua_offset" "I06"))
13136                          (const_int -8)))
13137          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13138          (and:SI (match_dup 1) (const_int 7))))]
13139   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13140   "#"
13141   ""
13142   [(pc)]
13143   "emit_insn (gen_ldlo_q (operands[0],
13144                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13145    DONE;")
13146
13147 (define_insn_and_split "*ldlo_q_comb1"
13148   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13149         (zero_extract:DI
13150          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13151                                   (match_operand:SI 2 "ua_offset" "I06"))
13152                          (const_int -8)))
13153          (minus:SI (const_int 8)
13154                    (and:SI (plus:SI (match_dup 1)
13155                                     (match_operand:SI 3 "ua_offset" "I06"))
13156                            (const_int 7)))
13157          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13158   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13159    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13160   "#"
13161   ""
13162   [(pc)]
13163   "emit_insn (gen_ldlo_q (operands[0],
13164                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13165    DONE;")
13166
13167 (define_insn "sthi_l"
13168   [(set (zero_extract:SI
13169          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13170                                   (const_int 3))
13171                           (const_int -3)))
13172          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13173          (const_int 0))
13174         (match_operand:SI 1 "arith_reg_operand" "r"))]
13175   "TARGET_SHMEDIA32"
13176   "sthi.l       %U0, %1"
13177   [(set_attr "type" "ustore_media")])
13178
13179 ;; All unaligned stores are considered to be 'narrow' because they typically
13180 ;; operate on less that a quadword, and when they operate on a full quadword,
13181 ;; the vanilla store high / store low sequence will cause a stall if not
13182 ;; scheduled apart.
13183 (define_insn "sthi_q"
13184   [(set (zero_extract:DI
13185          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13186                                   (const_int 7))
13187                           (const_int -7)))
13188          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13189          (const_int 0))
13190         (match_operand:DI 1 "arith_reg_operand" "r"))]
13191   "TARGET_SHMEDIA32"
13192   "sthi.q       %U0, %1"
13193   [(set_attr "type" "ustore_media")])
13194
13195 (define_insn_and_split "*sthi_q_comb0"
13196   [(set (zero_extract:DI
13197          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13198                                             "register_operand" "r")
13199                                            (match_operand:SI 1 "ua_offset"
13200                                             "I06"))
13201                                   (const_int 7))
13202                           (const_int -7)))
13203          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13204          (const_int 0))
13205         (match_operand:DI 2 "arith_reg_operand" "r"))]
13206   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13207   "#"
13208   ""
13209   [(pc)]
13210   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13211                           operands[2]));
13212    DONE;")
13213
13214 (define_insn_and_split "*sthi_q_comb1"
13215   [(set (zero_extract:DI
13216          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13217                                             "register_operand" "r")
13218                                            (match_operand:SI 1 "ua_offset"
13219                                             "I06"))
13220                                   (const_int 7))
13221                           (const_int -7)))
13222          (plus:SI (and:SI (plus:SI (match_dup 0)
13223                                    (match_operand:SI 2 "ua_offset" "I06"))
13224                           (const_int 7))
13225                   (const_int 1))
13226          (const_int 0))
13227         (match_operand:DI 3 "arith_reg_operand" "r"))]
13228   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13229    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13230   "#"
13231   ""
13232   [(pc)]
13233   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13234                           operands[3]));
13235    DONE;")
13236
13237 ;; This is highpart user because the address is used as full 64 bit.
13238 (define_insn "stlo_l"
13239   [(set (zero_extract:SI
13240          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13241                          (const_int -4)))
13242          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13243          (and:SI (match_dup 0) (const_int 3)))
13244         (match_operand:SI 1 "arith_reg_operand" "r"))]
13245   "TARGET_SHMEDIA32"
13246   "stlo.l       %U0, %1"
13247   [(set_attr "type" "ustore_media")])
13248
13249 (define_insn "stlo_q"
13250   [(set (zero_extract:DI
13251          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13252                          (const_int -8)))
13253          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13254          (and:SI (match_dup 0) (const_int 7)))
13255         (match_operand:DI 1 "arith_reg_operand" "r"))]
13256   "TARGET_SHMEDIA32"
13257   "stlo.q       %U0, %1"
13258   [(set_attr "type" "ustore_media")])
13259
13260 (define_insn_and_split "*stlo_q_comb0"
13261   [(set (zero_extract:DI
13262          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13263                                   (match_operand:SI 1 "ua_offset" "I06"))
13264                          (const_int -8)))
13265          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13266          (and:SI (match_dup 0) (const_int 7)))
13267         (match_operand:DI 2 "arith_reg_operand" "r"))]
13268   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13269   "#"
13270   ""
13271   [(pc)]
13272   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13273                           operands[2]));
13274    DONE;")
13275
13276 (define_insn_and_split "*stlo_q_comb1"
13277   [(set (zero_extract:DI
13278          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13279                                   (match_operand:SI 1 "ua_offset" "I06"))
13280                          (const_int -8)))
13281          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13282                                                   (match_operand:SI 2
13283                                                    "ua_offset" "I06"))
13284                                          (const_int 7)))
13285          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13286         (match_operand:DI 3 "arith_reg_operand" "r"))]
13287   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13288   "#"
13289   ""
13290   [(pc)]
13291   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13292                           operands[3]));
13293    DONE;")
13294
13295 (define_insn "ldhi_l64"
13296   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13297         (zero_extract:SI
13298          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13299                                   (const_int 3))
13300                           (const_int -3)))
13301          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13302          (const_int 0)))]
13303   "TARGET_SHMEDIA64"
13304   "ldhi.l       %U1, %0"
13305   [(set_attr "type" "load_media")])
13306
13307 (define_insn "ldhi_q64"
13308   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13309         (zero_extract:DI
13310          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13311                                   (const_int 7))
13312                           (const_int -7)))
13313          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13314          (const_int 0)))]
13315   "TARGET_SHMEDIA64"
13316   "ldhi.q       %U1, %0"
13317   [(set_attr "type" "load_media")])
13318
13319 (define_insn "ldlo_l64"
13320   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13321         (zero_extract:SI
13322          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13323                          (const_int -4)))
13324          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13325          (and:DI (match_dup 1) (const_int 3))))]
13326   "TARGET_SHMEDIA64"
13327   "ldlo.l       %U1, %0"
13328   [(set_attr "type" "load_media")])
13329
13330 (define_insn "ldlo_q64"
13331   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13332         (zero_extract:DI
13333          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13334                          (const_int -8)))
13335          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13336          (and:DI (match_dup 1) (const_int 7))))]
13337   "TARGET_SHMEDIA64"
13338   "ldlo.q       %U1, %0"
13339   [(set_attr "type" "load_media")])
13340
13341 (define_insn "sthi_l64"
13342   [(set (zero_extract:SI
13343          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13344                                   (const_int 3))
13345                           (const_int -3)))
13346          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13347          (const_int 0))
13348         (match_operand:SI 1 "arith_reg_operand" "r"))]
13349   "TARGET_SHMEDIA64"
13350   "sthi.l       %U0, %1"
13351   [(set_attr "type" "ustore_media")])
13352
13353 (define_insn "sthi_q64"
13354   [(set (zero_extract:DI
13355          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13356                                   (const_int 7))
13357                           (const_int -7)))
13358          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13359          (const_int 0))
13360         (match_operand:DI 1 "arith_reg_operand" "r"))]
13361   "TARGET_SHMEDIA64"
13362   "sthi.q       %U0, %1"
13363   [(set_attr "type" "ustore_media")])
13364
13365 (define_insn "stlo_l64"
13366   [(set (zero_extract:SI
13367          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13368                          (const_int -4)))
13369          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13370          (and:DI (match_dup 0) (const_int 3)))
13371         (match_operand:SI 1 "arith_reg_operand" "r"))]
13372   "TARGET_SHMEDIA64"
13373   "stlo.l       %U0, %1"
13374   [(set_attr "type" "ustore_media")])
13375
13376 (define_insn "stlo_q64"
13377   [(set (zero_extract:DI
13378          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13379                          (const_int -8)))
13380          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13381          (and:DI (match_dup 0) (const_int 7)))
13382         (match_operand:DI 1 "arith_reg_operand" "r"))]
13383   "TARGET_SHMEDIA64"
13384   "stlo.q       %U0, %1"
13385   [(set_attr "type" "ustore_media")])
13386
13387 (define_insn "nsb"
13388   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13389         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13390                    UNSPEC_NSB))]
13391   "TARGET_SHMEDIA"
13392   "nsb  %1, %0"
13393   [(set_attr "type" "arith_media")])
13394
13395 (define_insn "nsbsi"
13396   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13397         (zero_extend:SI
13398          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13399                     UNSPEC_NSB)))]
13400   "TARGET_SHMEDIA"
13401   "nsb  %1, %0"
13402   [(set_attr "type" "arith_media")])
13403
13404 (define_insn "nsbdi"
13405   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13406         (zero_extend:DI
13407          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13408                     UNSPEC_NSB)))]
13409   "TARGET_SHMEDIA"
13410   "nsb  %1, %0"
13411   [(set_attr "type" "arith_media")])
13412
13413 (define_expand "ffsdi2"
13414   [(set (match_operand:DI 0 "arith_reg_dest" "")
13415         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13416   "TARGET_SHMEDIA"
13417   "
13418 {
13419   rtx scratch = gen_reg_rtx (DImode);
13420   rtx last;
13421
13422   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13423   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13424   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13425   emit_insn (gen_nsbdi (scratch, scratch));
13426   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13427   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13428   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13429   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13430
13431   DONE;
13432 }")
13433
13434 (define_expand "ffssi2"
13435   [(set (match_operand:SI 0 "arith_reg_dest" "")
13436         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13437   "TARGET_SHMEDIA"
13438   "
13439 {
13440   rtx scratch = gen_reg_rtx (SImode);
13441   rtx discratch = gen_reg_rtx (DImode);
13442   rtx last;
13443
13444   emit_insn (gen_adddi3 (discratch,
13445                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13446                          constm1_rtx));
13447   emit_insn (gen_andcdi3 (discratch,
13448                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13449                           discratch));
13450   emit_insn (gen_nsbsi (scratch, discratch));
13451   last = emit_insn (gen_subsi3 (operands[0],
13452                                 force_reg (SImode, GEN_INT (63)), scratch));
13453   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13454
13455   DONE;
13456 }")
13457
13458 (define_insn "byterev"
13459   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13460         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13461                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13462                                     (const_int 4) (const_int 3) (const_int 2)
13463                                     (const_int 1) (const_int 0)])))]
13464   "TARGET_SHMEDIA"
13465   "byterev      %1, %0"
13466   [(set_attr "type" "arith_media")])
13467
13468 (define_insn "*prefetch_media"
13469   [(prefetch (match_operand:QI 0 "address_operand" "p")
13470              (match_operand:SI 1 "const_int_operand" "n")
13471              (match_operand:SI 2 "const_int_operand" "n"))]
13472   "TARGET_SHMEDIA"
13473   "*
13474 {
13475   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13476   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13477   return \"\";
13478 }"
13479   [(set_attr "type" "other")])
13480
13481 (define_insn "*prefetch_i4"
13482   [(prefetch (match_operand:SI 0 "register_operand" "r")
13483              (match_operand:SI 1 "const_int_operand" "n")
13484              (match_operand:SI 2 "const_int_operand" "n"))]
13485   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13486   "*
13487 {
13488   return \"pref @%0\";
13489 }"
13490   [(set_attr "type" "other")])
13491
13492 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13493 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13494 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13495 (define_expand "prefetch"
13496   [(prefetch (match_operand 0 "address_operand" "p")
13497              (match_operand:SI 1 "const_int_operand" "n")
13498              (match_operand:SI 2 "const_int_operand" "n"))]
13499   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13500    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13501   "
13502 {
13503   if (GET_MODE (operands[0]) != Pmode
13504       || !CONST_INT_P (operands[1])
13505       || !CONST_INT_P (operands[2]))
13506     FAIL;
13507   if (! TARGET_SHMEDIA)
13508     operands[0] = force_reg (Pmode, operands[0]);
13509 }")
13510
13511 (define_insn "prefetch_m2a"
13512   [(prefetch (match_operand:SI 0 "register_operand" "r")
13513              (match_operand:SI 1 "const_int_operand" "n")
13514              (match_operand:SI 2 "const_int_operand" "n"))]
13515   "TARGET_SH2A"
13516   "pref\\t@%0"
13517   [(set_attr "type" "other")])
13518
13519 (define_insn "alloco_i"
13520   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13521         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13522   "TARGET_SHMEDIA32"
13523   "*
13524 {
13525   rtx xops[2];
13526
13527   if (GET_CODE (operands[0]) == PLUS)
13528     {
13529       xops[0] = XEXP (operands[0], 0);
13530       xops[1] = XEXP (operands[0], 1);
13531     }
13532   else
13533     {
13534       xops[0] = operands[0];
13535       xops[1] = const0_rtx;
13536     }
13537   output_asm_insn (\"alloco   %0, %1\", xops);
13538   return \"\";
13539 }"
13540   [(set_attr "type" "other")])
13541
13542 (define_split
13543   [(set (match_operand 0 "any_register_operand" "")
13544         (match_operand 1 "" ""))]
13545   "TARGET_SHMEDIA && reload_completed"
13546   [(set (match_dup 0) (match_dup 1))]
13547   "
13548 {
13549   int n_changes = 0;
13550
13551   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13552   if (!n_changes)
13553     FAIL;
13554 }")
13555
13556 ; Stack Protector Patterns
13557
13558 (define_expand "stack_protect_set"
13559   [(set (match_operand 0 "memory_operand" "")
13560         (match_operand 1 "memory_operand" ""))]
13561   ""
13562 {
13563   if (TARGET_SHMEDIA)
13564     {
13565       if (TARGET_SHMEDIA64)
13566         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13567       else
13568         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13569     }
13570   else
13571     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13572
13573   DONE;
13574 })
13575
13576 (define_insn "stack_protect_set_si"
13577   [(set (match_operand:SI 0 "memory_operand" "=m")
13578         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13579    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13580   "!TARGET_SHMEDIA"
13581   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13582   [(set_attr "type" "other")
13583    (set_attr "length" "6")])
13584
13585 (define_insn "stack_protect_set_si_media"
13586   [(set (match_operand:SI 0 "memory_operand" "=m")
13587         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13588    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13589   "TARGET_SHMEDIA"
13590   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13591   [(set_attr "type" "other")
13592    (set_attr "length" "12")])
13593
13594 (define_insn "stack_protect_set_di_media"
13595   [(set (match_operand:DI 0 "memory_operand" "=m")
13596         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13597    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13598   "TARGET_SHMEDIA64"
13599   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13600   [(set_attr "type" "other")
13601    (set_attr "length" "12")])
13602
13603 (define_expand "stack_protect_test"
13604   [(match_operand 0 "memory_operand" "")
13605    (match_operand 1 "memory_operand" "")
13606    (match_operand 2 "" "")]
13607   ""
13608 {
13609   if (TARGET_SHMEDIA)
13610     {
13611       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13612       rtx test;
13613
13614       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13615       if (TARGET_SHMEDIA64)
13616         {
13617           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13618                                                       operands[1]));
13619           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13620         }
13621       else
13622         {
13623           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13624                                                       operands[1]));
13625           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13626         }
13627     }
13628   else
13629     {
13630       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13631       emit_jump_insn (gen_branch_true (operands[2]));
13632     }
13633
13634   DONE;
13635 })
13636
13637 (define_insn "stack_protect_test_si"
13638   [(set (reg:SI T_REG)
13639         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13640                     (match_operand:SI 1 "memory_operand" "m")]
13641                    UNSPEC_SP_TEST))
13642   (set (match_scratch:SI 2 "=&r") (const_int 0))
13643   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13644   "!TARGET_SHMEDIA"
13645   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13646   [(set_attr "type" "other")
13647    (set_attr "length" "10")])
13648
13649 (define_insn "stack_protect_test_si_media"
13650   [(set (match_operand:SI 0 "register_operand" "=&r")
13651         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13652                     (match_operand:SI 2 "memory_operand" "m")]
13653                    UNSPEC_SP_TEST))
13654   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13655   "TARGET_SHMEDIA"
13656   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13657   [(set_attr "type" "other")
13658    (set_attr "length" "16")])
13659
13660 (define_insn "stack_protect_test_di_media"
13661   [(set (match_operand:DI 0 "register_operand" "=&r")
13662         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13663                     (match_operand:DI 2 "memory_operand" "m")]
13664                    UNSPEC_SP_TEST))
13665   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13666   "TARGET_SHMEDIA64"
13667   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13668   [(set_attr "type" "other")
13669    (set_attr "length" "16")])
13670
13671 (include "sync.md")