OSDN Git Service

Backport from mainline
[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, 2012
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:SI 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_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_FPU_DOUBLE && ! 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_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
1840    && TARGET_FPU_SINGLE"
1841   "jsr  @%1%#"
1842   [(set_attr "type" "sfunc")
1843    (set_attr "needs_delay_slot" "yes")])
1844
1845 (define_insn "udivsi3_i4_int"
1846   [(set (match_operand:SI 0 "register_operand" "=z")
1847         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1848    (clobber (reg:SI T_REG))
1849    (clobber (reg:SI R1_REG))
1850    (clobber (reg:SI PR_REG))
1851    (clobber (reg:SI MACH_REG))
1852    (clobber (reg:SI MACL_REG))
1853    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1854   "TARGET_SH1"
1855   "jsr  @%1%#"
1856   [(set_attr "type" "sfunc")
1857    (set_attr "needs_delay_slot" "yes")])
1858
1859
1860 (define_expand "udivsi3"
1861   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1862    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1863    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1864    (parallel [(set (match_operand:SI 0 "register_operand" "")
1865                    (udiv:SI (reg:SI R4_REG)
1866                             (reg:SI R5_REG)))
1867               (clobber (reg:SI T_REG))
1868               (clobber (reg:SI PR_REG))
1869               (clobber (reg:SI R4_REG))
1870               (use (match_dup 3))])]
1871   ""
1872   "
1873 {
1874   rtx last;
1875
1876   operands[3] = gen_reg_rtx (Pmode);
1877   /* Emit the move of the address to a pseudo outside of the libcall.  */
1878   if (TARGET_DIVIDE_CALL_TABLE)
1879     {
1880       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1881          that causes problems when the divide code is supposed to come from a
1882          separate library.  Division by zero is undefined, so dividing 1 can be
1883          implemented by comparing with the divisor.  */
1884       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1885         {
1886           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1887           emit_insn (gen_cstoresi4 (operands[0], test,
1888                                     operands[1], operands[2]));
1889           DONE;
1890         }
1891       else if (operands[2] == const0_rtx)
1892         {
1893           emit_move_insn (operands[0], operands[2]);
1894           DONE;
1895         }
1896       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1897       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1898     }
1899   else if (TARGET_DIVIDE_CALL_FP)
1900     {
1901       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1902       if (TARGET_FPU_SINGLE)
1903         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1904       else
1905         last = gen_udivsi3_i4 (operands[0], operands[3]);
1906     }
1907   else if (TARGET_SHMEDIA_FPU)
1908     {
1909       operands[1] = force_reg (SImode, operands[1]);
1910       operands[2] = force_reg (SImode, operands[2]);
1911       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1912       DONE;
1913     }
1914   else if (TARGET_SH2A)
1915     {
1916       operands[1] = force_reg (SImode, operands[1]);
1917       operands[2] = force_reg (SImode, operands[2]);
1918       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1919       DONE;
1920     }
1921   else if (TARGET_SH5)
1922     {
1923       function_symbol (operands[3],
1924                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1925                        SFUNC_STATIC);
1926
1927       if (TARGET_SHMEDIA)
1928         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1929       else if (TARGET_FPU_ANY)
1930         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1931       else
1932         last = gen_udivsi3_i1 (operands[0], operands[3]);
1933     }
1934   else
1935     {
1936       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1937       last = gen_udivsi3_i1 (operands[0], operands[3]);
1938     }
1939   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1940   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1941   emit_insn (last);
1942   DONE;
1943 }")
1944
1945 (define_insn "divsi3_sh2a"
1946   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1947         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1948                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1949   "TARGET_SH2A"
1950   "divs %2,%1"
1951   [(set_attr "type" "arith")
1952    (set_attr "in_delay_slot" "no")])
1953
1954 (define_insn "divsi3_i1"
1955   [(set (match_operand:SI 0 "register_operand" "=z")
1956         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1957    (clobber (reg:SI T_REG))
1958    (clobber (reg:SI PR_REG))
1959    (clobber (reg:SI R1_REG))
1960    (clobber (reg:SI R2_REG))
1961    (clobber (reg:SI R3_REG))
1962    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1963   "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
1964   "jsr  @%1%#"
1965   [(set_attr "type" "sfunc")
1966    (set_attr "needs_delay_slot" "yes")])
1967
1968 (define_insn "divsi3_i1_media"
1969   [(set (match_operand:SI 0 "register_operand" "=z")
1970         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1971    (clobber (reg:SI T_MEDIA_REG))
1972    (clobber (reg:SI PR_MEDIA_REG))
1973    (clobber (reg:SI R1_REG))
1974    (clobber (reg:SI R20_REG))
1975    (clobber (reg:SI R21_REG))
1976    (clobber (reg:SI TR0_REG))
1977    (use (match_operand 1 "target_reg_operand" "b"))]
1978   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1979   "blink        %1, r18"
1980   [(set_attr "type" "sfunc")])
1981
1982 (define_insn "divsi3_media_2"
1983   [(set (match_operand:SI 0 "register_operand" "=z")
1984         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1985    (clobber (reg:SI T_MEDIA_REG))
1986    (clobber (reg:SI PR_MEDIA_REG))
1987    (clobber (reg:SI R1_REG))
1988    (clobber (reg:SI R21_REG))
1989    (clobber (reg:SI TR0_REG))
1990    (use (reg:SI R20_REG))
1991    (use (match_operand 1 "target_reg_operand" "b"))]
1992   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1993   "blink        %1, r18"
1994   [(set_attr "type" "sfunc")])
1995
1996 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1997 ;; hard reg clobbers and data dependencies that we need when we want
1998 ;; to rematerialize the division into a call.
1999 (define_insn_and_split "divsi_inv_call"
2000   [(set (match_operand:SI 0 "register_operand" "=r")
2001         (div:SI (match_operand:SI 1 "register_operand" "r")
2002                 (match_operand:SI 2 "register_operand" "r")))
2003    (clobber (reg:SI R4_REG))
2004    (clobber (reg:SI R5_REG))
2005    (clobber (reg:SI T_MEDIA_REG))
2006    (clobber (reg:SI PR_MEDIA_REG))
2007    (clobber (reg:SI R1_REG))
2008    (clobber (reg:SI R21_REG))
2009    (clobber (reg:SI TR0_REG))
2010    (clobber (reg:SI R20_REG))
2011    (use (match_operand:SI 3 "register_operand" "r"))]
2012   "TARGET_SHMEDIA"
2013   "#"
2014   "&& (high_life_started || reload_completed)"
2015   [(set (match_dup 0) (match_dup 3))]
2016   ""
2017   [(set_attr "highpart" "must_split")])
2018
2019 ;; This is the combiner pattern for -mdiv=inv:call .
2020 (define_insn_and_split "*divsi_inv_call_combine"
2021   [(set (match_operand:SI 0 "register_operand" "=z")
2022         (div:SI (match_operand:SI 1 "register_operand" "r")
2023                 (match_operand:SI 2 "register_operand" "r")))
2024    (clobber (reg:SI R4_REG))
2025    (clobber (reg:SI R5_REG))
2026    (clobber (reg:SI T_MEDIA_REG))
2027    (clobber (reg:SI PR_MEDIA_REG))
2028    (clobber (reg:SI R1_REG))
2029    (clobber (reg:SI R21_REG))
2030    (clobber (reg:SI TR0_REG))
2031    (clobber (reg:SI R20_REG))
2032    (use (unspec:SI [(match_dup 1)
2033                     (match_operand:SI 3 "" "")
2034                     (unspec:SI [(match_operand:SI 4 "" "")
2035                                 (match_dup 3)
2036                                 (match_operand:DI 5 "" "")]
2037                      UNSPEC_DIV_INV_M2)
2038                     (match_operand:DI 6 "" "")
2039                     (const_int 0)
2040                     (const_int 0)]
2041          UNSPEC_DIV_INV_M3))]
2042   "TARGET_SHMEDIA"
2043   "#"
2044   "&& (high_life_started || reload_completed)"
2045   [(pc)]
2046   "
2047 {
2048   const char *name = sh_divsi3_libfunc;
2049   enum sh_function_kind kind = SFUNC_GOT;
2050   rtx sym;
2051
2052   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2053   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2054   while (TARGET_DIVIDE_INV_CALL2)
2055     {
2056       rtx x = operands[3];
2057
2058       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2059         break;
2060       x = XVECEXP (x, 0, 0);
2061       name = \"__sdivsi3_2\";
2062       kind = SFUNC_STATIC;
2063       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2064       break;
2065     }
2066   sym = function_symbol (NULL, name, kind);
2067   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2068   DONE;
2069 }"
2070   [(set_attr "highpart" "must_split")])
2071
2072 (define_expand "divsi3_i4_media"
2073   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2074    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2075    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2076    (set (match_operand:SI 0 "register_operand" "=r")
2077         (fix:SI (match_dup 5)))]
2078   "TARGET_SHMEDIA_FPU"
2079   "
2080 {
2081   operands[3] = gen_reg_rtx (DFmode);
2082   operands[4] = gen_reg_rtx (DFmode);
2083   operands[5] = gen_reg_rtx (DFmode);
2084 }")
2085
2086 (define_insn "divsi3_i4"
2087   [(set (match_operand:SI 0 "register_operand" "=y")
2088         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2089    (clobber (reg:SI PR_REG))
2090    (clobber (reg:DF DR0_REG))
2091    (clobber (reg:DF DR2_REG))
2092    (use (reg:PSI FPSCR_REG))
2093    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2094   "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2095   "jsr  @%1%#"
2096   [(set_attr "type" "sfunc")
2097    (set_attr "fp_mode" "double")
2098    (set_attr "needs_delay_slot" "yes")])
2099
2100 (define_insn "divsi3_i4_single"
2101   [(set (match_operand:SI 0 "register_operand" "=y")
2102         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2103    (clobber (reg:SI PR_REG))
2104    (clobber (reg:DF DR0_REG))
2105    (clobber (reg:DF DR2_REG))
2106    (clobber (reg:SI R2_REG))
2107    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2108   "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2109    && TARGET_FPU_SINGLE"
2110   "jsr  @%1%#"
2111   [(set_attr "type" "sfunc")
2112    (set_attr "needs_delay_slot" "yes")])
2113
2114 (define_insn "divsi3_i4_int"
2115   [(set (match_operand:SI 0 "register_operand" "=z")
2116         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2117    (clobber (reg:SI T_REG))
2118    (clobber (reg:SI PR_REG))
2119    (clobber (reg:SI R1_REG))
2120    (clobber (reg:SI MACH_REG))
2121    (clobber (reg:SI MACL_REG))
2122    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2123   "TARGET_SH1"
2124   "jsr  @%1%#"
2125   [(set_attr "type" "sfunc")
2126    (set_attr "needs_delay_slot" "yes")])
2127
2128 (define_expand "divsi3"
2129   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2130    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2131    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2132    (parallel [(set (match_operand:SI 0 "register_operand" "")
2133                    (div:SI (reg:SI R4_REG)
2134                            (reg:SI R5_REG)))
2135               (clobber (reg:SI T_REG))
2136               (clobber (reg:SI PR_REG))
2137               (clobber (reg:SI R1_REG))
2138               (clobber (reg:SI R2_REG))
2139               (clobber (reg:SI R3_REG))
2140               (use (match_dup 3))])]
2141   ""
2142   "
2143 {
2144   rtx last;
2145
2146   operands[3] = gen_reg_rtx (Pmode);
2147   /* Emit the move of the address to a pseudo outside of the libcall.  */
2148   if (TARGET_DIVIDE_CALL_TABLE)
2149     {
2150       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2151       last = gen_divsi3_i4_int (operands[0], operands[3]);
2152     }
2153   else if (TARGET_DIVIDE_CALL_FP)
2154     {
2155       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2156       if (TARGET_FPU_SINGLE)
2157         last = gen_divsi3_i4_single (operands[0], operands[3]);
2158       else
2159         last = gen_divsi3_i4 (operands[0], operands[3]);
2160     }
2161   else if (TARGET_SH2A)
2162     {
2163       operands[1] = force_reg (SImode, operands[1]);
2164       operands[2] = force_reg (SImode, operands[2]);
2165       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2166       DONE;
2167     }
2168   else if (TARGET_DIVIDE_INV)
2169     {
2170       rtx dividend = operands[1];
2171       rtx divisor = operands[2];
2172       rtx tab_base;
2173       rtx nsb_res = gen_reg_rtx (DImode);
2174       rtx norm64 = gen_reg_rtx (DImode);
2175       rtx tab_ix = gen_reg_rtx (DImode);
2176       rtx norm32 = gen_reg_rtx (SImode);
2177       rtx i92 = force_reg (DImode, GEN_INT (92));
2178       rtx scratch0a = gen_reg_rtx (DImode);
2179       rtx scratch0b = gen_reg_rtx (DImode);
2180       rtx inv0 = gen_reg_rtx (SImode);
2181       rtx scratch1a = gen_reg_rtx (DImode);
2182       rtx scratch1b = gen_reg_rtx (DImode);
2183       rtx shift = gen_reg_rtx (DImode);
2184       rtx i2p27, i43;
2185       rtx inv1 = gen_reg_rtx (SImode);
2186       rtx scratch2a = gen_reg_rtx (DImode);
2187       rtx scratch2b = gen_reg_rtx (SImode);
2188       rtx inv2 = gen_reg_rtx (SImode);
2189       rtx scratch3a = gen_reg_rtx (DImode);
2190       rtx scratch3b = gen_reg_rtx (DImode);
2191       rtx scratch3c = gen_reg_rtx (DImode);
2192       rtx scratch3d = gen_reg_rtx (SImode);
2193       rtx scratch3e = gen_reg_rtx (DImode);
2194       rtx result = gen_reg_rtx (SImode);
2195
2196       if (! arith_reg_or_0_operand (dividend, SImode))
2197         dividend = force_reg (SImode, dividend);
2198       if (! arith_reg_operand (divisor, SImode))
2199         divisor = force_reg (SImode, divisor);
2200       if (flag_pic && Pmode != DImode)
2201         {
2202           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2203           tab_base = gen_datalabel_ref (tab_base);
2204           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2205         }
2206       else
2207         {
2208           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2209           tab_base = gen_datalabel_ref (tab_base);
2210           tab_base = force_reg (DImode, tab_base);
2211         }
2212       if (TARGET_DIVIDE_INV20U)
2213         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2214       else
2215         i2p27 = GEN_INT (0);
2216       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2217         i43 = force_reg (DImode, GEN_INT (43));
2218       else
2219         i43 = GEN_INT (0);
2220       emit_insn (gen_nsbdi (nsb_res,
2221                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2222       emit_insn (gen_ashldi3_media (norm64,
2223                                     gen_rtx_SUBREG (DImode, divisor, 0),
2224                                     nsb_res));
2225       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2226       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2227       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2228                                    inv0, scratch0a, scratch0b,
2229                                    scratch1a, scratch1b));
2230       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2231       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2232                                    scratch2a));
2233       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2234                                    i2p27, i43,
2235                                    scratch3a, scratch3b, scratch3c,
2236                                    scratch2a, scratch2b, scratch3d, scratch3e));
2237       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2238         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2239       else if (TARGET_DIVIDE_INV_FP)
2240         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2241                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2242                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2243                                      gen_reg_rtx (DFmode)));
2244       else
2245         emit_move_insn (operands[0], result);
2246       DONE;
2247     }
2248   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2249     {
2250       operands[1] = force_reg (SImode, operands[1]);
2251       operands[2] = force_reg (SImode, operands[2]);
2252       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2253       DONE;
2254     }
2255   else if (TARGET_SH5)
2256     {
2257       if (TARGET_DIVIDE_CALL2)
2258         {
2259           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2260           tab_base = gen_datalabel_ref (tab_base);
2261           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2262         }
2263       if (TARGET_FPU_ANY && TARGET_SH1)
2264         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2265       else if (TARGET_DIVIDE_CALL2)
2266         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2267       else
2268         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2269
2270       if (TARGET_SHMEDIA)
2271         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2272                 (operands[0], operands[3]));
2273       else if (TARGET_FPU_ANY)
2274         last = gen_divsi3_i4_single (operands[0], operands[3]);
2275       else
2276         last = gen_divsi3_i1 (operands[0], operands[3]);
2277     }
2278   else
2279     {
2280       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2281       last = gen_divsi3_i1 (operands[0], operands[3]);
2282     }
2283   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2284   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2285   emit_insn (last);
2286   DONE;
2287 }")
2288
2289 ;; operands: scratch, tab_base, tab_ix
2290 ;; These are unspecs because we could generate an indexed addressing mode
2291 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2292 ;; confuse reload.  See PR27117.
2293
2294 (define_insn "divsi_inv_qitable"
2295   [(set (match_operand:DI 0 "register_operand" "=r")
2296         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2297                                     (match_operand:DI 2 "register_operand" "r")]
2298                          UNSPEC_DIV_INV_TABLE)))]
2299   "TARGET_SHMEDIA"
2300   "@
2301         ldx.ub  %1, %2, %0"
2302   [(set_attr "type" "load_media")
2303    (set_attr "highpart" "user")])
2304
2305 ;; operands: scratch, tab_base, tab_ix
2306 (define_insn "divsi_inv_hitable"
2307   [(set (match_operand:DI 0 "register_operand" "=r")
2308         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2309                                     (match_operand:DI 2 "register_operand" "r")]
2310                          UNSPEC_DIV_INV_TABLE)))]
2311   "TARGET_SHMEDIA"
2312   "@
2313         ldx.w   %1, %2, %0"
2314   [(set_attr "type" "load_media")
2315    (set_attr "highpart" "user")])
2316
2317 ;; operands: inv0, tab_base, tab_ix, norm32
2318 ;; scratch equiv in sdivsi3_2: r19, r21
2319 (define_expand "divsi_inv_m0"
2320   [(set (match_operand:SI 0 "register_operand" "=r")
2321         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2322                     (match_operand:DI 2 "register_operand" "r")
2323                     (match_operand:SI 3 "register_operand" "r")]
2324          UNSPEC_DIV_INV_M0))
2325    (clobber (match_operand:DI 4 "register_operand" "=r"))
2326    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2327   "TARGET_SHMEDIA"
2328   "
2329 {
2330 /*
2331 tab_base: r20
2332 tab_ix: r21
2333 norm32: r25
2334  ldx.ub r20, r21, r19 // u0.8
2335  shlli r21, 1, r21
2336  muls.l r25, r19, r19 // s2.38
2337  ldx.w r20, r21, r21  // s2.14
2338  shari r19, 24, r19   // truncate to s2.14
2339  sub r21, r19, r19    // some 11 bit inverse in s1.14
2340 */
2341
2342   rtx inv0 = operands[0];
2343   rtx tab_base = operands[1];
2344   rtx tab_ix = operands[2];
2345   rtx norm32 = operands[3];
2346   rtx scratch0 = operands[4];
2347   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2348   rtx scratch1 = operands[5];
2349
2350   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2351   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2352   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2353   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2354   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2355   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2356   DONE;
2357 }")
2358
2359 ;; operands: inv1, tab_base, tab_ix, norm32
2360 (define_insn_and_split "divsi_inv_m1"
2361   [(set (match_operand:SI 0 "register_operand" "=r")
2362         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2363                     (match_operand:DI 2 "register_operand" "r")
2364                     (match_operand:SI 3 "register_operand" "r")]
2365          UNSPEC_DIV_INV_M1))
2366    (clobber (match_operand:SI 4 "register_operand" "=r"))
2367    (clobber (match_operand:DI 5 "register_operand" "=r"))
2368    (clobber (match_operand:DI 6 "register_operand" "=r"))
2369    (clobber (match_operand:DI 7 "register_operand" "=r"))
2370    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2371   "TARGET_SHMEDIA"
2372   "#"
2373   "&& !can_create_pseudo_p ()"
2374   [(pc)]
2375   "
2376 {
2377 /* inv0: r19
2378  muls.l r19, r19, r18 // u0.28
2379  muls.l r25, r18, r18 // s2.58
2380  shlli r19, 45, r0    // multiply by two and convert to s2.58
2381  sub r0, r18, r18
2382  shari r18, 28, r18   // some 18 bit inverse in s1.30
2383 */
2384
2385   rtx inv1 = operands[0];
2386   rtx tab_base = operands[1];
2387   rtx tab_ix = operands[2];
2388   rtx norm32 = operands[3];
2389   rtx inv0 = operands[4];
2390   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2391   rtx scratch0a = operands[5];
2392   rtx scratch0b = operands[6];
2393   rtx scratch0 = operands[7];
2394   rtx scratch1 = operands[8];
2395   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2396
2397   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2398                                scratch0a, scratch0b));
2399   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2400   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2401   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2402   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2403   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2404   DONE;
2405 }")
2406
2407 ;; operands: inv2, norm32, inv1, i92
2408 (define_insn_and_split "divsi_inv_m2"
2409   [(set (match_operand:SI 0 "register_operand" "=r")
2410         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2411                     (match_operand:SI 2 "register_operand" "r")
2412                     (match_operand:DI 3 "register_operand" "r")]
2413          UNSPEC_DIV_INV_M2))
2414    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2415   "TARGET_SHMEDIA"
2416   "#"
2417   "&& !can_create_pseudo_p ()"
2418   [(pc)]
2419   "
2420 {
2421 /*
2422  muls.l r18, r25, r0  // s2.60
2423  shari r0, 16, r0     // s-16.44
2424   sub
2425  muls.l r0, r18, r19  // s-16.74
2426  shari r19, 30, r19   // s-16.44
2427 */
2428   rtx inv2 = operands[0];
2429   rtx norm32 = operands[1];
2430   rtx inv1 = operands[2];
2431   rtx i92 = operands[3];
2432   rtx scratch0 = operands[4];
2433   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2434
2435   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2436   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2437   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2438   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2439   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2440   DONE;
2441 }")
2442
2443 (define_insn_and_split "divsi_inv_m3"
2444   [(set (match_operand:SI 0 "register_operand" "=r")
2445         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2446                     (match_operand:SI 2 "register_operand" "r")
2447                     (match_operand:SI 3 "register_operand" "r")
2448                     (match_operand:DI 4 "register_operand" "r")
2449                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2450                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2451          UNSPEC_DIV_INV_M3))
2452    (clobber (match_operand:DI 7 "register_operand" "=r"))
2453    (clobber (match_operand:DI 8 "register_operand" "=r"))
2454    (clobber (match_operand:DI 9 "register_operand" "=r"))
2455    (clobber (match_operand:DI 10 "register_operand" "=r"))
2456    (clobber (match_operand:SI 11 "register_operand" "=r"))
2457    (clobber (match_operand:SI 12 "register_operand" "=r"))
2458    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2459   "TARGET_SHMEDIA"
2460   "#"
2461   "&& !can_create_pseudo_p ()"
2462   [(pc)]
2463   "
2464 {
2465 /*
2466   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2467   r0: scratch0  r19: scratch1 r21: scratch2
2468
2469   muls.l r18, r4, r25 // s32.30
2470  muls.l r19, r4, r19  // s15.30
2471  shari r25, 63, r21
2472   shari r19, 14, r19  // s18.-14
2473  sub r25, r19, r0
2474  shard r0, r1, r0
2475  sub r0, r21, r0
2476 */
2477
2478   rtx result = operands[0];
2479   rtx dividend = operands[1];
2480   rtx inv1 = operands[2];
2481   rtx inv2 = operands[3];
2482   rtx shift = operands[4];
2483   rtx scratch0 = operands[7];
2484   rtx scratch1 = operands[8];
2485   rtx scratch2 = operands[9];
2486
2487   if (satisfies_constraint_N (dividend))
2488     {
2489       emit_move_insn (result, dividend);
2490       DONE;
2491     }
2492
2493   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2494   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2495   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2496   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2497   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2498   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2499   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2500   DONE;
2501 }")
2502
2503 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2504 ;; inv1: tab_base, tab_ix, norm32
2505 ;; inv2: norm32, inv1, i92
2506 (define_insn_and_split "divsi_inv_m1_3"
2507   [(set (match_operand:SI 0 "register_operand" "=r")
2508         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2509                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2510                                 (match_operand:DI 3 "register_operand" "r")
2511                                 (match_operand:SI 4 "register_operand" "r")]
2512                      UNSPEC_DIV_INV_M1)
2513                     (unspec:SI [(match_dup 4)
2514                                 (unspec:SI [(match_dup 2)
2515                                             (match_dup 3)
2516                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2517                                 (match_operand:SI 5 "" "")]
2518                      UNSPEC_DIV_INV_M2)
2519                     (match_operand:DI 6 "register_operand" "r")
2520                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2521                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2522          UNSPEC_DIV_INV_M3))
2523    (clobber (match_operand:DI 9 "register_operand" "=r"))
2524    (clobber (match_operand:DI 10 "register_operand" "=r"))
2525    (clobber (match_operand:DI 11 "register_operand" "=r"))
2526    (clobber (match_operand:DI 12 "register_operand" "=r"))
2527    (clobber (match_operand:SI 13 "register_operand" "=r"))
2528    (clobber (match_operand:SI 14 "register_operand" "=r"))
2529    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2530   "TARGET_SHMEDIA
2531    && (TARGET_DIVIDE_INV_MINLAT
2532        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2533   "#"
2534   "&& !can_create_pseudo_p ()"
2535   [(pc)]
2536   "
2537 {
2538   rtx result = operands[0];
2539   rtx dividend = operands[1];
2540   rtx tab_base = operands[2];
2541   rtx tab_ix = operands[3];
2542   rtx norm32 = operands[4];
2543   /* rtx i92 = operands[5]; */
2544   rtx shift = operands[6];
2545   rtx i2p27 = operands[7];
2546   rtx i43 = operands[8];
2547   rtx scratch0 = operands[9];
2548   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2549   rtx scratch1 = operands[10];
2550   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2551   rtx scratch2 = operands[11];
2552   rtx scratch3 = operands[12];
2553   rtx scratch4 = operands[13];
2554   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2555   rtx scratch5 = operands[14];
2556   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2557   rtx scratch6 = operands[15];
2558
2559   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2560                                scratch0, scratch1));
2561   /* inv0 == scratch4 */
2562   if (! TARGET_DIVIDE_INV20U)
2563     {
2564       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2565       i2p27 = scratch0;
2566       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2567     }
2568   else
2569     {
2570       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2571       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2572     }
2573   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2574   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2575   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2576   /* inv1 == scratch4 */
2577
2578   if (TARGET_DIVIDE_INV_MINLAT)
2579     {
2580       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2581       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2582       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2583       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2584       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2585       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2586       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2587       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2588       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2589       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2590       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2591     }
2592   else
2593     {
2594       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2595       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2596       emit_insn (gen_nsbdi (scratch6,
2597                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2598       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2599       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2600       emit_insn (gen_divsi_inv20 (scratch2,
2601                                   norm32, scratch4, dividend,
2602                                   scratch6, scratch3, i43,
2603                                   /* scratch0 may be shared with i2p27.  */
2604                                   scratch0, scratch1, scratch5,
2605                                   label, label, i2p27));
2606     }
2607   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2608   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2609   DONE;
2610 }")
2611
2612 (define_insn "divsi_inv20"
2613   [(set (match_operand:DI 0 "register_operand" "=&r")
2614         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2615                     (match_operand:SI 2 "register_operand" "r")
2616                     (match_operand:SI 3 "register_operand" "r")
2617                     (match_operand:DI 4 "register_operand" "r")
2618                     (match_operand:DI 5 "register_operand" "r")
2619                     (match_operand:DI 6 "register_operand" "r")
2620                     (match_operand:DI 12 "register_operand" "r")
2621                     (match_operand 10 "target_operand" "b")
2622                     (match_operand 11 "immediate_operand" "i")]
2623          UNSPEC_DIV_INV20))
2624    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2625    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2626    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2627   "TARGET_SHMEDIA
2628    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2629   "*
2630 {
2631 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2632              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2633              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2634              %10 label (tr), %11 label (imm)
2635
2636  muls.l inv1, norm32, scratch0  // s2.60
2637   muls.l inv1, dividend, result // s32.30
2638   xor i2p27, result_sign, round_scratch
2639  bge/u dividend_nsb, i43, tr.. (label)
2640  shari scratch0, 16, scratch0   // s-16.44
2641  muls.l sratch0_si, inv1, scratch0 // s-16.74
2642   sub result, round_scratch, result
2643   shari dividend, 14, scratch1   // s19.-14
2644  shari scratch0, 30, scratch0   // s-16.44
2645  muls.l scratch0, scratch1, round_scratch // s15.30
2646 label:
2647  sub result, round_scratch, result */
2648
2649   int likely = TARGET_DIVIDE_INV20L;
2650
2651   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2652   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2653   output_asm_insn (likely
2654                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2655                    : \"bge/u\t%4, %6, %10\", operands);
2656   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2657   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2658   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2659   return (likely
2660           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2661           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2662 }")
2663
2664 (define_insn_and_split "divsi_inv_fp"
2665   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2666         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2667                 (match_operand:SI 2 "register_operand" "rf")))
2668    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2669    (clobber (match_operand:SI 4 "register_operand" "=r"))
2670    (clobber (match_operand:SI 5 "register_operand" "=r"))
2671    (clobber (match_operand:DF 6 "register_operand" "=r"))
2672    (clobber (match_operand:DF 7 "register_operand" "=r"))
2673    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2674   "TARGET_SHMEDIA_FPU"
2675   "#"
2676   "&& (high_life_started || reload_completed)"
2677   [(set (match_dup 0) (match_dup 3))]
2678   ""
2679   [(set_attr "highpart" "must_split")])
2680
2681 ;; If a matching group of divide-by-inverse instructions is in the same
2682 ;; basic block after gcse & loop optimizations, we want to transform them
2683 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2684 (define_insn_and_split "*divsi_inv_fp_combine"
2685   [(set (match_operand:SI 0 "register_operand" "=f")
2686         (div:SI (match_operand:SI 1 "register_operand" "f")
2687                 (match_operand:SI 2 "register_operand" "f")))
2688    (use (unspec:SI [(match_dup 1)
2689                     (match_operand:SI 3 "" "")
2690                     (unspec:SI [(match_operand:SI 4 "" "")
2691                                 (match_dup 3)
2692                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2693                     (match_operand:DI 6 "" "")
2694                     (const_int 0)
2695                     (const_int 0)] UNSPEC_DIV_INV_M3))
2696    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2697    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2698    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2699    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2700    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2701   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2702   "#"
2703   "&& 1"
2704   [(set (match_dup 9) (float:DF (match_dup 1)))
2705    (set (match_dup 10) (float:DF (match_dup 2)))
2706    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2707    (set (match_dup 8)
2708         (fix:SI (match_dup 11)))
2709    (set (match_dup 0) (match_dup 8))]
2710   "
2711 {
2712   if (! fp_arith_reg_operand (operands[1], SImode))
2713     {
2714       emit_move_insn (operands[7], operands[1]);
2715       operands[1] = operands[7];
2716     }
2717   if (! fp_arith_reg_operand (operands[2], SImode))
2718     {
2719       emit_move_insn (operands[8], operands[2]);
2720       operands[2] = operands[8];
2721     }
2722 }"
2723   [(set_attr "highpart" "must_split")])
2724 \f
2725 ;; -------------------------------------------------------------------------
2726 ;; Multiplication instructions
2727 ;; -------------------------------------------------------------------------
2728
2729 (define_insn "umulhisi3_i"
2730   [(set (reg:SI MACL_REG)
2731         (mult:SI (zero_extend:SI
2732                   (match_operand:HI 0 "arith_reg_operand" "r"))
2733                  (zero_extend:SI
2734                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2735   "TARGET_SH1"
2736   "mulu.w       %1,%0"
2737   [(set_attr "type" "smpy")])
2738
2739 (define_insn "mulhisi3_i"
2740   [(set (reg:SI MACL_REG)
2741         (mult:SI (sign_extend:SI
2742                   (match_operand:HI 0 "arith_reg_operand" "r"))
2743                  (sign_extend:SI
2744                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2745   "TARGET_SH1"
2746   "muls.w       %1,%0"
2747   [(set_attr "type" "smpy")])
2748
2749 (define_expand "mulhisi3"
2750   [(set (reg:SI MACL_REG)
2751         (mult:SI (sign_extend:SI
2752                   (match_operand:HI 1 "arith_reg_operand" ""))
2753                  (sign_extend:SI
2754                   (match_operand:HI 2 "arith_reg_operand" ""))))
2755    (set (match_operand:SI 0 "arith_reg_operand" "")
2756         (reg:SI MACL_REG))]
2757   "TARGET_SH1"
2758   "
2759 {
2760   rtx insn, macl;
2761
2762   macl = gen_rtx_REG (SImode, MACL_REG);
2763   start_sequence ();
2764   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2765   insn = get_insns ();  
2766   end_sequence ();
2767   /* expand_binop can't find a suitable code in umul_widen_optab to
2768      make a REG_EQUAL note from, so make one here.
2769      See also smulsi3_highpart.
2770      ??? Alternatively, we could put this at the calling site of expand_binop,
2771      i.e. expand_expr.  */
2772   /* Use emit_libcall_block for loop invariant code motion and to make
2773      a REG_EQUAL note.  */
2774   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2775
2776   DONE;
2777 }")
2778
2779 (define_expand "umulhisi3"
2780   [(set (reg:SI MACL_REG)
2781         (mult:SI (zero_extend:SI
2782                   (match_operand:HI 1 "arith_reg_operand" ""))
2783                  (zero_extend:SI
2784                   (match_operand:HI 2 "arith_reg_operand" ""))))
2785    (set (match_operand:SI 0 "arith_reg_operand" "")
2786         (reg:SI MACL_REG))]
2787   "TARGET_SH1"
2788   "
2789 {
2790   rtx insn, macl;
2791
2792   macl = gen_rtx_REG (SImode, MACL_REG);
2793   start_sequence ();
2794   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2795   insn = get_insns ();  
2796   end_sequence ();
2797   /* expand_binop can't find a suitable code in umul_widen_optab to
2798      make a REG_EQUAL note from, so make one here.
2799      See also smulsi3_highpart.
2800      ??? Alternatively, we could put this at the calling site of expand_binop,
2801      i.e. expand_expr.  */
2802   /* Use emit_libcall_block for loop invariant code motion and to make
2803      a REG_EQUAL note.  */
2804   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2805
2806   DONE;
2807 }")
2808
2809 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2810 ;; a call to a routine which clobbers known registers.
2811
2812 (define_insn ""
2813   [(set (match_operand:SI 1 "register_operand" "=z")
2814         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2815    (clobber (reg:SI MACL_REG))
2816    (clobber (reg:SI T_REG))
2817    (clobber (reg:SI PR_REG))
2818    (clobber (reg:SI R3_REG))
2819    (clobber (reg:SI R2_REG))
2820    (clobber (reg:SI R1_REG))
2821    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2822   "TARGET_SH1"
2823   "jsr  @%0%#"
2824   [(set_attr "type" "sfunc")
2825    (set_attr "needs_delay_slot" "yes")])
2826
2827 (define_expand "mulsi3_call"
2828   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2829    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2830    (parallel[(set (match_operand:SI 0 "register_operand" "")
2831                   (mult:SI (reg:SI R4_REG)
2832                            (reg:SI R5_REG)))
2833              (clobber (reg:SI MACL_REG))
2834              (clobber (reg:SI T_REG))
2835              (clobber (reg:SI PR_REG))
2836              (clobber (reg:SI R3_REG))
2837              (clobber (reg:SI R2_REG))
2838              (clobber (reg:SI R1_REG))
2839              (use (match_operand:SI 3 "register_operand" ""))])]
2840   "TARGET_SH1"
2841   "")
2842
2843 (define_insn "mul_r"
2844   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2845         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2846                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2847   "TARGET_SH2A"
2848   "mulr %2,%0"
2849   [(set_attr "type" "dmpy")])
2850
2851 (define_insn "mul_l"
2852   [(set (reg:SI MACL_REG)
2853         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2854                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2855   "TARGET_SH2"
2856   "mul.l        %1,%0"
2857   [(set_attr "type" "dmpy")])
2858
2859 (define_expand "mulsi3"
2860   [(set (reg:SI MACL_REG)
2861         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2862                   (match_operand:SI 2 "arith_reg_operand" "")))
2863    (set (match_operand:SI 0 "arith_reg_operand" "")
2864         (reg:SI MACL_REG))]
2865   "TARGET_SH1"
2866   "
2867 {
2868   if (!TARGET_SH2)
2869     {
2870       /* The address must be set outside the libcall,
2871          since it goes into a pseudo.  */
2872       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2873       rtx addr = force_reg (SImode, sym);
2874       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2875                                    operands[2], addr);
2876       emit_insn (insns);
2877     }
2878   else
2879     {
2880       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2881
2882       emit_insn (gen_mul_l (operands[1], operands[2]));
2883       /* consec_sets_giv can only recognize the first insn that sets a
2884          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2885          note.  */
2886       emit_insn (gen_movsi_i ((operands[0]), macl));
2887     }
2888   DONE;
2889 }")
2890
2891 (define_insn "mulsidi3_i"
2892   [(set (reg:SI MACH_REG)
2893         (truncate:SI
2894          (lshiftrt:DI
2895           (mult:DI
2896            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2897            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2898           (const_int 32))))
2899    (set (reg:SI MACL_REG)
2900         (mult:SI (match_dup 0)
2901                  (match_dup 1)))]
2902   "TARGET_SH2"
2903   "dmuls.l      %1,%0"
2904   [(set_attr "type" "dmpy")])
2905
2906 (define_expand "mulsidi3"
2907   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2908         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2909                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2910   "TARGET_SH2 || TARGET_SHMEDIA"
2911   "
2912 {
2913   if (TARGET_SH2)
2914     {
2915        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2916                                         operands[2]));
2917        DONE;
2918     }
2919 }")
2920
2921 (define_insn "mulsidi3_media"
2922   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2923         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2924                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2925   "TARGET_SHMEDIA"
2926   "muls.l       %1, %2, %0"
2927   [(set_attr "type" "dmpy_media")
2928    (set_attr "highpart" "ignore")])
2929
2930 (define_insn "mulsidi3_compact"
2931   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2932         (mult:DI
2933          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2934          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2935    (clobber (reg:SI MACH_REG))
2936    (clobber (reg:SI MACL_REG))]
2937   "TARGET_SH2"
2938   "#")
2939
2940 (define_split
2941   [(set (match_operand:DI 0 "arith_reg_dest" "")
2942         (mult:DI
2943          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2944          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2945    (clobber (reg:SI MACH_REG))
2946    (clobber (reg:SI MACL_REG))]
2947   "TARGET_SH2"
2948   [(const_int 0)]
2949   "
2950 {
2951   rtx low_dst = gen_lowpart (SImode, operands[0]);
2952   rtx high_dst = gen_highpart (SImode, operands[0]);
2953
2954   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2955
2956   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2957   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2958   /* We need something to tag the possible REG_EQUAL notes on to.  */
2959   emit_move_insn (operands[0], operands[0]);
2960   DONE;
2961 }")
2962
2963 (define_insn "umulsidi3_i"
2964   [(set (reg:SI MACH_REG)
2965         (truncate:SI
2966          (lshiftrt:DI
2967           (mult:DI
2968            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2969            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2970           (const_int 32))))
2971    (set (reg:SI MACL_REG)
2972         (mult:SI (match_dup 0)
2973                  (match_dup 1)))]
2974   "TARGET_SH2"
2975   "dmulu.l      %1,%0"
2976   [(set_attr "type" "dmpy")])
2977
2978 (define_expand "umulsidi3"
2979   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2980         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2981                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2982   "TARGET_SH2 || TARGET_SHMEDIA"
2983   "
2984 {
2985   if (TARGET_SH2)
2986     {
2987        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2988                                          operands[2]));
2989        DONE;
2990     }
2991 }")
2992
2993 (define_insn "umulsidi3_media"
2994   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2995         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2996                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2997   "TARGET_SHMEDIA"
2998   "mulu.l       %1, %2, %0"
2999   [(set_attr "type" "dmpy_media")
3000    (set_attr "highpart" "ignore")])
3001
3002 (define_insn "umulsidi3_compact"
3003   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3004         (mult:DI
3005          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3006          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3007    (clobber (reg:SI MACH_REG))
3008    (clobber (reg:SI MACL_REG))]
3009   "TARGET_SH2"
3010   "#")
3011
3012 (define_split
3013   [(set (match_operand:DI 0 "arith_reg_dest" "")
3014         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3015                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3016    (clobber (reg:SI MACH_REG))
3017    (clobber (reg:SI MACL_REG))]
3018   "TARGET_SH2"
3019   [(const_int 0)]
3020   "
3021 {
3022   rtx low_dst = gen_lowpart (SImode, operands[0]);
3023   rtx high_dst = gen_highpart (SImode, operands[0]);
3024
3025   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3026
3027   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3028   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3029   /* We need something to tag the possible REG_EQUAL notes on to.  */
3030   emit_move_insn (operands[0], operands[0]);
3031   DONE;
3032 }")
3033
3034 (define_insn "smulsi3_highpart_i"
3035   [(set (reg:SI MACH_REG)
3036         (truncate:SI
3037          (lshiftrt:DI
3038           (mult:DI
3039            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3040            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3041           (const_int 32))))
3042    (clobber (reg:SI MACL_REG))]
3043   "TARGET_SH2"
3044   "dmuls.l      %1,%0"
3045   [(set_attr "type" "dmpy")])
3046
3047 (define_expand "smulsi3_highpart"
3048   [(parallel
3049     [(set (reg:SI MACH_REG)
3050           (truncate:SI
3051            (lshiftrt:DI
3052             (mult:DI
3053              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3054              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3055             (const_int 32))))
3056     (clobber (reg:SI MACL_REG))])
3057    (set (match_operand:SI 0 "arith_reg_operand" "")
3058         (reg:SI MACH_REG))]
3059   "TARGET_SH2"
3060   "
3061 {
3062   rtx insn, mach;
3063
3064   mach = gen_rtx_REG (SImode, MACH_REG);
3065   start_sequence ();
3066   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3067   insn = get_insns ();  
3068   end_sequence ();
3069   /* expand_binop can't find a suitable code in mul_highpart_optab to
3070      make a REG_EQUAL note from, so make one here.
3071      See also {,u}mulhisi.
3072      ??? Alternatively, we could put this at the calling site of expand_binop,
3073      i.e. expand_mult_highpart.  */
3074   /* Use emit_libcall_block for loop invariant code motion and to make
3075      a REG_EQUAL note.  */
3076   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3077
3078   DONE;
3079 }")
3080
3081 (define_insn "umulsi3_highpart_i"
3082   [(set (reg:SI MACH_REG)
3083         (truncate:SI
3084          (lshiftrt:DI
3085           (mult:DI
3086            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3087            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3088           (const_int 32))))
3089    (clobber (reg:SI MACL_REG))]
3090   "TARGET_SH2"
3091   "dmulu.l      %1,%0"
3092   [(set_attr "type" "dmpy")])
3093
3094 (define_expand "umulsi3_highpart"
3095   [(parallel
3096     [(set (reg:SI MACH_REG)
3097           (truncate:SI
3098            (lshiftrt:DI
3099             (mult:DI
3100              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3101              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3102             (const_int 32))))
3103     (clobber (reg:SI MACL_REG))])
3104    (set (match_operand:SI 0 "arith_reg_operand" "")
3105         (reg:SI MACH_REG))]
3106   "TARGET_SH2"
3107   "
3108 {
3109   rtx insn, mach;
3110
3111   mach = gen_rtx_REG (SImode, MACH_REG);
3112   start_sequence ();
3113   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3114   insn = get_insns ();  
3115   end_sequence ();
3116   /* Use emit_libcall_block for loop invariant code motion and to make
3117      a REG_EQUAL note.  */
3118   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3119
3120   DONE;
3121 }")
3122
3123 (define_insn_and_split "muldi3"
3124   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3125         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3126                  (match_operand:DI 2 "arith_reg_operand" "r")))
3127    (clobber (match_scratch:DI 3 "=&r"))
3128    (clobber (match_scratch:DI 4 "=r"))]
3129   "TARGET_SHMEDIA"
3130   "#"
3131   "reload_completed"
3132   [(const_int 0)]
3133   "
3134 {
3135   rtx op3_v2si, op2_v2si;
3136
3137   op3_v2si = operands[3];
3138   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3139     {
3140       op3_v2si = XEXP (op3_v2si, 0);
3141       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3142     }
3143   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3144   op2_v2si = operands[2];
3145   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3146     {
3147       op2_v2si = XEXP (op2_v2si, 0);
3148       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3149     }
3150   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3151   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3152   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3153   emit_insn (gen_umulsidi3_media (operands[4],
3154                                  sh_gen_truncate (SImode, operands[1], 0),
3155                                  sh_gen_truncate (SImode, operands[2], 0)));
3156   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3157   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3158   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3159   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3160   DONE;
3161 }")
3162
3163 \f
3164 ;; -------------------------------------------------------------------------
3165 ;; Logical operations
3166 ;; -------------------------------------------------------------------------
3167
3168 (define_insn "*andsi3_compact"
3169   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3170         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3171                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3172   "TARGET_SH1"
3173   "and  %2,%0"
3174   [(set_attr "type" "arith")])
3175
3176 (define_insn "*andsi3_media"
3177   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3178         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3179                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3180   "TARGET_SHMEDIA"
3181   "@
3182         and     %1, %2, %0
3183         andi    %1, %2, %0"
3184   [(set_attr "type" "arith_media")])
3185
3186 (define_insn "*andsi3_bclr"
3187   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3188         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3189                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3190   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3191   "bclr\\t%W2,%0"
3192   [(set_attr "type" "arith")])
3193
3194 ;; If the constant is 255, then emit an extu.b instruction instead of an
3195 ;; and, since that will give better code.
3196
3197 (define_expand "andsi3"
3198   [(set (match_operand:SI 0 "arith_reg_operand" "")
3199         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3200                 (match_operand:SI 2 "logical_operand" "")))]
3201   ""
3202   "
3203 {
3204   if (TARGET_SH1
3205       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3206     {
3207       emit_insn (gen_zero_extendqisi2 (operands[0],
3208                                        gen_lowpart (QImode, operands[1])));
3209       DONE;
3210     }
3211 }")
3212
3213 (define_insn_and_split "anddi3"
3214   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3215         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3216                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3217   "TARGET_SHMEDIA"
3218   "@
3219         and     %1, %2, %0
3220         andi    %1, %2, %0
3221         #"
3222   "reload_completed
3223    && ! logical_operand (operands[2], DImode)"
3224   [(const_int 0)]
3225   "
3226 {
3227   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3228     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3229   else
3230     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3231   DONE;
3232 }"
3233   [(set_attr "type" "arith_media")])
3234
3235 (define_insn "andcsi3"
3236   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3237         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3238                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3239   "TARGET_SHMEDIA"
3240   "andc %1,%2,%0"
3241   [(set_attr "type" "arith_media")])
3242
3243 (define_insn "andcdi3"
3244   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3245         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3246                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3247   "TARGET_SHMEDIA"
3248   "andc %1,%2,%0"
3249   [(set_attr "type" "arith_media")])
3250
3251 (define_expand "iorsi3"
3252   [(set (match_operand:SI 0 "arith_reg_operand" "")
3253         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3254                 (match_operand:SI 2 "logical_operand" "")))]
3255   ""
3256   "")
3257
3258 (define_insn "*iorsi3_compact"
3259   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3260         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3261                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3262   "TARGET_SH1
3263    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3264   "or   %2,%0"
3265   [(set_attr "type" "arith")])
3266
3267 (define_insn "*iorsi3_media"
3268   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3269         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3270                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3271   "TARGET_SHMEDIA"
3272   "@
3273         or      %1, %2, %0
3274         ori     %1, %2, %0"
3275   [(set_attr "type" "arith_media")])
3276
3277 (define_insn "*iorsi3_bset"
3278   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3279         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3280         (match_operand:SI 2 "const_int_operand" "Pso")))]
3281   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3282   "bset\\t%V2,%0"
3283   [(set_attr "type" "arith")])
3284
3285 (define_insn "iordi3"
3286   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3287         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3288                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3289   "TARGET_SHMEDIA"
3290   "@
3291         or      %1, %2, %0
3292         ori     %1, %2, %0"
3293   [(set_attr "type" "arith_media")])
3294
3295 (define_insn_and_split "*logical_sidi3"
3296   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3297         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3298                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3299                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3300   "TARGET_SHMEDIA"
3301   "#"
3302   "&& reload_completed"
3303   [(set (match_dup 0) (match_dup 3))]
3304   "
3305 {
3306   operands[3]
3307     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3308                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3309                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3310 }")
3311
3312 (define_insn_and_split "*logical_sidisi3"
3313   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3314         (truncate:SI (sign_extend:DI
3315                         (match_operator:SI 3 "logical_operator"
3316                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3317                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3318   "TARGET_SHMEDIA"
3319   "#"
3320   "&& 1"
3321   [(set (match_dup 0) (match_dup 3))])
3322
3323 (define_insn_and_split "*logical_sidi3_2"
3324   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325         (sign_extend:DI (truncate:SI (sign_extend:DI
3326                         (match_operator:SI 3 "logical_operator"
3327                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3328                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3329   "TARGET_SHMEDIA"
3330   "#"
3331   "&& 1"
3332   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3333
3334 (define_expand "xorsi3"
3335   [(set (match_operand:SI 0 "arith_reg_operand" "")
3336         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3337                 (match_operand:SI 2 "xor_operand" "")))]
3338   ""
3339   "")
3340
3341 (define_insn "*xorsi3_compact"
3342   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3343         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3344                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3345   "TARGET_SH1"
3346   "xor  %2,%0"
3347   [(set_attr "type" "arith")])
3348
3349 (define_insn "*xorsi3_media"
3350   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3351         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3352                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3353   "TARGET_SHMEDIA"
3354   "@
3355         xor     %1, %2, %0
3356         xori    %1, %2, %0"
3357   [(set_attr "type" "arith_media")])
3358
3359 ;; Store the complements of the T bit in a register.
3360 (define_insn "xorsi3_movrt"
3361   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3362         (xor:SI (reg:SI T_REG)
3363                 (const_int 1)))]
3364   "TARGET_SH2A"
3365   "movrt\\t%0"
3366   [(set_attr "type" "arith")])
3367
3368 (define_insn "xordi3"
3369   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3370         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3371                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3372   "TARGET_SHMEDIA"
3373   "@
3374         xor     %1, %2, %0
3375         xori    %1, %2, %0"
3376   [(set_attr "type" "arith_media")])
3377
3378 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3379 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3380 (define_split
3381   [(set (match_operand:DI 0 "arith_reg_dest" "")
3382         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3383                           [(match_operand 1 "any_register_operand" "")
3384                            (match_operand 2 "any_register_operand" "")])))]
3385   "TARGET_SHMEDIA"
3386   [(set (match_dup 5) (match_dup 4))
3387    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3388 "
3389 {
3390   enum machine_mode inmode = GET_MODE (operands[1]);
3391   int offset = 0;
3392
3393   if (GET_CODE (operands[0]) == SUBREG)
3394     {
3395       offset = SUBREG_BYTE (operands[0]);
3396       operands[0] = SUBREG_REG (operands[0]);
3397     }
3398   gcc_assert (REG_P (operands[0]));
3399   if (! TARGET_LITTLE_ENDIAN)
3400     offset += 8 - GET_MODE_SIZE (inmode);
3401   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3402 }")
3403 \f
3404 ;; -------------------------------------------------------------------------
3405 ;; Shifts and rotates
3406 ;; -------------------------------------------------------------------------
3407
3408 (define_expand "rotldi3"
3409   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3410         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3411                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3412   "TARGET_SHMEDIA"
3413   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3414
3415 (define_insn "rotldi3_mextr"
3416   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3417         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3418                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3419   "TARGET_SHMEDIA"
3420   "*
3421 {
3422   static char templ[16];
3423
3424   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3425            8 - (int) (INTVAL (operands[2]) >> 3));
3426   return templ;
3427 }"
3428   [(set_attr "type" "arith_media")])
3429
3430 (define_expand "rotrdi3"
3431   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3432         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3433                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3434   "TARGET_SHMEDIA"
3435   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3436
3437 (define_insn "rotrdi3_mextr"
3438   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3439         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3440                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3441   "TARGET_SHMEDIA"
3442   "*
3443 {
3444   static char templ[16];
3445
3446   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3447   return templ;
3448 }"
3449   [(set_attr "type" "arith_media")])
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "arith_reg_dest" "")
3453         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3454                                          "ua_address_operand" "")))
3455                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3456                            (const_int 8))))
3457    (clobber (match_operand:DI 3 "register_operand" ""))]
3458   "TARGET_SHMEDIA"
3459   [(match_dup 4) (match_dup 5)]
3460   "
3461 {
3462   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3463                  (operands[3], operands[1]));
3464   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3465                               GEN_INT (56), GEN_INT (8));
3466 }")
3467
3468 (define_insn "rotlsi3_1"
3469   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3471                    (const_int 1)))
3472    (set (reg:SI T_REG)
3473         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3474   "TARGET_SH1"
3475   "rotl %0"
3476   [(set_attr "type" "arith")])
3477
3478 (define_insn "rotlsi3_31"
3479   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3480         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3481                    (const_int 31)))
3482    (clobber (reg:SI T_REG))]
3483   "TARGET_SH1"
3484   "rotr %0"
3485   [(set_attr "type" "arith")])
3486
3487 (define_insn "rotlsi3_16"
3488   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3489         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3490                    (const_int 16)))]
3491   "TARGET_SH1"
3492   "swap.w       %1,%0"
3493   [(set_attr "type" "arith")])
3494
3495 (define_expand "rotlsi3"
3496   [(set (match_operand:SI 0 "arith_reg_dest" "")
3497         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3498                    (match_operand:SI 2 "immediate_operand" "")))]
3499   "TARGET_SH1"
3500   "
3501 {
3502   static const char rot_tab[] = {
3503     000, 000, 000, 000, 000, 000, 010, 001,
3504     001, 001, 011, 013, 003, 003, 003, 003,
3505     003, 003, 003, 003, 003, 013, 012, 002,
3506     002, 002, 010, 000, 000, 000, 000, 000,
3507   };
3508
3509   int count, choice;
3510
3511   if (!CONST_INT_P (operands[2]))
3512     FAIL;
3513   count = INTVAL (operands[2]);
3514   choice = rot_tab[count];
3515   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3516     FAIL;
3517   choice &= 7;
3518   switch (choice)
3519     {
3520     case 0:
3521       emit_move_insn (operands[0], operands[1]);
3522       count -= (count & 16) * 2;
3523       break;
3524     case 3:
3525      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3526      count -= 16;
3527      break;
3528     case 1:
3529     case 2:
3530       {
3531         rtx parts[2];
3532         parts[0] = gen_reg_rtx (SImode);
3533         parts[1] = gen_reg_rtx (SImode);
3534         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3535         emit_move_insn (parts[choice-1], operands[1]);
3536         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3537         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3538         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3539         count = (count & ~16) - 8;
3540       }
3541     }
3542
3543   for (; count > 0; count--)
3544     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3545   for (; count < 0; count++)
3546     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3547
3548   DONE;
3549 }")
3550
3551 (define_insn "*rotlhi3_8"
3552   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3553         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3554                    (const_int 8)))]
3555   "TARGET_SH1"
3556   "swap.b       %1,%0"
3557   [(set_attr "type" "arith")])
3558
3559 (define_expand "rotlhi3"
3560   [(set (match_operand:HI 0 "arith_reg_operand" "")
3561         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3562                    (match_operand:HI 2 "immediate_operand" "")))]
3563   "TARGET_SH1"
3564   "
3565 {
3566   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3567     FAIL;
3568 }")
3569
3570 ;;
3571 ;; shift left
3572
3573 ;; This pattern is used by init_expmed for computing the costs of shift
3574 ;; insns.
3575
3576 (define_insn_and_split "ashlsi3_std"
3577   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3578         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3579                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3580    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3581   "(TARGET_SH3 || TARGET_SH2A)
3582    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3583   "@
3584    shld %2,%0
3585    add  %0,%0
3586    shll%O2      %0
3587    #"
3588   "(TARGET_SH3 || TARGET_SH2A)
3589    && reload_completed
3590    && CONST_INT_P (operands[2])
3591    && ! satisfies_constraint_P27 (operands[2])"
3592   [(set (match_dup 3) (match_dup 2))
3593    (parallel
3594     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3595      (clobber (match_dup 4))])]
3596   "operands[4] = gen_rtx_SCRATCH (SImode);"
3597   [(set_attr "length" "*,*,*,4")
3598    (set_attr "type" "dyn_shift,arith,arith,arith")])
3599
3600 (define_insn "ashlhi3_k"
3601   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3602         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3603                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3604   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3605   "@
3606         add     %0,%0
3607         shll%O2 %0"
3608   [(set_attr "type" "arith")])
3609
3610 (define_insn "ashlsi3_n"
3611   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3612         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3613                    (match_operand:SI 2 "const_int_operand" "n")))
3614    (clobber (reg:SI T_REG))]
3615   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3616   "#"
3617   [(set (attr "length")
3618         (cond [(match_test "shift_insns_rtx (insn)")
3619                (const_string "2")
3620                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3621                (const_string "4")
3622                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3623                (const_string "6")]
3624               (const_string "8")))
3625    (set_attr "type" "arith")])
3626
3627 (define_split
3628   [(set (match_operand:SI 0 "arith_reg_dest" "")
3629         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3630                    (match_operand:SI 2 "const_int_operand" "")))
3631    (clobber (reg:SI T_REG))]
3632   "TARGET_SH1 && reload_completed"
3633   [(use (reg:SI R0_REG))]
3634   "
3635 {
3636   gen_shifty_op (ASHIFT, operands);
3637   DONE;
3638 }")
3639
3640 (define_insn "ashlsi3_media"
3641   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3642         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3643                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3644   "TARGET_SHMEDIA"
3645   "@
3646         shlld.l %1, %2, %0
3647         shlli.l %1, %2, %0"
3648   [(set_attr "type" "arith_media")
3649    (set_attr "highpart" "ignore")])
3650
3651 (define_expand "ashlsi3"
3652   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3653                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3654                               (match_operand:SI 2 "nonmemory_operand" "")))
3655               (clobber (reg:SI T_REG))])]
3656   ""
3657   "
3658 {
3659   if (TARGET_SHMEDIA)
3660     {
3661       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3662       DONE;
3663     }
3664   if (CONST_INT_P (operands[2])
3665       && sh_dynamicalize_shift_p (operands[2]))
3666     operands[2] = force_reg (SImode, operands[2]);
3667   if (TARGET_SH3 || TARGET_SH2A)
3668     {
3669       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3670       DONE;
3671     }
3672   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3673     FAIL;
3674 }")
3675
3676 (define_insn "*ashlhi3_n"
3677   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3678         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3679                    (match_operand:HI 2 "const_int_operand" "n")))
3680    (clobber (reg:SI T_REG))]
3681   "TARGET_SH1"
3682   "#"
3683   [(set (attr "length")
3684         (cond [(match_test "shift_insns_rtx (insn)")
3685                (const_string "2")
3686                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3687                (const_string "4")]
3688               (const_string "6")))
3689    (set_attr "type" "arith")])
3690
3691 (define_expand "ashlhi3"
3692   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3693                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3694                               (match_operand:SI 2 "nonmemory_operand" "")))
3695               (clobber (reg:SI T_REG))])]
3696   "TARGET_SH1"
3697   "
3698 {
3699   if (!CONST_INT_P (operands[2]))
3700     FAIL;
3701   /* It may be possible to call gen_ashlhi3 directly with more generic
3702      operands.  Make sure operands[1] is a HImode register here.  */
3703   if (!arith_reg_operand (operands[1], HImode))
3704     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3705 }")
3706
3707 (define_split
3708   [(set (match_operand:HI 0 "arith_reg_dest" "")
3709         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3710                    (match_operand:HI 2 "const_int_operand" "")))
3711    (clobber (reg:SI T_REG))]
3712   "TARGET_SH1 && reload_completed"
3713   [(use (reg:SI R0_REG))]
3714   "
3715 {
3716   gen_shifty_hi_op (ASHIFT, operands);
3717   DONE;
3718 }")
3719
3720 ;
3721 ; arithmetic shift right
3722 ;
3723
3724 (define_insn "ashrsi3_k"
3725   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3726         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3727                      (match_operand:SI 2 "const_int_operand" "M")))
3728    (clobber (reg:SI T_REG))]
3729   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3730   "shar %0"
3731   [(set_attr "type" "arith")])
3732
3733 ;; We can't do HImode right shifts correctly unless we start out with an
3734 ;; explicit zero / sign extension; doing that would result in worse overall
3735 ;; code, so just let the machine independent code widen the mode.
3736 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3737
3738
3739 ;; ??? This should be a define expand.
3740
3741 (define_insn "ashrsi2_16"
3742   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3743         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3744                      (const_int 16)))]
3745   "TARGET_SH1"
3746   "#"
3747   [(set_attr "length" "4")])
3748
3749 (define_split
3750   [(set (match_operand:SI 0 "arith_reg_dest" "")
3751         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3752                      (const_int 16)))]
3753   "TARGET_SH1"
3754   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3755    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3756   "operands[2] = gen_lowpart (HImode, operands[0]);")
3757
3758 ;; ??? This should be a define expand.
3759
3760 (define_insn "ashrsi2_31"
3761   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3762         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3763                      (const_int 31)))
3764    (clobber (reg:SI T_REG))]
3765   "TARGET_SH1"
3766   "#"
3767   [(set_attr "length" "4")])
3768
3769 (define_split
3770   [(set (match_operand:SI 0 "arith_reg_dest" "")
3771         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3772                      (const_int 31)))
3773    (clobber (reg:SI T_REG))]
3774   "TARGET_SH1"
3775   [(const_int 0)]
3776   "
3777 {
3778   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3779   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3780   DONE;
3781 }")
3782
3783 (define_peephole2
3784   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3785    (set (reg:SI T_REG)
3786         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3787   "TARGET_SH1
3788    && peep2_reg_dead_p (2, operands[0])
3789    && peep2_reg_dead_p (2, operands[1])"
3790   [(const_int 0)]
3791   "
3792 {
3793   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3794   DONE;
3795 }")
3796
3797 (define_insn "ashlsi_c"
3798   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3799         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3800    (set (reg:SI T_REG)
3801         (lt:SI (match_dup 1) (const_int 0)))]
3802   "TARGET_SH1"
3803   "shll %0"
3804   [(set_attr "type" "arith")])
3805
3806 (define_insn "*ashlsi_c_void"
3807   [(set (reg:SI T_REG)
3808         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3809    (clobber (match_scratch:SI 1 "=0"))]
3810   "TARGET_SH1 && cse_not_expected"
3811   "shll %0"
3812   [(set_attr "type" "arith")])
3813
3814 (define_insn "ashrsi3_d"
3815   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3816         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3817                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3818   "TARGET_SH3 || TARGET_SH2A"
3819   "shad %2,%0"
3820   [(set_attr "type" "dyn_shift")])
3821
3822 (define_insn "ashrsi3_n"
3823   [(set (reg:SI R4_REG)
3824         (ashiftrt:SI (reg:SI R4_REG)
3825                      (match_operand:SI 0 "const_int_operand" "i")))
3826    (clobber (reg:SI T_REG))
3827    (clobber (reg:SI PR_REG))
3828    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3829   "TARGET_SH1"
3830   "jsr  @%1%#"
3831   [(set_attr "type" "sfunc")
3832    (set_attr "needs_delay_slot" "yes")])
3833
3834 (define_insn "ashrsi3_media"
3835   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3836         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3837                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3838   "TARGET_SHMEDIA"
3839   "@
3840         shard.l %1, %2, %0
3841         shari.l %1, %2, %0"
3842   [(set_attr "type" "arith_media")
3843    (set_attr "highpart" "ignore")])
3844
3845 (define_expand "ashrsi3"
3846   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3847                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3848                                 (match_operand:SI 2 "nonmemory_operand" "")))
3849               (clobber (reg:SI T_REG))])]
3850   ""
3851   "
3852 {
3853   if (TARGET_SHMEDIA)
3854     {
3855       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3856       DONE;
3857     }
3858   if (expand_ashiftrt (operands))
3859     DONE;
3860   else
3861     FAIL;
3862 }")
3863
3864 ;; logical shift right
3865
3866 (define_insn "lshrsi3_d"
3867   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3868         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3869                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3870   "TARGET_SH3 || TARGET_SH2A"
3871   "shld %2,%0"
3872   [(set_attr "type" "dyn_shift")])
3873
3874 ;;  Only the single bit shift clobbers the T bit.
3875
3876 (define_insn "lshrsi3_m"
3877   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879                      (match_operand:SI 2 "const_int_operand" "M")))
3880    (clobber (reg:SI T_REG))]
3881   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3882   "shlr %0"
3883   [(set_attr "type" "arith")])
3884
3885 (define_insn "lshrsi3_k"
3886   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3887         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3888                      (match_operand:SI 2 "const_int_operand" "P27")))]
3889   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3890    && ! satisfies_constraint_M (operands[2])"
3891   "shlr%O2      %0"
3892   [(set_attr "type" "arith")])
3893
3894 (define_insn "lshrsi3_n"
3895   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3896         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3897                      (match_operand:SI 2 "const_int_operand" "n")))
3898    (clobber (reg:SI T_REG))]
3899   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3900   "#"
3901   [(set (attr "length")
3902         (cond [(match_test "shift_insns_rtx (insn)")
3903                (const_string "2")
3904                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3905                (const_string "4")
3906                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3907                (const_string "6")]
3908               (const_string "8")))
3909    (set_attr "type" "arith")])
3910
3911 (define_split
3912   [(set (match_operand:SI 0 "arith_reg_dest" "")
3913         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3914                      (match_operand:SI 2 "const_int_operand" "")))
3915    (clobber (reg:SI T_REG))]
3916   "TARGET_SH1 && reload_completed"
3917   [(use (reg:SI R0_REG))]
3918   "
3919 {
3920   gen_shifty_op (LSHIFTRT, operands);
3921   DONE;
3922 }")
3923
3924 (define_insn "lshrsi3_media"
3925   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3926         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3927                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3928   "TARGET_SHMEDIA"
3929   "@
3930         shlrd.l %1, %2, %0
3931         shlri.l %1, %2, %0"
3932   [(set_attr "type" "arith_media")
3933    (set_attr "highpart" "ignore")])
3934
3935 (define_expand "lshrsi3"
3936   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3937                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3938                                 (match_operand:SI 2 "nonmemory_operand" "")))
3939               (clobber (reg:SI T_REG))])]
3940   ""
3941   "
3942 {
3943   if (TARGET_SHMEDIA)
3944     {
3945       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3946       DONE;
3947     }
3948   if (CONST_INT_P (operands[2])
3949       && sh_dynamicalize_shift_p (operands[2]))
3950     operands[2] = force_reg (SImode, operands[2]);
3951   if ((TARGET_SH3 || TARGET_SH2A)
3952       && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3953     {
3954       rtx count = copy_to_mode_reg (SImode, operands[2]);
3955       emit_insn (gen_negsi2 (count, count));
3956       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3957       DONE;
3958     }
3959   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3960     FAIL;
3961 }")
3962
3963 ;; ??? This should be a define expand.
3964
3965 (define_insn "ashldi3_k"
3966   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3967         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3968                    (const_int 1)))
3969    (clobber (reg:SI T_REG))]
3970   "TARGET_SH1"
3971   "shll %R0\;rotcl      %S0"
3972   [(set_attr "length" "4")
3973    (set_attr "type" "arith")])
3974
3975 ;; Expander for DImode shift left with SImode operations.
3976
3977 (define_expand "ashldi3_std"
3978   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3979         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3980                    (match_operand:DI 2 "const_int_operand" "n")))]
3981   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3982   "
3983 {
3984   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3985   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3986   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3987   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3988   rtx dst = gen_reg_rtx (DImode);
3989   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3990   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3991   rtx tmp0, tmp1;
3992
3993   tmp0 = gen_reg_rtx (SImode);
3994   tmp1 = gen_reg_rtx (SImode);
3995   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3996   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3997   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3998   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3999   emit_move_insn (operands[0], dst);
4000   DONE;
4001 }")
4002
4003 (define_insn "ashldi3_media"
4004   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4005         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4006                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
4007   "TARGET_SHMEDIA"
4008   "@
4009         shlld   %1, %2, %0
4010         shlli   %1, %2, %0"
4011   [(set_attr "type" "arith_media")])
4012
4013 (define_insn "*ashldisi3_media"
4014   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4015         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4016                    (match_operand:DI 2 "const_int_operand" "n")))]
4017   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4018   "shlli.l      %1, %2, %0"
4019   [(set_attr "type" "arith_media")
4020    (set_attr "highpart" "ignore")])
4021
4022 (define_expand "ashldi3"
4023   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4024                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4025                               (match_operand:DI 2 "immediate_operand" "")))
4026               (clobber (reg:SI T_REG))])]
4027   ""
4028   "
4029 {
4030   if (TARGET_SHMEDIA)
4031     {
4032       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4033       DONE;
4034     }
4035   if (CONST_INT_P (operands[2])
4036       && INTVAL (operands[2]) == 1)
4037     {
4038       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4039       DONE;
4040     }
4041   else if (CONST_INT_P (operands[2])
4042       && INTVAL (operands[2]) < 32)
4043     {
4044       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4045       DONE;
4046     }
4047   else
4048     FAIL;
4049 }")
4050
4051 ;; ??? This should be a define expand.
4052
4053 (define_insn "lshrdi3_k"
4054   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4055         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4056                      (const_int 1)))
4057    (clobber (reg:SI T_REG))]
4058   "TARGET_SH1"
4059   "shlr %S0\;rotcr      %R0"
4060   [(set_attr "length" "4")
4061    (set_attr "type" "arith")])
4062
4063 (define_insn "lshrdi3_media"
4064   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4065         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4066                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4067   "TARGET_SHMEDIA
4068    && (arith_reg_dest (operands[0], DImode)
4069        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4070   "@
4071         shlrd   %1, %2, %0
4072         shlri   %1, %2, %0"
4073   [(set_attr "type" "arith_media")])
4074
4075 (define_insn "*lshrdisi3_media"
4076   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4077         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4078                      (match_operand:DI 2 "const_int_operand" "n")))]
4079   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4080   "shlri.l      %1, %2, %0"
4081   [(set_attr "type" "arith_media")
4082    (set_attr "highpart" "ignore")])
4083
4084 (define_expand "lshrdi3"
4085   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4086                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4087                                (match_operand:DI 2 "immediate_operand" "")))
4088              (clobber (reg:SI T_REG))])]
4089   ""
4090   "
4091 {
4092   if (TARGET_SHMEDIA)
4093     {
4094       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4095       DONE;
4096     }
4097   if (!CONST_INT_P (operands[2])
4098       || INTVAL (operands[2]) != 1)
4099     FAIL;
4100 }")
4101
4102 ;; ??? This should be a define expand.
4103
4104 (define_insn "ashrdi3_k"
4105   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4106         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4107                      (const_int 1)))
4108    (clobber (reg:SI T_REG))]
4109   "TARGET_SH1"
4110   "shar %S0\;rotcr      %R0"
4111   [(set_attr "length" "4")
4112    (set_attr "type" "arith")])
4113
4114 (define_insn "ashrdi3_media"
4115   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4116         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4117                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4118   "TARGET_SHMEDIA
4119    && (arith_reg_dest (operands[0], DImode)
4120        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4121   "@
4122         shard   %1, %2, %0
4123         shari   %1, %2, %0"
4124   [(set_attr "type" "arith_media")])
4125
4126 (define_insn "*ashrdisi3_media"
4127   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4128         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4129                      (match_operand:DI 2 "const_int_operand" "n")))]
4130   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4131   "shari.l      %1, %2, %0"
4132   [(set_attr "type" "arith_media")
4133    (set_attr "highpart" "ignore")])
4134
4135 (define_insn "ashrdisi3_media_high"
4136   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4137         (truncate:SI
4138            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4139                         (match_operand:DI 2 "const_int_operand" "n"))))]
4140   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4141   "shari        %1, %2, %0"
4142   [(set_attr "type" "arith_media")])
4143
4144 (define_insn "ashrdisi3_media_opaque"
4145   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4146         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4147                     (match_operand:DI 2 "const_int_operand" "n")]
4148          UNSPEC_ASHIFTRT))]
4149   "TARGET_SHMEDIA"
4150   "shari        %1, %2, %0"
4151   [(set_attr "type" "arith_media")])
4152
4153 (define_expand "ashrdi3"
4154   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4155                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4156                                 (match_operand:DI 2 "immediate_operand" "")))
4157               (clobber (reg:SI T_REG))])]
4158   ""
4159   "
4160 {
4161   if (TARGET_SHMEDIA)
4162     {
4163       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4164       DONE;
4165     }
4166   if (!CONST_INT_P (operands[2])
4167       || INTVAL (operands[2]) != 1)
4168     FAIL;
4169 }")
4170
4171 ;; combined left/right shift
4172
4173 (define_split
4174   [(set (match_operand:SI 0 "register_operand" "")
4175         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4176                            (match_operand:SI 2 "const_int_operand" ""))
4177                 (match_operand:SI 3 "const_int_operand" "")))]
4178   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4179   [(use (reg:SI R0_REG))]
4180   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4181    DONE;")
4182
4183 (define_split
4184   [(set (match_operand:SI 0 "register_operand" "")
4185         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4186                            (match_operand:SI 2 "const_int_operand" ""))
4187                 (match_operand:SI 3 "const_int_operand" "")))
4188    (clobber (reg:SI T_REG))]
4189   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4190   [(use (reg:SI R0_REG))]
4191   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4192    DONE;")
4193
4194 (define_insn ""
4195   [(set (match_operand:SI 0 "register_operand" "=r")
4196         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4197                            (match_operand:SI 2 "const_int_operand" "n"))
4198                 (match_operand:SI 3 "const_int_operand" "n")))
4199    (clobber (reg:SI T_REG))]
4200   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4201  "#"
4202   [(set (attr "length")
4203         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4204                (const_string "4")
4205                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4206                (const_string "6")
4207                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4208                (const_string "8")
4209                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4210                (const_string "10")
4211                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4212                (const_string "12")
4213                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4214                (const_string "14")
4215                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4216                (const_string "16")]
4217               (const_string "18")))
4218    (set_attr "type" "arith")])
4219
4220 (define_insn ""
4221   [(set (match_operand:SI 0 "register_operand" "=z")
4222         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4223                            (match_operand:SI 2 "const_int_operand" "n"))
4224                 (match_operand:SI 3 "const_int_operand" "n")))
4225    (clobber (reg:SI T_REG))]
4226   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4227  "#"
4228   [(set (attr "length")
4229         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4230                (const_string "4")
4231                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4232                (const_string "6")
4233                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4234                (const_string "8")]
4235               (const_string "10")))
4236    (set_attr "type" "arith")])
4237
4238 ;; shift left / and combination with a scratch register: The combine pass
4239 ;; does not accept the individual instructions, even though they are
4240 ;; cheap.  But it needs a precise description so that it is usable after
4241 ;; reload.
4242 (define_insn "and_shl_scratch"
4243   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4244         (lshiftrt:SI
4245          (ashift:SI
4246           (and:SI
4247            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4248                         (match_operand:SI 2 "const_int_operand" "N,n"))
4249            (match_operand:SI 3 "" "0,r"))
4250           (match_operand:SI 4 "const_int_operand" "n,n"))
4251          (match_operand:SI 5 "const_int_operand" "n,n")))
4252    (clobber (reg:SI T_REG))]
4253   "TARGET_SH1"
4254   "#"
4255   [(set (attr "length")
4256         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4257                (const_string "4")
4258                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4259                (const_string "6")
4260                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4261                (const_string "8")
4262                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4263                (const_string "10")]
4264               (const_string "12")))
4265    (set_attr "type" "arith")])
4266
4267 (define_split
4268   [(set (match_operand:SI 0 "register_operand" "")
4269         (lshiftrt:SI
4270          (ashift:SI
4271           (and:SI
4272            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4273                         (match_operand:SI 2 "const_int_operand" ""))
4274            (match_operand:SI 3 "register_operand" ""))
4275           (match_operand:SI 4 "const_int_operand" ""))
4276          (match_operand:SI 5 "const_int_operand" "")))
4277    (clobber (reg:SI T_REG))]
4278   "TARGET_SH1"
4279   [(use (reg:SI R0_REG))]
4280   "
4281 {
4282   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4283
4284   if (INTVAL (operands[2]))
4285     {
4286       gen_shifty_op (LSHIFTRT, operands);
4287     }
4288   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4289   operands[2] = operands[4];
4290   gen_shifty_op (ASHIFT, operands);
4291   if (INTVAL (operands[5]))
4292     {
4293       operands[2] = operands[5];
4294       gen_shifty_op (LSHIFTRT, operands);
4295     }
4296   DONE;
4297 }")
4298
4299 ;; signed left/right shift combination.
4300 (define_split
4301   [(set (match_operand:SI 0 "register_operand" "")
4302         (sign_extract:SI
4303          (ashift:SI (match_operand:SI 1 "register_operand" "")
4304                     (match_operand:SI 2 "const_int_operand" ""))
4305          (match_operand:SI 3 "const_int_operand" "")
4306          (const_int 0)))
4307    (clobber (reg:SI T_REG))]
4308   "TARGET_SH1"
4309   [(use (reg:SI R0_REG))]
4310   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4311    DONE;")
4312
4313 (define_insn "shl_sext_ext"
4314   [(set (match_operand:SI 0 "register_operand" "=r")
4315         (sign_extract:SI
4316          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4317                     (match_operand:SI 2 "const_int_operand" "n"))
4318          (match_operand:SI 3 "const_int_operand" "n")
4319          (const_int 0)))
4320    (clobber (reg:SI T_REG))]
4321   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4322   "#"
4323   [(set (attr "length")
4324         (cond [(match_test "shl_sext_length (insn)")
4325                (const_string "2")
4326                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4327                (const_string "4")
4328                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4329                (const_string "6")
4330                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4331                (const_string "8")
4332                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4333                (const_string "10")
4334                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4335                (const_string "12")
4336                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4337                (const_string "14")
4338                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4339                (const_string "16")]
4340               (const_string "18")))
4341     (set_attr "type" "arith")])
4342
4343 (define_insn "shl_sext_sub"
4344   [(set (match_operand:SI 0 "register_operand" "=z")
4345         (sign_extract:SI
4346          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4347                     (match_operand:SI 2 "const_int_operand" "n"))
4348          (match_operand:SI 3 "const_int_operand" "n")
4349          (const_int 0)))
4350    (clobber (reg:SI T_REG))]
4351   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4352   "#"
4353   [(set (attr "length")
4354         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4355                (const_string "6")
4356                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4357                (const_string "8")
4358                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4359                (const_string "10")
4360                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4361                (const_string "12")]
4362               (const_string "14")))
4363     (set_attr "type" "arith")])
4364
4365 ;; These patterns are found in expansions of DImode shifts by 16, and
4366 ;; allow the xtrct instruction to be generated from C source.
4367
4368 (define_insn "xtrct_left"
4369   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4370         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4371                            (const_int 16))
4372                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4373                              (const_int 16))))]
4374   "TARGET_SH1"
4375   "xtrct        %1,%0"
4376   [(set_attr "type" "arith")])
4377
4378 (define_insn "xtrct_right"
4379   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4380         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4381                              (const_int 16))
4382                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4383                            (const_int 16))))]
4384   "TARGET_SH1"
4385   "xtrct        %2,%0"
4386   [(set_attr "type" "arith")])
4387
4388 ;; -------------------------------------------------------------------------
4389 ;; Unary arithmetic
4390 ;; -------------------------------------------------------------------------
4391
4392 (define_insn "negc"
4393   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4394         (neg:SI (plus:SI (reg:SI T_REG)
4395                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4396    (set (reg:SI T_REG)
4397         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4398                (const_int 0)))]
4399   "TARGET_SH1"
4400   "negc %1,%0"
4401   [(set_attr "type" "arith")])
4402
4403 (define_insn "*negdi_media"
4404   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4405         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4406   "TARGET_SHMEDIA"
4407   "sub  r63, %1, %0"
4408   [(set_attr "type" "arith_media")])
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   "TARGET_SH1"
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 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4501 ;; This can be used as some kind of conditional execution, which is useful
4502 ;; for abs.
4503 ;; Actually the instruction scheduling should decide whether to use a
4504 ;; zero-offset branch or not for any generic case involving a single
4505 ;; instruction on SH4 202.
4506
4507 (define_insn_and_split "negsi_cond"
4508   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4509         (if_then_else:SI (eq:SI (reg:SI T_REG)
4510                           (match_operand:SI 3 "const_int_operand" "M,N"))
4511          (match_operand:SI 1 "arith_reg_operand" "0,0")
4512          (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4513   "TARGET_HARD_SH4"
4514   "@
4515         bt\\t0f\;neg\\t%2,%0\\n0:
4516         bf\\t0f\;neg\\t%2,%0\\n0:"
4517   "!TARGET_HARD_SH4"
4518   [(const_int 0)]
4519   "
4520 {
4521   rtx skip_neg_label = gen_label_rtx ();
4522
4523   emit_insn (gen_movsi (operands[0], operands[1]));
4524
4525   emit_jump_insn (INTVAL (operands[3])
4526                   ? gen_branch_true (skip_neg_label)
4527                   : gen_branch_false (skip_neg_label));
4528
4529   emit_label_after (skip_neg_label,
4530                     emit_insn (gen_negsi2 (operands[0], operands[1])));
4531   DONE;
4532 }"
4533   [(set_attr "type" "arith") ;; poor approximation
4534    (set_attr "length" "4")])
4535
4536 \f
4537 ;; -------------------------------------------------------------------------
4538 ;; Zero extension instructions
4539 ;; -------------------------------------------------------------------------
4540
4541 (define_insn "zero_extendsidi2"
4542   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4543         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4544   "TARGET_SHMEDIA"
4545   "addz.l       %1, r63, %0"
4546   [(set_attr "type" "arith_media")
4547    (set_attr "highpart" "extend")])
4548
4549 (define_insn "zero_extendhidi2"
4550   [(set (match_operand:DI 0 "register_operand" "=r,r")
4551         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4552   "TARGET_SHMEDIA"
4553   "@
4554         #
4555         ld%M1.uw        %m1, %0"
4556   [(set_attr "type" "*,load_media")
4557    (set (attr "highpart")
4558         (cond [(match_test "sh_contains_memref_p (insn)")
4559                (const_string "user")]
4560               (const_string "ignore")))])
4561
4562 (define_split
4563   [(set (match_operand:DI 0 "register_operand" "")
4564         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4565   "TARGET_SHMEDIA && reload_completed"
4566   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4567    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4568   "
4569 {
4570   if (GET_CODE (operands[1]) == TRUNCATE)
4571     operands[1] = XEXP (operands[1], 0);
4572 }")
4573
4574 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4575 ;; reload the entire truncate expression.
4576 (define_insn_and_split "*loaddi_trunc"
4577   [(set (match_operand 0 "any_register_operand" "=r")
4578         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4579   "TARGET_SHMEDIA && reload_completed"
4580   "#"
4581   "TARGET_SHMEDIA && reload_completed"
4582   [(set (match_dup 0) (match_dup 1))]
4583   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4584
4585 (define_insn "zero_extendqidi2"
4586   [(set (match_operand:DI 0 "register_operand" "=r,r")
4587         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4588   "TARGET_SHMEDIA"
4589   "@
4590         andi    %1, 255, %0
4591         ld%M1.ub        %m1, %0"
4592   [(set_attr "type" "arith_media,load_media")
4593    (set (attr "highpart")
4594         (cond [(match_test "sh_contains_memref_p (insn)")
4595                (const_string "user")]
4596               (const_string "ignore")))])
4597
4598 (define_expand "zero_extendhisi2"
4599   [(set (match_operand:SI 0 "arith_reg_operand" "")
4600         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4601   ""
4602   "
4603 {
4604   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4605     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4606 }")
4607
4608 (define_insn "*zero_extendhisi2_compact"
4609   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4610         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4611   "TARGET_SH1"
4612   "extu.w       %1,%0"
4613   [(set_attr "type" "arith")])
4614
4615 (define_insn "*zero_extendhisi2_media"
4616   [(set (match_operand:SI 0 "register_operand" "=r,r")
4617         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4618   "TARGET_SHMEDIA"
4619   "@
4620         #
4621         ld%M1.uw        %m1, %0"
4622   [(set_attr "type" "arith_media,load_media")
4623    (set (attr "highpart")
4624         (cond [(match_test "sh_contains_memref_p (insn)")
4625                (const_string "user")]
4626               (const_string "ignore")))])
4627
4628 (define_split
4629   [(set (match_operand:SI 0 "register_operand" "")
4630         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4631   "TARGET_SHMEDIA && reload_completed"
4632   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4633    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4634   "
4635 {
4636   rtx op1 = operands[1];
4637
4638   if (GET_CODE (op1) == TRUNCATE)
4639     op1 = XEXP (op1, 0);
4640   operands[2]
4641     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4642                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4643 }")
4644
4645 (define_expand "zero_extendqisi2"
4646   [(set (match_operand:SI 0 "arith_reg_operand" "")
4647         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4648   ""
4649   "
4650 {
4651   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4652     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4653 }")
4654
4655 (define_insn "*zero_extendqisi2_compact"
4656   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4657         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4658   "TARGET_SH1"
4659   "extu.b       %1,%0"
4660   [(set_attr "type" "arith")])
4661
4662 (define_insn "*zero_extendqisi2_media"
4663   [(set (match_operand:SI 0 "register_operand" "=r,r")
4664         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4665   "TARGET_SHMEDIA"
4666   "@
4667         andi    %1, 255, %0
4668         ld%M1.ub        %m1, %0"
4669   [(set_attr "type" "arith_media,load_media")
4670    (set (attr "highpart")
4671         (cond [(match_test "sh_contains_memref_p (insn)")
4672                (const_string "user")]
4673               (const_string "ignore")))])
4674
4675 (define_insn "zero_extendqihi2"
4676   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4677         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4678   "TARGET_SH1"
4679   "extu.b       %1,%0"
4680   [(set_attr "type" "arith")])
4681
4682 ;; -------------------------------------------------------------------------
4683 ;; Sign extension instructions
4684 ;; -------------------------------------------------------------------------
4685
4686 ;; ??? This should be a define expand.
4687 ;; ??? Or perhaps it should be dropped?
4688
4689 ;; convert_move generates good code for SH[1-4].
4690 (define_insn "extendsidi2"
4691   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4692         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4693   "TARGET_SHMEDIA"
4694   "@
4695         add.l   %1, r63, %0
4696         ld%M1.l %m1, %0
4697         fmov.sl %1, %0"
4698   [(set_attr "type" "arith_media,load_media,fpconv_media")
4699    (set (attr "highpart")
4700         (cond [(match_test "sh_contains_memref_p (insn)")
4701                (const_string "user")]
4702               (const_string "extend")))])
4703
4704 (define_insn "extendhidi2"
4705   [(set (match_operand:DI 0 "register_operand" "=r,r")
4706         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4707   "TARGET_SHMEDIA"
4708   "@
4709         #
4710         ld%M1.w %m1, %0"
4711   [(set_attr "type" "*,load_media")
4712    (set (attr "highpart")
4713         (cond [(match_test "sh_contains_memref_p (insn)")
4714                (const_string "user")]
4715               (const_string "ignore")))])
4716
4717 (define_split
4718   [(set (match_operand:DI 0 "register_operand" "")
4719         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4720   "TARGET_SHMEDIA && reload_completed"
4721   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4722    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4723   "
4724 {
4725   if (GET_CODE (operands[1]) == TRUNCATE)
4726     operands[1] = XEXP (operands[1], 0);
4727 }")
4728
4729 (define_insn "extendqidi2"
4730   [(set (match_operand:DI 0 "register_operand" "=r,r")
4731         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4732   "TARGET_SHMEDIA"
4733   "@
4734         #
4735         ld%M1.b %m1, %0"
4736   [(set_attr "type" "*,load_media")
4737    (set (attr "highpart")
4738         (cond [(match_test "sh_contains_memref_p (insn)")
4739                (const_string "user")]
4740               (const_string "ignore")))])
4741
4742 (define_split
4743   [(set (match_operand:DI 0 "register_operand" "")
4744         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4745   "TARGET_SHMEDIA && reload_completed"
4746   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4747    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4748   "
4749 {
4750   if (GET_CODE (operands[1]) == TRUNCATE)
4751     operands[1] = XEXP (operands[1], 0);
4752 }")
4753
4754 (define_expand "extendhisi2"
4755   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4756         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4757   ""
4758   "")
4759
4760 (define_insn "*extendhisi2_compact"
4761   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4762         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4763   "TARGET_SH1"
4764   "@
4765         exts.w  %1,%0
4766         mov.w   %1,%0"
4767   [(set_attr "type" "arith,load")])
4768
4769 (define_insn "*extendhisi2_media"
4770   [(set (match_operand:SI 0 "register_operand" "=r,r")
4771         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4772   "TARGET_SHMEDIA"
4773   "@
4774         #
4775         ld%M1.w %m1, %0"
4776   [(set_attr "type" "arith_media,load_media")
4777    (set (attr "highpart")
4778         (cond [(match_test "sh_contains_memref_p (insn)")
4779                (const_string "user")]
4780               (const_string "ignore")))])
4781
4782 (define_split
4783   [(set (match_operand:SI 0 "register_operand" "")
4784         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4785   "TARGET_SHMEDIA && reload_completed"
4786   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4787    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4788   "
4789 {
4790   rtx op1 = operands[1];
4791   if (GET_CODE (op1) == TRUNCATE)
4792     op1 = XEXP (op1, 0);
4793   operands[2]
4794     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4795                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4796 }")
4797
4798 (define_expand "extendqisi2"
4799   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4800         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4801   ""
4802   "")
4803
4804 (define_insn "*extendqisi2_compact"
4805   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4806         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4807   "TARGET_SH1"
4808   "@
4809         exts.b  %1,%0
4810         mov.b   %1,%0"
4811   [(set_attr "type" "arith,load")
4812    (set_attr_alternative "length"
4813      [(const_int 2)
4814        (if_then_else
4815         (match_test "TARGET_SH2A")
4816         (const_int 4) (const_int 2))])])
4817
4818 (define_insn "*extendqisi2_media"
4819   [(set (match_operand:SI 0 "register_operand" "=r,r")
4820         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4821   "TARGET_SHMEDIA"
4822   "@
4823         #
4824         ld%M1.b %m1, %0"
4825   [(set_attr "type" "arith_media,load_media")
4826    (set (attr "highpart")
4827         (cond [(match_test "sh_contains_memref_p (insn)")
4828                (const_string "user")]
4829               (const_string "ignore")))])
4830
4831 (define_split
4832   [(set (match_operand:SI 0 "register_operand" "")
4833         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4834   "TARGET_SHMEDIA && reload_completed"
4835   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4836    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4837    "
4838 {
4839   rtx op1 = operands[1];
4840   if (GET_CODE (op1) == TRUNCATE)
4841     op1 = XEXP (op1, 0);
4842   operands[2]
4843     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4844                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4845 }")
4846
4847 (define_insn "extendqihi2"
4848   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4849         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4850   "TARGET_SH1"
4851   "@
4852         exts.b  %1,%0
4853         mov.b   %1,%0"
4854   [(set_attr "type" "arith,load")
4855    (set_attr_alternative "length"
4856      [(const_int 2)
4857        (if_then_else
4858         (match_test "TARGET_SH2A")
4859         (const_int 4) (const_int 2))])])
4860
4861 /* It would seem useful to combine the truncXi patterns into the movXi
4862    patterns, but unary operators are ignored when matching constraints,
4863    so we need separate patterns.  */
4864 (define_insn "truncdisi2"
4865   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4866         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4867   "TARGET_SHMEDIA"
4868   "@
4869         add.l   %1, r63, %0
4870         st%M0.l %m0, %1
4871         fst%M0.s        %m0, %T1
4872         fmov.ls %1, %0
4873         fmov.sl %T1, %0
4874         fmov.s  %T1, %0"
4875   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4876    (set (attr "highpart")
4877         (cond [(match_test "sh_contains_memref_p (insn)")
4878                (const_string "user")]
4879               (const_string "extend")))])
4880
4881 (define_insn "truncdihi2"
4882   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4883         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4884   "TARGET_SHMEDIA"
4885   "@
4886         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4887         st%M0.w %m0, %1"
4888   [(set_attr "type"   "arith_media,store_media")
4889    (set_attr "length" "8,4")
4890    (set (attr "highpart")
4891         (cond [(match_test "sh_contains_memref_p (insn)")
4892                (const_string "user")]
4893               (const_string "extend")))])
4894
4895 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4896 ; Because we use zero extension, we can't provide signed QImode compares
4897 ; using a simple compare or conditional branch insn.
4898 (define_insn "truncdiqi2"
4899   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4900         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4901   "TARGET_SHMEDIA"
4902   "@
4903         andi    %1, 255, %0
4904         st%M0.b %m0, %1"
4905   [(set_attr "type"   "arith_media,store")
4906    (set (attr "highpart")
4907         (cond [(match_test "sh_contains_memref_p (insn)")
4908                (const_string "user")]
4909               (const_string "extend")))])
4910 ;; -------------------------------------------------------------------------
4911 ;; Move instructions
4912 ;; -------------------------------------------------------------------------
4913
4914 ;; define push and pop so it is easy for sh.c
4915 ;; We can't use push and pop on SHcompact because the stack must always
4916 ;; be 8-byte aligned.
4917
4918 (define_expand "push"
4919   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4920         (match_operand:SI 0 "register_operand" "r,l,x"))]
4921   "TARGET_SH1 && ! TARGET_SH5"
4922   "")
4923
4924 (define_expand "pop"
4925   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4926         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4927   "TARGET_SH1 && ! TARGET_SH5"
4928   "")
4929
4930 (define_expand "push_e"
4931   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4932                    (match_operand:SF 0 "" ""))
4933               (use (reg:PSI FPSCR_REG))
4934               (clobber (scratch:SI))])]
4935   "TARGET_SH1 && ! TARGET_SH5"
4936   "")
4937
4938 (define_insn "push_fpul"
4939   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4940   "TARGET_SH2E && ! TARGET_SH5"
4941   "sts.l        fpul,@-r15"
4942   [(set_attr "type" "fstore")
4943    (set_attr "late_fp_use" "yes")
4944    (set_attr "hit_stack" "yes")])
4945
4946 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4947 ;; so use that.
4948 (define_expand "push_4"
4949   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4950                    (match_operand:DF 0 "" ""))
4951               (use (reg:PSI FPSCR_REG))
4952               (clobber (scratch:SI))])]
4953   "TARGET_SH1 && ! TARGET_SH5"
4954   "")
4955
4956 (define_expand "pop_e"
4957   [(parallel [(set (match_operand:SF 0 "" "")
4958               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4959               (use (reg:PSI FPSCR_REG))
4960               (clobber (scratch:SI))])]
4961   "TARGET_SH1 && ! TARGET_SH5"
4962   "")
4963
4964 (define_insn "pop_fpul"
4965   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4966   "TARGET_SH2E && ! TARGET_SH5"
4967   "lds.l        @r15+,fpul"
4968   [(set_attr "type" "load")
4969    (set_attr "hit_stack" "yes")])
4970
4971 (define_expand "pop_4"
4972   [(parallel [(set (match_operand:DF 0 "" "")
4973                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4974               (use (reg:PSI FPSCR_REG))
4975               (clobber (scratch:SI))])]
4976   "TARGET_SH1 && ! TARGET_SH5"
4977   "")
4978
4979 (define_expand "push_fpscr"
4980   [(const_int 0)]
4981   "TARGET_SH2E"
4982   "
4983 {
4984   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4985                                                  gen_rtx_PRE_DEC (Pmode,
4986                                                           stack_pointer_rtx)),
4987                                         get_fpscr_rtx ()));
4988   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4989   DONE;
4990 }")
4991
4992 (define_expand "pop_fpscr"
4993   [(const_int 0)]
4994   "TARGET_SH2E"
4995   "
4996 {
4997   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4998                                         gen_frame_mem (PSImode,
4999                                                  gen_rtx_POST_INC (Pmode,
5000                                                           stack_pointer_rtx))));
5001   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5002   DONE;
5003 }")
5004
5005 ;; These two patterns can happen as the result of optimization, when
5006 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5007 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5008
5009 (define_insn "clrt"
5010   [(set (reg:SI T_REG) (const_int 0))]
5011   "TARGET_SH1"
5012   "clrt")
5013
5014 (define_insn "sett"
5015   [(set (reg:SI T_REG) (const_int 1))]
5016   "TARGET_SH1"
5017   "sett")
5018
5019 ;; Define additional pop for SH1 and SH2 so it does not get 
5020 ;; placed in the delay slot.
5021 (define_insn "*movsi_pop"
5022   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5023         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5024   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5025    && ! TARGET_SH3"
5026   "@
5027    mov.l   %1,%0
5028    lds.l   %1,%0
5029    lds.l   %1,%0"
5030   [(set_attr "type" "load_si,mem_mac,pload")
5031    (set_attr "length" "2,2,2")
5032    (set_attr "in_delay_slot" "no,no,no")])
5033
5034 ;; t/r must come after r/r, lest reload will try to reload stuff like
5035 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5036 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5037 (define_insn "movsi_i"
5038   [(set (match_operand:SI 0 "general_movdst_operand"
5039             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5040         (match_operand:SI 1 "general_movsrc_operand"
5041          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5042   "TARGET_SH1
5043    && ! TARGET_SH2E
5044    && ! TARGET_SH2A
5045    && (register_operand (operands[0], SImode)
5046        || register_operand (operands[1], SImode))"
5047   "@
5048         mov.l   %1,%0
5049         mov     %1,%0
5050         mov     %1,%0
5051         cmp/pl  %1
5052         mov.l   %1,%0
5053         sts     %1,%0
5054         sts     %1,%0
5055         movt    %0
5056         mov.l   %1,%0
5057         sts.l   %1,%0
5058         sts.l   %1,%0
5059         lds     %1,%0
5060         lds     %1,%0
5061         lds.l   %1,%0
5062         lds.l   %1,%0
5063         fake    %1,%0"
5064   [(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")
5065    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5066
5067 ;; t/r must come after r/r, lest reload will try to reload stuff like
5068 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5069 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5070 ;; will require a reload.
5071 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5072 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5073 (define_insn "movsi_ie"
5074   [(set (match_operand:SI 0 "general_movdst_operand"
5075             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5076         (match_operand:SI 1 "general_movsrc_operand"
5077          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5078   "(TARGET_SH2E || TARGET_SH2A)
5079    && (register_operand (operands[0], SImode)
5080        || register_operand (operands[1], SImode))"
5081   "@
5082         mov.l   %1,%0
5083         mov     %1,%0
5084         mov     %1,%0
5085         movi20  %1,%0
5086         movi20s %1,%0
5087         cmp/pl  %1
5088         mov.l   %1,%0
5089         sts     %1,%0
5090         sts     %1,%0
5091         movt    %0
5092         mov.l   %1,%0
5093         sts.l   %1,%0
5094         sts.l   %1,%0
5095         lds     %1,%0
5096         lds     %1,%0
5097         lds.l   %1,%0
5098         lds.l   %1,%0
5099         lds.l   %1,%0
5100         sts.l   %1,%0
5101         fake    %1,%0
5102         lds     %1,%0
5103         sts     %1,%0
5104         fsts    fpul,%0
5105         flds    %1,fpul
5106         fmov    %1,%0
5107         ! move optimized away"
5108   [(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")
5109    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5110    (set_attr_alternative "length"
5111      [(const_int 2)
5112       (const_int 2)
5113       (const_int 2)
5114       (const_int 4)
5115       (const_int 4)
5116       (const_int 2)
5117       (if_then_else
5118         (match_test "TARGET_SH2A")
5119         (const_int 4) (const_int 2))
5120       (const_int 2)
5121       (const_int 2)
5122       (const_int 2)
5123       (if_then_else
5124         (match_test "TARGET_SH2A")
5125         (const_int 4) (const_int 2))
5126       (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 0)])])
5141
5142 (define_insn "movsi_i_lowpart"
5143   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5144         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5145    "TARGET_SH1
5146     && (register_operand (operands[0], SImode)
5147         || register_operand (operands[1], SImode))"
5148   "@
5149         mov.l   %1,%0
5150         mov     %1,%0
5151         mov     %1,%0
5152         mov.l   %1,%0
5153         sts     %1,%0
5154         sts     %1,%0
5155         movt    %0
5156         mov.l   %1,%0
5157         fake    %1,%0"
5158   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5159
5160 (define_insn_and_split "load_ra"
5161   [(set (match_operand:SI 0 "general_movdst_operand" "")
5162         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5163   "TARGET_SH1"
5164   "#"
5165   "&& ! currently_expanding_to_rtl"
5166   [(set (match_dup 0) (match_dup 1))]
5167   "
5168 {
5169   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5170     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5171 }")
5172
5173 ;; The '?'s in the following constraints may not reflect the time taken
5174 ;; to perform the move. They are there to discourage the use of floating-
5175 ;; point registers for storing integer values.
5176 (define_insn "*movsi_media"
5177   [(set (match_operand:SI 0 "general_movdst_operand"
5178                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5179         (match_operand:SI 1 "general_movsrc_operand"
5180          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5181   "TARGET_SHMEDIA_FPU
5182    && (register_operand (operands[0], SImode)
5183        || sh_register_operand (operands[1], SImode)
5184        || GET_CODE (operands[1]) == TRUNCATE)"
5185   "@
5186         add.l   %1, r63, %0
5187         movi    %1, %0
5188         #
5189         ld%M1.l %m1, %0
5190         st%M0.l %m0, %N1
5191         fld%M1.s        %m1, %0
5192         fst%M0.s        %m0, %1
5193         fmov.ls %N1, %0
5194         fmov.sl %1, %0
5195         fmov.s  %1, %0
5196         ptabs   %1, %0
5197         gettr   %1, %0
5198         pt      %1, %0"
5199   [(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")
5200    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5201    (set (attr "highpart")
5202         (cond [(match_test "sh_contains_memref_p (insn)")
5203                (const_string "user")]
5204               (const_string "ignore")))])
5205
5206 (define_insn "*movsi_media_nofpu"
5207   [(set (match_operand:SI 0 "general_movdst_operand"
5208                 "=r,r,r,r,m,*b,r,*b")
5209         (match_operand:SI 1 "general_movsrc_operand"
5210          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5211   "TARGET_SHMEDIA
5212    && (register_operand (operands[0], SImode)
5213        || sh_register_operand (operands[1], SImode)
5214        || GET_CODE (operands[1]) == TRUNCATE)"
5215   "@
5216         add.l   %1, r63, %0
5217         movi    %1, %0
5218         #
5219         ld%M1.l %m1, %0
5220         st%M0.l %m0, %N1
5221         ptabs   %1, %0
5222         gettr   %1, %0
5223         pt      %1, %0"
5224   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5225    (set_attr "length" "4,4,8,4,4,4,4,12")
5226    (set (attr "highpart")
5227         (cond [(match_test "sh_contains_memref_p (insn)")
5228                (const_string "user")]
5229               (const_string "ignore")))])
5230
5231 (define_expand "movsi_const"
5232   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5233         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5234                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5235    (set (match_dup 0)
5236         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5237                 (const:SI (unspec:SI [(match_dup 1)
5238                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5239   "TARGET_SHMEDIA && reload_completed
5240    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5241   "
5242 {
5243   if (GET_CODE (operands[1]) == LABEL_REF
5244       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5245     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5246   else if (GOTOFF_P (operands[1]))
5247     {
5248       rtx unspec = XEXP (operands[1], 0);
5249
5250       if (! UNSPEC_GOTOFF_P (unspec))
5251         {
5252           unspec = XEXP (unspec, 0);
5253           if (! UNSPEC_GOTOFF_P (unspec))
5254             abort ();
5255         }
5256       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5257           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5258         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5259     }
5260 }")
5261
5262 (define_expand "movsi_const_16bit"
5263   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5264         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5265                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5266   "TARGET_SHMEDIA && flag_pic && reload_completed
5267    && GET_CODE (operands[1]) == SYMBOL_REF"
5268   "")
5269
5270 (define_split
5271   [(set (match_operand:SI 0 "arith_reg_dest" "")
5272         (match_operand:SI 1 "immediate_operand" ""))]
5273   "TARGET_SHMEDIA && reload_completed
5274    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5275   [(const_int 0)]
5276   "
5277 {
5278   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5279
5280   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5281
5282   DONE;
5283 }")
5284
5285 (define_split
5286   [(set (match_operand:SI 0 "register_operand" "")
5287         (match_operand:SI 1 "immediate_operand" ""))]
5288   "TARGET_SHMEDIA && reload_completed
5289    && ((CONST_INT_P (operands[1])
5290         && ! satisfies_constraint_I16 (operands[1]))
5291        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5292   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5293
5294 (define_expand "movsi"
5295   [(set (match_operand:SI 0 "general_movdst_operand" "")
5296         (match_operand:SI 1 "general_movsrc_operand" ""))]
5297   ""
5298   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5299
5300 (define_expand "ic_invalidate_line"
5301   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5302                                 (match_dup 1)] UNSPEC_ICACHE)
5303               (clobber (scratch:SI))])]
5304   "TARGET_HARD_SH4 || TARGET_SH5"
5305   "
5306 {
5307   if (TARGET_SHMEDIA)
5308     {
5309       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5310       DONE;
5311     }
5312   else if (TARGET_SHCOMPACT)
5313     {
5314       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5315       operands[1] = force_reg (Pmode, operands[1]);
5316       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5317       DONE;
5318     }
5319   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5320     {
5321       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5322       DONE;
5323     }
5324   operands[0] = force_reg (Pmode, operands[0]);
5325   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5326                                                                Pmode)));
5327 }")
5328
5329 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5330 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5331 ;; the requirement *1*00 for associative address writes.  The alignment of
5332 ;; %0 implies that its least significant bit is cleared,
5333 ;; thus we clear the V bit of a matching entry if there is one.
5334 (define_insn "ic_invalidate_line_i"
5335   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5336                      (match_operand:SI 1 "register_operand" "r")]
5337                      UNSPEC_ICACHE)
5338    (clobber (match_scratch:SI 2 "=&r"))]
5339   "TARGET_HARD_SH4"
5340   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5341   [(set_attr "length" "8")
5342    (set_attr "type" "cwb")])
5343
5344 (define_insn "ic_invalidate_line_sh4a"
5345   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5346                     UNSPEC_ICACHE)]
5347   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5348   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5349   [(set_attr "length" "16")
5350    (set_attr "type" "cwb")])
5351
5352 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5353 ;; an add in the code that calculates the address.
5354 (define_insn "ic_invalidate_line_media"
5355   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5356                     UNSPEC_ICACHE)]
5357   "TARGET_SHMEDIA"
5358   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5359   [(set_attr "length" "16")
5360    (set_attr "type" "invalidate_line_media")])
5361
5362 (define_insn "ic_invalidate_line_compact"
5363   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5364                      (match_operand:SI 1 "register_operand" "r")]
5365                     UNSPEC_ICACHE)
5366    (clobber (reg:SI PR_REG))]
5367   "TARGET_SHCOMPACT"
5368   "jsr @%1%#"
5369   [(set_attr "type" "sfunc")
5370    (set_attr "needs_delay_slot" "yes")])
5371
5372 (define_expand "initialize_trampoline"
5373   [(match_operand:SI 0 "" "")
5374    (match_operand:SI 1 "" "")
5375    (match_operand:SI 2 "" "")]
5376   "TARGET_SHCOMPACT"
5377   "
5378 {
5379   rtx sfun, tramp;
5380
5381   tramp = force_reg (Pmode, operands[0]);
5382   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5383                                             SFUNC_STATIC));
5384   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5385   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5386
5387   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5388   DONE;
5389 }")
5390
5391 (define_insn "initialize_trampoline_compact"
5392   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5393                      (match_operand:SI 1 "register_operand" "r")
5394                      (reg:SI R2_REG) (reg:SI R3_REG)]
5395                     UNSPEC_INIT_TRAMP)
5396
5397    (clobber (reg:SI PR_REG))]
5398   "TARGET_SHCOMPACT"
5399   "jsr @%1%#"
5400   [(set_attr "type" "sfunc")
5401    (set_attr "needs_delay_slot" "yes")])
5402
5403 (define_insn "movqi_i"
5404   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5405         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5406   "TARGET_SH1
5407    && (arith_reg_operand (operands[0], QImode)
5408        || arith_reg_operand (operands[1], QImode))"
5409   "@
5410         mov     %1,%0
5411         mov     %1,%0
5412         mov.b   %1,%0
5413         mov.b   %1,%0
5414         movt    %0
5415         sts     %1,%0
5416         lds     %1,%0"
5417  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5418   (set_attr_alternative "length"
5419      [(const_int 2)
5420       (const_int 2)
5421       (if_then_else
5422         (match_test "TARGET_SH2A")
5423         (const_int 4) (const_int 2))
5424       (if_then_else
5425         (match_test "TARGET_SH2A")
5426         (const_int 4) (const_int 2))
5427       (const_int 2)
5428       (const_int 2)
5429       (const_int 2)])])
5430
5431 (define_insn "*movqi_media"
5432   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5433         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5434   "TARGET_SHMEDIA
5435    && (arith_reg_operand (operands[0], QImode)
5436        || extend_reg_or_0_operand (operands[1], QImode))"
5437   "@
5438         add.l   %1, r63, %0
5439         movi    %1, %0
5440         ld%M1.ub        %m1, %0
5441         st%M0.b %m0, %N1"
5442   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5443    (set (attr "highpart")
5444         (cond [(match_test "sh_contains_memref_p (insn)")
5445                (const_string "user")]
5446               (const_string "ignore")))])
5447
5448 (define_expand "movqi"
5449   [(set (match_operand:QI 0 "general_operand" "")
5450         (match_operand:QI 1 "general_operand"  ""))]
5451   ""
5452   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5453
5454 (define_expand "reload_inqi"
5455   [(set (match_operand:SI 2 "" "=&r")
5456         (match_operand:QI 1 "inqhi_operand" ""))
5457    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5458         (truncate:QI (match_dup 3)))]
5459   "TARGET_SHMEDIA"
5460   "
5461 {
5462   rtx inner = XEXP (operands[1], 0);
5463   int regno = REGNO (inner);
5464
5465   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5466   operands[1] = gen_rtx_REG (SImode, regno);
5467   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5468 }")
5469
5470 ;; When storing r0, we have to avoid reg+reg addressing.
5471 (define_insn "movhi_i"
5472   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5473         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5474   "TARGET_SH1
5475    && (arith_reg_operand (operands[0], HImode)
5476        || arith_reg_operand (operands[1], HImode))
5477    && (!MEM_P (operands[0])
5478        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5479        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5480        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5481   "@
5482         mov.w   %1,%0
5483         mov     %1,%0
5484         mov.w   %1,%0
5485         movt    %0
5486         mov.w   %1,%0
5487         sts     %1,%0
5488         lds     %1,%0
5489         fake    %1,%0"
5490   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5491
5492 (define_insn "*movhi_media"
5493   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5494         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5495   "TARGET_SHMEDIA
5496    && (arith_reg_operand (operands[0], HImode)
5497        || arith_reg_or_0_operand (operands[1], HImode))"
5498   "@
5499         add.l   %1, r63, %0
5500         movi    %1, %0
5501         #
5502         ld%M1.w %m1, %0
5503         st%M0.w %m0, %N1"
5504   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5505    (set (attr "highpart")
5506         (cond [(match_test "sh_contains_memref_p (insn)")
5507                (const_string "user")]
5508               (const_string "ignore")))])
5509
5510 (define_split
5511   [(set (match_operand:HI 0 "register_operand" "")
5512         (match_operand:HI 1 "immediate_operand" ""))]
5513   "TARGET_SHMEDIA && reload_completed
5514    && ! satisfies_constraint_I16 (operands[1])"
5515   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5516
5517 (define_expand "movhi"
5518   [(set (match_operand:HI 0 "general_movdst_operand" "")
5519         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5520   ""
5521   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5522
5523 (define_expand "reload_inhi"
5524   [(set (match_operand:SI 2 "" "=&r")
5525         (match_operand:HI 1 "inqhi_operand" ""))
5526    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5527         (truncate:HI (match_dup 3)))]
5528   "TARGET_SHMEDIA"
5529   "
5530 {
5531   rtx inner = XEXP (operands[1], 0);
5532   int regno = REGNO (inner);
5533
5534   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5535   operands[1] = gen_rtx_REG (SImode, regno);
5536   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5537 }")
5538
5539 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5540 ;; compiled with -m2 -ml -O3 -funroll-loops
5541 (define_insn "*movdi_i"
5542   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5543         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5544   "TARGET_SH1
5545    && (arith_reg_operand (operands[0], DImode)
5546        || arith_reg_operand (operands[1], DImode))"
5547   "* return output_movedouble (insn, operands, DImode);"
5548   [(set_attr "length" "4")
5549    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5550
5551 ;; If the output is a register and the input is memory or a register, we have
5552 ;; to be careful and see which word needs to be loaded first.
5553
5554 (define_split
5555   [(set (match_operand:DI 0 "general_movdst_operand" "")
5556         (match_operand:DI 1 "general_movsrc_operand" ""))]
5557   "TARGET_SH1 && reload_completed"
5558   [(set (match_dup 2) (match_dup 3))
5559    (set (match_dup 4) (match_dup 5))]
5560   "
5561 {
5562   int regno;
5563
5564   if ((MEM_P (operands[0])
5565        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5566       || (MEM_P (operands[1])
5567           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5568     FAIL;
5569
5570   switch (GET_CODE (operands[0]))
5571     {
5572     case REG:
5573       regno = REGNO (operands[0]);
5574       break;
5575     case SUBREG:
5576       regno = subreg_regno (operands[0]);
5577       break;
5578     case MEM:
5579       regno = -1;
5580       break;
5581     default:
5582       gcc_unreachable ();
5583     }
5584
5585   if (regno == -1
5586       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5587     {
5588       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5589       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5590       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5591       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5592     }
5593   else
5594     {
5595       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5596       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5597       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5598       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5599     }
5600
5601   if (operands[2] == 0 || operands[3] == 0
5602       || operands[4] == 0 || operands[5] == 0)
5603     FAIL;
5604 }")
5605
5606 ;; The '?'s in the following constraints may not reflect the time taken
5607 ;; to perform the move. They are there to discourage the use of floating-
5608 ;; point registers for storing integer values.
5609 (define_insn "*movdi_media"
5610   [(set (match_operand:DI 0 "general_movdst_operand"
5611                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5612         (match_operand:DI 1 "general_movsrc_operand"
5613          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5614   "TARGET_SHMEDIA_FPU
5615    && (register_operand (operands[0], DImode)
5616        || sh_register_operand (operands[1], DImode))"
5617   "@
5618         add     %1, r63, %0
5619         movi    %1, %0
5620         #
5621         ld%M1.q %m1, %0
5622         st%M0.q %m0, %N1
5623         fld%M1.d        %m1, %0
5624         fst%M0.d        %m0, %1
5625         fmov.qd %N1, %0
5626         fmov.dq %1, %0
5627         fmov.d  %1, %0
5628         ptabs   %1, %0
5629         gettr   %1, %0
5630         pt      %1, %0"
5631   [(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")
5632    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5633
5634 (define_insn "*movdi_media_nofpu"
5635   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5636         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5637   "TARGET_SHMEDIA
5638    && (register_operand (operands[0], DImode)
5639        || sh_register_operand (operands[1], DImode))"
5640   "@
5641         add     %1, r63, %0
5642         movi    %1, %0
5643         #
5644         ld%M1.q %m1, %0
5645         st%M0.q %m0, %N1
5646         ptabs   %1, %0
5647         gettr   %1, %0
5648         pt      %1, %0"
5649   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5650    (set_attr "length" "4,4,16,4,4,4,4,*")])
5651
5652 (define_insn "*movdi_media_I16"
5653   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5654         (match_operand:DI 1 "const_int_operand" "I16"))]
5655   "TARGET_SHMEDIA && reload_completed"
5656   "movi %1, %0"
5657   [(set_attr "type" "arith_media")
5658    (set_attr "length" "4")])
5659
5660 (define_split
5661   [(set (match_operand:DI 0 "arith_reg_dest" "")
5662         (match_operand:DI 1 "immediate_operand" ""))]
5663   "TARGET_SHMEDIA && reload_completed
5664    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5665   [(set (match_dup 0) (match_dup 1))]
5666   "
5667 {
5668   rtx insn;
5669
5670   if (TARGET_SHMEDIA64)
5671     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5672   else
5673     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5674
5675   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5676
5677   DONE;
5678 }")
5679
5680 (define_expand "movdi_const"
5681   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5682         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5683                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5684    (set (match_dup 0)
5685         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5686                 (const:DI (unspec:DI [(match_dup 1)
5687                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5688    (set (match_dup 0)
5689         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5690                 (const:DI (unspec:DI [(match_dup 1)
5691                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5692    (set (match_dup 0)
5693         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5694                 (const:DI (unspec:DI [(match_dup 1)
5695                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5696   "TARGET_SHMEDIA64 && reload_completed
5697    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5698   "
5699 {
5700   sh_mark_label (operands[1], 4);
5701 }")
5702
5703 (define_expand "movdi_const_32bit"
5704   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5705         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5706                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5707    (set (match_dup 0)
5708         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5709                 (const:DI (unspec:DI [(match_dup 1)
5710                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5711   "TARGET_SHMEDIA32 && reload_completed
5712    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5713   "
5714 {
5715   sh_mark_label (operands[1], 2);
5716 }")
5717
5718 (define_expand "movdi_const_16bit"
5719   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5720         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5721                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5722   "TARGET_SHMEDIA && flag_pic && reload_completed
5723    && GET_CODE (operands[1]) == SYMBOL_REF"
5724   "")
5725
5726 (define_split
5727   [(set (match_operand:DI 0 "ext_dest_operand" "")
5728         (match_operand:DI 1 "immediate_operand" ""))]
5729   "TARGET_SHMEDIA && reload_completed
5730    && CONST_INT_P (operands[1])
5731    && ! satisfies_constraint_I16 (operands[1])"
5732   [(set (match_dup 0) (match_dup 2))
5733    (match_dup 1)]
5734   "
5735 {
5736   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5737   unsigned HOST_WIDE_INT low = val;
5738   unsigned HOST_WIDE_INT high = val;
5739   unsigned HOST_WIDE_INT sign;
5740   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5741
5742   /* Zero-extend the 16 least-significant bits.  */
5743   low &= 0xffff;
5744
5745   /* Arithmetic shift right the word by 16 bits.  */
5746   high >>= 16;
5747   if (GET_CODE (operands[0]) == SUBREG
5748       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5749     {
5750       high &= 0xffff;
5751       high ^= 0x8000;
5752       high -= 0x8000;
5753     }
5754   else
5755     {
5756       sign = 1;
5757       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5758       high ^= sign;
5759       high -= sign;
5760     }
5761   do
5762     {
5763       /* If we can't generate the constant with a two-insn movi / shori
5764          sequence, try some other strategies.  */
5765       if (! CONST_OK_FOR_I16 (high))
5766         {
5767           /* Try constant load / left shift.  We know VAL != 0.  */
5768           val2 = val ^ (val-1);
5769           if (val2 > 0x1ffff)
5770             {
5771               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5772
5773               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5774                   || (! CONST_OK_FOR_I16 (high >> 16)
5775                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5776                 {
5777                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5778                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5779                                                    GEN_INT (trailing_zeroes));
5780                   break;
5781                 }
5782             }
5783           /* Try constant load / right shift.  */
5784           val2 = (val >> 15) + 1;
5785           if (val2 == (val2 & -val2))
5786             {
5787               int shift = 49 - exact_log2 (val2);
5788
5789               val2 = trunc_int_for_mode (val << shift, DImode);
5790               if (CONST_OK_FOR_I16 (val2))
5791                 {
5792                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5793                                                    GEN_INT (shift));
5794                   break;
5795                 }
5796             }
5797           /* Try mperm.w .  */
5798           val2 = val & 0xffff;
5799           if ((val >> 16 & 0xffff) == val2
5800               && (val >> 32 & 0xffff) == val2
5801               && (val >> 48 & 0xffff) == val2)
5802             {
5803               val2 = (HOST_WIDE_INT) val >> 48;
5804               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5805               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5806               break;
5807             }
5808           /* Try movi / mshflo.l  */
5809           val2 = (HOST_WIDE_INT) val >> 32;
5810           if (val2 == ((unsigned HOST_WIDE_INT)
5811                         trunc_int_for_mode (val, SImode)))
5812             {
5813               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5814                                              operands[0]);
5815               break;
5816             }
5817           /* Try movi / mshflo.l w/ r63.  */
5818           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5819           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5820             {
5821               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5822                                              const0_rtx);
5823               break;
5824             }
5825         }
5826       val2 = high;
5827       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5828     }
5829   while (0);
5830   operands[2] = GEN_INT (val2);
5831 }")
5832
5833 (define_split
5834   [(set (match_operand:DI 0 "ext_dest_operand" "")
5835         (match_operand:DI 1 "immediate_operand" ""))]
5836   "TARGET_SHMEDIA && reload_completed
5837    && GET_CODE (operands[1]) == CONST_DOUBLE"
5838   [(set (match_dup 0) (match_dup 2))
5839   (set (match_dup 0)
5840        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5841   "
5842 {
5843   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5844   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5845   unsigned HOST_WIDE_INT val = low;
5846   unsigned HOST_WIDE_INT sign;
5847
5848   /* Zero-extend the 16 least-significant bits.  */
5849   val &= 0xffff;
5850   operands[1] = GEN_INT (val);
5851
5852   /* Arithmetic shift right the double-word by 16 bits.  */
5853   low >>= 16;
5854   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5855   high >>= 16;
5856   sign = 1;
5857   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5858   high ^= sign;
5859   high -= sign;
5860
5861   /* This will only be true if high is a sign-extension of low, i.e.,
5862      it must be either 0 or (unsigned)-1, and be zero iff the
5863      most-significant bit of low is set.  */
5864   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5865     operands[2] = GEN_INT (low);
5866   else
5867     operands[2] = immed_double_const (low, high, DImode);
5868 }")
5869
5870 (define_insn "shori_media"
5871   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5872         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5873                            (const_int 16))
5874                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5875   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5876   "@
5877         shori   %u2, %0
5878         #"
5879   [(set_attr "type" "arith_media,*")])
5880
5881 (define_insn "*shori_media_si"
5882   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5883         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5884                            (const_int 16))
5885                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5886   "TARGET_SHMEDIA"
5887   "shori        %u2, %0")
5888
5889 (define_expand "movdi"
5890   [(set (match_operand:DI 0 "general_movdst_operand" "")
5891         (match_operand:DI 1 "general_movsrc_operand" ""))]
5892   ""
5893   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5894
5895 (define_insn "movdf_media"
5896   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5897         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5898   "TARGET_SHMEDIA_FPU
5899    && (register_operand (operands[0], DFmode)
5900        || sh_register_operand (operands[1], DFmode))"
5901   "@
5902         fmov.d  %1, %0
5903         fmov.qd %N1, %0
5904         fmov.dq %1, %0
5905         add     %1, r63, %0
5906         #
5907         fld%M1.d        %m1, %0
5908         fst%M0.d        %m0, %1
5909         ld%M1.q %m1, %0
5910         st%M0.q %m0, %N1"
5911   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5912
5913 (define_insn "movdf_media_nofpu"
5914   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5915         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5916   "TARGET_SHMEDIA
5917    && (register_operand (operands[0], DFmode)
5918        || sh_register_operand (operands[1], DFmode))"
5919   "@
5920         add     %1, r63, %0
5921         #
5922         ld%M1.q %m1, %0
5923         st%M0.q %m0, %N1"
5924   [(set_attr "type" "arith_media,*,load_media,store_media")])
5925
5926 (define_split
5927   [(set (match_operand:DF 0 "arith_reg_dest" "")
5928         (match_operand:DF 1 "immediate_operand" ""))]
5929   "TARGET_SHMEDIA && reload_completed"
5930   [(set (match_dup 3) (match_dup 2))]
5931   "
5932 {
5933   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5934   long values[2];
5935   REAL_VALUE_TYPE value;
5936
5937   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5938   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5939
5940   if (HOST_BITS_PER_WIDE_INT >= 64)
5941     operands[2] = immed_double_const ((unsigned long) values[endian]
5942                                       | ((HOST_WIDE_INT) values[1 - endian]
5943                                          << 32), 0, DImode);
5944   else
5945     {
5946       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5947       operands[2] = immed_double_const (values[endian], values[1 - endian],
5948                                         DImode);
5949     }
5950
5951   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5952 }")
5953
5954 ;; ??? This should be a define expand.
5955
5956 (define_insn "movdf_k"
5957   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5958         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5959   "TARGET_SH1
5960    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5961        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5962        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5963        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5964    && (arith_reg_operand (operands[0], DFmode)
5965        || arith_reg_operand (operands[1], DFmode))"
5966   "* return output_movedouble (insn, operands, DFmode);"
5967   [(set_attr "length" "4")
5968    (set_attr "type" "move,pcload,load,store")])
5969
5970 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5971 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5972 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5973 ;; the d/m/c/X alternative, which is split later into single-precision
5974 ;; instructions.  And when not optimizing, no splits are done before fixing
5975 ;; up pcloads, so we need usable length information for that.
5976 (define_insn "movdf_i4"
5977   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5978         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5979    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5980    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5981   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5982    && (arith_reg_operand (operands[0], DFmode)
5983        || arith_reg_operand (operands[1], DFmode))"
5984   {
5985     switch (which_alternative)
5986     {
5987     case 0:
5988       if (TARGET_FMOVD)
5989         return "fmov    %1,%0";
5990       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5991         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5992       else
5993         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5994     case 3:
5995     case 4:
5996       return "fmov.d    %1,%0";
5997     default:
5998       return "#";
5999     }
6000   }
6001   [(set_attr_alternative "length"
6002      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6003       (const_int 4)
6004       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
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       (const_int 4)
6008       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6009       ;; We can't use 4-byte push/pop on SHcompact, so we have to
6010       ;; increment or decrement r15 explicitly.
6011       (if_then_else
6012        (match_test "TARGET_SHCOMPACT")
6013        (const_int 10) (const_int 8))
6014       (if_then_else
6015        (match_test "TARGET_SHCOMPACT")
6016        (const_int 10) (const_int 8))])
6017    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6018    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6019    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6020                                            (const_string "double")
6021                                            (const_string "none")))])
6022
6023 ;; Moving DFmode between fp/general registers through memory
6024 ;; (the top of the stack) is faster than moving through fpul even for
6025 ;; little endian.  Because the type of an instruction is important for its
6026 ;; scheduling,  it is beneficial to split these operations, rather than
6027 ;; emitting them in one single chunk, even if this will expose a stack
6028 ;; use that will prevent scheduling of other stack accesses beyond this
6029 ;; instruction.
6030 (define_split
6031   [(set (match_operand:DF 0 "register_operand" "")
6032         (match_operand:DF 1 "register_operand" ""))
6033    (use (match_operand:PSI 2 "fpscr_operand" ""))
6034    (clobber (match_scratch:SI 3 "=X"))]
6035   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6036    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6037   [(const_int 0)]
6038   "
6039 {
6040   rtx insn, tos;
6041
6042   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6043     {
6044       emit_move_insn (stack_pointer_rtx,
6045                       plus_constant (stack_pointer_rtx, -8));
6046       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6047     }
6048   else
6049     tos = gen_tmp_stack_mem (DFmode,
6050                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6051   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6052   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6053     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6054   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6055     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6056   else
6057     tos = gen_tmp_stack_mem (DFmode,
6058                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6059   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6060   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6061     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6062   else
6063     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6064   DONE;
6065 }")
6066
6067 ;; local-alloc sometimes allocates scratch registers even when not required,
6068 ;; so we must be prepared to handle these.
6069
6070 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6071 (define_split
6072   [(set (match_operand:DF 0 "general_movdst_operand" "")
6073         (match_operand:DF 1 "general_movsrc_operand"  ""))
6074    (use (match_operand:PSI 2 "fpscr_operand" ""))
6075    (clobber (match_scratch:SI 3 ""))]
6076   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6077    && reload_completed
6078    && true_regnum (operands[0]) < 16
6079    && true_regnum (operands[1]) < 16"
6080   [(set (match_dup 0) (match_dup 1))]
6081   "
6082 {
6083   /* If this was a reg <-> mem operation with base + index reg addressing,
6084      we have to handle this in a special way.  */
6085   rtx mem = operands[0];
6086   int store_p = 1;
6087   if (! memory_operand (mem, DFmode))
6088     {
6089       mem = operands[1];
6090       store_p = 0;
6091     }
6092   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6093     mem = SUBREG_REG (mem);
6094   if (MEM_P (mem))
6095     {
6096       rtx addr = XEXP (mem, 0);
6097       if (GET_CODE (addr) == PLUS
6098           && REG_P (XEXP (addr, 0))
6099           && REG_P (XEXP (addr, 1)))
6100         {
6101           int offset;
6102           rtx reg0 = gen_rtx_REG (Pmode, 0);
6103           rtx regop = operands[store_p], word0 ,word1;
6104
6105           if (GET_CODE (regop) == SUBREG)
6106             alter_subreg (&regop);
6107           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6108             offset = 2;
6109           else
6110             offset = 4;
6111           mem = copy_rtx (mem);
6112           PUT_MODE (mem, SImode);
6113           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6114           alter_subreg (&word0);
6115           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6116           alter_subreg (&word1);
6117           if (store_p || ! refers_to_regno_p (REGNO (word0),
6118                                               REGNO (word0) + 1, addr, 0))
6119             {
6120               emit_insn (store_p
6121                          ? gen_movsi_ie (mem, word0)
6122                          : gen_movsi_ie (word0, mem));
6123               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6124               mem = copy_rtx (mem);
6125               emit_insn (store_p
6126                          ? gen_movsi_ie (mem, word1)
6127                          : gen_movsi_ie (word1, mem));
6128               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6129             }
6130           else
6131             {
6132               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6133               emit_insn (gen_movsi_ie (word1, mem));
6134               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6135               mem = copy_rtx (mem);
6136               emit_insn (gen_movsi_ie (word0, mem));
6137             }
6138           DONE;
6139         }
6140     }
6141 }")
6142
6143 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6144 (define_split
6145   [(set (match_operand:DF 0 "register_operand" "")
6146         (match_operand:DF 1 "memory_operand"  ""))
6147    (use (match_operand:PSI 2 "fpscr_operand" ""))
6148    (clobber (reg:SI R0_REG))]
6149   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6150   [(parallel [(set (match_dup 0) (match_dup 1))
6151               (use (match_dup 2))
6152               (clobber (scratch:SI))])]
6153   "")
6154
6155 (define_expand "reload_indf__frn"
6156   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6157                    (match_operand:DF 1 "immediate_operand" "FQ"))
6158               (use (reg:PSI FPSCR_REG))
6159               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6160   "TARGET_SH1"
6161   "")
6162
6163 (define_expand "reload_outdf__RnFRm"
6164   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6165                    (match_operand:DF 1 "register_operand" "af,r"))
6166               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6167   "TARGET_SH1"
6168   "")
6169
6170 ;; Simplify no-op moves.
6171 (define_split
6172   [(set (match_operand:SF 0 "register_operand" "")
6173         (match_operand:SF 1 "register_operand" ""))
6174    (use (match_operand:PSI 2 "fpscr_operand" ""))
6175    (clobber (match_scratch:SI 3 ""))]
6176   "TARGET_SH2E && reload_completed
6177    && true_regnum (operands[0]) == true_regnum (operands[1])"
6178   [(set (match_dup 0) (match_dup 0))]
6179   "")
6180
6181 ;; fmovd substitute post-reload splits
6182 (define_split
6183   [(set (match_operand:DF 0 "register_operand" "")
6184         (match_operand:DF 1 "register_operand" ""))
6185    (use (match_operand:PSI 2 "fpscr_operand" ""))
6186    (clobber (match_scratch:SI 3 ""))]
6187   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6188    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6189    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6190   [(const_int 0)]
6191   "
6192 {
6193   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6194   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6195                            gen_rtx_REG (SFmode, src), operands[2]));
6196   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6197                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6198   DONE;
6199 }")
6200
6201 (define_split
6202   [(set (match_operand:DF 0 "register_operand" "")
6203         (mem:DF (match_operand:SI 1 "register_operand" "")))
6204    (use (match_operand:PSI 2 "fpscr_operand" ""))
6205    (clobber (match_scratch:SI 3 ""))]
6206   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6207    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6208    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6209   [(const_int 0)]
6210   "
6211 {
6212   int regno = true_regnum (operands[0]);
6213   rtx insn;
6214   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6215   rtx mem2
6216     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6217   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6218                                            regno + !! TARGET_LITTLE_ENDIAN),
6219                                   mem2, operands[2]));
6220   add_reg_note (insn, REG_INC, operands[1]);
6221   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6222                                                regno + ! TARGET_LITTLE_ENDIAN),
6223                                   change_address (mem, SFmode, NULL_RTX),
6224                                   operands[2]));
6225   DONE;
6226 }")
6227
6228 (define_split
6229   [(set (match_operand:DF 0 "register_operand" "")
6230         (match_operand:DF 1 "memory_operand" ""))
6231    (use (match_operand:PSI 2 "fpscr_operand" ""))
6232    (clobber (match_scratch:SI 3 ""))]
6233   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6234    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6235   [(const_int 0)]
6236 {
6237   int regno = true_regnum (operands[0]);
6238   rtx addr, insn;
6239   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6240   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6241   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6242
6243   operands[1] = copy_rtx (mem2);
6244   addr = XEXP (mem2, 0);
6245
6246   switch (GET_CODE (addr))
6247     {
6248     case REG:
6249       /* This is complicated.  If the register is an arithmetic register
6250          we can just fall through to the REG+DISP case below.  Otherwise
6251          we have to use a combination of POST_INC and REG addressing...  */
6252       if (! arith_reg_operand (operands[1], SFmode))
6253         {
6254           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6255           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6256           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6257           
6258           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6259
6260           /* If we have modified the stack pointer, the value that we have
6261              read with post-increment might be modified by an interrupt,
6262              so write it back.  */
6263           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6264             emit_insn (gen_push_e (reg0));
6265           else
6266             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6267           break;
6268         }
6269       /* Fall through.  */
6270          
6271     case PLUS:
6272       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6273       operands[1] = copy_rtx (operands[1]);
6274       XEXP (operands[1], 0) = plus_constant (addr, 4);
6275       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6276       break;
6277       
6278     case POST_INC:
6279       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6280       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6281     
6282       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6283       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6284       break;
6285
6286     default:
6287       debug_rtx (addr);
6288       gcc_unreachable ();
6289     }
6290
6291   DONE;
6292 })
6293
6294 (define_split
6295   [(set (match_operand:DF 0 "memory_operand" "")
6296         (match_operand:DF 1 "register_operand" ""))
6297    (use (match_operand:PSI 2 "fpscr_operand" ""))
6298    (clobber (match_scratch:SI 3 ""))]
6299   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6300    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6301   [(const_int 0)]
6302 {
6303   int regno = true_regnum (operands[1]);
6304   rtx insn, addr;
6305   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6306   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6307
6308   operands[0] = copy_rtx (operands[0]);
6309   PUT_MODE (operands[0], SFmode);
6310   addr = XEXP (operands[0], 0);
6311
6312   switch (GET_CODE (addr))
6313     {
6314     case REG:
6315       /* This is complicated.  If the register is an arithmetic register
6316          we can just fall through to the REG+DISP case below.  Otherwise
6317          we have to use a combination of REG and PRE_DEC addressing...  */
6318       if (! arith_reg_operand (operands[0], SFmode))
6319         {
6320           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6321           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6322
6323           operands[0] = copy_rtx (operands[0]);
6324           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6325           
6326           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6327           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6328           break;
6329         }
6330       /* Fall through.  */
6331       
6332     case PLUS:
6333       /* Since REG+DISP addressing has already been decided upon by gcc
6334          we can rely upon it having chosen an arithmetic register as the
6335          register component of the address.  Just emit the lower numbered
6336          register first, to the lower address, then the higher numbered
6337          register to the higher address.  */
6338       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6339
6340       operands[0] = copy_rtx (operands[0]);
6341       XEXP (operands[0], 0) = plus_constant (addr, 4);
6342
6343       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6344       break;
6345       
6346     case PRE_DEC:
6347       /* This is easy.  Output the word to go to the higher address
6348          first (ie the word in the higher numbered register) then the
6349          word to go to the lower address.  */
6350
6351       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6352       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6353
6354       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6355       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6356       break;
6357       
6358     default:
6359       /* FAIL; */
6360       debug_rtx (addr);
6361       gcc_unreachable ();
6362     }
6363
6364   DONE;
6365 })
6366
6367 ;; If the output is a register and the input is memory or a register, we have
6368 ;; to be careful and see which word needs to be loaded first.
6369
6370 (define_split
6371   [(set (match_operand:DF 0 "general_movdst_operand" "")
6372         (match_operand:DF 1 "general_movsrc_operand" ""))]
6373   "TARGET_SH1 && reload_completed"
6374   [(set (match_dup 2) (match_dup 3))
6375    (set (match_dup 4) (match_dup 5))]
6376   "
6377 {
6378   int regno;
6379
6380   if ((MEM_P (operands[0])
6381        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6382       || (MEM_P (operands[1])
6383           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6384     FAIL;
6385
6386   switch (GET_CODE (operands[0]))
6387     {
6388     case REG:
6389       regno = REGNO (operands[0]);
6390       break;
6391     case SUBREG:
6392       regno = subreg_regno (operands[0]);
6393       break;
6394     case MEM:
6395       regno = -1;
6396       break;
6397     default:
6398       gcc_unreachable ();
6399     }
6400
6401   if (regno == -1
6402       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6403     {
6404       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6405       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6406       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6407       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6408     }
6409   else
6410     {
6411       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6412       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6413       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6414       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6415     }
6416
6417   if (operands[2] == 0 || operands[3] == 0
6418       || operands[4] == 0 || operands[5] == 0)
6419     FAIL;
6420 }")
6421
6422 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6423 ;; used only once, let combine add in the index again.
6424
6425 (define_split
6426   [(set (match_operand:SI 0 "register_operand" "")
6427         (match_operand:SI 1 "" ""))
6428    (clobber (match_operand 2 "register_operand" ""))]
6429   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6430    && ALLOW_INDEXED_ADDRESS"
6431   [(use (reg:SI R0_REG))]
6432   "
6433 {
6434   rtx addr, reg, const_int;
6435
6436   if (!MEM_P (operands[1]))
6437     FAIL;
6438   addr = XEXP (operands[1], 0);
6439   if (GET_CODE (addr) != PLUS)
6440     FAIL;
6441   reg = XEXP (addr, 0);
6442   const_int = XEXP (addr, 1);
6443   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6444          && CONST_INT_P (const_int)))
6445     FAIL;
6446   emit_move_insn (operands[2], const_int);
6447   emit_move_insn (operands[0],
6448                   change_address (operands[1], VOIDmode,
6449                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6450   DONE;
6451 }")
6452
6453 (define_split
6454   [(set (match_operand:SI 1 "" "")
6455         (match_operand:SI 0 "register_operand" ""))
6456    (clobber (match_operand 2 "register_operand" ""))]
6457   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6458    && ALLOW_INDEXED_ADDRESS"
6459   [(use (reg:SI R0_REG))]
6460   "
6461 {
6462   rtx addr, reg, const_int;
6463
6464   if (!MEM_P (operands[1]))
6465     FAIL;
6466   addr = XEXP (operands[1], 0);
6467   if (GET_CODE (addr) != PLUS)
6468     FAIL;
6469   reg = XEXP (addr, 0);
6470   const_int = XEXP (addr, 1);
6471   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6472          && CONST_INT_P (const_int)))
6473     FAIL;
6474   emit_move_insn (operands[2], const_int);
6475   emit_move_insn (change_address (operands[1], VOIDmode,
6476                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6477                   operands[0]);
6478   DONE;
6479 }")
6480
6481 (define_expand "movdf"
6482   [(set (match_operand:DF 0 "general_movdst_operand" "")
6483         (match_operand:DF 1 "general_movsrc_operand" ""))]
6484   ""
6485   "
6486 {
6487   if (prepare_move_operands (operands, DFmode)) DONE;
6488   if (TARGET_SHMEDIA)
6489     {
6490       if (TARGET_SHMEDIA_FPU)
6491         emit_insn (gen_movdf_media (operands[0], operands[1]));
6492       else
6493         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6494       DONE;
6495     }
6496   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6497     {
6498       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6499       DONE;
6500     }
6501 }")
6502
6503 ;;This is incompatible with the way gcc uses subregs.
6504 ;;(define_insn "movv2sf_i"
6505 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6506 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6507 ;;  "TARGET_SHMEDIA_FPU
6508 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6509 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6510 ;;  "@
6511 ;;      #
6512 ;;      fld%M1.p        %m1, %0
6513 ;;      fst%M0.p        %m0, %1"
6514 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6515
6516 (define_insn_and_split "movv2sf_i"
6517   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6518         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6519   "TARGET_SHMEDIA_FPU"
6520   "#"
6521   "TARGET_SHMEDIA_FPU && reload_completed"
6522   [(set (match_dup 0) (match_dup 1))]
6523   "
6524 {
6525   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6526   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6527 }")
6528
6529 (define_expand "movv2sf"
6530   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6531         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6532   "TARGET_SHMEDIA_FPU"
6533   "
6534 {
6535   if (prepare_move_operands (operands, V2SFmode))
6536     DONE;
6537 }")
6538
6539 (define_expand "addv2sf3"
6540   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6541    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6542    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6543   "TARGET_SHMEDIA_FPU"
6544   "
6545 {
6546   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6547   DONE;
6548 }")
6549
6550 (define_expand "subv2sf3"
6551   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6552    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6553    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6554   "TARGET_SHMEDIA_FPU"
6555   "
6556 {
6557   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6558   DONE;
6559 }")
6560
6561 (define_expand "mulv2sf3"
6562   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6563    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6564    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6565   "TARGET_SHMEDIA_FPU"
6566   "
6567 {
6568   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6569   DONE;
6570 }")
6571
6572 (define_expand "divv2sf3"
6573   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6574    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6575    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6576   "TARGET_SHMEDIA_FPU"
6577   "
6578 {
6579   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6580   DONE;
6581 }")
6582
6583 (define_insn_and_split "*movv4sf_i"
6584   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6585         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6586   "TARGET_SHMEDIA_FPU"
6587   "#"
6588   "&& reload_completed"
6589   [(const_int 0)]
6590   "
6591 {
6592   int i;
6593
6594   for (i = 0; i < 4/2; i++)
6595     {
6596       rtx x, y;
6597
6598       if (MEM_P (operands[0]))
6599         x = adjust_address (operands[0], V2SFmode,
6600                             i * GET_MODE_SIZE (V2SFmode));
6601       else
6602         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6603
6604       if (MEM_P (operands[1]))
6605         y = adjust_address (operands[1], V2SFmode,
6606                             i * GET_MODE_SIZE (V2SFmode));
6607       else
6608         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6609
6610       emit_insn (gen_movv2sf_i (x, y));
6611     }
6612
6613   DONE;
6614 }"
6615   [(set_attr "length" "8")])
6616
6617 (define_expand "movv4sf"
6618   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6619         (match_operand:V4SF 1 "general_operand" ""))]
6620   "TARGET_SHMEDIA_FPU"
6621   "
6622 {
6623   if (prepare_move_operands (operands, V4SFmode))
6624     DONE;
6625 }")
6626
6627 (define_insn_and_split "*movv16sf_i"
6628   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6629         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6630   "TARGET_SHMEDIA_FPU"
6631   "#"
6632   "&& reload_completed"
6633   [(const_int 0)]
6634   "
6635 {
6636   int i;
6637
6638   for (i = 0; i < 16/2; i++)
6639     {
6640       rtx x,y;
6641
6642       if (MEM_P (operands[0]))
6643         x = adjust_address (operands[0], V2SFmode,
6644                             i * GET_MODE_SIZE (V2SFmode));
6645       else
6646         {
6647           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6648           alter_subreg (&x);
6649         }
6650
6651       if (MEM_P (operands[1]))
6652         y = adjust_address (operands[1], V2SFmode,
6653                             i * GET_MODE_SIZE (V2SFmode));
6654       else
6655         {
6656           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6657           alter_subreg (&y);
6658         }
6659
6660       emit_insn (gen_movv2sf_i (x, y));
6661     }
6662
6663   DONE;
6664 }"
6665   [(set_attr "length" "32")])
6666
6667 (define_expand "movv16sf"
6668   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6669         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6670   "TARGET_SHMEDIA_FPU"
6671   "
6672 {
6673   if (prepare_move_operands (operands, V16SFmode))
6674     DONE;
6675 }")
6676
6677 (define_insn "movsf_media"
6678   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6679         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6680   "TARGET_SHMEDIA_FPU
6681    && (register_operand (operands[0], SFmode)
6682        || sh_register_operand (operands[1], SFmode))"
6683   "@
6684         fmov.s  %1, %0
6685         fmov.ls %N1, %0
6686         fmov.sl %1, %0
6687         add.l   %1, r63, %0
6688         #
6689         fld%M1.s        %m1, %0
6690         fst%M0.s        %m0, %1
6691         ld%M1.l %m1, %0
6692         st%M0.l %m0, %N1"
6693   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6694    (set (attr "highpart")
6695         (cond [(match_test "sh_contains_memref_p (insn)")
6696                (const_string "user")]
6697               (const_string "ignore")))])
6698
6699 (define_insn "movsf_media_nofpu"
6700   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6701         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6702   "TARGET_SHMEDIA
6703    && (register_operand (operands[0], SFmode)
6704        || sh_register_operand (operands[1], SFmode))"
6705   "@
6706         add.l   %1, r63, %0
6707         #
6708         ld%M1.l %m1, %0
6709         st%M0.l %m0, %N1"
6710   [(set_attr "type" "arith_media,*,load_media,store_media")
6711    (set (attr "highpart")
6712         (cond [(match_test "sh_contains_memref_p (insn)")
6713                (const_string "user")]
6714               (const_string "ignore")))])
6715
6716 (define_split
6717   [(set (match_operand:SF 0 "arith_reg_dest" "")
6718         (match_operand:SF 1 "immediate_operand" ""))]
6719   "TARGET_SHMEDIA && reload_completed
6720    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6721   [(set (match_dup 3) (match_dup 2))]
6722   "
6723 {
6724   long values;
6725   REAL_VALUE_TYPE value;
6726
6727   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6728   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6729   operands[2] = GEN_INT (values);
6730
6731   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6732 }")
6733
6734 (define_insn "movsf_i"
6735   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6736         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6737   "TARGET_SH1
6738    && (! TARGET_SH2E
6739        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6740        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6741        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6742    && (arith_reg_operand (operands[0], SFmode)
6743        || arith_reg_operand (operands[1], SFmode))"
6744   "@
6745         mov     %1,%0
6746         mov     #0,%0
6747         mov.l   %1,%0
6748         mov.l   %1,%0
6749         mov.l   %1,%0
6750         lds     %1,%0
6751         sts     %1,%0"
6752   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6753
6754 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6755 ;; update_flow_info would not know where to put REG_EQUAL notes
6756 ;; when the destination changes mode.
6757 (define_insn "movsf_ie"
6758   [(set (match_operand:SF 0 "general_movdst_operand"
6759          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6760         (match_operand:SF 1 "general_movsrc_operand"
6761           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6762    (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"))
6763    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6764
6765   "TARGET_SH2E
6766    && (arith_reg_operand (operands[0], SFmode)
6767        || arith_reg_operand (operands[1], SFmode)
6768        || arith_reg_operand (operands[3], SImode)
6769        || (fpul_operand (operands[0], SFmode)
6770            && memory_operand (operands[1], SFmode)
6771            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6772        || (fpul_operand (operands[1], SFmode)
6773            && memory_operand (operands[0], SFmode)
6774            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6775   "@
6776         fmov    %1,%0
6777         mov     %1,%0
6778         fldi0   %0
6779         fldi1   %0
6780         #
6781         fmov.s  %1,%0
6782         fmov.s  %1,%0
6783         mov.l   %1,%0
6784         mov.l   %1,%0
6785         mov.l   %1,%0
6786         fsts    fpul,%0
6787         flds    %1,fpul
6788         lds.l   %1,%0
6789         #
6790         sts     %1,%0
6791         lds     %1,%0
6792         sts.l   %1,%0
6793         lds.l   %1,%0
6794         ! move optimized away"
6795   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6796    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6797    (set_attr_alternative "length"
6798      [(const_int 2)
6799       (const_int 2)
6800       (const_int 2)
6801       (const_int 2)
6802       (const_int 4)
6803       (if_then_else
6804         (match_test "TARGET_SH2A")
6805         (const_int 4) (const_int 2))
6806       (if_then_else
6807         (match_test "TARGET_SH2A")
6808         (const_int 4) (const_int 2))
6809       (const_int 2)
6810       (if_then_else
6811         (match_test "TARGET_SH2A")
6812         (const_int 4) (const_int 2))
6813       (if_then_else
6814         (match_test "TARGET_SH2A")
6815         (const_int 4) (const_int 2))
6816       (const_int 2)
6817       (const_int 2)
6818       (const_int 2)
6819       (const_int 4)
6820       (const_int 2)
6821       (const_int 2)
6822       (const_int 2)
6823       (const_int 2)
6824       (const_int 0)])
6825    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6826                                            (const_string "single")
6827                                            (const_string "single")))])
6828
6829 (define_split
6830   [(set (match_operand:SF 0 "register_operand" "")
6831         (match_operand:SF 1 "register_operand" ""))
6832    (use (match_operand:PSI 2 "fpscr_operand" ""))
6833    (clobber (reg:SI FPUL_REG))]
6834   "TARGET_SH1"
6835   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6836               (use (match_dup 2))
6837               (clobber (scratch:SI))])
6838    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6839               (use (match_dup 2))
6840               (clobber (scratch:SI))])]
6841   "")
6842
6843 (define_expand "movsf"
6844   [(set (match_operand:SF 0 "general_movdst_operand" "")
6845         (match_operand:SF 1 "general_movsrc_operand" ""))]
6846   ""
6847   "
6848 {
6849   if (prepare_move_operands (operands, SFmode))
6850     DONE;
6851   if (TARGET_SHMEDIA)
6852     {
6853       if (TARGET_SHMEDIA_FPU)
6854         emit_insn (gen_movsf_media (operands[0], operands[1]));
6855       else
6856         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6857       DONE;
6858     }
6859   if (TARGET_SH2E)
6860     {
6861       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6862       DONE;
6863     }
6864 }")
6865
6866 (define_insn "mov_nop"
6867   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6868   "TARGET_SH2E"
6869   ""
6870   [(set_attr "length" "0")
6871    (set_attr "type" "nil")])
6872
6873 (define_expand "reload_insf__frn"
6874   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6875                    (match_operand:SF 1 "immediate_operand" "FQ"))
6876               (use (reg:PSI FPSCR_REG))
6877               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6878   "TARGET_SH1"
6879   "")
6880
6881 (define_expand "reload_insi__i_fpul"
6882   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6883                    (match_operand:SI 1 "immediate_operand" "i"))
6884               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6885   "TARGET_SH1"
6886   "")
6887
6888 (define_expand "ptabs"
6889   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6890   "TARGET_SHMEDIA"
6891   "
6892 {
6893   if (!TARGET_PT_FIXED)
6894     {
6895       rtx eq = operands[1];
6896
6897       /* ??? For canonical RTL we really should remove any CONST from EQ
6898          before wrapping it in the AND, and finally wrap the EQ into a
6899          const if is constant.  However, for reload we must expose the
6900          input register or symbolic constant, and we can't have
6901          different insn structures outside of the operands for different
6902          alternatives of the same pattern.  */
6903       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6904                        GEN_INT (3));
6905       operands[1]
6906         = (gen_rtx_IF_THEN_ELSE
6907             (PDImode,
6908              eq,
6909              gen_rtx_MEM (PDImode, operands[1]),
6910              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6911                             PDImode, operands[1])));
6912     }
6913 }")
6914
6915 ;; expanded by ptabs expander.
6916 (define_insn "*extendsipdi_media"
6917   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6918         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6919                                                           "r,Csy")
6920                                       (const_int 3))
6921                               (const_int 3))
6922                           (mem:PDI (match_dup 1))
6923                           (sign_extend:PDI (match_dup 1))))]
6924   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6925   "@
6926         ptabs   %1, %0
6927         pt      %1, %0"
6928   [(set_attr "type"   "ptabs_media,pt_media")
6929    (set_attr "length" "4,*")])
6930
6931 (define_insn "*truncdipdi_media"
6932   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6933         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6934                                                           "r,Csy")
6935                                       (const_int 3))
6936                               (const_int 3))
6937                           (mem:PDI (match_dup 1))
6938                           (truncate:PDI (match_dup 1))))]
6939   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6940   "@
6941         ptabs   %1, %0
6942         pt      %1, %0"
6943   [(set_attr "type"   "ptabs_media,pt_media")
6944    (set_attr "length" "4,*")])
6945
6946 (define_insn "*movsi_y"
6947   [(set (match_operand:SI 0 "register_operand" "=y,y")
6948         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6949    (clobber (match_scratch:SI 2 "=&z,r"))]
6950   "TARGET_SH2E
6951    && (reload_in_progress || reload_completed)"
6952   "#"
6953   [(set_attr "length" "4")
6954    (set_attr "type" "pcload,move")])
6955
6956 (define_split
6957   [(set (match_operand:SI 0 "register_operand" "")
6958         (match_operand:SI 1 "immediate_operand" ""))
6959    (clobber (match_operand:SI 2 "register_operand" ""))]
6960   "TARGET_SH1"
6961   [(set (match_dup 2) (match_dup 1))
6962    (set (match_dup 0) (match_dup 2))]
6963   "")
6964
6965 (define_split
6966   [(set (match_operand:SI 0 "register_operand" "")
6967         (match_operand:SI 1 "memory_operand" ""))
6968    (clobber (reg:SI R0_REG))]
6969   "TARGET_SH1"
6970   [(set (match_dup 0) (match_dup 1))]
6971   "")
6972 \f
6973 ;; ------------------------------------------------------------------------
6974 ;; Define the real conditional branch instructions.
6975 ;; ------------------------------------------------------------------------
6976
6977 (define_insn "branch_true"
6978   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6979                            (label_ref (match_operand 0 "" ""))
6980                            (pc)))]
6981   "TARGET_SH1"
6982   "* return output_branch (1, insn, operands);"
6983   [(set_attr "type" "cbranch")])
6984
6985 (define_insn "branch_false"
6986   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6987                            (label_ref (match_operand 0 "" ""))
6988                            (pc)))]
6989   "TARGET_SH1"
6990   "* return output_branch (0, insn, operands);"
6991   [(set_attr "type" "cbranch")])
6992
6993 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6994 ;; which destination is too far away.
6995 ;; The const_int_operand is distinct for each branch target; it avoids
6996 ;; unwanted matches with redundant_insn.
6997 (define_insn "block_branch_redirect"
6998   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6999   "TARGET_SH1"
7000   ""
7001   [(set_attr "length" "0")])
7002
7003 ;; This one has the additional purpose to record a possible scratch register
7004 ;; for the following branch.
7005 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7006 ;; because the insn then might be deemed dead and deleted.  And we can't
7007 ;; make the use in the jump insn explicit because that would disable
7008 ;; delay slot scheduling from the target.
7009 (define_insn "indirect_jump_scratch"
7010   [(set (match_operand:SI 0 "register_operand" "=r")
7011         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7012    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7013   "TARGET_SH1"
7014   ""
7015   [(set_attr "length" "0")])
7016
7017 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7018 ;; being pulled into the delay slot of a condbranch that has been made to
7019 ;; jump around the unconditional jump because it was out of range.
7020 (define_insn "stuff_delay_slot"
7021   [(set (pc)
7022         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7023                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7024   "TARGET_SH1"
7025   ""
7026   [(set_attr "length" "0")
7027    (set_attr "cond_delay_slot" "yes")])
7028 \f
7029 ;; Conditional branch insns
7030
7031 (define_expand "cbranchint4_media"
7032   [(set (pc)
7033         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7034                        [(match_operand 1 "" "")
7035                         (match_operand 2 "" "")])
7036                       (match_operand 3 "" "")
7037                       (pc)))]
7038   "TARGET_SHMEDIA"
7039   "
7040 {
7041   enum machine_mode mode = GET_MODE (operands[1]);
7042   if (mode == VOIDmode)
7043     mode = GET_MODE (operands[2]);
7044   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7045     {
7046       operands[1] = force_reg (mode, operands[1]);
7047       if (CONSTANT_P (operands[2])
7048           && (! satisfies_constraint_I06 (operands[2])))
7049         operands[2] = force_reg (mode, operands[2]);
7050     }
7051   else
7052     {
7053       if (operands[1] != const0_rtx)
7054         operands[1] = force_reg (mode, operands[1]);
7055       if (operands[2] != const0_rtx)
7056         operands[2] = force_reg (mode, operands[2]);
7057     }
7058   switch (GET_CODE (operands[0]))
7059     {
7060     case LEU:
7061     case LE:
7062     case LTU:
7063     case LT:
7064       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7065                                     VOIDmode, operands[2], operands[1]);
7066       operands[1] = XEXP (operands[0], 0);
7067       operands[2] = XEXP (operands[0], 1);
7068       break;
7069     default:
7070       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7071                                     VOIDmode, operands[1], operands[2]);
7072       break;
7073     }
7074   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7075 }")
7076
7077 (define_expand "cbranchfp4_media"
7078   [(set (pc)
7079         (if_then_else (match_operator 0 "sh_float_comparison_operator"
7080                        [(match_operand 1 "" "")
7081                         (match_operand 2 "" "")])
7082                       (match_operand 3 "" "")
7083                       (pc)))]
7084   "TARGET_SHMEDIA"
7085   "
7086 {
7087   rtx tmp = gen_reg_rtx (SImode);
7088   rtx cmp;
7089   if (GET_CODE (operands[0]) == NE)
7090     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7091   else
7092     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7093                           operands[1], operands[2]);
7094
7095   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7096
7097   if (GET_CODE (cmp) == GET_CODE (operands[0]))
7098     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7099   else
7100     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7101   operands[1] = tmp;
7102   operands[2] = const0_rtx;
7103   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7104 }")
7105
7106 (define_insn "*beq_media_i"
7107   [(set (pc)
7108         (if_then_else (match_operator 3 "equality_comparison_operator"
7109                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
7110                          (match_operand:DI 2 "arith_operand" "r,I06")])
7111                       (match_operand 0 "target_operand" "b,b")
7112                       (pc)))]
7113   "TARGET_SHMEDIA"
7114   "@
7115         b%o3%'  %1, %2, %0%>
7116         b%o3i%' %1, %2, %0%>"
7117   [(set_attr "type" "cbranch_media")])
7118
7119 (define_insn "*beq_media_i32"
7120   [(set (pc)
7121         (if_then_else (match_operator 3 "equality_comparison_operator"
7122                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
7123                          (match_operand:SI 2 "arith_operand" "r,I06")])
7124                       (match_operand 0 "target_operand" "b,b")
7125                       (pc)))]
7126   "TARGET_SHMEDIA"
7127   "@
7128         b%o3%'  %1, %2, %0%>
7129         b%o3i%' %1, %2, %0%>"
7130   [(set_attr "type" "cbranch_media")])
7131
7132 (define_insn "*bgt_media_i"
7133   [(set (pc)
7134         (if_then_else (match_operator 3 "greater_comparison_operator"
7135                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7136                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7137                       (match_operand 0 "target_operand" "b")
7138                       (pc)))]
7139   "TARGET_SHMEDIA"
7140   "b%o3%'       %N1, %N2, %0%>"
7141   [(set_attr "type" "cbranch_media")])
7142
7143 (define_insn "*bgt_media_i32"
7144   [(set (pc)
7145         (if_then_else (match_operator 3 "greater_comparison_operator"
7146                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7147                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7148                       (match_operand 0 "target_operand" "b")
7149                       (pc)))]
7150   "TARGET_SHMEDIA"
7151   "b%o3%'       %N1, %N2, %0%>"
7152   [(set_attr "type" "cbranch_media")])
7153
7154 ;; These are only needed to make invert_jump() happy - otherwise, jump
7155 ;; optimization will be silently disabled.
7156 (define_insn "*blt_media_i"
7157   [(set (pc)
7158         (if_then_else (match_operator 3 "less_comparison_operator"
7159                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7160                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7161                       (match_operand 0 "target_operand" "b")
7162                       (pc)))]
7163   "TARGET_SHMEDIA"
7164   "b%o3%'       %N2, %N1, %0%>"
7165   [(set_attr "type" "cbranch_media")])
7166
7167 (define_insn "*blt_media_i32"
7168   [(set (pc)
7169         (if_then_else (match_operator 3 "less_comparison_operator"
7170                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7171                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7172                       (match_operand 0 "target_operand" "b")
7173                       (pc)))]
7174   "TARGET_SHMEDIA"
7175   "b%o3%'       %N2, %N1, %0%>"
7176   [(set_attr "type" "cbranch_media")])
7177
7178 ;; combiner splitter for test-and-branch on single bit in register.  This
7179 ;; is endian dependent because the non-paradoxical subreg looks different
7180 ;; on big endian.
7181 (define_split
7182   [(set (pc)
7183         (if_then_else
7184           (match_operator 3 "equality_comparison_operator"
7185             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7186                                                       "extend_reg_operand" "")
7187                                                     0)
7188                                          (const_int 1)
7189                                          (match_operand 2
7190                                           "const_int_operand" "")) 0)
7191              (const_int 0)])
7192           (match_operand 0 "target_operand" "")
7193           (pc)))
7194    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7195   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7196   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7197    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7198
7199   "
7200 {
7201   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7202   operands[6] = (GET_CODE (operands[3]) == EQ
7203                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7204                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7205 }")
7206
7207 ; operand 0 is the loop count pseudo register
7208 ; operand 1 is the number of loop iterations or 0 if it is unknown
7209 ; operand 2 is the maximum number of loop iterations
7210 ; operand 3 is the number of levels of enclosed loops
7211 ; operand 4 is the label to jump to at the top of the loop
7212
7213 (define_expand "doloop_end"
7214   [(parallel [(set (pc) (if_then_else
7215                           (ne:SI (match_operand:SI 0 "" "")
7216                               (const_int 1))
7217                           (label_ref (match_operand 4 "" ""))
7218                           (pc)))
7219               (set (match_dup 0)
7220                    (plus:SI (match_dup 0) (const_int -1)))
7221               (clobber (reg:SI T_REG))])]
7222   "TARGET_SH2"
7223   "
7224 {
7225   if (GET_MODE (operands[0]) != SImode)
7226     FAIL;
7227 }
7228 ")
7229
7230 (define_insn_and_split "doloop_end_split"
7231   [(set (pc)
7232         (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7233                           (const_int 1))
7234                       (label_ref (match_operand 1 "" ""))
7235                       (pc)))
7236    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7237         (plus (match_dup 2) (const_int -1)))
7238    (clobber (reg:SI T_REG))]
7239   "TARGET_SH2"
7240   "#"
7241   ""
7242   [(parallel [(set (reg:SI T_REG)
7243                    (eq:SI (match_dup 2) (const_int 1)))
7244               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7245    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7246                            (label_ref (match_dup 1))
7247                            (pc)))]
7248 ""
7249    [(set_attr "type" "cbranch")])
7250
7251 \f
7252 ;; ------------------------------------------------------------------------
7253 ;; Jump and linkage insns
7254 ;; ------------------------------------------------------------------------
7255
7256 (define_insn "jump_compact"
7257   [(set (pc)
7258         (label_ref (match_operand 0 "" "")))]
7259   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7260   "*
7261 {
7262   /* The length is 16 if the delay slot is unfilled.  */
7263   if (get_attr_length(insn) > 4)
7264     return output_far_jump(insn, operands[0]);
7265   else
7266     return   \"bra      %l0%#\";
7267 }"
7268   [(set_attr "type" "jump")
7269    (set_attr "needs_delay_slot" "yes")])
7270
7271 ;; ??? It would be much saner to explicitly use the scratch register
7272 ;; in the jump insn, and have indirect_jump_scratch only set it,
7273 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7274 ;; from the target then, as it uses simplejump_p.
7275 ;;(define_insn "jump_compact_far"
7276 ;;  [(set (pc)
7277 ;;      (label_ref (match_operand 0 "" "")))
7278 ;;   (use (match_operand 1 "register_operand" "r")]
7279 ;;  "TARGET_SH1"
7280 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7281 ;;  [(set_attr "type" "jump")
7282 ;;   (set_attr "needs_delay_slot" "yes")])
7283
7284 (define_insn "jump_media"
7285   [(set (pc)
7286         (match_operand 0 "target_operand" "b"))]
7287   "TARGET_SHMEDIA"
7288   "blink        %0, r63%>"
7289   [(set_attr "type" "jump_media")])
7290
7291 (define_expand "jump"
7292   [(set (pc)
7293         (label_ref (match_operand 0 "" "")))]
7294   ""
7295   "
7296 {
7297   if (TARGET_SH1)
7298     emit_jump_insn (gen_jump_compact (operands[0]));
7299   else if (TARGET_SHMEDIA)
7300     {
7301       if (reload_in_progress || reload_completed)
7302         FAIL;
7303       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7304                                                          operands[0])));
7305     }
7306   DONE;
7307 }")
7308
7309 (define_insn "force_mode_for_call"
7310   [(use (reg:PSI FPSCR_REG))]
7311   "TARGET_SHCOMPACT"
7312   ""
7313   [(set_attr "length" "0")
7314    (set (attr "fp_mode")
7315         (if_then_else (eq_attr "fpu_single" "yes")
7316                       (const_string "single") (const_string "double")))])
7317
7318 (define_insn "calli"
7319   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7320          (match_operand 1 "" ""))
7321    (use (reg:PSI FPSCR_REG))
7322    (clobber (reg:SI PR_REG))]
7323   "TARGET_SH1"
7324   "*
7325    {
7326      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7327         return \"jsr/n\\t@%0\";
7328      else
7329         return \"jsr\\t@%0%#\";
7330    }"
7331
7332   [(set_attr "type" "call")
7333    (set (attr "fp_mode")
7334         (if_then_else (eq_attr "fpu_single" "yes")
7335                       (const_string "single") (const_string "double")))
7336    (set_attr "needs_delay_slot" "yes")
7337    (set_attr "fp_set" "unknown")])
7338
7339 ;; This is TBR relative jump instruction for SH2A architecture.
7340 ;; Its use is enabled assigning an attribute "function_vector"
7341 ;; and the vector number to a function during its declaration.
7342
7343 (define_insn "calli_tbr_rel"
7344   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7345          (match_operand 1 "" ""))
7346    (use (reg:PSI FPSCR_REG))
7347    (clobber (reg:SI PR_REG))]
7348   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7349   "*
7350 {
7351   unsigned HOST_WIDE_INT vect_num;
7352   vect_num = sh2a_get_function_vector_number (operands[0]);
7353   operands[2] = GEN_INT (vect_num * 4);
7354
7355   return \"jsr/n\\t@@(%O2,tbr)\";
7356 }"
7357   [(set_attr "type" "call")
7358    (set (attr "fp_mode")
7359         (if_then_else (eq_attr "fpu_single" "yes")
7360                       (const_string "single") (const_string "double")))
7361    (set_attr "needs_delay_slot" "no")
7362    (set_attr "fp_set" "unknown")])
7363
7364 ;; This is a pc-rel call, using bsrf, for use with PIC.
7365
7366 (define_insn "calli_pcrel"
7367   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7368          (match_operand 1 "" ""))
7369    (use (reg:PSI FPSCR_REG))
7370    (use (reg:SI PIC_REG))
7371    (use (match_operand 2 "" ""))
7372    (clobber (reg:SI PR_REG))]
7373   "TARGET_SH2"
7374   "bsrf %0\\n%O2:%#"
7375   [(set_attr "type" "call")
7376    (set (attr "fp_mode")
7377         (if_then_else (eq_attr "fpu_single" "yes")
7378                       (const_string "single") (const_string "double")))
7379    (set_attr "needs_delay_slot" "yes")
7380    (set_attr "fp_set" "unknown")])
7381
7382 (define_insn_and_split "call_pcrel"
7383   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7384          (match_operand 1 "" ""))
7385    (use (reg:PSI FPSCR_REG))
7386    (use (reg:SI PIC_REG))
7387    (clobber (reg:SI PR_REG))
7388    (clobber (match_scratch:SI 2 "=r"))]
7389   "TARGET_SH2"
7390   "#"
7391   "reload_completed"
7392   [(const_int 0)]
7393   "
7394 {
7395   rtx lab = PATTERN (gen_call_site ());
7396
7397   if (SYMBOL_REF_LOCAL_P (operands[0]))
7398     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7399   else
7400     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7401   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7402   DONE;
7403 }"
7404   [(set_attr "type" "call")
7405    (set (attr "fp_mode")
7406         (if_then_else (eq_attr "fpu_single" "yes")
7407                       (const_string "single") (const_string "double")))
7408    (set_attr "needs_delay_slot" "yes")
7409    (set_attr "fp_set" "unknown")])
7410
7411 (define_insn "call_compact"
7412   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7413          (match_operand 1 "" ""))
7414    (match_operand 2 "immediate_operand" "n")
7415    (use (reg:SI R0_REG))
7416    (use (reg:SI R1_REG))
7417    (use (reg:PSI FPSCR_REG))
7418    (clobber (reg:SI PR_REG))]
7419   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7420   "jsr  @%0%#"
7421   [(set_attr "type" "call")
7422    (set (attr "fp_mode")
7423         (if_then_else (eq_attr "fpu_single" "yes")
7424                       (const_string "single") (const_string "double")))
7425    (set_attr "needs_delay_slot" "yes")])
7426
7427 (define_insn "call_compact_rettramp"
7428   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7429          (match_operand 1 "" ""))
7430    (match_operand 2 "immediate_operand" "n")
7431    (use (reg:SI R0_REG))
7432    (use (reg:SI R1_REG))
7433    (use (reg:PSI FPSCR_REG))
7434    (clobber (reg:SI R10_REG))
7435    (clobber (reg:SI PR_REG))]
7436   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7437   "jsr  @%0%#"
7438   [(set_attr "type" "call")
7439    (set (attr "fp_mode")
7440         (if_then_else (eq_attr "fpu_single" "yes")
7441                       (const_string "single") (const_string "double")))
7442    (set_attr "needs_delay_slot" "yes")])
7443
7444 (define_insn "call_media"
7445   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7446          (match_operand 1 "" ""))
7447    (clobber (reg:DI PR_MEDIA_REG))]
7448   "TARGET_SHMEDIA"
7449   "blink        %0, r18"
7450   [(set_attr "type" "jump_media")])
7451
7452 (define_insn "call_valuei"
7453   [(set (match_operand 0 "" "=rf")
7454         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7455               (match_operand 2 "" "")))
7456    (use (reg:PSI FPSCR_REG))
7457    (clobber (reg:SI PR_REG))]
7458   "TARGET_SH1"
7459   "*
7460    {
7461      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7462         return \"jsr/n\\t@%1\";
7463      else
7464         return \"jsr\\t@%1%#\";
7465    }"
7466   [(set_attr "type" "call")
7467    (set (attr "fp_mode")
7468         (if_then_else (eq_attr "fpu_single" "yes")
7469                       (const_string "single") (const_string "double")))
7470    (set_attr "needs_delay_slot" "yes")
7471    (set_attr "fp_set" "unknown")])
7472
7473 ;; This is TBR relative jump instruction for SH2A architecture.
7474 ;; Its use is enabled by assigning an attribute "function_vector"
7475 ;; and the vector number to a function during its declaration.
7476
7477 (define_insn "call_valuei_tbr_rel"
7478   [(set (match_operand 0 "" "=rf")
7479         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7480               (match_operand 2 "" "")))
7481    (use (reg:PSI FPSCR_REG))
7482    (clobber (reg:SI PR_REG))]
7483   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7484   "*
7485 {
7486   unsigned HOST_WIDE_INT vect_num;
7487   vect_num = sh2a_get_function_vector_number (operands[1]);
7488   operands[3] = GEN_INT (vect_num * 4);
7489
7490   return \"jsr/n\\t@@(%O3,tbr)\";
7491 }"
7492   [(set_attr "type" "call")
7493    (set (attr "fp_mode")
7494         (if_then_else (eq_attr "fpu_single" "yes")
7495                       (const_string "single") (const_string "double")))
7496    (set_attr "needs_delay_slot" "no")
7497    (set_attr "fp_set" "unknown")])
7498
7499 (define_insn "call_valuei_pcrel"
7500   [(set (match_operand 0 "" "=rf")
7501         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7502               (match_operand 2 "" "")))
7503    (use (reg:PSI FPSCR_REG))
7504    (use (reg:SI PIC_REG))
7505    (use (match_operand 3 "" ""))
7506    (clobber (reg:SI PR_REG))]
7507   "TARGET_SH2"
7508   "bsrf %1\\n%O3:%#"
7509   [(set_attr "type" "call")
7510    (set (attr "fp_mode")
7511         (if_then_else (eq_attr "fpu_single" "yes")
7512                       (const_string "single") (const_string "double")))
7513    (set_attr "needs_delay_slot" "yes")
7514    (set_attr "fp_set" "unknown")])
7515
7516 (define_insn_and_split "call_value_pcrel"
7517   [(set (match_operand 0 "" "=rf")
7518         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7519               (match_operand 2 "" "")))
7520    (use (reg:PSI FPSCR_REG))
7521    (use (reg:SI PIC_REG))
7522    (clobber (reg:SI PR_REG))
7523    (clobber (match_scratch:SI 3 "=r"))]
7524   "TARGET_SH2"
7525   "#"
7526   "reload_completed"
7527   [(const_int 0)]
7528   "
7529 {
7530   rtx lab = PATTERN (gen_call_site ());
7531
7532   if (SYMBOL_REF_LOCAL_P (operands[1]))
7533     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7534   else
7535     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7536   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7537                                          operands[2], copy_rtx (lab)));
7538   DONE;
7539 }"
7540   [(set_attr "type" "call")
7541    (set (attr "fp_mode")
7542         (if_then_else (eq_attr "fpu_single" "yes")
7543                       (const_string "single") (const_string "double")))
7544    (set_attr "needs_delay_slot" "yes")
7545    (set_attr "fp_set" "unknown")])
7546
7547 (define_insn "call_value_compact"
7548   [(set (match_operand 0 "" "=rf")
7549         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7550               (match_operand 2 "" "")))
7551    (match_operand 3 "immediate_operand" "n")
7552    (use (reg:SI R0_REG))
7553    (use (reg:SI R1_REG))
7554    (use (reg:PSI FPSCR_REG))
7555    (clobber (reg:SI PR_REG))]
7556   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7557   "jsr  @%1%#"
7558   [(set_attr "type" "call")
7559    (set (attr "fp_mode")
7560         (if_then_else (eq_attr "fpu_single" "yes")
7561                       (const_string "single") (const_string "double")))
7562    (set_attr "needs_delay_slot" "yes")])
7563
7564 (define_insn "call_value_compact_rettramp"
7565   [(set (match_operand 0 "" "=rf")
7566         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7567               (match_operand 2 "" "")))
7568    (match_operand 3 "immediate_operand" "n")
7569    (use (reg:SI R0_REG))
7570    (use (reg:SI R1_REG))
7571    (use (reg:PSI FPSCR_REG))
7572    (clobber (reg:SI R10_REG))
7573    (clobber (reg:SI PR_REG))]
7574   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7575   "jsr  @%1%#"
7576   [(set_attr "type" "call")
7577    (set (attr "fp_mode")
7578         (if_then_else (eq_attr "fpu_single" "yes")
7579                       (const_string "single") (const_string "double")))
7580    (set_attr "needs_delay_slot" "yes")])
7581
7582 (define_insn "call_value_media"
7583   [(set (match_operand 0 "" "=rf")
7584         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7585               (match_operand 2 "" "")))
7586    (clobber (reg:DI PR_MEDIA_REG))]
7587   "TARGET_SHMEDIA"
7588   "blink        %1, r18"
7589   [(set_attr "type" "jump_media")])
7590
7591 (define_expand "call"
7592   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7593                             (match_operand 1 "" ""))
7594               (match_operand 2 "" "")
7595               (use (reg:PSI FPSCR_REG))
7596               (clobber (reg:SI PR_REG))])]
7597   ""
7598   "
7599 {
7600   if (TARGET_SHMEDIA)
7601     {
7602       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7603       emit_call_insn (gen_call_media (operands[0], operands[1]));
7604       DONE;
7605     }
7606   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7607     {
7608       rtx cookie_rtx = operands[2];
7609       long cookie = INTVAL (cookie_rtx);
7610       rtx func = XEXP (operands[0], 0);
7611       rtx r0, r1;
7612
7613       if (flag_pic)
7614         {
7615           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7616             {
7617               rtx reg = gen_reg_rtx (Pmode);
7618
7619               emit_insn (gen_symGOTPLT2reg (reg, func));
7620               func = reg;
7621             }
7622           else
7623             func = legitimize_pic_address (func, Pmode, 0);
7624         }
7625
7626       r0 = gen_rtx_REG (SImode, R0_REG);
7627       r1 = gen_rtx_REG (SImode, R1_REG);
7628
7629       /* Since such a call function may use all call-clobbered
7630          registers, we force a mode switch earlier, so that we don't
7631          run out of registers when adjusting fpscr for the call.  */
7632       emit_insn (gen_force_mode_for_call ());
7633
7634       operands[0]
7635         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7636                            SFUNC_GOT);
7637       operands[0] = force_reg (SImode, operands[0]);
7638
7639       emit_move_insn (r0, func);
7640       emit_move_insn (r1, cookie_rtx);
7641
7642       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7643         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7644                                                    operands[2]));
7645       else
7646         emit_call_insn (gen_call_compact (operands[0], operands[1],
7647                                           operands[2]));
7648
7649       DONE;
7650     }
7651   else if (TARGET_SHCOMPACT && flag_pic
7652            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7653            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7654     {
7655       rtx reg = gen_reg_rtx (Pmode);
7656
7657       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7658       XEXP (operands[0], 0) = reg;
7659     }
7660   if (!flag_pic && TARGET_SH2A
7661       && MEM_P (operands[0])
7662       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7663     {
7664       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7665         {
7666           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7667                                              operands[1]));
7668           DONE;
7669         }
7670     }
7671   if (flag_pic && TARGET_SH2
7672       && MEM_P (operands[0])
7673       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7674     {
7675       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7676       DONE;
7677     }
7678   else
7679   {
7680     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7681     operands[1] = operands[2];
7682   }
7683
7684   emit_call_insn (gen_calli (operands[0], operands[1]));
7685   DONE;
7686 }")
7687
7688 (define_insn "call_pop_compact"
7689   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7690          (match_operand 1 "" ""))
7691    (match_operand 2 "immediate_operand" "n")
7692    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7693                                  (match_operand 3 "immediate_operand" "n")))
7694    (use (reg:SI R0_REG))
7695    (use (reg:SI R1_REG))
7696    (use (reg:PSI FPSCR_REG))
7697    (clobber (reg:SI PR_REG))]
7698   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7699   "jsr  @%0%#"
7700   [(set_attr "type" "call")
7701    (set (attr "fp_mode")
7702         (if_then_else (eq_attr "fpu_single" "yes")
7703                       (const_string "single") (const_string "double")))
7704    (set_attr "needs_delay_slot" "yes")])
7705
7706 (define_insn "call_pop_compact_rettramp"
7707   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7708          (match_operand 1 "" ""))
7709    (match_operand 2 "immediate_operand" "n")
7710    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7711                                  (match_operand 3 "immediate_operand" "n")))
7712    (use (reg:SI R0_REG))
7713    (use (reg:SI R1_REG))
7714    (use (reg:PSI FPSCR_REG))
7715    (clobber (reg:SI R10_REG))
7716    (clobber (reg:SI PR_REG))]
7717   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7718   "jsr  @%0%#"
7719   [(set_attr "type" "call")
7720    (set (attr "fp_mode")
7721         (if_then_else (eq_attr "fpu_single" "yes")
7722                       (const_string "single") (const_string "double")))
7723    (set_attr "needs_delay_slot" "yes")])
7724
7725 (define_expand "call_pop"
7726   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7727                     (match_operand 1 "" ""))
7728              (match_operand 2 "" "")
7729              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7730                                            (match_operand 3 "" "")))])]
7731   "TARGET_SHCOMPACT"
7732   "
7733 {
7734   rtx cookie_rtx;
7735   long cookie;
7736   rtx func;
7737   rtx r0, r1;
7738
7739   gcc_assert (operands[2] && INTVAL (operands[2]));
7740   cookie_rtx = operands[2];
7741   cookie = INTVAL (cookie_rtx);
7742   func = XEXP (operands[0], 0);
7743
7744   if (flag_pic)
7745     {
7746       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7747         {
7748           rtx reg = gen_reg_rtx (Pmode);
7749           emit_insn (gen_symGOTPLT2reg (reg, func));
7750           func = reg;
7751         }
7752       else
7753         func = legitimize_pic_address (func, Pmode, 0);
7754     }
7755
7756   r0 = gen_rtx_REG (SImode, R0_REG);
7757   r1 = gen_rtx_REG (SImode, R1_REG);
7758
7759   /* Since such a call function may use all call-clobbered
7760      registers, we force a mode switch earlier, so that we don't
7761      run out of registers when adjusting fpscr for the call.  */
7762   emit_insn (gen_force_mode_for_call ());
7763
7764   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7765                                  SFUNC_GOT);
7766   operands[0] = force_reg (SImode, operands[0]);
7767
7768   emit_move_insn (r0, func);
7769   emit_move_insn (r1, cookie_rtx);
7770
7771   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7772     emit_call_insn (gen_call_pop_compact_rettramp
7773                      (operands[0], operands[1], operands[2], operands[3]));
7774   else
7775     emit_call_insn (gen_call_pop_compact
7776                      (operands[0], operands[1], operands[2], operands[3]));
7777
7778   DONE;
7779 }")
7780
7781 (define_expand "call_value"
7782   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7783                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7784                                  (match_operand 2 "" "")))
7785               (match_operand 3 "" "")
7786               (use (reg:PSI FPSCR_REG))
7787               (clobber (reg:SI PR_REG))])]
7788   ""
7789   "
7790 {
7791   if (TARGET_SHMEDIA)
7792     {
7793       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7794       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7795                                             operands[2]));
7796       DONE;
7797     }
7798   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7799     {
7800       rtx cookie_rtx = operands[3];
7801       long cookie = INTVAL (cookie_rtx);
7802       rtx func = XEXP (operands[1], 0);
7803       rtx r0, r1;
7804
7805       if (flag_pic)
7806         {
7807           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7808             {
7809               rtx reg = gen_reg_rtx (Pmode);
7810
7811               emit_insn (gen_symGOTPLT2reg (reg, func));
7812               func = reg;
7813             }
7814           else
7815             func = legitimize_pic_address (func, Pmode, 0);
7816         }
7817
7818       r0 = gen_rtx_REG (SImode, R0_REG);
7819       r1 = gen_rtx_REG (SImode, R1_REG);
7820
7821       /* Since such a call function may use all call-clobbered
7822          registers, we force a mode switch earlier, so that we don't
7823          run out of registers when adjusting fpscr for the call.  */
7824       emit_insn (gen_force_mode_for_call ());
7825
7826       operands[1]
7827         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7828                            SFUNC_GOT);
7829       operands[1] = force_reg (SImode, operands[1]);
7830
7831       emit_move_insn (r0, func);
7832       emit_move_insn (r1, cookie_rtx);
7833
7834       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7835         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7836                                                          operands[1],
7837                                                          operands[2],
7838                                                          operands[3]));
7839       else
7840         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7841                                                 operands[2], operands[3]));
7842
7843       DONE;
7844     }
7845   else if (TARGET_SHCOMPACT && flag_pic
7846            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7847            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7848     {
7849       rtx reg = gen_reg_rtx (Pmode);
7850
7851       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7852       XEXP (operands[1], 0) = reg;
7853     }
7854   if (!flag_pic && TARGET_SH2A
7855       && MEM_P (operands[1])
7856       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7857     {
7858       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7859         {
7860           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7861                                  XEXP (operands[1], 0), operands[2]));
7862           DONE;
7863         }
7864     }
7865   if (flag_pic && TARGET_SH2
7866       && MEM_P (operands[1])
7867       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7868     {
7869       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7870                                             operands[2]));
7871       DONE;
7872     }
7873   else
7874     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7875
7876   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7877   DONE;
7878 }")
7879
7880 (define_insn "sibcalli"
7881   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7882          (match_operand 1 "" ""))
7883    (use (reg:PSI FPSCR_REG))
7884    (return)]
7885   "TARGET_SH1"
7886   "jmp  @%0%#"
7887   [(set_attr "needs_delay_slot" "yes")
7888    (set (attr "fp_mode")
7889         (if_then_else (eq_attr "fpu_single" "yes")
7890                       (const_string "single") (const_string "double")))
7891    (set_attr "type" "jump_ind")])
7892
7893 (define_insn "sibcalli_pcrel"
7894   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7895          (match_operand 1 "" ""))
7896    (use (match_operand 2 "" ""))
7897    (use (reg:PSI FPSCR_REG))
7898    (return)]
7899   "TARGET_SH2"
7900   "braf %0\\n%O2:%#"
7901   [(set_attr "needs_delay_slot" "yes")
7902    (set (attr "fp_mode")
7903         (if_then_else (eq_attr "fpu_single" "yes")
7904                       (const_string "single") (const_string "double")))
7905    (set_attr "type" "jump_ind")])
7906
7907 ;; This uses an unspec to describe that the symbol_ref is very close.
7908 (define_insn "sibcalli_thunk"
7909   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7910                              UNSPEC_THUNK))
7911          (match_operand 1 "" ""))
7912    (use (reg:PSI FPSCR_REG))
7913    (return)]
7914   "TARGET_SH1"
7915   "bra  %O0"
7916   [(set_attr "needs_delay_slot" "yes")
7917    (set (attr "fp_mode")
7918         (if_then_else (eq_attr "fpu_single" "yes")
7919                       (const_string "single") (const_string "double")))
7920    (set_attr "type" "jump")
7921    (set_attr "length" "2")])
7922
7923 (define_insn_and_split "sibcall_pcrel"
7924   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7925          (match_operand 1 "" ""))
7926    (use (reg:PSI FPSCR_REG))
7927    (clobber (match_scratch:SI 2 "=k"))
7928    (return)]
7929   "TARGET_SH2"
7930   "#"
7931   "reload_completed"
7932   [(const_int 0)]
7933   "
7934 {
7935   rtx lab = PATTERN (gen_call_site ());
7936   rtx call_insn;
7937
7938   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7939   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7940                                                   copy_rtx (lab)));
7941   SIBLING_CALL_P (call_insn) = 1;
7942   DONE;
7943 }"
7944   [(set_attr "needs_delay_slot" "yes")
7945    (set (attr "fp_mode")
7946         (if_then_else (eq_attr "fpu_single" "yes")
7947                       (const_string "single") (const_string "double")))
7948    (set_attr "type" "jump_ind")])
7949
7950 (define_insn "sibcall_compact"
7951   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7952          (match_operand 1 "" ""))
7953    (return)
7954    (use (match_operand:SI 2 "register_operand" "z,x"))
7955    (use (reg:SI R1_REG))
7956    (use (reg:PSI FPSCR_REG))
7957    ;; We want to make sure the `x' above will only match MACH_REG
7958    ;; because sibcall_epilogue may clobber MACL_REG.
7959    (clobber (reg:SI MACL_REG))]
7960   "TARGET_SHCOMPACT"
7961   "@
7962         jmp     @%0%#
7963         jmp     @%0\\n  sts     %2, r0"
7964   [(set_attr "needs_delay_slot" "yes,no")
7965    (set_attr "length" "2,4")
7966    (set (attr "fp_mode") (const_string "single"))
7967    (set_attr "type" "jump_ind")])
7968
7969 (define_insn "sibcall_media"
7970   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7971          (match_operand 1 "" ""))
7972    (use (reg:SI PR_MEDIA_REG))
7973    (return)]
7974   "TARGET_SHMEDIA"
7975   "blink        %0, r63"
7976   [(set_attr "type" "jump_media")])
7977
7978 (define_expand "sibcall"
7979   [(parallel
7980     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7981            (match_operand 1 "" ""))
7982      (match_operand 2 "" "")
7983      (use (reg:PSI FPSCR_REG))
7984      (return)])]
7985   ""
7986   "
7987 {
7988   if (TARGET_SHMEDIA)
7989     {
7990       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7991       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7992       DONE;
7993     }
7994   else if (TARGET_SHCOMPACT && operands[2]
7995            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7996     {
7997       rtx cookie_rtx = operands[2];
7998       long cookie = INTVAL (cookie_rtx);
7999       rtx func = XEXP (operands[0], 0);
8000       rtx mach, r1;
8001
8002       if (flag_pic)
8003         {
8004           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8005             {
8006               rtx reg = gen_reg_rtx (Pmode);
8007
8008               emit_insn (gen_symGOT2reg (reg, func));
8009               func = reg;
8010             }
8011           else
8012             func = legitimize_pic_address (func, Pmode, 0);
8013         }
8014
8015       /* FIXME: if we could tell whether all argument registers are
8016          already taken, we could decide whether to force the use of
8017          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8018          simple way to tell.  We could use the CALL_COOKIE, but we
8019          can't currently tell a register used for regular argument
8020          passing from one that is unused.  If we leave it up to reload
8021          to decide which register to use, it seems to always choose
8022          R0_REG, which leaves no available registers in SIBCALL_REGS
8023          to hold the address of the trampoline.  */
8024       mach = gen_rtx_REG (SImode, MACH_REG);
8025       r1 = gen_rtx_REG (SImode, R1_REG);
8026
8027       /* Since such a call function may use all call-clobbered
8028          registers, we force a mode switch earlier, so that we don't
8029          run out of registers when adjusting fpscr for the call.  */
8030       emit_insn (gen_force_mode_for_call ());
8031
8032       operands[0]
8033         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8034                            SFUNC_GOT);
8035       operands[0] = force_reg (SImode, operands[0]);
8036
8037       /* We don't need a return trampoline, since the callee will
8038          return directly to the upper caller.  */
8039       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8040         {
8041           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8042           cookie_rtx = GEN_INT (cookie);
8043         }
8044
8045       emit_move_insn (mach, func);
8046       emit_move_insn (r1, cookie_rtx);
8047
8048       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8049       DONE;
8050     }
8051   else if (TARGET_SHCOMPACT && flag_pic
8052            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8053            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8054     {
8055       rtx reg = gen_reg_rtx (Pmode);
8056
8057       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8058       XEXP (operands[0], 0) = reg;
8059     }
8060   if (flag_pic && TARGET_SH2
8061       && MEM_P (operands[0])
8062       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8063       /* The PLT needs the PIC register, but the epilogue would have
8064          to restore it, so we can only use PC-relative PIC calls for
8065          static functions.  */
8066       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8067     {
8068       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8069       DONE;
8070     }
8071   else
8072     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8073
8074   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8075   DONE;
8076 }")
8077
8078 (define_insn "sibcall_valuei"
8079   [(set (match_operand 0 "" "=rf")
8080         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8081               (match_operand 2 "" "")))
8082    (use (reg:PSI FPSCR_REG))
8083    (return)]
8084   "TARGET_SH1"
8085   "jmp  @%1%#"
8086   [(set_attr "needs_delay_slot" "yes")
8087    (set (attr "fp_mode")
8088         (if_then_else (eq_attr "fpu_single" "yes")
8089                       (const_string "single") (const_string "double")))
8090    (set_attr "type" "jump_ind")])
8091
8092 (define_insn "sibcall_valuei_pcrel"
8093   [(set (match_operand 0 "" "=rf")
8094         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8095               (match_operand 2 "" "")))
8096    (use (match_operand 3 "" ""))
8097    (use (reg:PSI FPSCR_REG))
8098    (return)]
8099   "TARGET_SH2"
8100   "braf %1\\n%O3:%#"
8101   [(set_attr "needs_delay_slot" "yes")
8102    (set (attr "fp_mode")
8103         (if_then_else (eq_attr "fpu_single" "yes")
8104                       (const_string "single") (const_string "double")))
8105    (set_attr "type" "jump_ind")])
8106
8107 (define_insn_and_split "sibcall_value_pcrel"
8108   [(set (match_operand 0 "" "=rf")
8109         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8110               (match_operand 2 "" "")))
8111    (use (reg:PSI FPSCR_REG))
8112    (clobber (match_scratch:SI 3 "=k"))
8113    (return)]
8114   "TARGET_SH2"
8115   "#"
8116   "reload_completed"
8117   [(const_int 0)]
8118   "
8119 {
8120   rtx lab = PATTERN (gen_call_site ());
8121   rtx call_insn;
8122
8123   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8124   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8125                                                         operands[3],
8126                                                         operands[2],
8127                                                         copy_rtx (lab)));
8128   SIBLING_CALL_P (call_insn) = 1;
8129   DONE;
8130 }"
8131   [(set_attr "needs_delay_slot" "yes")
8132    (set (attr "fp_mode")
8133         (if_then_else (eq_attr "fpu_single" "yes")
8134                       (const_string "single") (const_string "double")))
8135    (set_attr "type" "jump_ind")])
8136
8137 (define_insn "sibcall_value_compact"
8138   [(set (match_operand 0 "" "=rf,rf")
8139         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8140               (match_operand 2 "" "")))
8141    (return)
8142    (use (match_operand:SI 3 "register_operand" "z,x"))
8143    (use (reg:SI R1_REG))
8144    (use (reg:PSI FPSCR_REG))
8145    ;; We want to make sure the `x' above will only match MACH_REG
8146    ;; because sibcall_epilogue may clobber MACL_REG.
8147    (clobber (reg:SI MACL_REG))]
8148   "TARGET_SHCOMPACT"
8149   "@
8150         jmp     @%1%#
8151         jmp     @%1\\n  sts     %3, r0"
8152   [(set_attr "needs_delay_slot" "yes,no")
8153    (set_attr "length" "2,4")
8154    (set (attr "fp_mode") (const_string "single"))
8155    (set_attr "type" "jump_ind")])
8156
8157 (define_insn "sibcall_value_media"
8158   [(set (match_operand 0 "" "=rf")
8159         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8160               (match_operand 2 "" "")))
8161    (use (reg:SI PR_MEDIA_REG))
8162    (return)]
8163   "TARGET_SHMEDIA"
8164   "blink        %1, r63"
8165   [(set_attr "type" "jump_media")])
8166
8167 (define_expand "sibcall_value"
8168   [(parallel
8169     [(set (match_operand 0 "arith_reg_operand" "")
8170           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8171                 (match_operand 2 "" "")))
8172      (match_operand 3 "" "")
8173      (use (reg:PSI FPSCR_REG))
8174      (return)])]
8175   ""
8176   "
8177 {
8178   if (TARGET_SHMEDIA)
8179     {
8180       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8181       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8182                                                operands[2]));
8183       DONE;
8184     }
8185   else if (TARGET_SHCOMPACT && operands[3]
8186            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8187     {
8188       rtx cookie_rtx = operands[3];
8189       long cookie = INTVAL (cookie_rtx);
8190       rtx func = XEXP (operands[1], 0);
8191       rtx mach, r1;
8192
8193       if (flag_pic)
8194         {
8195           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8196             {
8197               rtx reg = gen_reg_rtx (Pmode);
8198
8199               emit_insn (gen_symGOT2reg (reg, func));
8200               func = reg;
8201             }
8202           else
8203             func = legitimize_pic_address (func, Pmode, 0);
8204         }
8205
8206       /* FIXME: if we could tell whether all argument registers are
8207          already taken, we could decide whether to force the use of
8208          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8209          simple way to tell.  We could use the CALL_COOKIE, but we
8210          can't currently tell a register used for regular argument
8211          passing from one that is unused.  If we leave it up to reload
8212          to decide which register to use, it seems to always choose
8213          R0_REG, which leaves no available registers in SIBCALL_REGS
8214          to hold the address of the trampoline.  */
8215       mach = gen_rtx_REG (SImode, MACH_REG);
8216       r1 = gen_rtx_REG (SImode, R1_REG);
8217
8218       /* Since such a call function may use all call-clobbered
8219          registers, we force a mode switch earlier, so that we don't
8220          run out of registers when adjusting fpscr for the call.  */
8221       emit_insn (gen_force_mode_for_call ());
8222
8223       operands[1]
8224         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8225                            SFUNC_GOT);
8226       operands[1] = force_reg (SImode, operands[1]);
8227
8228       /* We don't need a return trampoline, since the callee will
8229          return directly to the upper caller.  */
8230       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8231         {
8232           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8233           cookie_rtx = GEN_INT (cookie);
8234         }
8235
8236       emit_move_insn (mach, func);
8237       emit_move_insn (r1, cookie_rtx);
8238
8239       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8240                                                  operands[2], mach));
8241       DONE;
8242     }
8243   else if (TARGET_SHCOMPACT && flag_pic
8244            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8245            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8246     {
8247       rtx reg = gen_reg_rtx (Pmode);
8248
8249       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8250       XEXP (operands[1], 0) = reg;
8251     }
8252   if (flag_pic && TARGET_SH2
8253       && MEM_P (operands[1])
8254       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8255       /* The PLT needs the PIC register, but the epilogue would have
8256          to restore it, so we can only use PC-relative PIC calls for
8257          static functions.  */
8258       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8259     {
8260       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8261                                                XEXP (operands[1], 0),
8262                                                operands[2]));
8263       DONE;
8264     }
8265   else
8266     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8267
8268   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8269   DONE;
8270 }")
8271
8272 (define_insn "call_value_pop_compact"
8273   [(set (match_operand 0 "" "=rf")
8274         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8275               (match_operand 2 "" "")))
8276    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8277                                  (match_operand 4 "immediate_operand" "n")))
8278    (match_operand 3 "immediate_operand" "n")
8279    (use (reg:SI R0_REG))
8280    (use (reg:SI R1_REG))
8281    (use (reg:PSI FPSCR_REG))
8282    (clobber (reg:SI PR_REG))]
8283   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8284   "jsr  @%1%#"
8285   [(set_attr "type" "call")
8286    (set (attr "fp_mode")
8287         (if_then_else (eq_attr "fpu_single" "yes")
8288                       (const_string "single") (const_string "double")))
8289    (set_attr "needs_delay_slot" "yes")])
8290
8291 (define_insn "call_value_pop_compact_rettramp"
8292   [(set (match_operand 0 "" "=rf")
8293         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8294               (match_operand 2 "" "")))
8295    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8296                                  (match_operand 4 "immediate_operand" "n")))
8297    (match_operand 3 "immediate_operand" "n")
8298    (use (reg:SI R0_REG))
8299    (use (reg:SI R1_REG))
8300    (use (reg:PSI FPSCR_REG))
8301    (clobber (reg:SI R10_REG))
8302    (clobber (reg:SI PR_REG))]
8303   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8304   "jsr  @%1%#"
8305   [(set_attr "type" "call")
8306    (set (attr "fp_mode")
8307         (if_then_else (eq_attr "fpu_single" "yes")
8308                       (const_string "single") (const_string "double")))
8309    (set_attr "needs_delay_slot" "yes")])
8310
8311 (define_expand "call_value_pop"
8312   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8313                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8314                                  (match_operand 2 "" "")))
8315               (match_operand 3 "" "")
8316               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8317                                             (match_operand 4 "" "")))])]
8318   "TARGET_SHCOMPACT"
8319   "
8320 {
8321   rtx cookie_rtx;
8322   long cookie;
8323   rtx func;
8324   rtx r0, r1;
8325
8326   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8327   cookie_rtx = operands[3];
8328   cookie = INTVAL (cookie_rtx);
8329   func = XEXP (operands[1], 0);
8330
8331   if (flag_pic)
8332     {
8333       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8334         {
8335           rtx reg = gen_reg_rtx (Pmode);
8336
8337           emit_insn (gen_symGOTPLT2reg (reg, func));
8338           func = reg;
8339         }
8340       else
8341         func = legitimize_pic_address (func, Pmode, 0);
8342     }
8343
8344   r0 = gen_rtx_REG (SImode, R0_REG);
8345   r1 = gen_rtx_REG (SImode, R1_REG);
8346
8347   /* Since such a call function may use all call-clobbered
8348      registers, we force a mode switch earlier, so that we don't
8349      run out of registers when adjusting fpscr for the call.  */
8350   emit_insn (gen_force_mode_for_call ());
8351
8352   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8353                                  SFUNC_GOT);
8354   operands[1] = force_reg (SImode, operands[1]);
8355
8356   emit_move_insn (r0, func);
8357   emit_move_insn (r1, cookie_rtx);
8358
8359   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8360     emit_call_insn (gen_call_value_pop_compact_rettramp
8361                         (operands[0], operands[1], operands[2],
8362                          operands[3], operands[4]));
8363   else
8364     emit_call_insn (gen_call_value_pop_compact
8365                         (operands[0], operands[1], operands[2],
8366                          operands[3], operands[4]));
8367
8368   DONE;
8369 }")
8370
8371 (define_expand "sibcall_epilogue"
8372   [(return)]
8373   ""
8374   "
8375 {
8376   sh_expand_epilogue (1);
8377   if (TARGET_SHCOMPACT)
8378     {
8379       rtx insn, set;
8380
8381       /* If epilogue clobbers r0, preserve it in macl.  */
8382       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8383         if ((set = single_set (insn))
8384             && REG_P (SET_DEST (set))
8385             && REGNO (SET_DEST (set)) == R0_REG)
8386           {
8387             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8388             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8389
8390             /* We can't tell at this point whether the sibcall is a
8391                sibcall_compact and, if it is, whether it uses r0 or
8392                mach as operand 2, so let the instructions that
8393                preserve r0 be optimized away if r0 turns out to be
8394                dead.  */
8395             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8396             emit_move_insn (r0, tmp);
8397             break;
8398           }
8399     }
8400   DONE;
8401 }")
8402
8403 (define_insn "indirect_jump_compact"
8404   [(set (pc)
8405         (match_operand:SI 0 "arith_reg_operand" "r"))]
8406   "TARGET_SH1"
8407   "jmp  @%0%#"
8408   [(set_attr "needs_delay_slot" "yes")
8409    (set_attr "type" "jump_ind")])
8410
8411 (define_expand "indirect_jump"
8412   [(set (pc)
8413         (match_operand 0 "register_operand" ""))]
8414   ""
8415   "
8416 {
8417   if (GET_MODE (operands[0]) != Pmode)
8418     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8419 }")
8420
8421 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8422 ;; which can be present in structured code from indirect jumps which can not
8423 ;; be present in structured code.  This allows -fprofile-arcs to work.
8424
8425 ;; For SH1 processors.
8426 (define_insn "casesi_jump_1"
8427   [(set (pc)
8428         (match_operand:SI 0 "register_operand" "r"))
8429    (use (label_ref (match_operand 1 "" "")))]
8430   "TARGET_SH1"
8431   "jmp  @%0%#"
8432   [(set_attr "needs_delay_slot" "yes")
8433    (set_attr "type" "jump_ind")])
8434
8435 ;; For all later processors.
8436 (define_insn "casesi_jump_2"
8437   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8438                       (label_ref (match_operand 1 "" ""))))
8439    (use (label_ref (match_operand 2 "" "")))]
8440   "TARGET_SH2
8441    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8442   "braf %0%#"
8443   [(set_attr "needs_delay_slot" "yes")
8444    (set_attr "type" "jump_ind")])
8445
8446 (define_insn "casesi_jump_media"
8447   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8448    (use (label_ref (match_operand 1 "" "")))]
8449   "TARGET_SHMEDIA"
8450   "blink        %0, r63"
8451   [(set_attr "type" "jump_media")])
8452
8453 ;; Call subroutine returning any type.
8454 ;; ??? This probably doesn't work.
8455
8456 (define_expand "untyped_call"
8457   [(parallel [(call (match_operand 0 "" "")
8458                     (const_int 0))
8459               (match_operand 1 "" "")
8460               (match_operand 2 "" "")])]
8461   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8462   "
8463 {
8464   int i;
8465
8466   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8467
8468   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8469     {
8470       rtx set = XVECEXP (operands[2], 0, i);
8471       emit_move_insn (SET_DEST (set), SET_SRC (set));
8472     }
8473
8474   /* The optimizer does not know that the call sets the function value
8475      registers we stored in the result block.  We avoid problems by
8476      claiming that all hard registers are used and clobbered at this
8477      point.  */
8478   emit_insn (gen_blockage ());
8479
8480   DONE;
8481 }")
8482 \f
8483 ;; ------------------------------------------------------------------------
8484 ;; Misc insns
8485 ;; ------------------------------------------------------------------------
8486
8487 (define_insn "dect"
8488   [(set (reg:SI T_REG)
8489         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8490    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8491         (plus:SI (match_dup 1) (const_int -1)))]
8492   "TARGET_SH2"
8493   "dt   %0"
8494   [(set_attr "type" "arith")])
8495
8496 (define_insn "nop"
8497   [(const_int 0)]
8498   ""
8499   "nop")
8500
8501 ;; Load address of a label. This is only generated by the casesi expand,
8502 ;; and by machine_dependent_reorg (fixing up fp moves).
8503 ;; This must use unspec, because this only works for labels that are
8504 ;; within range,
8505
8506 (define_insn "mova"
8507   [(set (reg:SI R0_REG)
8508         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8509   "TARGET_SH1"
8510   "mova %O0,r0"
8511   [(set_attr "in_delay_slot" "no")
8512    (set_attr "type" "arith")])
8513
8514 ;; machine_dependent_reorg will make this a `mova'.
8515 (define_insn "mova_const"
8516   [(set (reg:SI R0_REG)
8517         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8518   "TARGET_SH1"
8519   "#"
8520   [(set_attr "in_delay_slot" "no")
8521    (set_attr "type" "arith")])
8522
8523 (define_expand "GOTaddr2picreg"
8524   [(set (reg:SI R0_REG)
8525         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8526                    UNSPEC_MOVA))
8527    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8528    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8529   "" "
8530 {
8531   if (TARGET_VXWORKS_RTP)
8532     {
8533       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8534       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8535       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8536       DONE;
8537     }
8538
8539   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8540   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8541
8542   if (TARGET_SHMEDIA)
8543     {
8544       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8545       rtx pic = operands[0];
8546       rtx lab = PATTERN (gen_call_site ());
8547       rtx insn, equiv;
8548
8549       equiv = operands[1];
8550       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8551                                     UNSPEC_PCREL_SYMOFF);
8552       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8553
8554       if (Pmode == SImode)
8555         {
8556           emit_insn (gen_movsi_const (pic, operands[1]));
8557           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8558         }
8559       else
8560         {
8561           emit_insn (gen_movdi_const (pic, operands[1]));
8562           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8563         }
8564
8565       insn = emit_move_insn (operands[0], tr);
8566
8567       set_unique_reg_note (insn, REG_EQUAL, equiv);
8568
8569       DONE;
8570     }
8571 }
8572 ")
8573
8574 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8575 ;; PIC register.
8576
8577 (define_expand "vxworks_picreg"
8578   [(set (reg:SI PIC_REG)
8579         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8580    (set (reg:SI R0_REG)
8581         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8582    (set (reg:SI PIC_REG)
8583         (mem:SI (reg:SI PIC_REG)))
8584    (set (reg:SI PIC_REG)
8585         (mem:SI (plus:SI (reg:SI PIC_REG)
8586                          (reg:SI R0_REG))))]
8587   "TARGET_VXWORKS_RTP")
8588
8589 (define_insn "*ptb"
8590   [(set (match_operand 0 "target_reg_operand" "=b")
8591         (const (unspec [(match_operand 1 "" "Csy")]
8592                              UNSPEC_DATALABEL)))]
8593   "TARGET_SHMEDIA && flag_pic
8594    && satisfies_constraint_Csy (operands[1])"
8595   "ptb/u        datalabel %1, %0"
8596   [(set_attr "type" "ptabs_media")
8597    (set_attr "length" "*")])
8598
8599 (define_insn "ptrel_si"
8600   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8601         (plus:SI (match_operand:SI 1 "register_operand" "r")
8602               (pc)))
8603    (match_operand:SI 2 "" "")]
8604   "TARGET_SHMEDIA"
8605   "%O2: ptrel/u %1, %0"
8606   [(set_attr "type" "ptabs_media")])
8607
8608 (define_insn "ptrel_di"
8609   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8610         (plus:DI (match_operand:DI 1 "register_operand" "r")
8611               (pc)))
8612    (match_operand:DI 2 "" "")]
8613   "TARGET_SHMEDIA"
8614   "%O2: ptrel/u %1, %0"
8615   [(set_attr "type" "ptabs_media")])
8616
8617 (define_expand "builtin_setjmp_receiver"
8618   [(match_operand 0 "" "")]
8619   "flag_pic"
8620   "
8621 {
8622   emit_insn (gen_GOTaddr2picreg ());
8623   DONE;
8624 }")
8625
8626 (define_expand "call_site"
8627   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8628   "TARGET_SH1"
8629   "
8630 {
8631   static HOST_WIDE_INT i = 0;
8632   operands[0] = GEN_INT (i);
8633   i++;
8634 }")
8635
8636 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8637 ;; in symGOT_load expand.
8638
8639 (define_insn_and_split "chk_guard_add"
8640   [(set (match_operand:SI 0 "register_operand" "=&r")
8641         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8642                     (reg:SI PIC_REG)]
8643                    UNSPEC_CHKADD))]
8644   "TARGET_SH1"
8645   "#"
8646   "TARGET_SH1 && reload_completed"
8647   [(set (match_dup 0) (reg:SI PIC_REG))
8648    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8649   ""
8650   [(set_attr "type" "arith")])
8651
8652 (define_expand "sym_label2reg"
8653   [(set (match_operand:SI 0 "" "")
8654         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8655                               (const (plus:SI (match_operand:SI 2 "" "")
8656                                               (const_int 2)))]
8657                              UNSPEC_SYMOFF)))]
8658   "TARGET_SH1" "")
8659
8660 (define_expand "symGOT_load"
8661   [(set (match_dup 2) (match_operand 1 "" ""))
8662    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8663    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8664   ""
8665   "
8666 {
8667   rtx mem;
8668
8669   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8670   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8671
8672   if (TARGET_SHMEDIA)
8673     {
8674       rtx reg = operands[2];
8675
8676       if (Pmode == DImode)
8677         {      
8678           if (flag_pic > 1)
8679             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8680           else
8681             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8682         }
8683       else
8684         {
8685           if (flag_pic > 1)
8686             emit_insn (gen_movsi_const (reg, operands[1]));
8687           else
8688             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8689         }
8690     }
8691   else
8692     emit_move_insn (operands[2], operands[1]);
8693
8694   /* When stack protector inserts codes after the result is set to
8695      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8696      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8697      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8698      matter because this is a rare situation.  */
8699   if (!TARGET_SHMEDIA
8700       && flag_stack_protect
8701       && GET_CODE (operands[1]) == CONST
8702       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8703       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8704       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8705                  \"__stack_chk_guard\") == 0)
8706     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8707   else
8708     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8709                                                gen_rtx_REG (Pmode, PIC_REG)));
8710
8711   /* N.B. This is not constant for a GOTPLT relocation.  */
8712   mem = gen_rtx_MEM (Pmode, operands[3]);
8713   MEM_NOTRAP_P (mem) = 1;
8714   /* ??? Should we have a special alias set for the GOT?  */
8715   emit_move_insn (operands[0], mem);
8716
8717   DONE;
8718 }")
8719
8720 (define_expand "sym2GOT"
8721   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8722   ""
8723   "")
8724
8725 (define_expand "symGOT2reg"
8726   [(match_operand 0 "" "") (match_operand 1 "" "")]
8727   ""
8728   "
8729 {
8730   rtx gotsym, insn;
8731
8732   gotsym = gen_sym2GOT (operands[1]);
8733   PUT_MODE (gotsym, Pmode);
8734   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8735
8736   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8737
8738   DONE;
8739 }")
8740
8741 (define_expand "symGOTPLT2reg"
8742   [(match_operand 0 "" "") (match_operand 1 "" "")]
8743   ""
8744   "
8745 {
8746   rtx pltsym = gen_rtx_CONST (Pmode,
8747                               gen_rtx_UNSPEC (Pmode,
8748                                               gen_rtvec (1, operands[1]),
8749                                               UNSPEC_GOTPLT));
8750   emit_insn (gen_symGOT_load (operands[0], pltsym));
8751   DONE;
8752 }")
8753
8754 (define_expand "sym2GOTOFF"
8755   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8756   ""
8757   "")
8758
8759 (define_expand "symGOTOFF2reg"
8760   [(match_operand 0 "" "") (match_operand 1 "" "")]
8761   ""
8762   "
8763 {
8764   rtx gotoffsym, insn;
8765   rtx t = (!can_create_pseudo_p ()
8766            ? operands[0]
8767            : gen_reg_rtx (GET_MODE (operands[0])));
8768
8769   gotoffsym = gen_sym2GOTOFF (operands[1]);
8770   PUT_MODE (gotoffsym, Pmode);
8771   emit_move_insn (t, gotoffsym);
8772   insn = emit_move_insn (operands[0],
8773                          gen_rtx_PLUS (Pmode, t,
8774                                        gen_rtx_REG (Pmode, PIC_REG)));
8775
8776   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8777
8778   DONE;
8779 }")
8780
8781 (define_expand "symPLT_label2reg"
8782   [(set (match_operand:SI 0 "" "")
8783         (const:SI
8784          (unspec:SI
8785           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8786            (const:SI (plus:SI (match_operand:SI 2 "" "")
8787                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8788    ;; Even though the PIC register is not really used by the call
8789    ;; sequence in which this is expanded, the PLT code assumes the PIC
8790    ;; register is set, so we must not skip its initialization.  Since
8791    ;; we only use this expand as part of calling sequences, and never
8792    ;; to take the address of a function, this is the best point to
8793    ;; insert the (use).  Using the PLT to take the address of a
8794    ;; function would be wrong, not only because the PLT entry could
8795    ;; then be called from a function that doesn't initialize the PIC
8796    ;; register to the proper GOT, but also because pointers to the
8797    ;; same function might not compare equal, should they be set by
8798    ;; different shared libraries.
8799    (use (reg:SI PIC_REG))]
8800   "TARGET_SH1"
8801   "")
8802
8803 (define_expand "sym2PIC"
8804   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8805   ""
8806   "")
8807
8808 ;; TLS code generation.
8809 ;; ??? this should be a define_insn_and_split
8810 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8811 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8812 ;; for details.
8813
8814 (define_insn "tls_global_dynamic"
8815   [(set (match_operand:SI 0 "register_operand" "=&z")
8816         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8817                                   UNSPEC_TLSGD))
8818               (const_int 0)))
8819    (use (reg:PSI FPSCR_REG))
8820    (use (reg:SI PIC_REG))
8821    (clobber (reg:SI PR_REG))
8822    (clobber (scratch:SI))]
8823   "TARGET_SH1"
8824   "*
8825 {
8826   return \"\\
8827 mov.l\\t1f,r4\\n\\
8828 \\tmova\\t2f,r0\\n\\
8829 \\tmov.l\\t2f,r1\\n\\
8830 \\tadd\\tr0,r1\\n\\
8831 \\tjsr\\t@r1\\n\\
8832 \\tadd\\tr12,r4\\n\\
8833 \\tbra\\t3f\\n\\
8834 \\tnop\\n\\
8835 \\t.align\\t2\\n\\
8836 1:\\t.long\\t%a1@TLSGD\\n\\
8837 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8838 3:\";
8839 }"
8840   [(set_attr "type" "tls_load")
8841    (set_attr "length" "26")])
8842
8843 (define_insn "tls_local_dynamic"
8844   [(set (match_operand:SI 0 "register_operand" "=&z")
8845         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8846                                   UNSPEC_TLSLDM))
8847               (const_int 0)))
8848    (use (reg:PSI FPSCR_REG))
8849    (use (reg:SI PIC_REG))
8850    (clobber (reg:SI PR_REG))
8851    (clobber (scratch:SI))]
8852   "TARGET_SH1"
8853   "*
8854 {
8855   return \"\\
8856 mov.l\\t1f,r4\\n\\
8857 \\tmova\\t2f,r0\\n\\
8858 \\tmov.l\\t2f,r1\\n\\
8859 \\tadd\\tr0,r1\\n\\
8860 \\tjsr\\t@r1\\n\\
8861 \\tadd\\tr12,r4\\n\\
8862 \\tbra\\t3f\\n\\
8863 \\tnop\\n\\
8864 \\t.align\\t2\\n\\
8865 1:\\t.long\\t%a1@TLSLDM\\n\\
8866 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8867 3:\";
8868 }"
8869   [(set_attr "type" "tls_load")
8870    (set_attr "length" "26")])
8871
8872 (define_expand "sym2DTPOFF"
8873   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8874   ""
8875   "")
8876
8877 (define_expand "symDTPOFF2reg"
8878   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8879   ""
8880   "
8881 {
8882   rtx dtpoffsym;
8883   rtx t = (!can_create_pseudo_p ()
8884            ? operands[0]
8885            : gen_reg_rtx (GET_MODE (operands[0])));
8886
8887   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8888   PUT_MODE (dtpoffsym, Pmode);
8889   emit_move_insn (t, dtpoffsym);
8890   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8891   DONE;
8892 }")
8893
8894 (define_expand "sym2GOTTPOFF"
8895   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8896   ""
8897   "")
8898
8899 (define_insn "tls_initial_exec"
8900   [(set (match_operand:SI 0 "register_operand" "=&r")
8901         (unspec:SI [(match_operand:SI 1 "" "")]
8902                     UNSPEC_TLSIE))
8903    (use (reg:SI GBR_REG))
8904    (use (reg:SI PIC_REG))
8905    (clobber (reg:SI R0_REG))]
8906   ""
8907   "*
8908 {
8909   return \"\\
8910 mov.l\\t1f,r0\\n\\
8911 \\tstc\\tgbr,%0\\n\\
8912 \\tmov.l\\t@(r0,r12),r0\\n\\
8913 \\tbra\\t2f\\n\\
8914 \\tadd\\tr0,%0\\n\\
8915 \\t.align\\t2\\n\\
8916 1:\\t.long\\t%a1\\n\\
8917 2:\";
8918 }"
8919   [(set_attr "type" "tls_load")
8920    (set_attr "length" "16")])
8921
8922 (define_expand "sym2TPOFF"
8923   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8924   ""
8925   "")
8926
8927 (define_expand "symTPOFF2reg"
8928   [(match_operand 0 "" "") (match_operand 1 "" "")]
8929   ""
8930   "
8931 {
8932   rtx tpoffsym;
8933
8934   tpoffsym = gen_sym2TPOFF (operands[1]);
8935   PUT_MODE (tpoffsym, Pmode);
8936   emit_move_insn (operands[0], tpoffsym);
8937   DONE;
8938 }")
8939
8940 (define_insn "load_gbr"
8941   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8942    (use (reg:SI GBR_REG))]
8943   ""
8944   "stc  gbr,%0"
8945   [(set_attr "type" "tls_load")])
8946
8947 ;; case instruction for switch statements.
8948
8949 ;; Operand 0 is index
8950 ;; operand 1 is the minimum bound
8951 ;; operand 2 is the maximum bound - minimum bound + 1
8952 ;; operand 3 is CODE_LABEL for the table;
8953 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8954
8955 (define_expand "casesi"
8956   [(match_operand:SI 0 "arith_reg_operand" "")
8957    (match_operand:SI 1 "arith_reg_operand" "")
8958    (match_operand:SI 2 "arith_reg_operand" "")
8959    (match_operand 3 "" "") (match_operand 4 "" "")]
8960   ""
8961   "
8962 {
8963   rtx reg = gen_reg_rtx (SImode);
8964   rtx reg2 = gen_reg_rtx (SImode);
8965   if (TARGET_SHMEDIA)
8966     {
8967       rtx reg = gen_reg_rtx (DImode);
8968       rtx reg2 = gen_reg_rtx (DImode);
8969       rtx reg3 = gen_reg_rtx (Pmode);
8970       rtx reg4 = gen_reg_rtx (Pmode);
8971       rtx reg5 = gen_reg_rtx (Pmode);
8972       rtx load, test;
8973
8974       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8975       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8976       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8977
8978       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8979       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8980       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8981       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8982       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8983       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8984       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8985                                                (Pmode, operands[3])));
8986       /* Messy: can we subreg to clean this up? */
8987       if (Pmode == DImode)
8988         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8989       else
8990         load = gen_casesi_load_media (reg4,
8991                                       gen_rtx_SUBREG (DImode, reg3, 0),
8992                                       reg2, operands[3]);
8993       PUT_MODE (SET_SRC (load), Pmode);
8994       emit_insn (load);
8995       /* ??? The following add could be eliminated if we used ptrel.  */
8996       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8997       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8998       emit_barrier ();
8999       DONE;
9000     }
9001   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9002   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9003   /* If optimizing, casesi_worker depends on the mode of the instruction
9004      before label it 'uses' - operands[3].  */
9005   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9006                            reg));
9007   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9008   if (TARGET_SH2)
9009     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9010   else
9011     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9012   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9013      operands[3], but to lab.  We will fix this up in
9014      machine_dependent_reorg.  */
9015   emit_barrier ();
9016   DONE;
9017 }")
9018
9019 (define_expand "casesi_0"
9020   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9021    (set (match_dup 4) (minus:SI (match_dup 4)
9022                                 (match_operand:SI 1 "arith_operand" "")))
9023    (set (reg:SI T_REG)
9024         (gtu:SI (match_dup 4)
9025                 (match_operand:SI 2 "arith_reg_operand" "")))
9026    (set (pc)
9027         (if_then_else (ne (reg:SI T_REG)
9028                           (const_int 0))
9029                       (label_ref (match_operand 3 "" ""))
9030                       (pc)))]
9031   "TARGET_SH1"
9032   "")
9033
9034 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9035 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9036 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9037
9038 (define_insn "casesi_worker_0"
9039   [(set (match_operand:SI 0 "register_operand" "=r,r")
9040         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9041                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9042    (clobber (match_scratch:SI 3 "=X,1"))
9043    (clobber (match_scratch:SI 4 "=&z,z"))]
9044   "TARGET_SH1"
9045   "#")
9046
9047 (define_split
9048   [(set (match_operand:SI 0 "register_operand" "")
9049         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9050                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9051    (clobber (match_scratch:SI 3 ""))
9052    (clobber (match_scratch:SI 4 ""))]
9053   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9054   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9055    (parallel [(set (match_dup 0)
9056               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9057                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9058               (clobber (match_dup 3))])
9059    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9060   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9061
9062 (define_split
9063   [(set (match_operand:SI 0 "register_operand" "")
9064         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9065                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9066    (clobber (match_scratch:SI 3 ""))
9067    (clobber (match_scratch:SI 4 ""))]
9068   "TARGET_SH2 && reload_completed"
9069   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9070    (parallel [(set (match_dup 0)
9071               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9072                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9073               (clobber (match_dup 3))])]
9074   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9075
9076 (define_insn "casesi_worker_1"
9077   [(set (match_operand:SI 0 "register_operand" "=r,r")
9078         (unspec:SI [(reg:SI R0_REG)
9079                     (match_operand:SI 1 "register_operand" "0,r")
9080                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9081    (clobber (match_scratch:SI 3 "=X,1"))]
9082   "TARGET_SH1"
9083   "*
9084 {
9085   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9086
9087   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9088
9089   switch (GET_MODE (diff_vec))
9090     {
9091     case SImode:
9092       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9093     case HImode:
9094       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9095     case QImode:
9096       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9097         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9098       return \"mov.b    @(r0,%1),%0\";
9099     default:
9100       gcc_unreachable ();
9101     }
9102 }"
9103   [(set_attr "length" "4")])
9104
9105 (define_insn "casesi_worker_2"
9106   [(set (match_operand:SI 0 "register_operand" "=r,r")
9107         (unspec:SI [(reg:SI R0_REG)
9108                     (match_operand:SI 1 "register_operand" "0,r")
9109                     (label_ref (match_operand 2 "" ""))
9110                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9111    (clobber (match_operand:SI 4 "" "=X,1"))]
9112   "TARGET_SH2 && reload_completed && flag_pic"
9113   "*
9114 {
9115   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9116   const char *load;
9117
9118   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9119
9120   switch (GET_MODE (diff_vec))
9121     {
9122     case SImode:
9123       output_asm_insn (\"shll2    %1\", operands);
9124       load = \"mov.l    @(r0,%1),%0\"; break;
9125     case HImode:
9126       output_asm_insn (\"add    %1,%1\", operands);
9127       load = \"mov.w    @(r0,%1),%0\"; break;
9128     case QImode:
9129       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9130         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9131       else
9132         load = \"mov.b  @(r0,%1),%0\";
9133       break;
9134     default:
9135       gcc_unreachable ();
9136     }
9137   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9138   return load;
9139 }"
9140   [(set_attr "length" "8")])
9141
9142 (define_insn "casesi_shift_media"
9143   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9144         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9145                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9146                     UNSPEC_CASESI)))]
9147   "TARGET_SHMEDIA"
9148   "*
9149 {
9150   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9151
9152   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9153
9154   switch (GET_MODE (diff_vec))
9155     {
9156     case SImode:
9157       return \"shlli    %1, 2, %0\";
9158     case HImode:
9159       return \"shlli    %1, 1, %0\";
9160     case QImode:
9161       if (rtx_equal_p (operands[0], operands[1]))
9162         return \"\";
9163       return \"add      %1, r63, %0\";
9164     default:
9165       gcc_unreachable ();
9166     }
9167 }"
9168   [(set_attr "type" "arith_media")])
9169
9170 (define_insn "casesi_load_media"
9171   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9172         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9173                          (match_operand:DI 2 "arith_reg_operand" "r")
9174                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9175   "TARGET_SHMEDIA"
9176   "*
9177 {
9178   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9179
9180   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9181
9182   switch (GET_MODE (diff_vec))
9183     {
9184     case SImode:
9185       return \"ldx.l    %1, %2, %0\";
9186     case HImode:
9187 #if 0
9188       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9189         return \"ldx.uw %1, %2, %0\";
9190 #endif
9191       return \"ldx.w    %1, %2, %0\";
9192     case QImode:
9193       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9194         return \"ldx.ub %1, %2, %0\";
9195       return \"ldx.b    %1, %2, %0\";
9196     default:
9197       gcc_unreachable ();
9198     }
9199 }"
9200   [(set_attr "type" "load_media")])
9201
9202 (define_expand "return"
9203   [(return)]
9204   "reload_completed && ! sh_need_epilogue ()"
9205   "
9206 {
9207   if (TARGET_SHMEDIA)
9208     {
9209       emit_jump_insn (gen_return_media ());
9210       DONE;
9211     }
9212
9213   if (TARGET_SHCOMPACT
9214       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9215     {
9216       emit_jump_insn (gen_shcompact_return_tramp ());
9217       DONE;
9218     }
9219 }")
9220
9221 (define_insn "*return_i"
9222   [(return)]
9223   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9224                     && (crtl->args.info.call_cookie
9225                         & CALL_COOKIE_RET_TRAMP (1)))
9226    && reload_completed
9227    && lookup_attribute (\"trap_exit\",
9228                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9229   "*
9230   {
9231     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9232                         && !current_function_interrupt)
9233        return \"rts/n\";
9234     else
9235        return \"%@      %#\";
9236   }"
9237   [(set_attr "type" "return")
9238    (set_attr "needs_delay_slot" "yes")])
9239
9240 ;; trapa has no delay slot.
9241 (define_insn "*return_trapa"
9242   [(return)]
9243   "TARGET_SH1 && !TARGET_SHCOMPACT
9244    && reload_completed"
9245   "%@"
9246   [(set_attr "type" "return")])
9247
9248 (define_expand "shcompact_return_tramp"
9249   [(return)]
9250   "TARGET_SHCOMPACT
9251    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9252   "
9253 {
9254   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9255
9256   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9257   emit_jump_insn (gen_shcompact_return_tramp_i ());
9258   DONE;
9259 }")
9260
9261 (define_insn "shcompact_return_tramp_i"
9262   [(parallel [(return) (use (reg:SI R0_REG))])]
9263   "TARGET_SHCOMPACT
9264    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9265   "jmp  @r0%#"
9266   [(set_attr "type" "jump_ind")
9267    (set_attr "needs_delay_slot" "yes")])
9268
9269 (define_insn "return_media_i"
9270   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9271   "TARGET_SHMEDIA && reload_completed"
9272   "blink        %0, r63"
9273   [(set_attr "type" "jump_media")])
9274
9275 (define_insn "return_media_rte"
9276   [(return)]
9277   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9278   "rte"
9279   [(set_attr "type" "jump_media")])
9280
9281 (define_expand "return_media"
9282   [(return)]
9283   "TARGET_SHMEDIA && reload_completed"
9284   "
9285 {
9286   int tr_regno = sh_media_register_for_return ();
9287   rtx tr;
9288
9289   if (current_function_interrupt)
9290     {
9291       emit_jump_insn (gen_return_media_rte ());
9292       DONE;
9293     }
9294   if (tr_regno < 0)
9295     {
9296       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9297
9298       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9299       tr_regno = TR0_REG;
9300       tr = gen_rtx_REG (Pmode, tr_regno);
9301       emit_move_insn (tr, r18);
9302     }
9303   else
9304     tr = gen_rtx_REG (Pmode, tr_regno);
9305
9306   emit_jump_insn (gen_return_media_i (tr));
9307   DONE;
9308 }")
9309
9310 (define_insn "shcompact_preserve_incoming_args"
9311   [(set (match_operand:SI 0 "register_operand" "+r")
9312         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9313   "TARGET_SHCOMPACT"
9314   ""
9315   [(set_attr "length" "0")])
9316
9317 (define_insn "shcompact_incoming_args"
9318   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9319    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9320    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9321    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9322    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9323    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9324    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9325    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9326    (set (mem:BLK (reg:SI MACL_REG))
9327         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9328    (use (reg:SI R0_REG))
9329    (clobber (reg:SI R0_REG))
9330    (clobber (reg:SI MACL_REG))
9331    (clobber (reg:SI MACH_REG))
9332    (clobber (reg:SI PR_REG))]
9333   "TARGET_SHCOMPACT"
9334   "jsr  @r0%#"
9335   [(set_attr "needs_delay_slot" "yes")])
9336
9337 (define_insn "shmedia_save_restore_regs_compact"
9338   [(set (reg:SI SP_REG)
9339         (plus:SI (reg:SI SP_REG)
9340                  (match_operand:SI 0 "immediate_operand" "i")))
9341    (use (reg:SI R0_REG))
9342    (clobber (reg:SI PR_REG))]
9343   "TARGET_SHCOMPACT
9344    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9345        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9346   "jsr @r0%#"
9347   [(set_attr "needs_delay_slot" "yes")])
9348
9349 (define_expand "prologue"
9350   [(const_int 0)]
9351   ""
9352   "sh_expand_prologue (); DONE;")
9353
9354 (define_expand "epilogue"
9355   [(return)]
9356   ""
9357   "
9358 {
9359   sh_expand_epilogue (0);
9360   emit_jump_insn (gen_return ());
9361   DONE;
9362 }")
9363
9364 (define_expand "eh_return"
9365   [(use (match_operand 0 "register_operand" ""))]
9366   ""
9367 {
9368   rtx ra = operands[0];
9369
9370   if (TARGET_SHMEDIA64)
9371     emit_insn (gen_eh_set_ra_di (ra));
9372   else
9373     emit_insn (gen_eh_set_ra_si (ra));
9374
9375   DONE;
9376 })
9377
9378 ;; Clobber the return address on the stack.  We can't expand this
9379 ;; until we know where it will be put in the stack frame.
9380
9381 (define_insn "eh_set_ra_si"
9382   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9383       UNSPECV_EH_RETURN)
9384    (clobber (match_scratch:SI 1 "=&r"))]
9385   "! TARGET_SHMEDIA64"
9386   "#")
9387
9388 (define_insn "eh_set_ra_di"
9389   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9390       UNSPECV_EH_RETURN)
9391    (clobber (match_scratch:DI 1 "=&r"))]
9392   "TARGET_SHMEDIA64"
9393   "#")
9394
9395 (define_split
9396   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9397       UNSPECV_EH_RETURN)
9398    (clobber (match_scratch 1 ""))]
9399   "reload_completed"
9400   [(const_int 0)]
9401   "
9402 {
9403   sh_set_return_address (operands[0], operands[1]);
9404   DONE;
9405 }")
9406
9407 (define_insn "blockage"
9408   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9409   ""
9410   ""
9411   [(set_attr "length" "0")])
9412 \f
9413 ;; Define movml instructions for SH2A target.  Currently they are
9414 ;; used to push and pop all banked registers only.
9415
9416 (define_insn "movml_push_banked"
9417   [(set (match_operand:SI 0 "register_operand" "=r")
9418           (plus (match_dup 0) (const_int -32)))
9419    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9420    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9421    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9422    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9423    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9424    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9425    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9426    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9427   "TARGET_SH2A && REGNO (operands[0]) == 15"
9428   "movml.l\tr7,@-r15"
9429   [(set_attr "in_delay_slot" "no")])
9430
9431 (define_insn "movml_pop_banked"
9432   [(set (match_operand:SI 0 "register_operand" "=r")
9433           (plus (match_dup 0) (const_int 32)))
9434    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9435    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9436    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9437    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9438    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9439    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9440    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9441    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9442   "TARGET_SH2A && REGNO (operands[0]) == 15"
9443   "movml.l\t@r15+,r7"
9444   [(set_attr "in_delay_slot" "no")])
9445 \f
9446 ;; ------------------------------------------------------------------------
9447 ;; Scc instructions
9448 ;; ------------------------------------------------------------------------
9449
9450 (define_insn "movt"
9451   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9452         (eq:SI (reg:SI T_REG) (const_int 1)))]
9453   "TARGET_SH1"
9454   "movt %0"
9455   [(set_attr "type" "arith")])
9456
9457 (define_expand "cstore4_media"
9458   [(set (match_operand:SI 0 "register_operand" "=r")
9459         (match_operator:SI 1 "sh_float_comparison_operator"
9460          [(match_operand 2 "logical_operand" "")
9461           (match_operand 3 "cmp_operand" "")]))]
9462   "TARGET_SHMEDIA"
9463   "
9464 {
9465   enum machine_mode mode = GET_MODE (operands[2]);
9466   enum rtx_code code = GET_CODE (operands[1]);
9467   bool invert, swap;
9468   if (mode == VOIDmode)
9469     mode = GET_MODE (operands[3]);
9470   if (operands[2] == const0_rtx)
9471     {
9472       if (code == EQ || code == NE)
9473         operands[2] = operands[3], operands[3] = const0_rtx;
9474     }
9475   else
9476     operands[2] = force_reg (mode, operands[2]);
9477   if (operands[3] != const0_rtx)
9478     operands[3] = force_reg (mode, operands[3]);
9479
9480   switch (code)
9481     {
9482     case GEU:
9483     case GE:
9484       swap = invert = !FLOAT_MODE_P (mode);
9485       break;
9486
9487     case LEU:
9488     case LE:
9489       swap = FLOAT_MODE_P (mode), invert = !swap;
9490       break;
9491
9492     case LTU:
9493     case LT:
9494       swap = true, invert = false;
9495       break;
9496
9497     case GTU:
9498     case GT:
9499     case EQ:
9500     case UNORDERED:
9501       swap = invert = false;
9502       break;
9503
9504     case NE:
9505       swap = invert = true;
9506       break;
9507
9508     default:
9509       gcc_unreachable ();
9510   }
9511
9512   if (swap)
9513     {
9514       rtx tem = operands[2];
9515       operands[2] = operands[3];
9516       operands[3] = tem;
9517       code = swap_condition (code);
9518     }
9519
9520   if (invert)
9521     {
9522       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9523       code = reverse_condition (code);
9524       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9525       emit_insn (gen_cstore4_media (tem, operands[1],
9526                                     operands[2], operands[3]));
9527       code = EQ;
9528       operands[2] = tem;
9529       operands[3] = const0_rtx;
9530     }
9531
9532   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9533 }")
9534
9535 (define_expand "cstoresi4"
9536   [(set (match_operand:SI 0 "register_operand" "=r")
9537         (match_operator:SI 1 "comparison_operator"
9538          [(match_operand:SI 2 "cmpsi_operand" "")
9539           (match_operand:SI 3 "arith_operand" "")]))]
9540   "TARGET_SH1 || TARGET_SHMEDIA"
9541   "if (TARGET_SHMEDIA)
9542     {
9543       emit_insn (gen_cstore4_media (operands[0], operands[1],
9544                                     operands[2], operands[3]));
9545       DONE;
9546     }
9547
9548    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9549        && sh_expand_t_scc (operands))
9550      DONE;
9551
9552    if (! currently_expanding_to_rtl)
9553      FAIL;
9554    
9555    sh_emit_compare_and_set (operands, SImode);
9556    DONE;
9557 ")
9558
9559 (define_expand "cstoredi4"
9560   [(set (match_operand:SI 0 "register_operand" "=r")
9561         (match_operator:SI 1 "comparison_operator"
9562          [(match_operand:DI 2 "arith_operand" "")
9563           (match_operand:DI 3 "arith_operand" "")]))]
9564   "TARGET_SH2 || TARGET_SHMEDIA"
9565   "if (TARGET_SHMEDIA)
9566     {
9567       emit_insn (gen_cstore4_media (operands[0], operands[1],
9568                                     operands[2], operands[3]));
9569       DONE;
9570     }
9571
9572    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9573        && sh_expand_t_scc (operands))
9574      DONE;
9575
9576    if (! currently_expanding_to_rtl)
9577      FAIL;
9578    
9579    sh_emit_compare_and_set (operands, DImode);
9580    DONE;
9581 ")
9582
9583 ;; sne moves the complement of the T reg to DEST like this:
9584 ;;      cmp/eq ...
9585 ;;      mov    #-1,temp
9586 ;;      negc   temp,dest
9587 ;;   This is better than xoring compare result with 1 because it does
9588 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9589 ;;   loop.
9590
9591 (define_expand "movnegt"
9592   [(set (match_dup 1) (const_int -1))
9593    (parallel [(set (match_operand:SI 0 "" "")
9594                    (neg:SI (plus:SI (reg:SI T_REG)
9595                                     (match_dup 1))))
9596               (set (reg:SI T_REG)
9597                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9598                           (const_int 0)))])]
9599   ""
9600   "
9601 {
9602   operands[1] = gen_reg_rtx (SImode);
9603 }")
9604
9605 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9606 ;; This prevents a regression that occurred when we switched from xor to
9607 ;; mov/neg for sne.
9608
9609 (define_split
9610   [(set (match_operand:SI 0 "arith_reg_dest" "")
9611         (plus:SI (reg:SI T_REG)
9612                  (const_int -1)))]
9613   "TARGET_SH1"
9614   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9615    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9616   "")
9617
9618 (define_expand "cstoresf4"
9619   [(set (match_operand:SI 0 "register_operand" "=r")
9620         (match_operator:SI 1 "sh_float_comparison_operator"
9621          [(match_operand:SF 2 "arith_operand" "")
9622           (match_operand:SF 3 "arith_operand" "")]))]
9623   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9624   "if (TARGET_SHMEDIA)
9625      {
9626        emit_insn (gen_cstore4_media (operands[0], operands[1],
9627                                      operands[2], operands[3]));
9628        DONE;
9629      }
9630
9631    if (! currently_expanding_to_rtl)
9632      FAIL;
9633    
9634    sh_emit_compare_and_set (operands, SFmode);
9635    DONE;
9636 ")
9637
9638 (define_expand "cstoredf4"
9639   [(set (match_operand:SI 0 "register_operand" "=r")
9640         (match_operator:SI 1 "sh_float_comparison_operator"
9641          [(match_operand:DF 2 "arith_operand" "")
9642           (match_operand:DF 3 "arith_operand" "")]))]
9643   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9644   "if (TARGET_SHMEDIA)
9645      {
9646        emit_insn (gen_cstore4_media (operands[0], operands[1],
9647                                      operands[2], operands[3]));
9648        DONE;
9649      }
9650
9651     if (! currently_expanding_to_rtl)
9652       FAIL;
9653    
9654    sh_emit_compare_and_set (operands, DFmode);
9655    DONE;
9656 ")
9657
9658 ;; -------------------------------------------------------------------------
9659 ;; Instructions to cope with inline literal tables
9660 ;; -------------------------------------------------------------------------
9661
9662 ; 2 byte integer in line
9663
9664 (define_insn "consttable_2"
9665  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9666                     (match_operand 1 "" "")]
9667                    UNSPECV_CONST2)]
9668  ""
9669  "*
9670 {
9671   if (operands[1] != const0_rtx)
9672     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9673   return \"\";
9674 }"
9675  [(set_attr "length" "2")
9676  (set_attr "in_delay_slot" "no")])
9677
9678 ; 4 byte integer in line
9679
9680 (define_insn "consttable_4"
9681  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9682                     (match_operand 1 "" "")]
9683                    UNSPECV_CONST4)]
9684  ""
9685  "*
9686 {
9687   if (operands[1] != const0_rtx)
9688     {
9689       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9690       mark_symbol_refs_as_used (operands[0]);
9691     }
9692   return \"\";
9693 }"
9694  [(set_attr "length" "4")
9695   (set_attr "in_delay_slot" "no")])
9696
9697 ; 8 byte integer in line
9698
9699 (define_insn "consttable_8"
9700  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9701                     (match_operand 1 "" "")]
9702                    UNSPECV_CONST8)]
9703  ""
9704  "*
9705 {
9706   if (operands[1] != const0_rtx)
9707     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9708   return \"\";
9709 }"
9710  [(set_attr "length" "8")
9711   (set_attr "in_delay_slot" "no")])
9712
9713 ; 4 byte floating point
9714
9715 (define_insn "consttable_sf"
9716  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9717                     (match_operand 1 "" "")]
9718                    UNSPECV_CONST4)]
9719  ""
9720  "*
9721 {
9722   if (operands[1] != const0_rtx)
9723     {
9724       REAL_VALUE_TYPE d;
9725       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9726       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9727     }
9728   return \"\";
9729 }"
9730  [(set_attr "length" "4")
9731   (set_attr "in_delay_slot" "no")])
9732
9733 ; 8 byte floating point
9734
9735 (define_insn "consttable_df"
9736  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9737                     (match_operand 1 "" "")]
9738                    UNSPECV_CONST8)]
9739  ""
9740  "*
9741 {
9742   if (operands[1] != const0_rtx)
9743     {
9744       REAL_VALUE_TYPE d;
9745       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9746       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9747     }
9748   return \"\";
9749 }"
9750  [(set_attr "length" "8")
9751   (set_attr "in_delay_slot" "no")])
9752
9753 ;; Alignment is needed for some constant tables; it may also be added for
9754 ;; Instructions at the start of loops, or after unconditional branches.
9755 ;; ??? We would get more accurate lengths if we did instruction
9756 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9757 ;; here is too conservative.
9758
9759 ; align to a two byte boundary
9760
9761 (define_expand "align_2"
9762  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9763  ""
9764  "")
9765
9766 ; align to a four byte boundary
9767 ;; align_4 and align_log are instructions for the starts of loops, or
9768 ;; after unconditional branches, which may take up extra room.
9769
9770 (define_expand "align_4"
9771  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9772  ""
9773  "")
9774
9775 ; align to a cache line boundary
9776
9777 (define_insn "align_log"
9778  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9779  ""
9780  ""
9781  [(set_attr "length" "0")
9782   (set_attr "in_delay_slot" "no")])
9783
9784 ; emitted at the end of the literal table, used to emit the
9785 ; 32bit branch labels if needed.
9786
9787 (define_insn "consttable_end"
9788   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9789   ""
9790   "* return output_jump_label_table ();"
9791   [(set_attr "in_delay_slot" "no")])
9792
9793 ; emitted at the end of the window in the literal table.
9794
9795 (define_insn "consttable_window_end"
9796   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9797   ""
9798   ""
9799   [(set_attr "length" "0")
9800    (set_attr "in_delay_slot" "no")])
9801
9802 ;; -------------------------------------------------------------------------
9803 ;; Misc
9804 ;; -------------------------------------------------------------------------
9805
9806 ;; String/block move insn.
9807
9808 (define_expand "movmemsi"
9809   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9810                    (mem:BLK (match_operand:BLK 1 "" "")))
9811               (use (match_operand:SI 2 "nonmemory_operand" ""))
9812               (use (match_operand:SI 3 "immediate_operand" ""))
9813               (clobber (reg:SI PR_REG))
9814               (clobber (reg:SI R4_REG))
9815               (clobber (reg:SI R5_REG))
9816               (clobber (reg:SI R0_REG))])]
9817   "TARGET_SH1 && ! TARGET_SH5"
9818   "
9819 {
9820   if(expand_block_move (operands))
9821      DONE;
9822   else FAIL;
9823 }")
9824
9825 (define_insn "block_move_real"
9826   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9827                    (mem:BLK (reg:SI R5_REG)))
9828               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9829               (clobber (reg:SI PR_REG))
9830               (clobber (reg:SI R0_REG))])]
9831   "TARGET_SH1 && ! TARGET_HARD_SH4"
9832   "jsr  @%0%#"
9833   [(set_attr "type" "sfunc")
9834    (set_attr "needs_delay_slot" "yes")])
9835
9836 (define_insn "block_lump_real"
9837   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9838                    (mem:BLK (reg:SI R5_REG)))
9839               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9840               (use (reg:SI R6_REG))
9841               (clobber (reg:SI PR_REG))
9842               (clobber (reg:SI T_REG))
9843               (clobber (reg:SI R4_REG))
9844               (clobber (reg:SI R5_REG))
9845               (clobber (reg:SI R6_REG))
9846               (clobber (reg:SI R0_REG))])]
9847   "TARGET_SH1 && ! TARGET_HARD_SH4"
9848   "jsr  @%0%#"
9849   [(set_attr "type" "sfunc")
9850    (set_attr "needs_delay_slot" "yes")])
9851
9852 (define_insn "block_move_real_i4"
9853   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9854                    (mem:BLK (reg:SI R5_REG)))
9855               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9856               (clobber (reg:SI PR_REG))
9857               (clobber (reg:SI R0_REG))
9858               (clobber (reg:SI R1_REG))
9859               (clobber (reg:SI R2_REG))])]
9860   "TARGET_HARD_SH4"
9861   "jsr  @%0%#"
9862   [(set_attr "type" "sfunc")
9863    (set_attr "needs_delay_slot" "yes")])
9864
9865 (define_insn "block_lump_real_i4"
9866   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9867                    (mem:BLK (reg:SI R5_REG)))
9868               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9869               (use (reg:SI R6_REG))
9870               (clobber (reg:SI PR_REG))
9871               (clobber (reg:SI T_REG))
9872               (clobber (reg:SI R4_REG))
9873               (clobber (reg:SI R5_REG))
9874               (clobber (reg:SI R6_REG))
9875               (clobber (reg:SI R0_REG))
9876               (clobber (reg:SI R1_REG))
9877               (clobber (reg:SI R2_REG))
9878               (clobber (reg:SI R3_REG))])]
9879   "TARGET_HARD_SH4"
9880   "jsr  @%0%#"
9881   [(set_attr "type" "sfunc")
9882    (set_attr "needs_delay_slot" "yes")])
9883 \f
9884 ;; -------------------------------------------------------------------------
9885 ;; Floating point instructions.
9886 ;; -------------------------------------------------------------------------
9887
9888 ;; ??? All patterns should have a type attribute.
9889
9890 (define_expand "movpsi"
9891   [(set (match_operand:PSI 0 "register_operand" "")
9892         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9893   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9894   "")
9895
9896 ;; The c / m alternative is a fake to guide reload to load directly into
9897 ;; fpscr, since reload doesn't know how to use post-increment.
9898 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9899 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9900 ;; predicate after reload.
9901 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9902 ;; like a mac -> gpr move.
9903 (define_insn "fpu_switch"
9904   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9905         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9906   "TARGET_SH2E
9907    && (! reload_completed
9908        || true_regnum (operands[0]) != FPSCR_REG
9909        || !MEM_P (operands[1])
9910        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9911   "@
9912         ! precision stays the same
9913         lds.l   %1,fpscr
9914         mov.l   %1,%0
9915         #
9916         lds     %1,fpscr
9917         mov     %1,%0
9918         mov.l   %1,%0
9919         sts     fpscr,%0
9920         sts.l   fpscr,%0"
9921   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9922    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9923
9924 (define_peephole2
9925   [(set (reg:PSI FPSCR_REG)
9926         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9927   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9928   [(const_int 0)]
9929 {
9930   rtx fpscr, mem, new_insn;
9931
9932   fpscr = SET_DEST (PATTERN (curr_insn));
9933   mem = SET_SRC (PATTERN (curr_insn));
9934   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9935
9936   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9937   add_reg_note (new_insn, REG_INC, operands[0]);
9938   DONE;
9939 })
9940
9941 (define_split
9942   [(set (reg:PSI FPSCR_REG)
9943         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9944   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9945    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9946   [(const_int 0)]
9947 {
9948   rtx fpscr, mem, new_insn;
9949
9950   fpscr = SET_DEST (PATTERN (curr_insn));
9951   mem = SET_SRC (PATTERN (curr_insn));
9952   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9953
9954   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9955   add_reg_note (new_insn, REG_INC, operands[0]);
9956
9957   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9958     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9959   DONE;
9960 })
9961
9962 ;; ??? This uses the fp unit, but has no type indicating that.
9963 ;; If we did that, this would either give a bogus latency or introduce
9964 ;; a bogus FIFO constraint.
9965 ;; Since this insn is currently only used for prologues/epilogues,
9966 ;; it is probably best to claim no function unit, which matches the
9967 ;; current setting.
9968 (define_insn "toggle_sz"
9969   [(set (reg:PSI FPSCR_REG)
9970         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9971   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9972   "fschg"
9973   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9974
9975 ;; There's no way we can use it today, since optimize mode switching
9976 ;; doesn't enable us to know from which mode we're switching to the
9977 ;; mode it requests, to tell whether we can use a relative mode switch
9978 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9979 ;; memory).
9980 (define_insn "toggle_pr"
9981   [(set (reg:PSI FPSCR_REG)
9982         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9983   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9984   "fpchg"
9985   [(set_attr "type" "fpscr_toggle")])
9986
9987 (define_expand "addsf3"
9988   [(set (match_operand:SF 0 "arith_reg_operand" "")
9989         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9990                  (match_operand:SF 2 "arith_reg_operand" "")))]
9991   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9992   "
9993 {
9994   if (TARGET_SH2E)
9995     {
9996       expand_sf_binop (&gen_addsf3_i, operands);
9997       DONE;
9998     }
9999 }")
10000
10001 (define_insn "*addsf3_media"
10002   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10003         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10004                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10005   "TARGET_SHMEDIA_FPU"
10006   "fadd.s       %1, %2, %0"
10007   [(set_attr "type" "fparith_media")])
10008
10009 (define_insn_and_split "unary_sf_op"
10010   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10011         (vec_select:V2SF
10012          (vec_concat:V2SF
10013           (vec_select:SF
10014            (match_dup 0)
10015            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10016           (match_operator:SF 2 "unary_float_operator"
10017             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10018                             (parallel [(match_operand 4
10019                                         "const_int_operand" "n")]))]))
10020          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10021   "TARGET_SHMEDIA_FPU"
10022   "#"
10023   "TARGET_SHMEDIA_FPU && reload_completed"
10024   [(set (match_dup 5) (match_dup 6))]
10025   "
10026 {
10027   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10028   rtx op1 = gen_rtx_REG (SFmode,
10029                          (true_regnum (operands[1])
10030                           + (INTVAL (operands[4]) ^ endian)));
10031
10032   operands[7] = gen_rtx_REG (SFmode,
10033                              (true_regnum (operands[0])
10034                               + (INTVAL (operands[3]) ^ endian)));
10035   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10036 }"
10037   [(set_attr "type" "fparith_media")])
10038
10039 (define_insn_and_split "binary_sf_op0"
10040   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10041         (vec_concat:V2SF
10042           (match_operator:SF 3 "binary_float_operator"
10043             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10044                             (parallel [(const_int 0)]))
10045              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10046                             (parallel [(const_int 0)]))])
10047           (vec_select:SF
10048            (match_dup 0)
10049            (parallel [(const_int 1)]))))]
10050   "TARGET_SHMEDIA_FPU"
10051   "#"
10052   "&& reload_completed"
10053   [(set (match_dup 4) (match_dup 5))]
10054   "
10055 {
10056   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10057   rtx op1 = gen_rtx_REG (SFmode,
10058                          true_regnum (operands[1]) + endian);
10059   rtx op2 = gen_rtx_REG (SFmode,
10060                          true_regnum (operands[2]) + endian);
10061
10062   operands[4] = gen_rtx_REG (SFmode,
10063                              true_regnum (operands[0]) + endian);
10064   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10065 }"
10066   [(set_attr "type" "fparith_media")])
10067
10068 (define_insn_and_split "binary_sf_op1"
10069   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10070         (vec_concat:V2SF
10071           (vec_select:SF
10072            (match_dup 0)
10073            (parallel [(const_int 0)]))
10074           (match_operator:SF 3 "binary_float_operator"
10075             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10076                             (parallel [(const_int 1)]))
10077              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10078                             (parallel [(const_int 1)]))])))]
10079   "TARGET_SHMEDIA_FPU"
10080   "#"
10081   "&& reload_completed"
10082   [(set (match_dup 4) (match_dup 5))]
10083   "
10084 {
10085   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10086   rtx op1 = gen_rtx_REG (SFmode,
10087                          true_regnum (operands[1]) + (1 ^ endian));
10088   rtx op2 = gen_rtx_REG (SFmode,
10089                          true_regnum (operands[2]) + (1 ^ endian));
10090
10091   operands[4] = gen_rtx_REG (SFmode,
10092                              true_regnum (operands[0]) + (1 ^ endian));
10093   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10094 }"
10095   [(set_attr "type" "fparith_media")])
10096
10097 (define_insn "addsf3_i"
10098   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10099         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10100                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10101    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10102   "TARGET_SH2E"
10103   "fadd %2,%0"
10104   [(set_attr "type" "fp")
10105    (set_attr "fp_mode" "single")])
10106
10107 (define_expand "subsf3"
10108   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10109         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10110                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10111   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10112   "
10113 {
10114   if (TARGET_SH2E)
10115     {
10116       expand_sf_binop (&gen_subsf3_i, operands);
10117       DONE;
10118     }
10119 }")
10120
10121 (define_insn "*subsf3_media"
10122   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10123         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10124                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10125   "TARGET_SHMEDIA_FPU"
10126   "fsub.s       %1, %2, %0"
10127   [(set_attr "type" "fparith_media")])
10128
10129 (define_insn "subsf3_i"
10130   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10131         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10132                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10133    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10134   "TARGET_SH2E"
10135   "fsub %2,%0"
10136   [(set_attr "type" "fp")
10137    (set_attr "fp_mode" "single")])
10138
10139 (define_expand "mulsf3"
10140   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10141         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10142                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10143   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10144   "")
10145
10146 (define_insn "*mulsf3_media"
10147   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10148         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10149                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10150   "TARGET_SHMEDIA_FPU"
10151   "fmul.s       %1, %2, %0"
10152   [(set_attr "type" "fparith_media")])
10153
10154 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10155 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10156 ;; we start out with a mulsf pattern that does not depend on fpscr.
10157 ;; This is split after combine to introduce the dependency, in order to
10158 ;; get mode switching and scheduling right.
10159 (define_insn_and_split "mulsf3_ie"
10160   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10161         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10162                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10163   "TARGET_SH2E"
10164   "fmul %2,%0"
10165   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10166   [(const_int 0)]
10167   "
10168 {
10169   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10170              get_fpscr_rtx ()));
10171   DONE;
10172 }"
10173   [(set_attr "type" "fp")])
10174
10175 (define_insn "mulsf3_i4"
10176   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10177         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10178                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10179    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10180   "TARGET_SH2E"
10181   "fmul %2,%0"
10182   [(set_attr "type" "fp")
10183    (set_attr "fp_mode" "single")])
10184
10185 (define_insn "mac_media"
10186   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10187         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10188                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10189                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10190   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10191   "fmac.s %1, %2, %0"
10192   [(set_attr "type" "fparith_media")])
10193
10194 (define_insn "*macsf3"
10195   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10196         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10197                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10198                  (match_operand:SF 3 "arith_reg_operand" "0")))
10199    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10200   "TARGET_SH2E && TARGET_FMAC"
10201   "fmac fr0,%2,%0"
10202   [(set_attr "type" "fp")
10203    (set_attr "fp_mode" "single")])
10204
10205 (define_expand "divsf3"
10206   [(set (match_operand:SF 0 "arith_reg_operand" "")
10207         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10208                 (match_operand:SF 2 "arith_reg_operand" "")))]
10209   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10210   "
10211 {
10212   if (TARGET_SH2E)
10213     {
10214       expand_sf_binop (&gen_divsf3_i, operands);
10215       DONE;
10216     }
10217 }")
10218
10219 (define_insn "*divsf3_media"
10220   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10221         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10222                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10223   "TARGET_SHMEDIA_FPU"
10224   "fdiv.s       %1, %2, %0"
10225   [(set_attr "type" "fdiv_media")])
10226
10227 (define_insn "divsf3_i"
10228   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10229         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10230                  (match_operand:SF 2 "arith_reg_operand" "f")))
10231    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10232   "TARGET_SH2E"
10233   "fdiv %2,%0"
10234   [(set_attr "type" "fdiv")
10235    (set_attr "fp_mode" "single")])
10236
10237 (define_insn "floatdisf2"
10238   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10239         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10240   "TARGET_SHMEDIA_FPU"
10241   "float.qs %1, %0"
10242   [(set_attr "type" "fpconv_media")])
10243
10244 (define_expand "floatsisf2"
10245   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10246         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10247   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10248   "
10249 {
10250   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10251     {
10252       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10253       DONE;
10254     }
10255 }")
10256
10257 (define_insn "*floatsisf2_media"
10258   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10259         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10260   "TARGET_SHMEDIA_FPU"
10261   "float.ls     %1, %0"
10262   [(set_attr "type" "fpconv_media")])
10263
10264 (define_insn "floatsisf2_i4"
10265   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10266         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10267    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10268   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10269   "float        %1,%0"
10270   [(set_attr "type" "fp")
10271    (set_attr "fp_mode" "single")])
10272
10273 (define_insn "*floatsisf2_ie"
10274   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10275         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10276   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10277   "float        %1,%0"
10278   [(set_attr "type" "fp")])
10279
10280 (define_insn "fix_truncsfdi2"
10281   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10282         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10283   "TARGET_SHMEDIA_FPU"
10284   "ftrc.sq %1, %0"
10285   [(set_attr "type" "fpconv_media")])
10286
10287 (define_expand "fix_truncsfsi2"
10288   [(set (match_operand:SI 0 "fpul_operand" "=y")
10289         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10290   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10291   "
10292 {
10293   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10294     {
10295       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10296       DONE;
10297     }
10298 }")
10299
10300 (define_insn "*fix_truncsfsi2_media"
10301   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10302         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10303   "TARGET_SHMEDIA_FPU"
10304   "ftrc.sl      %1, %0"
10305   [(set_attr "type" "fpconv_media")])
10306
10307 (define_insn "fix_truncsfsi2_i4"
10308   [(set (match_operand:SI 0 "fpul_operand" "=y")
10309         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10310    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10311   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10312   "ftrc %1,%0"
10313   [(set_attr "type" "ftrc_s")
10314    (set_attr "fp_mode" "single")])
10315
10316 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10317 ;; fix_truncsfsi2_i4.
10318 ;; (define_insn "fix_truncsfsi2_i4_2"
10319 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10320 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10321 ;;   (use (reg:PSI FPSCR_REG))
10322 ;;   (clobber (reg:SI FPUL_REG))]
10323 ;;  "TARGET_SH4"
10324 ;;  "#"
10325 ;;  [(set_attr "length" "4")
10326 ;;   (set_attr "fp_mode" "single")])
10327
10328 ;;(define_split
10329 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10330 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10331 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10332 ;;   (clobber (reg:SI FPUL_REG))]
10333 ;;  "TARGET_SH4"
10334 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10335 ;;            (use (match_dup 2))])
10336 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10337
10338 (define_insn "*fixsfsi"
10339   [(set (match_operand:SI 0 "fpul_operand" "=y")
10340         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10341   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10342   "ftrc %1,%0"
10343   [(set_attr "type" "fp")])
10344
10345 (define_insn "cmpgtsf_t"
10346   [(set (reg:SI T_REG)
10347         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10348                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10349   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10350   "fcmp/gt      %1,%0"
10351   [(set_attr "type" "fp_cmp")
10352    (set_attr "fp_mode" "single")])
10353
10354 (define_insn "cmpeqsf_t"
10355   [(set (reg:SI T_REG)
10356         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10357                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10358   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10359   "fcmp/eq      %1,%0"
10360   [(set_attr "type" "fp_cmp")
10361    (set_attr "fp_mode" "single")])
10362
10363 (define_insn "ieee_ccmpeqsf_t"
10364   [(set (reg:SI T_REG)
10365         (ior:SI (reg:SI T_REG)
10366                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10367                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10368   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10369   "* return output_ieee_ccmpeq (insn, operands);"
10370   [(set_attr "length" "4")])
10371
10372
10373 (define_insn "cmpgtsf_t_i4"
10374   [(set (reg:SI T_REG)
10375         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10376                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10377    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10378   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10379   "fcmp/gt      %1,%0"
10380   [(set_attr "type" "fp_cmp")
10381    (set_attr "fp_mode" "single")])
10382
10383 (define_insn "cmpeqsf_t_i4"
10384   [(set (reg:SI T_REG)
10385         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10386                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10387    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10388   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10389   "fcmp/eq      %1,%0"
10390   [(set_attr "type" "fp_cmp")
10391    (set_attr "fp_mode" "single")])
10392
10393 (define_insn "*ieee_ccmpeqsf_t_4"
10394   [(set (reg:SI T_REG)
10395         (ior:SI (reg:SI T_REG)
10396                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10397                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10398    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10399   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10400   "* return output_ieee_ccmpeq (insn, operands);"
10401   [(set_attr "length" "4")
10402    (set_attr "fp_mode" "single")])
10403
10404 (define_insn "cmpeqsf_media"
10405   [(set (match_operand:SI 0 "register_operand" "=r")
10406         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10407                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10408   "TARGET_SHMEDIA_FPU"
10409   "fcmpeq.s     %1, %2, %0"
10410   [(set_attr "type" "fcmp_media")])
10411
10412 (define_insn "cmpgtsf_media"
10413   [(set (match_operand:SI 0 "register_operand" "=r")
10414         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10415                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10416   "TARGET_SHMEDIA_FPU"
10417   "fcmpgt.s     %1, %2, %0"
10418   [(set_attr "type" "fcmp_media")])
10419
10420 (define_insn "cmpgesf_media"
10421   [(set (match_operand:SI 0 "register_operand" "=r")
10422         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10423                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10424   "TARGET_SHMEDIA_FPU"
10425   "fcmpge.s     %1, %2, %0"
10426   [(set_attr "type" "fcmp_media")])
10427
10428 (define_insn "cmpunsf_media"
10429   [(set (match_operand:SI 0 "register_operand" "=r")
10430         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10431                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10432   "TARGET_SHMEDIA_FPU"
10433   "fcmpun.s     %1, %2, %0"
10434   [(set_attr "type" "fcmp_media")])
10435
10436 (define_expand "cbranchsf4"
10437   [(set (pc)
10438         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10439                        [(match_operand:SF 1 "arith_operand" "")
10440                         (match_operand:SF 2 "arith_operand" "")])
10441                       (match_operand 3 "" "")
10442                       (pc)))]
10443   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10444   "
10445 {
10446   if (TARGET_SHMEDIA)
10447     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10448                                           operands[3]));
10449   else
10450     sh_emit_compare_and_branch (operands, SFmode);
10451   DONE;
10452 }")
10453
10454 (define_expand "negsf2"
10455   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10456         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10457   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10458   "
10459 {
10460   if (TARGET_SH2E)
10461     {
10462       expand_sf_unop (&gen_negsf2_i, operands);
10463       DONE;
10464     }
10465 }")
10466
10467 (define_insn "*negsf2_media"
10468   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10469         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10470   "TARGET_SHMEDIA_FPU"
10471   "fneg.s       %1, %0"
10472   [(set_attr "type" "fmove_media")])
10473
10474 (define_insn "negsf2_i"
10475   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10476         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10477    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10478   "TARGET_SH2E"
10479   "fneg %0"
10480   [(set_attr "type" "fmove")
10481    (set_attr "fp_mode" "single")])
10482
10483 (define_expand "sqrtsf2"
10484   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10485         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10486   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10487   "
10488 {
10489   if (TARGET_SH3E)
10490     {
10491       expand_sf_unop (&gen_sqrtsf2_i, operands);
10492       DONE;
10493     }
10494 }")
10495
10496 (define_insn "*sqrtsf2_media"
10497   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10498         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10499   "TARGET_SHMEDIA_FPU"
10500   "fsqrt.s      %1, %0"
10501   [(set_attr "type" "fdiv_media")])
10502
10503 (define_insn "sqrtsf2_i"
10504   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10505         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10506    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10507   "TARGET_SH3E"
10508   "fsqrt        %0"
10509   [(set_attr "type" "fdiv")
10510    (set_attr "fp_mode" "single")])
10511
10512 (define_insn "rsqrtsf2"
10513   [(set (match_operand:SF 0 "register_operand" "=f")
10514         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10515                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10516    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10517   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10518    && operands[1] == CONST1_RTX (SFmode)"
10519   "fsrra        %0"
10520   [(set_attr "type" "fsrra")
10521    (set_attr "fp_mode" "single")])
10522
10523 (define_insn "fsca"
10524   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10525         (vec_concat:V2SF
10526          (unspec:SF [(mult:SF
10527                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10528                       (match_operand:SF 2 "immediate_operand" "i"))
10529                     ] UNSPEC_FSINA)
10530          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10531                     ] UNSPEC_FCOSA)))
10532    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10533   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10534    && operands[2] == sh_fsca_int2sf ()"
10535   "fsca fpul,%d0"
10536   [(set_attr "type" "fsca")
10537    (set_attr "fp_mode" "single")])
10538
10539 (define_expand "sinsf2"
10540   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10541         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10542                    UNSPEC_FSINA))]
10543   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10544   "
10545 {
10546   rtx scaled = gen_reg_rtx (SFmode);
10547   rtx truncated = gen_reg_rtx (SImode);
10548   rtx fsca = gen_reg_rtx (V2SFmode);
10549   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10550
10551   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10552   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10553   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10554                           get_fpscr_rtx ()));
10555   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10556   DONE;
10557 }")
10558
10559 (define_expand "cossf2"
10560   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10561         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10562                    UNSPEC_FCOSA))]
10563   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10564   "
10565 {
10566   rtx scaled = gen_reg_rtx (SFmode);
10567   rtx truncated = gen_reg_rtx (SImode);
10568   rtx fsca = gen_reg_rtx (V2SFmode);
10569   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10570
10571   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10572   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10573   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10574                           get_fpscr_rtx ()));
10575   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10576   DONE;
10577 }")
10578
10579 (define_expand "sindf2"
10580   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10581         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10582                    UNSPEC_FSINA))]
10583   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10584   "
10585 {
10586   rtx scaled = gen_reg_rtx (DFmode);
10587   rtx truncated = gen_reg_rtx (SImode);
10588   rtx fsca = gen_reg_rtx (V2SFmode);
10589   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10590   rtx sfresult = gen_reg_rtx (SFmode);
10591
10592   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10593   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10594   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10595                           get_fpscr_rtx ()));
10596   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10597   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10598   DONE;
10599 }")
10600
10601 (define_expand "cosdf2"
10602   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10603         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10604                    UNSPEC_FCOSA))]
10605   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10606   "
10607 {
10608   rtx scaled = gen_reg_rtx (DFmode);
10609   rtx truncated = gen_reg_rtx (SImode);
10610   rtx fsca = gen_reg_rtx (V2SFmode);
10611   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10612   rtx sfresult = gen_reg_rtx (SFmode);
10613
10614   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10615   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10616   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10617                           get_fpscr_rtx ()));
10618   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10619   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10620   DONE;
10621 }")
10622
10623 (define_expand "abssf2"
10624   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10625         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10626   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10627   "
10628 {
10629   if (TARGET_SH2E)
10630     {
10631       expand_sf_unop (&gen_abssf2_i, operands);
10632       DONE;
10633     }
10634 }")
10635
10636 (define_insn "*abssf2_media"
10637   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10638         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10639   "TARGET_SHMEDIA_FPU"
10640   "fabs.s       %1, %0"
10641   [(set_attr "type" "fmove_media")])
10642
10643 (define_insn "abssf2_i"
10644   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10645         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10646    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10647   "TARGET_SH2E"
10648   "fabs %0"
10649   [(set_attr "type" "fmove")
10650    (set_attr "fp_mode" "single")])
10651
10652 (define_expand "adddf3"
10653   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10654         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10655                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10656   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10657   "
10658 {
10659   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10660     {
10661       expand_df_binop (&gen_adddf3_i, operands);
10662       DONE;
10663     }
10664 }")
10665
10666 (define_insn "*adddf3_media"
10667   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10668         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10669                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10670   "TARGET_SHMEDIA_FPU"
10671   "fadd.d       %1, %2, %0"
10672   [(set_attr "type" "dfparith_media")])
10673
10674 (define_insn "adddf3_i"
10675   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10676         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10677                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10678    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10679   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10680   "fadd %2,%0"
10681   [(set_attr "type" "dfp_arith")
10682    (set_attr "fp_mode" "double")])
10683
10684 (define_expand "subdf3"
10685   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10686         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10687                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10688   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10689   "
10690 {
10691   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10692     {
10693       expand_df_binop (&gen_subdf3_i, operands);
10694       DONE;
10695     }
10696 }")
10697
10698 (define_insn "*subdf3_media"
10699   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10700         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10701                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10702   "TARGET_SHMEDIA_FPU"
10703   "fsub.d       %1, %2, %0"
10704   [(set_attr "type" "dfparith_media")])
10705
10706 (define_insn "subdf3_i"
10707   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10708         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10709                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10710    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10711   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10712   "fsub %2,%0"
10713   [(set_attr "type" "dfp_arith")
10714    (set_attr "fp_mode" "double")])
10715
10716 (define_expand "muldf3"
10717   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10718         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10719                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10720   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10721   "
10722 {
10723   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10724     {
10725       expand_df_binop (&gen_muldf3_i, operands);
10726       DONE;
10727     }
10728 }")
10729
10730 (define_insn "*muldf3_media"
10731   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10732         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10733                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10734   "TARGET_SHMEDIA_FPU"
10735   "fmul.d       %1, %2, %0"
10736   [(set_attr "type" "dfmul_media")])
10737
10738 (define_insn "muldf3_i"
10739   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10740         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10741                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10742    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10743   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10744   "fmul %2,%0"
10745   [(set_attr "type" "dfp_mul")
10746    (set_attr "fp_mode" "double")])
10747
10748 (define_expand "divdf3"
10749   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10750         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10751                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10752   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10753   "
10754 {
10755   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10756     {
10757       expand_df_binop (&gen_divdf3_i, operands);
10758       DONE;
10759     }
10760 }")
10761
10762 (define_insn "*divdf3_media"
10763   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10764         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10765                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10766   "TARGET_SHMEDIA_FPU"
10767   "fdiv.d       %1, %2, %0"
10768   [(set_attr "type" "dfdiv_media")])
10769
10770 (define_insn "divdf3_i"
10771   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10772         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10773                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10774    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10775   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10776   "fdiv %2,%0"
10777   [(set_attr "type" "dfdiv")
10778    (set_attr "fp_mode" "double")])
10779
10780 (define_insn "floatdidf2"
10781   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10782         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10783   "TARGET_SHMEDIA_FPU"
10784   "float.qd     %1, %0"
10785   [(set_attr "type" "dfpconv_media")])
10786
10787 (define_expand "floatsidf2"
10788   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10789         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10791   "
10792 {
10793   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10794     {
10795       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10796                                       get_fpscr_rtx ()));
10797       DONE;
10798     }
10799 }")
10800
10801 (define_insn "*floatsidf2_media"
10802   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10803         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10804   "TARGET_SHMEDIA_FPU"
10805   "float.ld     %1, %0"
10806   [(set_attr "type" "dfpconv_media")])
10807
10808 (define_insn "floatsidf2_i"
10809   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10810         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10811    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10812   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10813   "float        %1,%0"
10814   [(set_attr "type" "dfp_conv")
10815    (set_attr "fp_mode" "double")])
10816
10817 (define_insn "fix_truncdfdi2"
10818   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10819         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10820   "TARGET_SHMEDIA_FPU"
10821   "ftrc.dq      %1, %0"
10822   [(set_attr "type" "dfpconv_media")])
10823
10824 (define_expand "fix_truncdfsi2"
10825   [(set (match_operand:SI 0 "fpul_operand" "")
10826         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10827   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10828   "
10829 {
10830   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10831     {
10832       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10833                                           get_fpscr_rtx ()));
10834       DONE;
10835     }
10836 }")
10837
10838 (define_insn "*fix_truncdfsi2_media"
10839   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10840         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10841   "TARGET_SHMEDIA_FPU"
10842   "ftrc.dl      %1, %0"
10843   [(set_attr "type" "dfpconv_media")])
10844
10845 (define_insn "fix_truncdfsi2_i"
10846   [(set (match_operand:SI 0 "fpul_operand" "=y")
10847         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10848    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10849   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10850   "ftrc %1,%0"
10851   [(set_attr "type" "dfp_conv")
10852    (set_attr "dfp_comp" "no")
10853    (set_attr "fp_mode" "double")])
10854
10855 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10856 ;; fix_truncdfsi2_i.
10857 ;; (define_insn "fix_truncdfsi2_i4"
10858 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10859 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10860 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10861 ;;    (clobber (reg:SI FPUL_REG))]
10862 ;;   "TARGET_SH4"
10863 ;;   "#"
10864 ;;   [(set_attr "length" "4")
10865 ;;    (set_attr "fp_mode" "double")])
10866 ;;
10867 ;; (define_split
10868 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10869 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10870 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10871 ;;    (clobber (reg:SI FPUL_REG))]
10872 ;;   "TARGET_SH4"
10873 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10874 ;;            (use (match_dup 2))])
10875 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10876
10877 (define_insn "cmpgtdf_t"
10878   [(set (reg:SI T_REG)
10879         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10880                (match_operand:DF 1 "arith_reg_operand" "f")))
10881    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10882   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10883   "fcmp/gt      %1,%0"
10884   [(set_attr "type" "dfp_cmp")
10885    (set_attr "fp_mode" "double")])
10886
10887 (define_insn "cmpeqdf_t"
10888   [(set (reg:SI T_REG)
10889         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10890                (match_operand:DF 1 "arith_reg_operand" "f")))
10891    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10892   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10893   "fcmp/eq      %1,%0"
10894   [(set_attr "type" "dfp_cmp")
10895    (set_attr "fp_mode" "double")])
10896
10897 (define_insn "*ieee_ccmpeqdf_t"
10898   [(set (reg:SI T_REG)
10899         (ior:SI (reg:SI T_REG)
10900                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10901                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10902    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10903   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10904   "* return output_ieee_ccmpeq (insn, operands);"
10905   [(set_attr "length" "4")
10906    (set_attr "fp_mode" "double")])
10907
10908 (define_insn "cmpeqdf_media"
10909   [(set (match_operand:SI 0 "register_operand" "=r")
10910         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10911                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10912   "TARGET_SHMEDIA_FPU"
10913   "fcmpeq.d     %1,%2,%0"
10914   [(set_attr "type" "fcmp_media")])
10915
10916 (define_insn "cmpgtdf_media"
10917   [(set (match_operand:SI 0 "register_operand" "=r")
10918         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10919                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10920   "TARGET_SHMEDIA_FPU"
10921   "fcmpgt.d     %1,%2,%0"
10922   [(set_attr "type" "fcmp_media")])
10923
10924 (define_insn "cmpgedf_media"
10925   [(set (match_operand:SI 0 "register_operand" "=r")
10926         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10927                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10928   "TARGET_SHMEDIA_FPU"
10929   "fcmpge.d     %1,%2,%0"
10930   [(set_attr "type" "fcmp_media")])
10931
10932 (define_insn "cmpundf_media"
10933   [(set (match_operand:SI 0 "register_operand" "=r")
10934         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10935                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10936   "TARGET_SHMEDIA_FPU"
10937   "fcmpun.d     %1,%2,%0"
10938   [(set_attr "type" "fcmp_media")])
10939
10940 (define_expand "cbranchdf4"
10941   [(set (pc)
10942         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10943                        [(match_operand:DF 1 "arith_operand" "")
10944                         (match_operand:DF 2 "arith_operand" "")])
10945                       (match_operand 3 "" "")
10946                       (pc)))]
10947   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10948   "
10949 {
10950   if (TARGET_SHMEDIA)
10951     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10952                                           operands[3]));
10953   else
10954     sh_emit_compare_and_branch (operands, DFmode);
10955   DONE;
10956 }")
10957
10958
10959 (define_expand "negdf2"
10960   [(set (match_operand:DF 0 "arith_reg_operand" "")
10961         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10962   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10963   "
10964 {
10965   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10966     {
10967       expand_df_unop (&gen_negdf2_i, operands);
10968       DONE;
10969     }
10970 }")
10971
10972 (define_insn "*negdf2_media"
10973   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10974         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10975   "TARGET_SHMEDIA_FPU"
10976   "fneg.d       %1, %0"
10977   [(set_attr "type" "fmove_media")])
10978
10979 (define_insn "negdf2_i"
10980   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10981         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10982    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10983   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10984   "fneg %0"
10985   [(set_attr "type" "fmove")
10986    (set_attr "fp_mode" "double")])
10987
10988 (define_expand "sqrtdf2"
10989   [(set (match_operand:DF 0 "arith_reg_operand" "")
10990         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10991   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10992   "
10993 {
10994   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10995     {
10996       expand_df_unop (&gen_sqrtdf2_i, operands);
10997       DONE;
10998     }
10999 }")
11000
11001 (define_insn "*sqrtdf2_media"
11002   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11003         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11004   "TARGET_SHMEDIA_FPU"
11005   "fsqrt.d      %1, %0"
11006   [(set_attr "type" "dfdiv_media")])
11007
11008 (define_insn "sqrtdf2_i"
11009   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11010         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11011    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11012   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11013   "fsqrt        %0"
11014   [(set_attr "type" "dfdiv")
11015    (set_attr "fp_mode" "double")])
11016
11017 (define_expand "absdf2"
11018   [(set (match_operand:DF 0 "arith_reg_operand" "")
11019         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11020   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11021   "
11022 {
11023   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11024     {
11025       expand_df_unop (&gen_absdf2_i, operands);
11026       DONE;
11027     }
11028 }")
11029
11030 (define_insn "*absdf2_media"
11031   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11032         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11033   "TARGET_SHMEDIA_FPU"
11034   "fabs.d       %1, %0"
11035   [(set_attr "type" "fmove_media")])
11036
11037 (define_insn "absdf2_i"
11038   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11039         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11040    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11041   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11042   "fabs %0"
11043   [(set_attr "type" "fmove")
11044    (set_attr "fp_mode" "double")])
11045
11046 (define_expand "extendsfdf2"
11047   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11048         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11049   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11050   "
11051 {
11052   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11053     {
11054       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11055                                         get_fpscr_rtx ()));
11056       DONE;
11057     }
11058 }")
11059
11060 (define_insn "*extendsfdf2_media"
11061   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11062         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11063   "TARGET_SHMEDIA_FPU"
11064   "fcnv.sd      %1, %0"
11065   [(set_attr "type" "dfpconv_media")])
11066
11067 (define_insn "extendsfdf2_i4"
11068   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11069         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11070    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11071   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11072   "fcnvsd  %1,%0"
11073   [(set_attr "type" "fp")
11074    (set_attr "fp_mode" "double")])
11075
11076 (define_expand "truncdfsf2"
11077   [(set (match_operand:SF 0 "fpul_operand" "")
11078         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11079   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11080   "
11081 {
11082   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11083     {
11084       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11085                                        get_fpscr_rtx ()));
11086       DONE;
11087     }
11088 }")
11089
11090 (define_insn "*truncdfsf2_media"
11091   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11092         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11093   "TARGET_SHMEDIA_FPU"
11094   "fcnv.ds      %1, %0"
11095   [(set_attr "type" "dfpconv_media")])
11096
11097 (define_insn "truncdfsf2_i4"
11098   [(set (match_operand:SF 0 "fpul_operand" "=y")
11099         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11100    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11101   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11102   "fcnvds  %1,%0"
11103   [(set_attr "type" "fp")
11104    (set_attr "fp_mode" "double")])
11105 \f
11106 ;; Bit field extract patterns.  These give better code for packed bitfields,
11107 ;; because they allow auto-increment addresses to be generated.
11108
11109 (define_expand "insv"
11110   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11111                          (match_operand:SI 1 "immediate_operand" "")
11112                          (match_operand:SI 2 "immediate_operand" ""))
11113         (match_operand:SI 3 "general_operand" ""))]
11114   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11115   "
11116 {
11117   rtx addr_target, orig_address, shift_reg, qi_val;
11118   HOST_WIDE_INT bitsize, size, v = 0;
11119   rtx x = operands[3];
11120
11121   if (TARGET_SH2A && TARGET_BITOPS
11122       && (satisfies_constraint_Sbw (operands[0])
11123           || satisfies_constraint_Sbv (operands[0]))
11124       && satisfies_constraint_M (operands[1])
11125       && satisfies_constraint_K03 (operands[2]))
11126     {
11127       if (satisfies_constraint_N (operands[3]))
11128         {
11129           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11130           DONE;
11131         }
11132       else if (satisfies_constraint_M (operands[3]))
11133         {
11134           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11135           DONE;
11136         }
11137       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11138                 && satisfies_constraint_M (operands[1]))
11139         {
11140           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11141           DONE;
11142         }
11143       else if (REG_P (operands[3])
11144                && satisfies_constraint_M (operands[1]))
11145         {
11146           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11147           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11148           DONE;
11149         }
11150     }
11151   /* ??? expmed doesn't care for non-register predicates.  */
11152   if (! memory_operand (operands[0], VOIDmode)
11153       || ! immediate_operand (operands[1], VOIDmode)
11154       || ! immediate_operand (operands[2], VOIDmode)
11155       || ! general_operand (x, VOIDmode))
11156     FAIL;
11157   /* If this isn't a 16 / 24 / 32 bit field, or if
11158      it doesn't start on a byte boundary, then fail.  */
11159   bitsize = INTVAL (operands[1]);
11160   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11161       || (INTVAL (operands[2]) % 8) != 0)
11162     FAIL;
11163
11164   size = bitsize / 8;
11165   orig_address = XEXP (operands[0], 0);
11166   shift_reg = gen_reg_rtx (SImode);
11167   if (CONST_INT_P (x))
11168     {
11169       v = INTVAL (x);
11170       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11171     }
11172   else
11173     {
11174       emit_insn (gen_movsi (shift_reg, operands[3]));
11175       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11176     }
11177   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11178
11179   operands[0] = replace_equiv_address (operands[0], addr_target);
11180   emit_insn (gen_movqi (operands[0], qi_val));
11181
11182   while (size -= 1)
11183     {
11184       if (CONST_INT_P (x))
11185         qi_val
11186           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11187       else
11188         {
11189           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11190           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11191         }
11192       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11193       emit_insn (gen_movqi (operands[0], qi_val));
11194     }
11195
11196   DONE;
11197 }")
11198
11199 (define_insn "movua"
11200   [(set (match_operand:SI 0 "register_operand" "=z")
11201         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11202                    UNSPEC_MOVUA))]
11203   "TARGET_SH4A_ARCH"
11204   "movua.l      %1,%0"
11205   [(set_attr "type" "movua")])
11206
11207 ;; We shouldn't need this, but cse replaces increments with references
11208 ;; to other regs before flow has a chance to create post_inc
11209 ;; addressing modes, and only postreload's cse_move2add brings the
11210 ;; increments back to a usable form.
11211 (define_peephole2
11212   [(set (match_operand:SI 0 "register_operand" "")
11213         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11214                          (const_int 32) (const_int 0)))
11215    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11216   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11217   [(set (match_operand:SI 0 "register_operand" "")
11218         (sign_extract:SI (mem:SI (post_inc:SI
11219                                   (match_operand:SI 1 "register_operand" "")))
11220                          (const_int 32) (const_int 0)))]
11221   "")
11222
11223 (define_expand "extv"
11224   [(set (match_operand:SI 0 "register_operand" "")
11225         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11226                          (match_operand 2 "const_int_operand" "")
11227                          (match_operand 3 "const_int_operand" "")))]
11228   "TARGET_SH4A_ARCH || TARGET_SH2A"
11229 {
11230   if (TARGET_SH2A && TARGET_BITOPS
11231       && (satisfies_constraint_Sbw (operands[1])
11232           || satisfies_constraint_Sbv (operands[1]))
11233       && satisfies_constraint_M (operands[2])
11234       && satisfies_constraint_K03 (operands[3]))
11235    {
11236       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11237       if (REGNO (operands[0]) != T_REG)
11238         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11239       DONE;
11240    }
11241   if (TARGET_SH4A_ARCH
11242       && INTVAL (operands[2]) == 32
11243       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11244       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11245     {
11246       rtx src = adjust_address (operands[1], BLKmode, 0);
11247       set_mem_size (src, 4);
11248       emit_insn (gen_movua (operands[0], src));
11249       DONE;
11250     }
11251
11252   FAIL;
11253 })
11254
11255 (define_expand "extzv"
11256   [(set (match_operand:SI 0 "register_operand" "")
11257         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11258                          (match_operand 2 "const_int_operand" "")
11259                          (match_operand 3 "const_int_operand" "")))]
11260   "TARGET_SH4A_ARCH || TARGET_SH2A"
11261 {
11262   if (TARGET_SH2A && TARGET_BITOPS
11263       && (satisfies_constraint_Sbw (operands[1])
11264           || satisfies_constraint_Sbv (operands[1]))
11265       && satisfies_constraint_M (operands[2])
11266       && satisfies_constraint_K03 (operands[3]))
11267     {
11268       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11269       if (REGNO (operands[0]) != T_REG)
11270         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11271       DONE;
11272     }
11273   if (TARGET_SH4A_ARCH
11274       && INTVAL (operands[2]) == 32
11275       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11276       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11277     {
11278       rtx src = adjust_address (operands[1], BLKmode, 0);
11279       set_mem_size (src, 4);
11280       emit_insn (gen_movua (operands[0], src));
11281       DONE;
11282     }
11283
11284   FAIL;
11285 })
11286
11287 ;; SH2A instructions for bitwise operations.
11288
11289 ;; Clear a bit in a memory location.
11290 (define_insn "bclr_m2a"
11291   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11292         (and:QI
11293             (not:QI (ashift:QI (const_int 1)
11294                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11295             (match_dup 0)))]
11296   "TARGET_SH2A && TARGET_BITOPS"
11297   "@
11298         bclr.b\\t%1,%0
11299         bclr.b\\t%1,@(0,%t0)"
11300 [(set_attr "length" "4,4")])
11301
11302 (define_insn "bclrmem_m2a"
11303   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11304         (and:QI (match_dup 0)
11305                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11306   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11307   "@
11308         bclr.b\\t%W1,%0
11309         bclr.b\\t%W1,@(0,%t0)"
11310   [(set_attr "length" "4,4")])
11311
11312 ;; Set a bit in a memory location.
11313 (define_insn "bset_m2a"
11314   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11315         (ior:QI
11316             (ashift:QI (const_int 1)
11317                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11318             (match_dup 0)))]
11319   "TARGET_SH2A && TARGET_BITOPS"
11320   "@
11321         bset.b\\t%1,%0
11322         bset.b\\t%1,@(0,%t0)"
11323   [(set_attr "length" "4,4")])
11324
11325 (define_insn "bsetmem_m2a"
11326   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11327         (ior:QI (match_dup 0)
11328                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11329   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11330   "@
11331         bset.b\\t%V1,%0
11332         bset.b\\t%V1,@(0,%t0)"
11333   [(set_attr "length" "4,4")])
11334
11335 ;;; Transfer the contents of the T bit to a specified bit of memory.
11336 (define_insn "bst_m2a"
11337   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11338         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11339             (and:QI
11340                 (not:QI (ashift:QI (const_int 1)
11341                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11342                 (match_dup 0))
11343             (ior:QI
11344                 (ashift:QI (const_int 1) (match_dup 1))
11345                 (match_dup 0))))]
11346   "TARGET_SH2A && TARGET_BITOPS"
11347   "@
11348         bst.b\\t%1,%0
11349         bst.b\\t%1,@(0,%t0)"
11350   [(set_attr "length" "4")])
11351
11352 ;; Store a specified bit of memory in the T bit.
11353 (define_insn "bld_m2a"
11354   [(set (reg:SI T_REG)
11355         (zero_extract:SI
11356             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11357             (const_int 1)
11358             (match_operand 1 "const_int_operand" "K03,K03")))]
11359   "TARGET_SH2A && TARGET_BITOPS"
11360   "@
11361         bld.b\\t%1,%0
11362         bld.b\\t%1,@(0,%t0)"
11363   [(set_attr "length" "4,4")])
11364
11365 ;; Store a specified bit of memory in the T bit.
11366 (define_insn "bldsign_m2a"
11367   [(set (reg:SI T_REG)
11368         (sign_extract:SI
11369             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11370             (const_int 1)
11371             (match_operand 1 "const_int_operand" "K03,K03")))]
11372   "TARGET_SH2A && TARGET_BITOPS"
11373   "@
11374         bld.b\\t%1,%0
11375         bld.b\\t%1,@(0,%t0)"
11376   [(set_attr "length" "4,4")])
11377
11378 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11379 (define_insn "bld_reg"
11380   [(set (reg:SI T_REG)
11381         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11382                          (const_int 1)
11383                          (match_operand 1 "const_int_operand" "K03")))]
11384   "TARGET_SH2A"
11385   "bld\\t%1,%0")
11386
11387 (define_insn "*bld_regqi"
11388   [(set (reg:SI T_REG)
11389         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11390                          (const_int 1)
11391                          (match_operand 1 "const_int_operand" "K03")))]
11392   "TARGET_SH2A"
11393   "bld\\t%1,%0")
11394
11395 ;; Take logical and of a specified bit of memory with the T bit and
11396 ;; store its result in the T bit.
11397 (define_insn "band_m2a"
11398   [(set (reg:SI T_REG)
11399         (and:SI (reg:SI T_REG)
11400                 (zero_extract:SI
11401                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11402                     (const_int 1)
11403                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11404   "TARGET_SH2A && TARGET_BITOPS"
11405   "@
11406         band.b\\t%1,%0
11407         band.b\\t%1,@(0,%t0)"
11408   [(set_attr "length" "4,4")])
11409
11410 (define_insn "bandreg_m2a"
11411   [(set (match_operand:SI 0 "register_operand" "=r,r")
11412         (and:SI (zero_extract:SI
11413                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11414                     (const_int 1)
11415                     (match_operand 2 "const_int_operand" "K03,K03"))
11416                 (match_operand:SI 3 "register_operand" "r,r")))]
11417   "TARGET_SH2A && TARGET_BITOPS"
11418   "@
11419         band.b\\t%2,%1\;movt\\t%0
11420         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11421   [(set_attr "length" "6,6")])
11422
11423 ;; Take logical or of a specified bit of memory with the T bit and
11424 ;; store its result in the T bit.
11425 (define_insn "bor_m2a"
11426   [(set (reg:SI T_REG)
11427         (ior:SI (reg:SI T_REG)
11428                 (zero_extract:SI
11429                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11430                     (const_int 1)
11431                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11432   "TARGET_SH2A && TARGET_BITOPS"
11433   "@
11434         bor.b\\t%1,%0
11435         bor.b\\t%1,@(0,%t0)"
11436   [(set_attr "length" "4,4")])
11437
11438 (define_insn "borreg_m2a"
11439   [(set (match_operand:SI 0 "register_operand" "=r,r")
11440         (ior:SI (zero_extract:SI
11441                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11442                     (const_int 1)
11443                     (match_operand 2 "const_int_operand" "K03,K03"))
11444                 (match_operand:SI 3 "register_operand" "=r,r")))]
11445   "TARGET_SH2A && TARGET_BITOPS"
11446   "@
11447         bor.b\\t%2,%1\;movt\\t%0
11448         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11449   [(set_attr "length" "6,6")])
11450
11451 ;; Take exclusive or of a specified bit of memory with the T bit and
11452 ;; store its result in the T bit.
11453 (define_insn "bxor_m2a"
11454   [(set (reg:SI T_REG)
11455         (xor:SI (reg:SI T_REG)
11456                 (zero_extract:SI
11457                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11458                     (const_int 1)
11459                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11460   "TARGET_SH2A && TARGET_BITOPS"
11461   "@
11462         bxor.b\\t%1,%0
11463         bxor.b\\t%1,@(0,%t0)"
11464   [(set_attr "length" "4,4")])
11465
11466 (define_insn "bxorreg_m2a"
11467   [(set (match_operand:SI 0 "register_operand" "=r,r")
11468         (xor:SI (zero_extract:SI
11469                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11470                     (const_int 1)
11471                     (match_operand 2 "const_int_operand" "K03,K03"))
11472                 (match_operand:SI 3 "register_operand" "=r,r")))]
11473   "TARGET_SH2A && TARGET_BITOPS"
11474   "@
11475         bxor.b\\t%2,%1\;movt\\t%0
11476         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11477   [(set_attr "length" "6,6")])
11478
11479 \f
11480 ;; -------------------------------------------------------------------------
11481 ;; Peepholes
11482 ;; -------------------------------------------------------------------------
11483 ;; This matches cases where the bit in a memory location is set.
11484 (define_peephole2
11485   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11486         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11487    (set (match_dup 0)
11488         (ior:SI (match_dup 0)
11489         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11490    (set (match_dup 1)
11491         (match_operand 3 "arith_reg_operand" "r,r"))]
11492   "TARGET_SH2A && TARGET_BITOPS
11493    && satisfies_constraint_Pso (operands[2])
11494    && REGNO (operands[0]) == REGNO (operands[3])"
11495   [(set (match_dup 1)
11496         (ior:QI (match_dup 1)
11497                 (match_dup 2)))]
11498   "")
11499
11500 ;; This matches cases where the bit in a memory location is cleared.
11501 (define_peephole2
11502   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11503         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11504    (set (match_dup 0)
11505         (and:SI (match_dup 0)
11506         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11507    (set (match_dup 1)
11508         (match_operand 3 "arith_reg_operand" "r,r"))]
11509   "TARGET_SH2A && TARGET_BITOPS
11510    && satisfies_constraint_Psz (operands[2])
11511    && REGNO (operands[0]) == REGNO (operands[3])"
11512   [(set (match_dup 1)
11513         (and:QI (match_dup 1)
11514                 (match_dup 2)))]
11515   "")
11516
11517 ;; This matches cases where a stack pointer increment at the start of the
11518 ;; epilogue combines with a stack slot read loading the return value.
11519
11520 (define_peephole
11521   [(set (match_operand:SI 0 "arith_reg_operand" "")
11522         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11523    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11524   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11525   "mov.l        @%1+,%0")
11526
11527 ;; See the comment on the dt combiner pattern above.
11528
11529 (define_peephole
11530   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11531         (plus:SI (match_dup 0)
11532                  (const_int -1)))
11533    (set (reg:SI T_REG)
11534         (eq:SI (match_dup 0)
11535                (const_int 0)))]
11536   "TARGET_SH2"
11537   "dt   %0")
11538
11539 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11540 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11541 ;; reload when the constant is too large for a reg+offset address.
11542
11543 ;; ??? We would get much better code if this was done in reload.  This would
11544 ;; require modifying find_reloads_address to recognize that if the constant
11545 ;; is out-of-range for an immediate add, then we get better code by reloading
11546 ;; the constant into a register than by reloading the sum into a register,
11547 ;; since the former is one instruction shorter if the address does not need
11548 ;; to be offsettable.  Unfortunately this does not work, because there is
11549 ;; only one register, r0, that can be used as an index register.  This register
11550 ;; is also the function return value register.  So, if we try to force reload
11551 ;; to use double-reg addresses, then we end up with some instructions that
11552 ;; need to use r0 twice.  The only way to fix this is to change the calling
11553 ;; convention so that r0 is not used to return values.
11554
11555 (define_peephole
11556   [(set (match_operand:SI 0 "register_operand" "=r")
11557         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11558    (set (mem:SI (match_dup 0))
11559         (match_operand:SI 2 "general_movsrc_operand" ""))]
11560   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11561   "mov.l        %2,@(%0,%1)")
11562
11563 (define_peephole
11564   [(set (match_operand:SI 0 "register_operand" "=r")
11565         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11566    (set (match_operand:SI 2 "general_movdst_operand" "")
11567         (mem:SI (match_dup 0)))]
11568   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11569   "mov.l        @(%0,%1),%2")
11570
11571 (define_peephole
11572   [(set (match_operand:SI 0 "register_operand" "=r")
11573         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11574    (set (mem:HI (match_dup 0))
11575         (match_operand:HI 2 "general_movsrc_operand" ""))]
11576   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11577   "mov.w        %2,@(%0,%1)")
11578
11579 (define_peephole
11580   [(set (match_operand:SI 0 "register_operand" "=r")
11581         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11582    (set (match_operand:HI 2 "general_movdst_operand" "")
11583         (mem:HI (match_dup 0)))]
11584   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11585   "mov.w        @(%0,%1),%2")
11586
11587 (define_peephole
11588   [(set (match_operand:SI 0 "register_operand" "=r")
11589         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11590    (set (mem:QI (match_dup 0))
11591         (match_operand:QI 2 "general_movsrc_operand" ""))]
11592   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11593   "mov.b        %2,@(%0,%1)")
11594
11595 (define_peephole
11596   [(set (match_operand:SI 0 "register_operand" "=r")
11597         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11598    (set (match_operand:QI 2 "general_movdst_operand" "")
11599         (mem:QI (match_dup 0)))]
11600   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11601   "mov.b        @(%0,%1),%2")
11602
11603 (define_peephole
11604   [(set (match_operand:SI 0 "register_operand" "=r")
11605         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11606    (set (mem:SF (match_dup 0))
11607         (match_operand:SF 2 "general_movsrc_operand" ""))]
11608   "TARGET_SH1 && REGNO (operands[0]) == 0
11609    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11610        || (GET_CODE (operands[2]) == SUBREG
11611            && REGNO (SUBREG_REG (operands[2])) < 16))
11612    && reg_unused_after (operands[0], insn)"
11613   "mov.l        %2,@(%0,%1)")
11614
11615 (define_peephole
11616   [(set (match_operand:SI 0 "register_operand" "=r")
11617         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11618    (set (match_operand:SF 2 "general_movdst_operand" "")
11619
11620         (mem:SF (match_dup 0)))]
11621   "TARGET_SH1 && REGNO (operands[0]) == 0
11622    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11623        || (GET_CODE (operands[2]) == SUBREG
11624            && REGNO (SUBREG_REG (operands[2])) < 16))
11625    && reg_unused_after (operands[0], insn)"
11626   "mov.l        @(%0,%1),%2")
11627
11628 (define_peephole
11629   [(set (match_operand:SI 0 "register_operand" "=r")
11630         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11631    (set (mem:SF (match_dup 0))
11632         (match_operand:SF 2 "general_movsrc_operand" ""))]
11633   "TARGET_SH2E && REGNO (operands[0]) == 0
11634    && ((REG_P (operands[2])
11635         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11636        || (GET_CODE (operands[2]) == SUBREG
11637            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11638    && reg_unused_after (operands[0], insn)"
11639   "fmov{.s|}    %2,@(%0,%1)")
11640
11641 (define_peephole
11642   [(set (match_operand:SI 0 "register_operand" "=r")
11643         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11644    (set (match_operand:SF 2 "general_movdst_operand" "")
11645
11646         (mem:SF (match_dup 0)))]
11647   "TARGET_SH2E && REGNO (operands[0]) == 0
11648    && ((REG_P (operands[2])
11649         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11650        || (GET_CODE (operands[2]) == SUBREG
11651            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11652    && reg_unused_after (operands[0], insn)"
11653   "fmov{.s|}    @(%0,%1),%2")
11654
11655 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11656 (define_insn "sp_switch_1"
11657   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11658   "TARGET_SH1"
11659   "*
11660 {
11661   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11662   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11663   return \"mov r0,r15\";
11664 }"
11665   [(set_attr "length" "10")])
11666
11667 ;; Switch back to the original stack for interrupt functions with the
11668 ;; sp_switch attribute.  */
11669 (define_insn "sp_switch_2"
11670   [(const_int 2)]
11671   "TARGET_SH1"
11672   "mov.l @r15+,r15\;mov.l @r15+,r0"
11673   [(set_attr "length" "4")])
11674
11675 ;; Integer vector moves
11676
11677 (define_expand "movv8qi"
11678   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11679         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11680   "TARGET_SHMEDIA"
11681   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11682
11683 (define_insn "movv8qi_i"
11684   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11685         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11686   "TARGET_SHMEDIA
11687    && (register_operand (operands[0], V8QImode)
11688        || sh_register_operand (operands[1], V8QImode))"
11689   "@
11690         add     %1, r63, %0
11691         movi    %1, %0
11692         #
11693         ld%M1.q %m1, %0
11694         st%M0.q %m0, %N1"
11695   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11696    (set_attr "length" "4,4,16,4,4")])
11697
11698 (define_split
11699   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11700         (subreg:V8QI (const_int 0) 0))]
11701   "TARGET_SHMEDIA"
11702   [(set (match_dup 0)
11703         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11704                             (const_int 0) (const_int 0) (const_int 0)
11705                             (const_int 0) (const_int 0)]))])
11706
11707 (define_split
11708   [(set (match_operand 0 "arith_reg_dest" "")
11709         (match_operand 1 "sh_rep_vec" ""))]
11710   "TARGET_SHMEDIA && reload_completed
11711    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11712    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11713    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11714    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11715        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11716    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11717        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11718   [(set (match_dup 0) (match_dup 1))
11719    (match_dup 2)]
11720   "
11721 {
11722   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11723   rtx elt1 = XVECEXP (operands[1], 0, 1);
11724
11725   if (unit_size > 2)
11726     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11727   else
11728     {
11729       if (unit_size < 2)
11730         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11731       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11732     }
11733   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11734   operands[1] = XVECEXP (operands[1], 0, 0);
11735   if (unit_size < 2)
11736     {
11737       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11738         operands[1]
11739           = GEN_INT (TARGET_LITTLE_ENDIAN
11740                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11741                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11742       else
11743         {
11744           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11745           operands[1]
11746             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11747         }
11748     }
11749 }")
11750
11751 (define_split
11752   [(set (match_operand 0 "arith_reg_dest" "")
11753         (match_operand 1 "sh_const_vec" ""))]
11754   "TARGET_SHMEDIA && reload_completed
11755    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11756    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11757   [(set (match_dup 0) (match_dup 1))]
11758   "
11759 {
11760   rtx v = operands[1];
11761   enum machine_mode new_mode
11762     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11763
11764   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11765   operands[1]
11766     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11767 }")
11768
11769 (define_expand "movv2hi"
11770   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11771         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11772   "TARGET_SHMEDIA"
11773   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11774
11775 (define_insn "movv2hi_i"
11776   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11777         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11778   "TARGET_SHMEDIA
11779    && (register_operand (operands[0], V2HImode)
11780        || sh_register_operand (operands[1], V2HImode))"
11781   "@
11782         add.l   %1, r63, %0
11783         movi    %1, %0
11784         #
11785         ld%M1.l %m1, %0
11786         st%M0.l %m0, %N1"
11787   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11788    (set_attr "length" "4,4,16,4,4")
11789    (set (attr "highpart")
11790         (cond [(match_test "sh_contains_memref_p (insn)")
11791                (const_string "user")]
11792               (const_string "ignore")))])
11793
11794 (define_expand "movv4hi"
11795   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11796         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11797   "TARGET_SHMEDIA"
11798   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11799
11800 (define_insn "movv4hi_i"
11801   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11802         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11803   "TARGET_SHMEDIA
11804    && (register_operand (operands[0], V4HImode)
11805        || sh_register_operand (operands[1], V4HImode))"
11806   "@
11807         add     %1, r63, %0
11808         movi    %1, %0
11809         #
11810         ld%M1.q %m1, %0
11811         st%M0.q %m0, %N1"
11812   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11813    (set_attr "length" "4,4,16,4,4")
11814    (set_attr "highpart" "depend")])
11815
11816 (define_expand "movv2si"
11817   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11818         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11819   "TARGET_SHMEDIA"
11820   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11821
11822 (define_insn "movv2si_i"
11823   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11824         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11825   "TARGET_SHMEDIA
11826    && (register_operand (operands[0], V2SImode)
11827        || sh_register_operand (operands[1], V2SImode))"
11828   "@
11829         add     %1, r63, %0
11830         #
11831         #
11832         ld%M1.q %m1, %0
11833         st%M0.q %m0, %N1"
11834   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11835    (set_attr "length" "4,4,16,4,4")
11836    (set_attr "highpart" "depend")])
11837
11838 ;; Multimedia Intrinsics
11839
11840 (define_insn "absv2si2"
11841   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11842         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11843   "TARGET_SHMEDIA"
11844   "mabs.l       %1, %0"
11845   [(set_attr "type" "mcmp_media")
11846    (set_attr "highpart" "depend")])
11847
11848 (define_insn "absv4hi2"
11849   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11850         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11851   "TARGET_SHMEDIA"
11852   "mabs.w       %1, %0"
11853   [(set_attr "type" "mcmp_media")
11854    (set_attr "highpart" "depend")])
11855
11856 (define_insn "addv2si3"
11857   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11858         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11859                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11860   "TARGET_SHMEDIA"
11861   "madd.l       %1, %2, %0"
11862   [(set_attr "type" "arith_media")
11863    (set_attr "highpart" "depend")])
11864
11865 (define_insn "addv4hi3"
11866   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11867         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11868                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11869   "TARGET_SHMEDIA"
11870   "madd.w       %1, %2, %0"
11871   [(set_attr "type" "arith_media")
11872    (set_attr "highpart" "depend")])
11873
11874 (define_insn_and_split "addv2hi3"
11875   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11876         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11877                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11878   "TARGET_SHMEDIA"
11879   "#"
11880   "TARGET_SHMEDIA"
11881   [(const_int 0)]
11882   "
11883 {
11884   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11885   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11886   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11887   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11888   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11889
11890   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11891   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11892   DONE;
11893 }"
11894   [(set_attr "highpart" "must_split")])
11895
11896 (define_insn "ssaddv2si3"
11897   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11898         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11899                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11900   "TARGET_SHMEDIA"
11901   "madds.l      %1, %2, %0"
11902   [(set_attr "type" "mcmp_media")
11903    (set_attr "highpart" "depend")])
11904
11905 (define_insn "usaddv8qi3"
11906   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11907         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11908                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11909   "TARGET_SHMEDIA"
11910   "madds.ub     %1, %2, %0"
11911   [(set_attr "type" "mcmp_media")
11912    (set_attr "highpart" "depend")])
11913
11914 (define_insn "ssaddv4hi3"
11915   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11916         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11917                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11918   "TARGET_SHMEDIA"
11919   "madds.w      %1, %2, %0"
11920   [(set_attr "type" "mcmp_media")
11921    (set_attr "highpart" "depend")])
11922
11923 (define_insn "negcmpeqv8qi"
11924   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11925         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11926                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11927   "TARGET_SHMEDIA"
11928   "mcmpeq.b     %N1, %N2, %0"
11929   [(set_attr "type" "mcmp_media")
11930    (set_attr "highpart" "depend")])
11931
11932 (define_insn "negcmpeqv2si"
11933   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11934         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11935                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11936   "TARGET_SHMEDIA"
11937   "mcmpeq.l     %N1, %N2, %0"
11938   [(set_attr "type" "mcmp_media")
11939    (set_attr "highpart" "depend")])
11940
11941 (define_insn "negcmpeqv4hi"
11942   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11943         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11944                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11945   "TARGET_SHMEDIA"
11946   "mcmpeq.w     %N1, %N2, %0"
11947   [(set_attr "type" "mcmp_media")
11948    (set_attr "highpart" "depend")])
11949
11950 (define_insn "negcmpgtuv8qi"
11951   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11952         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11953                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11954   "TARGET_SHMEDIA"
11955   "mcmpgt.ub    %N1, %N2, %0"
11956   [(set_attr "type" "mcmp_media")
11957    (set_attr "highpart" "depend")])
11958
11959 (define_insn "negcmpgtv2si"
11960   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11961         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11962                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11963   "TARGET_SHMEDIA"
11964   "mcmpgt.l     %N1, %N2, %0"
11965   [(set_attr "type" "mcmp_media")
11966    (set_attr "highpart" "depend")])
11967
11968 (define_insn "negcmpgtv4hi"
11969   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11970         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11971                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11972   "TARGET_SHMEDIA"
11973   "mcmpgt.w     %N1, %N2, %0"
11974   [(set_attr "type" "mcmp_media")
11975    (set_attr "highpart" "depend")])
11976
11977 (define_insn "mcmv"
11978   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11979         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11980                         (match_operand:DI 2 "arith_reg_operand" "r"))
11981                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11982                         (not:DI (match_dup 2)))))]
11983   "TARGET_SHMEDIA"
11984   "mcmv %N1, %2, %0"
11985   [(set_attr "type" "arith_media")
11986    (set_attr "highpart" "depend")])
11987
11988 (define_insn "mcnvs_lw"
11989   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11990         (vec_concat:V4HI
11991          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11992          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11993   "TARGET_SHMEDIA"
11994   "mcnvs.lw     %N1, %N2, %0"
11995   [(set_attr "type" "mcmp_media")])
11996
11997 (define_insn "mcnvs_wb"
11998   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11999         (vec_concat:V8QI
12000          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12001          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12002   "TARGET_SHMEDIA"
12003   "mcnvs.wb     %N1, %N2, %0"
12004   [(set_attr "type" "mcmp_media")])
12005
12006 (define_insn "mcnvs_wub"
12007   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12008         (vec_concat:V8QI
12009          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12010          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12011   "TARGET_SHMEDIA"
12012   "mcnvs.wub    %N1, %N2, %0"
12013   [(set_attr "type" "mcmp_media")])
12014
12015 (define_insn "mextr_rl"
12016   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12017         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12018                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12019                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12020                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12021   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12022   "*
12023 {
12024   static char templ[21];
12025
12026   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12027            (int) INTVAL (operands[3]) >> 3);
12028   return templ;
12029 }"
12030   [(set_attr "type" "arith_media")])
12031
12032 (define_insn "*mextr_lr"
12033   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12034         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12035                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12036                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12037                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12038   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12039   "*
12040 {
12041   static char templ[21];
12042
12043   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12044            (int) INTVAL (operands[4]) >> 3);
12045   return templ;
12046 }"
12047   [(set_attr "type" "arith_media")])
12048
12049 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12050 ; vector then varies depending on endianness.
12051 (define_expand "mextr1"
12052   [(match_operand:DI 0 "arith_reg_dest" "")
12053    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12054    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12055   "TARGET_SHMEDIA"
12056   "
12057 {
12058   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12059                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12060   DONE;
12061 }")
12062
12063 (define_expand "mextr2"
12064   [(match_operand:DI 0 "arith_reg_dest" "")
12065    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12066    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12067   "TARGET_SHMEDIA"
12068   "
12069 {
12070   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12071                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12072   DONE;
12073 }")
12074
12075 (define_expand "mextr3"
12076   [(match_operand:DI 0 "arith_reg_dest" "")
12077    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12078    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12079   "TARGET_SHMEDIA"
12080   "
12081 {
12082   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12083                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12084   DONE;
12085 }")
12086
12087 (define_expand "mextr4"
12088   [(match_operand:DI 0 "arith_reg_dest" "")
12089    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12090    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12091   "TARGET_SHMEDIA"
12092   "
12093 {
12094   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12095                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12096   DONE;
12097 }")
12098
12099 (define_expand "mextr5"
12100   [(match_operand:DI 0 "arith_reg_dest" "")
12101    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12102    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12103   "TARGET_SHMEDIA"
12104   "
12105 {
12106   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12107                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12108   DONE;
12109 }")
12110
12111 (define_expand "mextr6"
12112   [(match_operand:DI 0 "arith_reg_dest" "")
12113    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12114    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12115   "TARGET_SHMEDIA"
12116   "
12117 {
12118   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12119                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12120   DONE;
12121 }")
12122
12123 (define_expand "mextr7"
12124   [(match_operand:DI 0 "arith_reg_dest" "")
12125    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12126    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12127   "TARGET_SHMEDIA"
12128   "
12129 {
12130   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12131                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12132   DONE;
12133 }")
12134
12135 (define_expand "mmacfx_wl"
12136   [(match_operand:V2SI 0 "arith_reg_dest" "")
12137    (match_operand:V2HI 1 "extend_reg_operand" "")
12138    (match_operand:V2HI 2 "extend_reg_operand" "")
12139    (match_operand:V2SI 3 "arith_reg_operand" "")]
12140   "TARGET_SHMEDIA"
12141   "
12142 {
12143   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12144                               operands[1], operands[2]));
12145   DONE;
12146 }")
12147
12148 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12149 ;; is depend
12150 (define_insn "mmacfx_wl_i"
12151   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12152         (ss_plus:V2SI
12153          (match_operand:V2SI 1 "arith_reg_operand" "0")
12154          (ss_truncate:V2SI
12155           (ashift:V2DI
12156            (sign_extend:V2DI
12157             (mult:V2SI
12158              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12159              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12160            (const_int 1)))))]
12161   "TARGET_SHMEDIA"
12162   "mmacfx.wl    %2, %3, %0"
12163   [(set_attr "type" "mac_media")
12164    (set_attr "highpart" "depend")])
12165
12166 (define_expand "mmacnfx_wl"
12167   [(match_operand:V2SI 0 "arith_reg_dest" "")
12168    (match_operand:V2HI 1 "extend_reg_operand" "")
12169    (match_operand:V2HI 2 "extend_reg_operand" "")
12170    (match_operand:V2SI 3 "arith_reg_operand" "")]
12171   "TARGET_SHMEDIA"
12172   "
12173 {
12174   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12175                                operands[1], operands[2]));
12176   DONE;
12177 }")
12178
12179 (define_insn "mmacnfx_wl_i"
12180   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12181         (ss_minus:V2SI
12182          (match_operand:V2SI 1 "arith_reg_operand" "0")
12183          (ss_truncate:V2SI
12184           (ashift:V2DI
12185            (sign_extend:V2DI
12186             (mult:V2SI
12187              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12188              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12189            (const_int 1)))))]
12190   "TARGET_SHMEDIA"
12191   "mmacnfx.wl   %2, %3, %0"
12192   [(set_attr "type" "mac_media")
12193    (set_attr "highpart" "depend")])
12194
12195 (define_insn "mulv2si3"
12196   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12197         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12198                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12199   "TARGET_SHMEDIA"
12200   "mmul.l       %1, %2, %0"
12201   [(set_attr "type" "d2mpy_media")
12202    (set_attr "highpart" "depend")])
12203
12204 (define_insn "mulv4hi3"
12205   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12206         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12207                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12208   "TARGET_SHMEDIA"
12209   "mmul.w       %1, %2, %0"
12210   [(set_attr "type" "dmpy_media")
12211    (set_attr "highpart" "depend")])
12212
12213 (define_insn "mmulfx_l"
12214   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12215         (ss_truncate:V2SI
12216          (ashiftrt:V2DI
12217           (mult:V2DI
12218            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12219            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12220           (const_int 31))))]
12221   "TARGET_SHMEDIA"
12222   "mmulfx.l     %1, %2, %0"
12223   [(set_attr "type" "d2mpy_media")
12224    (set_attr "highpart" "depend")])
12225
12226 (define_insn "mmulfx_w"
12227   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12228         (ss_truncate:V4HI
12229          (ashiftrt:V4SI
12230           (mult:V4SI
12231            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12232            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12233           (const_int 15))))]
12234   "TARGET_SHMEDIA"
12235   "mmulfx.w     %1, %2, %0"
12236   [(set_attr "type" "dmpy_media")
12237    (set_attr "highpart" "depend")])
12238
12239 (define_insn "mmulfxrp_w"
12240   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12241         (ss_truncate:V4HI
12242          (ashiftrt:V4SI
12243           (plus:V4SI
12244            (mult:V4SI
12245             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12246             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12247            (const_int 16384))
12248           (const_int 15))))]
12249   "TARGET_SHMEDIA"
12250   "mmulfxrp.w   %1, %2, %0"
12251   [(set_attr "type" "dmpy_media")
12252    (set_attr "highpart" "depend")])
12253
12254
12255 (define_expand "mmulhi_wl"
12256   [(match_operand:V2SI 0 "arith_reg_dest" "")
12257    (match_operand:V4HI 1 "arith_reg_operand" "")
12258    (match_operand:V4HI 2 "arith_reg_operand" "")]
12259   "TARGET_SHMEDIA"
12260   "
12261 {
12262   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12263              (operands[0], operands[1], operands[2]));
12264   DONE;
12265 }")
12266
12267 (define_expand "mmullo_wl"
12268   [(match_operand:V2SI 0 "arith_reg_dest" "")
12269    (match_operand:V4HI 1 "arith_reg_operand" "")
12270    (match_operand:V4HI 2 "arith_reg_operand" "")]
12271   "TARGET_SHMEDIA"
12272   "
12273 {
12274   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12275              (operands[0], operands[1], operands[2]));
12276   DONE;
12277 }")
12278
12279 (define_insn "mmul23_wl"
12280   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12281         (vec_select:V2SI
12282          (mult:V4SI
12283           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12284           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12285          (parallel [(const_int 2) (const_int 3)])))]
12286   "TARGET_SHMEDIA"
12287   "* return (TARGET_LITTLE_ENDIAN
12288              ? \"mmulhi.wl      %1, %2, %0\"
12289              : \"mmullo.wl      %1, %2, %0\");"
12290   [(set_attr "type" "dmpy_media")
12291    (set (attr "highpart")
12292         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12293          (const_string "user")))])
12294
12295 (define_insn "mmul01_wl"
12296   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12297         (vec_select:V2SI
12298          (mult:V4SI
12299           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12300           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12301          (parallel [(const_int 0) (const_int 1)])))]
12302   "TARGET_SHMEDIA"
12303   "* return (TARGET_LITTLE_ENDIAN
12304              ? \"mmullo.wl      %1, %2, %0\"
12305              : \"mmulhi.wl      %1, %2, %0\");"
12306   [(set_attr "type" "dmpy_media")
12307    (set (attr "highpart")
12308         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12309          (const_string "user")))])
12310
12311
12312 (define_expand "mmulsum_wq"
12313   [(match_operand:DI 0 "arith_reg_dest" "")
12314    (match_operand:V4HI 1 "arith_reg_operand" "")
12315    (match_operand:V4HI 2 "arith_reg_operand" "")
12316    (match_operand:DI 3 "arith_reg_operand" "")]
12317   "TARGET_SHMEDIA"
12318   "
12319 {
12320   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12321                                operands[1], operands[2]));
12322   DONE;
12323 }")
12324
12325 (define_insn "mmulsum_wq_i"
12326   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12327         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12328          (plus:DI
12329           (plus:DI
12330            (vec_select:DI
12331             (mult:V4DI
12332              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12333              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12334             (parallel [(const_int 0)]))
12335            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12336                                      (sign_extend:V4DI (match_dup 3)))
12337                           (parallel [(const_int 1)])))
12338           (plus:DI
12339            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12340                                      (sign_extend:V4DI (match_dup 3)))
12341                           (parallel [(const_int 2)]))
12342            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12343                                      (sign_extend:V4DI (match_dup 3)))
12344                           (parallel [(const_int 3)]))))))]
12345   "TARGET_SHMEDIA"
12346   "mmulsum.wq   %2, %3, %0"
12347   [(set_attr "type" "mac_media")])
12348
12349 (define_expand "mperm_w"
12350   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12351    (match_operand:V4HI 1 "arith_reg_operand" "r")
12352    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12353   "TARGET_SHMEDIA"
12354   "
12355 {
12356   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12357              (operands[0], operands[1], operands[2]));
12358   DONE;
12359 }")
12360
12361 ; This use of vec_select isn't exactly correct according to rtl.texi
12362 ; (because not constant), but it seems a straightforward extension.
12363 (define_insn "mperm_w_little"
12364   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12365         (vec_select:V4HI
12366          (match_operand:V4HI 1 "arith_reg_operand" "r")
12367          (parallel
12368           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12369                             (const_int 2) (const_int 0))
12370            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12371            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12372            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12373   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12374   "mperm.w      %1, %N2, %0"
12375   [(set_attr "type" "arith_media")])
12376
12377 (define_insn "mperm_w_big"
12378   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12379         (vec_select:V4HI
12380          (match_operand:V4HI 1 "arith_reg_operand" "r")
12381          (parallel
12382           [(zero_extract:QI (not:QI (match_operand:QI 2
12383                                      "extend_reg_or_0_operand" "rZ"))
12384                             (const_int 2) (const_int 0))
12385            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12386            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12387            (zero_extract:QI (not:QI (match_dup 2))
12388                             (const_int 2) (const_int 6))])))]
12389   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12390   "mperm.w      %1, %N2, %0"
12391   [(set_attr "type" "arith_media")])
12392
12393 (define_insn "mperm_w0"
12394   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12395         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12396                                           "trunc_hi_operand" "r"))))]
12397   "TARGET_SHMEDIA"
12398   "mperm.w      %1, r63, %0"
12399   [(set_attr "type" "arith_media")
12400    (set_attr "highpart" "ignore")])
12401
12402 (define_expand "msad_ubq"
12403   [(match_operand:DI 0 "arith_reg_dest" "")
12404    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12405    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12406    (match_operand:DI 3 "arith_reg_operand" "")]
12407   "TARGET_SHMEDIA"
12408   "
12409 {
12410   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12411                              operands[1], operands[2]));
12412   DONE;
12413 }")
12414
12415 (define_insn "msad_ubq_i"
12416   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12417         (plus:DI
12418          (plus:DI
12419           (plus:DI
12420            (plus:DI
12421             (match_operand:DI 1 "arith_reg_operand" "0")
12422             (abs:DI (vec_select:DI
12423                      (minus:V8DI
12424                       (zero_extend:V8DI
12425                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12426                       (zero_extend:V8DI
12427                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12428                      (parallel [(const_int 0)]))))
12429            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12430                                               (zero_extend:V8DI (match_dup 3)))
12431                                   (parallel [(const_int 1)]))))
12432           (plus:DI
12433            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12434                                               (zero_extend:V8DI (match_dup 3)))
12435                                   (parallel [(const_int 2)])))
12436            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12437                                               (zero_extend:V8DI (match_dup 3)))
12438                                   (parallel [(const_int 3)])))))
12439          (plus:DI
12440           (plus:DI
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 4)])))
12444            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12445                                               (zero_extend:V8DI (match_dup 3)))
12446                                   (parallel [(const_int 5)]))))
12447           (plus:DI
12448            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12449                                               (zero_extend:V8DI (match_dup 3)))
12450                                   (parallel [(const_int 6)])))
12451            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12452                                               (zero_extend:V8DI (match_dup 3)))
12453                                   (parallel [(const_int 7)])))))))]
12454   "TARGET_SHMEDIA"
12455   "msad.ubq     %N2, %N3, %0"
12456   [(set_attr "type" "mac_media")])
12457
12458 (define_insn "mshalds_l"
12459   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12460         (ss_truncate:V2SI
12461          (ashift:V2DI
12462           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12463           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12464                   (const_int 31)))))]
12465   "TARGET_SHMEDIA"
12466   "mshalds.l    %1, %2, %0"
12467   [(set_attr "type" "mcmp_media")
12468    (set_attr "highpart" "depend")])
12469
12470 (define_insn "mshalds_w"
12471   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12472         (ss_truncate:V4HI
12473          (ashift:V4SI
12474           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12475           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12476                   (const_int 15)))))]
12477   "TARGET_SHMEDIA"
12478   "mshalds.w    %1, %2, %0"
12479   [(set_attr "type" "mcmp_media")
12480    (set_attr "highpart" "depend")])
12481
12482 (define_insn "ashrv2si3"
12483   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12484         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12485                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12486   "TARGET_SHMEDIA"
12487   "mshard.l     %1, %2, %0"
12488   [(set_attr "type" "arith_media")
12489    (set_attr "highpart" "depend")])
12490
12491 (define_insn "ashrv4hi3"
12492   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12493         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12494                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12495   "TARGET_SHMEDIA"
12496   "mshard.w     %1, %2, %0"
12497   [(set_attr "type" "arith_media")
12498    (set_attr "highpart" "depend")])
12499
12500 (define_insn "mshards_q"
12501   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12502         (ss_truncate:HI
12503          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12504                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12505   "TARGET_SHMEDIA"
12506   "mshards.q    %1, %N2, %0"
12507   [(set_attr "type" "mcmp_media")])
12508
12509 (define_expand "mshfhi_b"
12510   [(match_operand:V8QI 0 "arith_reg_dest" "")
12511    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12512    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12513   "TARGET_SHMEDIA"
12514   "
12515 {
12516   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12517              (operands[0], operands[1], operands[2]));
12518   DONE;
12519 }")
12520
12521 (define_expand "mshflo_b"
12522   [(match_operand:V8QI 0 "arith_reg_dest" "")
12523    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12524    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12525   "TARGET_SHMEDIA"
12526   "
12527 {
12528   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12529              (operands[0], operands[1], operands[2]));
12530   DONE;
12531 }")
12532
12533 (define_insn "mshf4_b"
12534   [(set
12535     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12536     (vec_select:V8QI
12537      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12538                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12539      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12540                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12541   "TARGET_SHMEDIA"
12542   "* return (TARGET_LITTLE_ENDIAN
12543              ? \"mshfhi.b       %N1, %N2, %0\"
12544              : \"mshflo.b       %N1, %N2, %0\");"
12545   [(set_attr "type" "arith_media")
12546    (set (attr "highpart")
12547         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12548          (const_string "user")))])
12549
12550 (define_insn "mshf0_b"
12551   [(set
12552     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12553     (vec_select:V8QI
12554      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12555                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12556      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12557                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12558   "TARGET_SHMEDIA"
12559   "* return (TARGET_LITTLE_ENDIAN
12560              ? \"mshflo.b       %N1, %N2, %0\"
12561              : \"mshfhi.b       %N1, %N2, %0\");"
12562   [(set_attr "type" "arith_media")
12563    (set (attr "highpart")
12564         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12565          (const_string "user")))])
12566
12567 (define_expand "mshfhi_l"
12568   [(match_operand:V2SI 0 "arith_reg_dest" "")
12569    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12570    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12571   "TARGET_SHMEDIA"
12572   "
12573 {
12574   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12575              (operands[0], operands[1], operands[2]));
12576   DONE;
12577 }")
12578
12579 (define_expand "mshflo_l"
12580   [(match_operand:V2SI 0 "arith_reg_dest" "")
12581    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12582    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12583   "TARGET_SHMEDIA"
12584   "
12585 {
12586   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12587              (operands[0], operands[1], operands[2]));
12588   DONE;
12589 }")
12590
12591 (define_insn "mshf4_l"
12592   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12593         (vec_select:V2SI
12594          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12595                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12596          (parallel [(const_int 1) (const_int 3)])))]
12597   "TARGET_SHMEDIA"
12598   "* return (TARGET_LITTLE_ENDIAN
12599              ? \"mshfhi.l       %N1, %N2, %0\"
12600              : \"mshflo.l       %N1, %N2, %0\");"
12601   [(set_attr "type" "arith_media")
12602    (set (attr "highpart")
12603         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12604          (const_string "user")))])
12605
12606 (define_insn "mshf0_l"
12607   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12608         (vec_select:V2SI
12609          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12610                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12611          (parallel [(const_int 0) (const_int 2)])))]
12612   "TARGET_SHMEDIA"
12613   "* return (TARGET_LITTLE_ENDIAN
12614              ? \"mshflo.l       %N1, %N2, %0\"
12615              : \"mshfhi.l       %N1, %N2, %0\");"
12616   [(set_attr "type" "arith_media")
12617    (set (attr "highpart")
12618         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12619          (const_string "user")))])
12620
12621 (define_expand "mshfhi_w"
12622   [(match_operand:V4HI 0 "arith_reg_dest" "")
12623    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12624    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12625   "TARGET_SHMEDIA"
12626   "
12627 {
12628   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12629              (operands[0], operands[1], operands[2]));
12630   DONE;
12631 }")
12632
12633 (define_expand "mshflo_w"
12634   [(match_operand:V4HI 0 "arith_reg_dest" "")
12635    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12636    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12637   "TARGET_SHMEDIA"
12638   "
12639 {
12640   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12641              (operands[0], operands[1], operands[2]));
12642   DONE;
12643 }")
12644
12645 (define_insn "mshf4_w"
12646   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12647         (vec_select:V4HI
12648          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12649                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12650          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12651   "TARGET_SHMEDIA"
12652   "* return (TARGET_LITTLE_ENDIAN
12653              ? \"mshfhi.w       %N1, %N2, %0\"
12654              : \"mshflo.w       %N1, %N2, %0\");"
12655   [(set_attr "type" "arith_media")
12656    (set (attr "highpart")
12657         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12658          (const_string "user")))])
12659
12660 (define_insn "mshf0_w"
12661   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12662         (vec_select:V4HI
12663          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12664                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12665          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12666   "TARGET_SHMEDIA"
12667   "* return (TARGET_LITTLE_ENDIAN
12668              ? \"mshflo.w       %N1, %N2, %0\"
12669              : \"mshfhi.w       %N1, %N2, %0\");"
12670   [(set_attr "type" "arith_media")
12671    (set (attr "highpart")
12672         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12673          (const_string "user")))])
12674
12675 (define_insn "mshflo_w_x"
12676   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12677         (vec_select:V4HI
12678          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12679                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12680          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12681   "TARGET_SHMEDIA"
12682   "mshflo.w     %N1, %N2, %0"
12683   [(set_attr "type" "arith_media")
12684    (set_attr "highpart" "ignore")])
12685
12686 ;; These are useful to expand ANDs and as combiner patterns.
12687 (define_insn_and_split "mshfhi_l_di"
12688   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12689         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12690                              (const_int 32))
12691                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12692                         (const_int -4294967296))))]
12693   "TARGET_SHMEDIA"
12694   "@
12695         mshfhi.l        %N1, %N2, %0
12696         #"
12697   "TARGET_SHMEDIA && reload_completed
12698    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12699   [(set (match_dup 3) (match_dup 4))
12700    (set (match_dup 5) (match_dup 6))]
12701   "
12702 {
12703   operands[3] = gen_lowpart (SImode, operands[0]);
12704   operands[4] = gen_highpart (SImode, operands[1]);
12705   operands[5] = gen_highpart (SImode, operands[0]);
12706   operands[6] = gen_highpart (SImode, operands[2]);
12707 }"
12708   [(set_attr "type" "arith_media")])
12709
12710 (define_insn "*mshfhi_l_di_rev"
12711   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12712         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12713                         (const_int -4294967296))
12714                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12715                              (const_int 32))))]
12716   "TARGET_SHMEDIA"
12717   "mshfhi.l     %N2, %N1, %0"
12718   [(set_attr "type" "arith_media")])
12719
12720 (define_split
12721   [(set (match_operand:DI 0 "arith_reg_dest" "")
12722         (ior:DI (zero_extend:DI (match_operand:SI 1
12723                                               "extend_reg_or_0_operand" ""))
12724                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12725                         (const_int -4294967296))))
12726    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12727   "TARGET_SHMEDIA"
12728   [(const_int 0)]
12729   "
12730 {
12731   emit_insn (gen_ashldi3_media (operands[3],
12732                                 simplify_gen_subreg (DImode, operands[1],
12733                                                      SImode, 0),
12734                                 GEN_INT (32)));
12735   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12736   DONE;
12737 }")
12738
12739 (define_insn "mshflo_l_di"
12740   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12741         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12742                         (const_int 4294967295))
12743                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12744                            (const_int 32))))]
12745
12746   "TARGET_SHMEDIA"
12747   "mshflo.l     %N1, %N2, %0"
12748   [(set_attr "type" "arith_media")
12749    (set_attr "highpart" "ignore")])
12750
12751 (define_insn "*mshflo_l_di_rev"
12752   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12753         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12754                            (const_int 32))
12755                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12756                         (const_int 4294967295))))]
12757
12758   "TARGET_SHMEDIA"
12759   "mshflo.l     %N2, %N1, %0"
12760   [(set_attr "type" "arith_media")
12761    (set_attr "highpart" "ignore")])
12762
12763 ;; Combiner pattern for trampoline initialization.
12764 (define_insn_and_split "*double_shori"
12765   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12766         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12767                            (const_int 32))
12768                 (match_operand:DI 2 "const_int_operand" "n")))]
12769   "TARGET_SHMEDIA
12770    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12771   "#"
12772   "rtx_equal_p (operands[0], operands[1])"
12773   [(const_int 0)]
12774   "
12775 {
12776   HOST_WIDE_INT v = INTVAL (operands[2]);
12777
12778   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12779   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12780   DONE;
12781 }"
12782   [(set_attr "highpart" "ignore")])
12783
12784
12785 (define_insn "*mshflo_l_di_x"
12786   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12787         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12788                                  "rZ"))
12789                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12790                            (const_int 32))))]
12791
12792   "TARGET_SHMEDIA"
12793   "mshflo.l     %N1, %N2, %0"
12794   [(set_attr "type" "arith_media")
12795    (set_attr "highpart" "ignore")])
12796
12797 (define_insn_and_split "concat_v2sf"
12798   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12799 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12800         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12801                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12802
12803   "TARGET_SHMEDIA"
12804   "@
12805         mshflo.l        %N1, %N2, %0
12806         #
12807         #"
12808   "TARGET_SHMEDIA && reload_completed
12809    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12810   [(set (match_dup 3) (match_dup 1))
12811    (set (match_dup 4) (match_dup 2))]
12812   "
12813 {
12814   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12815   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12816 }"
12817   [(set_attr "type" "arith_media")
12818    (set_attr "highpart" "ignore")])
12819
12820 (define_insn "*mshflo_l_di_x_rev"
12821   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12822         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12823                            (const_int 32))
12824                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12825
12826   "TARGET_SHMEDIA"
12827   "mshflo.l     %N2, %N1, %0"
12828   [(set_attr "type" "arith_media")
12829    (set_attr "highpart" "ignore")])
12830
12831 (define_insn "ashlv2si3"
12832   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12833         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12834                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12835   "TARGET_SHMEDIA"
12836   "mshlld.l     %1, %2, %0"
12837   [(set_attr "type" "arith_media")
12838    (set_attr "highpart" "depend")])
12839
12840 (define_split
12841   [(set (match_operand 0 "any_register_operand" "")
12842         (match_operator 3 "shift_operator"
12843           [(match_operand 1 "any_register_operand" "")
12844            (match_operand 2 "shift_count_reg_operand" "")]))]
12845   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12846   [(set (match_dup 0) (match_dup 3))]
12847   "
12848 {
12849   rtx count = operands[2];
12850   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12851
12852   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12853          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12854          || GET_CODE (count) == TRUNCATE)
12855     count = XEXP (count, 0);
12856   inner_mode = GET_MODE (count);
12857   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12858                                subreg_lowpart_offset (outer_mode, inner_mode));
12859   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12860                                 operands[1], count);
12861 }")
12862
12863 (define_insn "ashlv4hi3"
12864   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12865         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12866                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12867   "TARGET_SHMEDIA"
12868   "mshlld.w     %1, %2, %0"
12869   [(set_attr "type" "arith_media")
12870    (set_attr "highpart" "depend")])
12871
12872 (define_insn "lshrv2si3"
12873   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12874         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12875                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12876   "TARGET_SHMEDIA"
12877   "mshlrd.l     %1, %2, %0"
12878   [(set_attr "type" "arith_media")
12879    (set_attr "highpart" "depend")])
12880
12881 (define_insn "lshrv4hi3"
12882   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12883         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12884                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12885   "TARGET_SHMEDIA"
12886   "mshlrd.w     %1, %2, %0"
12887   [(set_attr "type" "arith_media")
12888    (set_attr "highpart" "depend")])
12889
12890 (define_insn "subv2si3"
12891   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12892         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12893                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12894   "TARGET_SHMEDIA"
12895   "msub.l       %N1, %2, %0"
12896   [(set_attr "type" "arith_media")
12897    (set_attr "highpart" "depend")])
12898
12899 (define_insn "subv4hi3"
12900   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12901         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12902                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12903   "TARGET_SHMEDIA"
12904   "msub.w       %N1, %2, %0"
12905   [(set_attr "type" "arith_media")
12906    (set_attr "highpart" "depend")])
12907
12908 (define_insn_and_split "subv2hi3"
12909   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12910         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12911                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12912   "TARGET_SHMEDIA"
12913   "#"
12914   "TARGET_SHMEDIA"
12915   [(const_int 0)]
12916   "
12917 {
12918   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12919   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12920   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12921   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12922   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12923
12924   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12925   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12926   DONE;
12927 }"
12928   [(set_attr "highpart" "must_split")])
12929
12930 (define_insn "sssubv2si3"
12931   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12932         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12933                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12934   "TARGET_SHMEDIA"
12935   "msubs.l      %N1, %2, %0"
12936   [(set_attr "type" "mcmp_media")
12937    (set_attr "highpart" "depend")])
12938
12939 (define_insn "ussubv8qi3"
12940   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12941         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12942                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12943   "TARGET_SHMEDIA"
12944   "msubs.ub     %N1, %2, %0"
12945   [(set_attr "type" "mcmp_media")
12946    (set_attr "highpart" "depend")])
12947
12948 (define_insn "sssubv4hi3"
12949   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12950         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12951                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12952   "TARGET_SHMEDIA"
12953   "msubs.w      %N1, %2, %0"
12954   [(set_attr "type" "mcmp_media")
12955    (set_attr "highpart" "depend")])
12956
12957 ;; Floating Point Intrinsics
12958
12959 (define_insn "fcosa_s"
12960   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12961         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12962                    UNSPEC_FCOSA))]
12963   "TARGET_SHMEDIA"
12964   "fcosa.s      %1, %0"
12965   [(set_attr "type" "atrans_media")])
12966
12967 (define_insn "fsina_s"
12968   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12969         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12970                    UNSPEC_FSINA))]
12971   "TARGET_SHMEDIA"
12972   "fsina.s      %1, %0"
12973   [(set_attr "type" "atrans_media")])
12974
12975 (define_insn "fipr"
12976   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12977         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12978                                                     "fp_arith_reg_operand" "f")
12979                                                    (match_operand:V4SF 2
12980                                                     "fp_arith_reg_operand" "f"))
12981                                          (parallel [(const_int 0)]))
12982                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12983                                          (parallel [(const_int 1)])))
12984                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12985                                          (parallel [(const_int 2)]))
12986                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12987                                          (parallel [(const_int 3)])))))]
12988   "TARGET_SHMEDIA"
12989   "fipr.s       %1, %2, %0"
12990   [(set_attr "type" "fparith_media")])
12991
12992 (define_insn "fsrra_s"
12993   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12994         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12995                    UNSPEC_FSRRA))]
12996   "TARGET_SHMEDIA"
12997   "fsrra.s      %1, %0"
12998   [(set_attr "type" "atrans_media")])
12999
13000 (define_insn "ftrv"
13001   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13002         (plus:V4SF
13003          (plus:V4SF
13004           (mult:V4SF
13005            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13006                             (parallel [(const_int 0) (const_int 5)
13007                                        (const_int 10) (const_int 15)]))
13008            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13009           (mult:V4SF
13010            (vec_select:V4SF (match_dup 1)
13011                             (parallel [(const_int 4) (const_int 9)
13012                                        (const_int 14) (const_int 3)]))
13013            (vec_select:V4SF (match_dup 2)
13014                             (parallel [(const_int 1) (const_int 2)
13015                                        (const_int 3) (const_int 0)]))))
13016          (plus:V4SF
13017           (mult:V4SF
13018            (vec_select:V4SF (match_dup 1)
13019                             (parallel [(const_int 8) (const_int 13)
13020                                        (const_int 2) (const_int 7)]))
13021            (vec_select:V4SF (match_dup 2)
13022                             (parallel [(const_int 2) (const_int 3)
13023                                        (const_int 0) (const_int 1)])))
13024           (mult:V4SF
13025            (vec_select:V4SF (match_dup 1)
13026                             (parallel [(const_int 12) (const_int 1)
13027                                        (const_int 6) (const_int 11)]))
13028            (vec_select:V4SF (match_dup 2)
13029                             (parallel [(const_int 3) (const_int 0)
13030                                        (const_int 1) (const_int 2)]))))))]
13031   "TARGET_SHMEDIA"
13032   "ftrv.s %1, %2, %0"
13033   [(set_attr "type" "fparith_media")])
13034
13035 (define_insn "ldhi_l"
13036   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13037         (zero_extract:SI
13038          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13039                                   (const_int 3))
13040                           (const_int -3)))
13041          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13042          (const_int 0)))]
13043   "TARGET_SHMEDIA32"
13044   "ldhi.l       %U1, %0"
13045   [(set_attr "type" "load_media")])
13046
13047 (define_insn "ldhi_q"
13048   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13049         (zero_extract:DI
13050          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13051                                   (const_int 7))
13052                           (const_int -7)))
13053          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13054          (const_int 0)))]
13055   "TARGET_SHMEDIA32"
13056   "ldhi.q       %U1, %0"
13057   [(set_attr "type" "load_media")])
13058
13059 (define_insn_and_split "*ldhi_q_comb0"
13060   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13061         (zero_extract:DI
13062          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13063                                             "register_operand" "r")
13064                                            (match_operand:SI 2
13065                                             "ua_offset" "I06"))
13066                                   (const_int 7))
13067                           (const_int -7)))
13068          (plus:SI (and:SI (match_dup 1) (const_int 7))
13069                   (const_int 1))
13070          (const_int 0)))]
13071   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13072   "#"
13073   ""
13074   [(pc)]
13075   "emit_insn (gen_ldhi_q (operands[0],
13076                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13077    DONE;")
13078
13079
13080 (define_insn_and_split "*ldhi_q_comb1"
13081   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13082         (zero_extract:DI
13083          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13084                                             "register_operand" "r")
13085                                            (match_operand:SI 2
13086                                             "ua_offset" "I06"))
13087                                   (const_int 7))
13088                           (const_int -7)))
13089          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13090                                                    "ua_offset" "I06"))
13091                           (const_int 7))
13092                   (const_int 1))
13093          (const_int 0)))]
13094   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13095    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13096   "#"
13097   ""
13098   [(pc)]
13099   "emit_insn (gen_ldhi_q (operands[0],
13100                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13101    DONE;")
13102
13103
13104 (define_insn "ldlo_l"
13105   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13106         (zero_extract:SI
13107          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13108                          (const_int -4)))
13109          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13110          (and:SI (match_dup 1) (const_int 3))))]
13111   "TARGET_SHMEDIA32"
13112   "ldlo.l       %U1, %0"
13113   [(set_attr "type" "load_media")])
13114
13115 (define_insn "ldlo_q"
13116   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13117         (zero_extract:DI
13118          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13119                          (const_int -8)))
13120          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13121          (and:SI (match_dup 1) (const_int 7))))]
13122   "TARGET_SHMEDIA32"
13123   "ldlo.q       %U1, %0"
13124   [(set_attr "type" "load_media")])
13125
13126 (define_insn_and_split "*ldlo_q_comb0"
13127   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13128         (zero_extract:DI
13129          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13130                                   (match_operand:SI 2 "ua_offset" "I06"))
13131                          (const_int -8)))
13132          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13133          (and:SI (match_dup 1) (const_int 7))))]
13134   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13135   "#"
13136   ""
13137   [(pc)]
13138   "emit_insn (gen_ldlo_q (operands[0],
13139                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13140    DONE;")
13141
13142 (define_insn_and_split "*ldlo_q_comb1"
13143   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13144         (zero_extract:DI
13145          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13146                                   (match_operand:SI 2 "ua_offset" "I06"))
13147                          (const_int -8)))
13148          (minus:SI (const_int 8)
13149                    (and:SI (plus:SI (match_dup 1)
13150                                     (match_operand:SI 3 "ua_offset" "I06"))
13151                            (const_int 7)))
13152          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13153   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13154    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13155   "#"
13156   ""
13157   [(pc)]
13158   "emit_insn (gen_ldlo_q (operands[0],
13159                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13160    DONE;")
13161
13162 (define_insn "sthi_l"
13163   [(set (zero_extract:SI
13164          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13165                                   (const_int 3))
13166                           (const_int -3)))
13167          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13168          (const_int 0))
13169         (match_operand:SI 1 "arith_reg_operand" "r"))]
13170   "TARGET_SHMEDIA32"
13171   "sthi.l       %U0, %1"
13172   [(set_attr "type" "ustore_media")])
13173
13174 ;; All unaligned stores are considered to be 'narrow' because they typically
13175 ;; operate on less that a quadword, and when they operate on a full quadword,
13176 ;; the vanilla store high / store low sequence will cause a stall if not
13177 ;; scheduled apart.
13178 (define_insn "sthi_q"
13179   [(set (zero_extract:DI
13180          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13181                                   (const_int 7))
13182                           (const_int -7)))
13183          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13184          (const_int 0))
13185         (match_operand:DI 1 "arith_reg_operand" "r"))]
13186   "TARGET_SHMEDIA32"
13187   "sthi.q       %U0, %1"
13188   [(set_attr "type" "ustore_media")])
13189
13190 (define_insn_and_split "*sthi_q_comb0"
13191   [(set (zero_extract:DI
13192          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13193                                             "register_operand" "r")
13194                                            (match_operand:SI 1 "ua_offset"
13195                                             "I06"))
13196                                   (const_int 7))
13197                           (const_int -7)))
13198          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13199          (const_int 0))
13200         (match_operand:DI 2 "arith_reg_operand" "r"))]
13201   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13202   "#"
13203   ""
13204   [(pc)]
13205   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13206                           operands[2]));
13207    DONE;")
13208
13209 (define_insn_and_split "*sthi_q_comb1"
13210   [(set (zero_extract:DI
13211          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13212                                             "register_operand" "r")
13213                                            (match_operand:SI 1 "ua_offset"
13214                                             "I06"))
13215                                   (const_int 7))
13216                           (const_int -7)))
13217          (plus:SI (and:SI (plus:SI (match_dup 0)
13218                                    (match_operand:SI 2 "ua_offset" "I06"))
13219                           (const_int 7))
13220                   (const_int 1))
13221          (const_int 0))
13222         (match_operand:DI 3 "arith_reg_operand" "r"))]
13223   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13224    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13225   "#"
13226   ""
13227   [(pc)]
13228   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13229                           operands[3]));
13230    DONE;")
13231
13232 ;; This is highpart user because the address is used as full 64 bit.
13233 (define_insn "stlo_l"
13234   [(set (zero_extract:SI
13235          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13236                          (const_int -4)))
13237          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13238          (and:SI (match_dup 0) (const_int 3)))
13239         (match_operand:SI 1 "arith_reg_operand" "r"))]
13240   "TARGET_SHMEDIA32"
13241   "stlo.l       %U0, %1"
13242   [(set_attr "type" "ustore_media")])
13243
13244 (define_insn "stlo_q"
13245   [(set (zero_extract:DI
13246          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13247                          (const_int -8)))
13248          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13249          (and:SI (match_dup 0) (const_int 7)))
13250         (match_operand:DI 1 "arith_reg_operand" "r"))]
13251   "TARGET_SHMEDIA32"
13252   "stlo.q       %U0, %1"
13253   [(set_attr "type" "ustore_media")])
13254
13255 (define_insn_and_split "*stlo_q_comb0"
13256   [(set (zero_extract:DI
13257          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13258                                   (match_operand:SI 1 "ua_offset" "I06"))
13259                          (const_int -8)))
13260          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13261          (and:SI (match_dup 0) (const_int 7)))
13262         (match_operand:DI 2 "arith_reg_operand" "r"))]
13263   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13264   "#"
13265   ""
13266   [(pc)]
13267   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13268                           operands[2]));
13269    DONE;")
13270
13271 (define_insn_and_split "*stlo_q_comb1"
13272   [(set (zero_extract:DI
13273          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13274                                   (match_operand:SI 1 "ua_offset" "I06"))
13275                          (const_int -8)))
13276          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13277                                                   (match_operand:SI 2
13278                                                    "ua_offset" "I06"))
13279                                          (const_int 7)))
13280          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13281         (match_operand:DI 3 "arith_reg_operand" "r"))]
13282   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13283   "#"
13284   ""
13285   [(pc)]
13286   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13287                           operands[3]));
13288    DONE;")
13289
13290 (define_insn "ldhi_l64"
13291   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13292         (zero_extract:SI
13293          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13294                                   (const_int 3))
13295                           (const_int -3)))
13296          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13297          (const_int 0)))]
13298   "TARGET_SHMEDIA64"
13299   "ldhi.l       %U1, %0"
13300   [(set_attr "type" "load_media")])
13301
13302 (define_insn "ldhi_q64"
13303   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13304         (zero_extract:DI
13305          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13306                                   (const_int 7))
13307                           (const_int -7)))
13308          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13309          (const_int 0)))]
13310   "TARGET_SHMEDIA64"
13311   "ldhi.q       %U1, %0"
13312   [(set_attr "type" "load_media")])
13313
13314 (define_insn "ldlo_l64"
13315   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13316         (zero_extract:SI
13317          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13318                          (const_int -4)))
13319          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13320          (and:DI (match_dup 1) (const_int 3))))]
13321   "TARGET_SHMEDIA64"
13322   "ldlo.l       %U1, %0"
13323   [(set_attr "type" "load_media")])
13324
13325 (define_insn "ldlo_q64"
13326   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13327         (zero_extract:DI
13328          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13329                          (const_int -8)))
13330          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13331          (and:DI (match_dup 1) (const_int 7))))]
13332   "TARGET_SHMEDIA64"
13333   "ldlo.q       %U1, %0"
13334   [(set_attr "type" "load_media")])
13335
13336 (define_insn "sthi_l64"
13337   [(set (zero_extract:SI
13338          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13339                                   (const_int 3))
13340                           (const_int -3)))
13341          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13342          (const_int 0))
13343         (match_operand:SI 1 "arith_reg_operand" "r"))]
13344   "TARGET_SHMEDIA64"
13345   "sthi.l       %U0, %1"
13346   [(set_attr "type" "ustore_media")])
13347
13348 (define_insn "sthi_q64"
13349   [(set (zero_extract:DI
13350          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13351                                   (const_int 7))
13352                           (const_int -7)))
13353          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13354          (const_int 0))
13355         (match_operand:DI 1 "arith_reg_operand" "r"))]
13356   "TARGET_SHMEDIA64"
13357   "sthi.q       %U0, %1"
13358   [(set_attr "type" "ustore_media")])
13359
13360 (define_insn "stlo_l64"
13361   [(set (zero_extract:SI
13362          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13363                          (const_int -4)))
13364          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13365          (and:DI (match_dup 0) (const_int 3)))
13366         (match_operand:SI 1 "arith_reg_operand" "r"))]
13367   "TARGET_SHMEDIA64"
13368   "stlo.l       %U0, %1"
13369   [(set_attr "type" "ustore_media")])
13370
13371 (define_insn "stlo_q64"
13372   [(set (zero_extract:DI
13373          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13374                          (const_int -8)))
13375          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13376          (and:DI (match_dup 0) (const_int 7)))
13377         (match_operand:DI 1 "arith_reg_operand" "r"))]
13378   "TARGET_SHMEDIA64"
13379   "stlo.q       %U0, %1"
13380   [(set_attr "type" "ustore_media")])
13381
13382 (define_insn "nsb"
13383   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13384         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13385                    UNSPEC_NSB))]
13386   "TARGET_SHMEDIA"
13387   "nsb  %1, %0"
13388   [(set_attr "type" "arith_media")])
13389
13390 (define_insn "nsbsi"
13391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13392         (zero_extend:SI
13393          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13394                     UNSPEC_NSB)))]
13395   "TARGET_SHMEDIA"
13396   "nsb  %1, %0"
13397   [(set_attr "type" "arith_media")])
13398
13399 (define_insn "nsbdi"
13400   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13401         (zero_extend:DI
13402          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13403                     UNSPEC_NSB)))]
13404   "TARGET_SHMEDIA"
13405   "nsb  %1, %0"
13406   [(set_attr "type" "arith_media")])
13407
13408 (define_expand "ffsdi2"
13409   [(set (match_operand:DI 0 "arith_reg_dest" "")
13410         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13411   "TARGET_SHMEDIA"
13412   "
13413 {
13414   rtx scratch = gen_reg_rtx (DImode);
13415   rtx last;
13416
13417   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13418   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13419   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13420   emit_insn (gen_nsbdi (scratch, scratch));
13421   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13422   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13423   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13424   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13425
13426   DONE;
13427 }")
13428
13429 (define_expand "ffssi2"
13430   [(set (match_operand:SI 0 "arith_reg_dest" "")
13431         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13432   "TARGET_SHMEDIA"
13433   "
13434 {
13435   rtx scratch = gen_reg_rtx (SImode);
13436   rtx discratch = gen_reg_rtx (DImode);
13437   rtx last;
13438
13439   emit_insn (gen_adddi3 (discratch,
13440                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13441                          constm1_rtx));
13442   emit_insn (gen_andcdi3 (discratch,
13443                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13444                           discratch));
13445   emit_insn (gen_nsbsi (scratch, discratch));
13446   last = emit_insn (gen_subsi3 (operands[0],
13447                                 force_reg (SImode, GEN_INT (63)), scratch));
13448   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13449
13450   DONE;
13451 }")
13452
13453 (define_insn "byterev"
13454   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13455         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13456                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13457                                     (const_int 4) (const_int 3) (const_int 2)
13458                                     (const_int 1) (const_int 0)])))]
13459   "TARGET_SHMEDIA"
13460   "byterev      %1, %0"
13461   [(set_attr "type" "arith_media")])
13462
13463 (define_insn "*prefetch_media"
13464   [(prefetch (match_operand:QI 0 "address_operand" "p")
13465              (match_operand:SI 1 "const_int_operand" "n")
13466              (match_operand:SI 2 "const_int_operand" "n"))]
13467   "TARGET_SHMEDIA"
13468   "*
13469 {
13470   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13471   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13472   return \"\";
13473 }"
13474   [(set_attr "type" "other")])
13475
13476 (define_insn "*prefetch_i4"
13477   [(prefetch (match_operand:SI 0 "register_operand" "r")
13478              (match_operand:SI 1 "const_int_operand" "n")
13479              (match_operand:SI 2 "const_int_operand" "n"))]
13480   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13481   "*
13482 {
13483   return \"pref @%0\";
13484 }"
13485   [(set_attr "type" "other")])
13486
13487 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13488 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13489 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13490 (define_expand "prefetch"
13491   [(prefetch (match_operand 0 "address_operand" "p")
13492              (match_operand:SI 1 "const_int_operand" "n")
13493              (match_operand:SI 2 "const_int_operand" "n"))]
13494   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13495    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13496   "
13497 {
13498   if (GET_MODE (operands[0]) != Pmode
13499       || !CONST_INT_P (operands[1])
13500       || !CONST_INT_P (operands[2]))
13501     FAIL;
13502   if (! TARGET_SHMEDIA)
13503     operands[0] = force_reg (Pmode, operands[0]);
13504 }")
13505
13506 (define_insn "prefetch_m2a"
13507   [(prefetch (match_operand:SI 0 "register_operand" "r")
13508              (match_operand:SI 1 "const_int_operand" "n")
13509              (match_operand:SI 2 "const_int_operand" "n"))]
13510   "TARGET_SH2A"
13511   "pref\\t@%0"
13512   [(set_attr "type" "other")])
13513
13514 (define_insn "alloco_i"
13515   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13516         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13517   "TARGET_SHMEDIA32"
13518   "*
13519 {
13520   rtx xops[2];
13521
13522   if (GET_CODE (operands[0]) == PLUS)
13523     {
13524       xops[0] = XEXP (operands[0], 0);
13525       xops[1] = XEXP (operands[0], 1);
13526     }
13527   else
13528     {
13529       xops[0] = operands[0];
13530       xops[1] = const0_rtx;
13531     }
13532   output_asm_insn (\"alloco   %0, %1\", xops);
13533   return \"\";
13534 }"
13535   [(set_attr "type" "other")])
13536
13537 (define_split
13538   [(set (match_operand 0 "any_register_operand" "")
13539         (match_operand 1 "" ""))]
13540   "TARGET_SHMEDIA && reload_completed"
13541   [(set (match_dup 0) (match_dup 1))]
13542   "
13543 {
13544   int n_changes = 0;
13545
13546   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13547   if (!n_changes)
13548     FAIL;
13549 }")
13550
13551 ; Stack Protector Patterns
13552
13553 (define_expand "stack_protect_set"
13554   [(set (match_operand 0 "memory_operand" "")
13555         (match_operand 1 "memory_operand" ""))]
13556   ""
13557 {
13558   if (TARGET_SHMEDIA)
13559     {
13560       if (TARGET_SHMEDIA64)
13561         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13562       else
13563         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13564     }
13565   else
13566     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13567
13568   DONE;
13569 })
13570
13571 (define_insn "stack_protect_set_si"
13572   [(set (match_operand:SI 0 "memory_operand" "=m")
13573         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13574    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13575   "!TARGET_SHMEDIA"
13576   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13577   [(set_attr "type" "other")
13578    (set_attr "length" "6")])
13579
13580 (define_insn "stack_protect_set_si_media"
13581   [(set (match_operand:SI 0 "memory_operand" "=m")
13582         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13583    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13584   "TARGET_SHMEDIA"
13585   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13586   [(set_attr "type" "other")
13587    (set_attr "length" "12")])
13588
13589 (define_insn "stack_protect_set_di_media"
13590   [(set (match_operand:DI 0 "memory_operand" "=m")
13591         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13592    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13593   "TARGET_SHMEDIA64"
13594   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13595   [(set_attr "type" "other")
13596    (set_attr "length" "12")])
13597
13598 (define_expand "stack_protect_test"
13599   [(match_operand 0 "memory_operand" "")
13600    (match_operand 1 "memory_operand" "")
13601    (match_operand 2 "" "")]
13602   ""
13603 {
13604   if (TARGET_SHMEDIA)
13605     {
13606       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13607       rtx test;
13608
13609       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13610       if (TARGET_SHMEDIA64)
13611         {
13612           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13613                                                       operands[1]));
13614           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13615         }
13616       else
13617         {
13618           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13619                                                       operands[1]));
13620           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13621         }
13622     }
13623   else
13624     {
13625       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13626       emit_jump_insn (gen_branch_true (operands[2]));
13627     }
13628
13629   DONE;
13630 })
13631
13632 (define_insn "stack_protect_test_si"
13633   [(set (reg:SI T_REG)
13634         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13635                     (match_operand:SI 1 "memory_operand" "m")]
13636                    UNSPEC_SP_TEST))
13637   (set (match_scratch:SI 2 "=&r") (const_int 0))
13638   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13639   "!TARGET_SHMEDIA"
13640   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13641   [(set_attr "type" "other")
13642    (set_attr "length" "10")])
13643
13644 (define_insn "stack_protect_test_si_media"
13645   [(set (match_operand:SI 0 "register_operand" "=&r")
13646         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13647                     (match_operand:SI 2 "memory_operand" "m")]
13648                    UNSPEC_SP_TEST))
13649   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13650   "TARGET_SHMEDIA"
13651   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13652   [(set_attr "type" "other")
13653    (set_attr "length" "16")])
13654
13655 (define_insn "stack_protect_test_di_media"
13656   [(set (match_operand:DI 0 "register_operand" "=&r")
13657         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13658                     (match_operand:DI 2 "memory_operand" "m")]
13659                    UNSPEC_SP_TEST))
13660   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13661   "TARGET_SHMEDIA64"
13662   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13663   [(set_attr "type" "other")
13664    (set_attr "length" "16")])
13665
13666 (include "sync.md")