OSDN Git Service

ce660185dd386595c77cbb9238e93ab601a669c9
[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
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_CHKADD        38)
154   (UNSPEC_SP_SET        40)
155   (UNSPEC_SP_TEST       41)
156   (UNSPEC_MOVUA         42)
157
158   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160   (UNSPEC_EXTRACT_S16   43)
161   (UNSPEC_EXTRACT_U16   44)
162
163   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164   (UNSPEC_SYMOFF        45)
165
166   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167   (UNSPEC_PCREL_SYMOFF  46)
168
169   ;; These are used with unspec_volatile.
170   (UNSPECV_BLOCKAGE     0)
171   (UNSPECV_ALIGN        1)
172   (UNSPECV_CONST2       2)
173   (UNSPECV_CONST4       4)
174   (UNSPECV_CONST8       6)
175   (UNSPECV_WINDOW_END   10)
176   (UNSPECV_CONST_END    11)
177   (UNSPECV_EH_RETURN    12)
178 ])
179
180 ;; -------------------------------------------------------------------------
181 ;; Attributes
182 ;; -------------------------------------------------------------------------
183
184 ;; Target CPU.
185
186 (define_attr "cpu"
187  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188   (const (symbol_ref "sh_cpu_attr")))
189
190 (define_attr "endian" "big,little"
191  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192                       (const_string "little") (const_string "big"))))
193
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197                          (const_string "yes") (const_string "no"))))
198
199 (define_attr "fmovd" "yes,no"
200   (const (if_then_else (symbol_ref "TARGET_FMOVD")
201                        (const_string "yes") (const_string "no"))))
202 ;; pipeline model
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
204   (const
205    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207          (const_string "sh1"))))
208
209 ;; cbranch      conditional branch instructions
210 ;; jump         unconditional jumps
211 ;; arith        ordinary arithmetic
212 ;; arith3       a compound insn that behaves similarly to a sequence of
213 ;;              three insns of type arith
214 ;; arith3b      like above, but might end with a redirected branch
215 ;; load         from memory
216 ;; load_si      Likewise, SImode variant for general register.
217 ;; fload        Likewise, but load to fp register.
218 ;; store        to memory
219 ;; fstore       floating point register to memory
220 ;; move         general purpose register to register
221 ;; movi8        8-bit immediate to general purpose register
222 ;; mt_group     other sh4 mt instructions
223 ;; fmove        register to register, floating point
224 ;; smpy         word precision integer multiply
225 ;; dmpy         longword or doublelongword precision integer multiply
226 ;; return       rts
227 ;; pload        load of pr reg, which can't be put into delay slot of rts
228 ;; prset        copy register to pr reg, ditto
229 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
230 ;; prget        copy pr to register, ditto
231 ;; pcload       pc relative load of constant value
232 ;; pcfload      Likewise, but load to fp register.
233 ;; pcload_si    Likewise, SImode variant for general register.
234 ;; rte          return from exception
235 ;; sfunc        special function call with known used registers
236 ;; call         function call
237 ;; fp           floating point
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv         floating point divide (or square root)
240 ;; gp_fpul      move from general purpose register to fpul
241 ;; fpul_gp      move from fpul to general purpose register
242 ;; mac_gp       move from mac[lh] to general purpose register
243 ;; gp_mac       move from general purpose register to mac[lh]
244 ;; mac_mem      move from mac[lh] to memory
245 ;; mem_mac      move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s       fix_truncsfsi2_i4
248 ;; dfdiv        double precision floating point divide (or square root)
249 ;; cwb          ic_invalidate_line_i
250 ;; movua        SH4a unaligned load
251 ;; fsrra        square root reciprocal approximate
252 ;; fsca         sine and cosine approximate
253 ;; tls_load     load TLS related address
254 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media    SHmedia compare instructions
257 ;; dfdiv_media  SHmedia double precision divide and square root
258 ;; dfmul_media  SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media   SHmedia longword multiply
262 ;; fcmp_media   SHmedia floating point compare instructions
263 ;; fdiv_media   SHmedia single precision divide and square root
264 ;; fload_media  SHmedia floating point register load instructions
265 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media  SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media   SHmedia unconditional branch instructions
272 ;; load_media   SHmedia general register load instructions
273 ;; pt_media     SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media  SHmedia ptabs instruction
275 ;; store_media  SHmedia general register store instructions
276 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media    SHmedia mac-style fixed point operations
278 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil          no-op move, will be deleted.
282
283 (define_attr "type"
284  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
285   (const_string "other"))
286
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
289 ;;
290 ;; mt_group      SH4 "mt" group instructions.
291 ;;
292 ;; ex_group      SH4 "ex" group instructions.
293 ;;
294 ;; ls_group      SH4 "ls" group instructions.
295 ;;
296
297 (define_attr "insn_class"
298   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302          (eq_attr "type" "cbranch,jump") (const_string "br_group")
303          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304            (const_string "fe_group")
305          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306         (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
310
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
312
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
314
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
318 ;; state.
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long.  Something in the
325 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
328 ; 2 bytes.
329
330 ;; The maximum range used for SImode constant pool entries is 1018.  A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table.  That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
342 ;;
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
345
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347 ;; inside an le.
348 (define_attr "short_cbranch_p" "no,yes"
349   (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
350          (const_string "no")
351          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352          (const_string "yes")
353          (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356          (const_string "yes")
357          ] (const_string "no")))
358
359 (define_attr "med_branch_p" "no,yes"
360   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361               (const_int 1988))
362          (const_string "yes")
363          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366               (const_int 8186))
367          (const_string "yes")
368          ] (const_string "no")))
369
370 (define_attr "med_cbranch_p" "no,yes"
371   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372               (const_int 1986))
373          (const_string "yes")
374          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377                (const_int 8184))
378          (const_string "yes")
379          ] (const_string "no")))
380
381 (define_attr "braf_branch_p" "no,yes"
382   (cond [(match_test "! TARGET_SH2")
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385               (const_int 20660))
386          (const_string "yes")
387          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390               (const_int 65530))
391          (const_string "yes")
392          ] (const_string "no")))
393
394 (define_attr "braf_cbranch_p" "no,yes"
395   (cond [(match_test "! TARGET_SH2")
396          (const_string "no")
397          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398               (const_int 20658))
399          (const_string "yes")
400          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401          (const_string "no")
402          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403               (const_int 65528))
404          (const_string "yes")
405          ] (const_string "no")))
406
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
413
414 ; All other instructions are two bytes long by default.
415
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419   (cond [(eq_attr "type" "cbranch")
420          (cond [(eq_attr "short_cbranch_p" "yes")
421                 (const_int 2)
422                 (eq_attr "med_cbranch_p" "yes")
423                 (const_int 6)
424                 (eq_attr "braf_cbranch_p" "yes")
425                 (const_int 12)
426 ;; ??? using pc is not computed transitively.
427                 (ne (match_dup 0) (match_dup 0))
428                 (const_int 14)
429                 (match_test "flag_pic")
430                 (const_int 24)
431                 ] (const_int 16))
432          (eq_attr "type" "jump")
433          (cond [(eq_attr "med_branch_p" "yes")
434                 (const_int 2)
435                 (and (match_test "prev_nonnote_insn (insn)")
436                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")                              (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")                             (symbol_ref "code_for_indirect_jump_scratch"))))
438                 (cond [(eq_attr "braf_branch_p" "yes")
439                        (const_int 6)
440                        (not (match_test "flag_pic"))
441                        (const_int 10)
442                        (match_test "TARGET_SH2")
443                        (const_int 10)] (const_int 18))
444                 (eq_attr "braf_branch_p" "yes")
445                 (const_int 10)
446 ;; ??? using pc is not computed transitively.
447                 (ne (match_dup 0) (match_dup 0))
448                 (const_int 12)
449                 (match_test "flag_pic")
450                 (const_int 22)
451                 ] (const_int 14))
452          (eq_attr "type" "pt_media")
453          (if_then_else (match_test "TARGET_SHMEDIA64")
454                        (const_int 20) (const_int 12))
455          (and (eq_attr "type" "jump_media")
456               (match_test "TARGET_SH5_CUT2_WORKAROUND"))
457          (const_int 8)
458          ] (if_then_else (match_test "TARGET_SHMEDIA")
459                          (const_int 4)
460                          (const_int 2))))
461
462 ;; DFA descriptions for the pipelines
463
464 (include "sh1.md")
465 (include "shmedia.md")
466 (include "sh4.md")
467
468 (include "predicates.md")
469 (include "constraints.md")
470
471 ;; Definitions for filling delay slots
472
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
474
475 (define_attr "banked" "yes,no" 
476         (cond [(match_test "sh_loads_bankedreg_p (insn)")
477                (const_string "yes")]
478               (const_string "no")))
479
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482         (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
483                (const_string "no")]
484               (const_string "yes")))
485
486 (define_attr "interrupt_function" "no,yes"
487   (const (symbol_ref "current_function_interrupt")))
488
489 (define_attr "in_delay_slot" "yes,no"
490   (cond [(eq_attr "type" "cbranch") (const_string "no")
491          (eq_attr "type" "pcload,pcload_si") (const_string "no")
492          (eq_attr "needs_delay_slot" "yes") (const_string "no")
493          (eq_attr "length" "2") (const_string "yes")
494          ] (const_string "no")))
495
496 (define_attr "cond_delay_slot" "yes,no"
497   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498          ] (const_string "no")))
499
500 (define_attr "is_sfunc" ""
501   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
502
503 (define_attr "is_mac_media" ""
504   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
505
506 (define_attr "branch_zero" "yes,no"
507   (cond [(eq_attr "type" "!cbranch") (const_string "no")
508          (ne (symbol_ref "(next_active_insn (insn)\
509                            == (prev_active_insn\
510                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511                           && get_attr_length (next_active_insn (insn)) == 2")
512              (const_int 0))
513          (const_string "yes")]
514         (const_string "no")))
515
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520         (const_string "no")))
521
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527          (const_string "yes")]
528         (const_string "no")))
529
530 (define_attr "any_int_load" "yes,no"
531   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532          (const_string "yes")]
533         (const_string "no")))
534
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536   (const_string "user"))
537
538 (define_delay
539   (eq_attr "needs_delay_slot" "yes")
540   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
541
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
546
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
549
550 (define_delay
551   (eq_attr "type" "return")
552   [(and (eq_attr "in_delay_slot" "yes")
553         (ior (and (eq_attr "interrupt_function" "no")
554                   (eq_attr "type" "!pload,prset"))
555              (and (eq_attr "interrupt_function" "yes")
556                   (ior
557                    (not (match_test "TARGET_SH3"))
558                    (eq_attr "hit_stack" "no")
559                    (eq_attr "banked" "no"))))) (nil) (nil)])
560
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
563
564 (define_delay
565   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566   [(and (eq_attr "in_delay_slot" "yes")
567         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
568
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
571
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
575
576 (define_delay
577   (and (eq_attr "type" "cbranch")
578        (match_test "TARGET_SH2"))
579   ;; SH2e has a hardware bug that pretty much prohibits the use of
580   ;; annuled delay slots.
581   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
583 \f
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
587
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group 
592 ;; instructions and thus will be executed in parallel.  On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
595
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits 
598 ;; and single bits.
599
600 (define_insn "tstsi_t"
601   [(set (reg:SI T_REG)
602         (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603                        (match_operand:SI 1 "logical_operand" "K08,r"))
604                (const_int 0)))]
605   "TARGET_SH1"
606   "tst  %1,%0"
607   [(set_attr "type" "mt_group")])
608
609 (define_insn "tsthi_t"
610   [(set (reg:SI T_REG)
611         (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612                                   (match_operand 1 "const_int_operand")) 0)
613                (const_int 0)))]
614   "TARGET_SH1
615    && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
616   "tst  %1,%0"
617   [(set_attr "type" "mt_group")])
618
619 (define_insn "tstqi_t"
620   [(set (reg:SI T_REG)
621         (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622                                   (match_operand 1 "const_int_operand")) 0)
623                (const_int 0)))]
624   "TARGET_SH1
625    && (CONST_OK_FOR_K08 (INTVAL (operands[1])) 
626        || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
627 {
628   operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
629   return "tst   %1,%0";
630 }
631   [(set_attr "type" "mt_group")])
632
633 ;; Test low QI subreg against zero.
634 ;; This avoids unecessary zero extension before the test.
635
636 (define_insn "tstqi_t_zero"
637   [(set (reg:SI T_REG)
638         (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
639   "TARGET_SH1"
640   "tst  #255,%0"
641   [(set_attr "type" "mt_group")])
642
643 ;; Extract LSB, negate and store in T bit.
644
645 (define_insn "tstsi_t_and_not"
646   [(set (reg:SI T_REG)
647          (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
648                  (const_int 1)))]
649   "TARGET_SH1"
650   "tst  #1,%0"
651   [(set_attr "type" "mt_group")])
652
653 ;; Extract contiguous bits and compare them against zero.
654
655 (define_insn "tstsi_t_zero_extract_eq"
656   [(set (reg:SI T_REG)
657         (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658                 (match_operand:SI 1 "const_int_operand")
659                 (match_operand:SI 2 "const_int_operand"))
660          (const_int 0)))]
661   "TARGET_SH1
662    && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
663 {
664   operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
665   return "tst   %1,%0";
666 }
667   [(set_attr "type" "mt_group")])
668
669 ;; This split is required when testing bits in a QI subreg.
670
671 (define_split
672   [(set (reg:SI T_REG)
673    (eq:SI (if_then_else:SI (zero_extract:SI
674                             (match_operand 0 "logical_operand" "")
675                             (match_operand 1 "const_int_operand")
676                             (match_operand 2 "const_int_operand"))
677                            (match_operand 3 "const_int_operand")
678                            (const_int 0))
679           (const_int 0)))]
680   "TARGET_SH1
681    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683   [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
684                               (const_int 0)))]
685   "
686 {
687   if (GET_MODE (operands[0]) == QImode)
688     operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
689 }")
690
691 ;; Extract single bit, negate and store it in the T bit.
692 ;; Not used for SH4A.
693
694 (define_insn "tstsi_t_zero_extract_xor"
695   [(set (reg:SI T_REG)
696         (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
697                           (match_operand:SI 3 "const_int_operand"))
698                          (match_operand:SI 1 "const_int_operand")
699                          (match_operand:SI 2 "const_int_operand")))]
700   "TARGET_SH1
701    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
702    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
703   "tst  %3,%0"
704   [(set_attr "type" "mt_group")])
705
706 ;; Extract single bit, negate and store it in the T bit.
707 ;; Used for SH4A little endian.
708
709 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
710   [(set (reg:SI T_REG)
711         (zero_extract:SI
712          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
713                             (match_operand:SI 3 "const_int_operand")) 0)
714          (match_operand:SI 1 "const_int_operand")
715          (match_operand:SI 2 "const_int_operand")))]
716   "TARGET_SH1 && TARGET_LITTLE_ENDIAN
717    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
718       == (INTVAL (operands[3]) & 255)
719    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
720 {
721   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
722   return "tst   %3,%0";
723 }
724   [(set_attr "type" "mt_group")])
725
726 ;; Extract single bit, negate and store it in the T bit.
727 ;; Used for SH4A big endian.
728
729 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
730   [(set (reg:SI T_REG)
731         (zero_extract:SI
732          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
733                             (match_operand:SI 3 "const_int_operand")) 3)
734          (match_operand:SI 1 "const_int_operand")
735          (match_operand:SI 2 "const_int_operand")))]
736   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
737    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
738       == (INTVAL (operands[3]) & 255)
739    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
740 {
741   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
742   return "tst   %3,%0";
743 }
744   [(set_attr "type" "mt_group")])
745
746 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
747 ;; That would still allow reload to create cmpi instructions, but would
748 ;; perhaps allow forcing the constant into a register when that is better.
749 ;; Probably should use r0 for mem/imm compares, but force constant into a
750 ;; register for pseudo/imm compares.
751
752 (define_insn "cmpeqsi_t"
753   [(set (reg:SI T_REG)
754         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
755                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
756   "TARGET_SH1"
757   "@
758         tst     %0,%0
759         cmp/eq  %1,%0
760         cmp/eq  %1,%0"
761    [(set_attr "type" "mt_group")])
762
763 (define_insn "cmpgtsi_t"
764   [(set (reg:SI T_REG)
765         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
766                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
767   "TARGET_SH1"
768   "@
769         cmp/gt  %1,%0
770         cmp/pl  %0"
771    [(set_attr "type" "mt_group")])
772
773 (define_insn "cmpgesi_t"
774   [(set (reg:SI T_REG)
775         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
777   "TARGET_SH1"
778   "@
779         cmp/ge  %1,%0
780         cmp/pz  %0"
781    [(set_attr "type" "mt_group")])
782
783 ;; -------------------------------------------------------------------------
784 ;; SImode compare and branch
785 ;; -------------------------------------------------------------------------
786
787 (define_expand "cbranchsi4"
788   [(set (pc)
789         (if_then_else (match_operator 0 "comparison_operator"
790                         [(match_operand:SI 1 "arith_operand" "")
791                          (match_operand:SI 2 "arith_operand" "")])
792                       (label_ref (match_operand 3 "" ""))
793                       (pc)))
794    (clobber (reg:SI T_REG))]
795   ""
796   "if (TARGET_SHMEDIA)
797       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
798                                              operands[2], operands[3]));
799    else if (TARGET_CBRANCHDI4)
800      expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
801    else
802      sh_emit_compare_and_branch (operands, SImode);
803    DONE;")
804
805 ;; -------------------------------------------------------------------------
806 ;; SImode unsigned integer comparisons
807 ;; -------------------------------------------------------------------------
808
809 (define_insn_and_split "cmpgeusi_t"
810   [(set (reg:SI T_REG)
811         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
812                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
813   "TARGET_SH1"
814   "cmp/hs       %1,%0"
815   "&& operands[1] == CONST0_RTX (SImode)"
816   [(pc)]
817   "
818 {
819   emit_insn (gen_sett ());
820   DONE;
821 }"
822    [(set_attr "type" "mt_group")])
823
824 (define_insn "cmpgtusi_t"
825   [(set (reg:SI T_REG)
826         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
827                 (match_operand:SI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH1"
829   "cmp/hi       %1,%0"
830    [(set_attr "type" "mt_group")])
831
832 \f
833 ;; -------------------------------------------------------------------------
834 ;; DImode compare and branch
835 ;; -------------------------------------------------------------------------
836
837
838 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
839 ;; Therefore, we aim to have a set of three branches that go straight to the
840 ;; destination, i.e. only one of them is taken at any one time.
841 ;; This mechanism should also be slightly better for the sh4-200.
842
843 (define_expand "cbranchdi4"
844   [(set (pc)
845         (if_then_else (match_operator 0 "comparison_operator"
846                         [(match_operand:DI 1 "arith_operand" "")
847                          (match_operand:DI 2 "arith_operand" "")])
848                       (label_ref (match_operand 3 "" ""))
849                       (pc)))
850    (clobber (match_dup 4))
851    (clobber (reg:SI T_REG))]
852   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
853   "
854 {
855   enum rtx_code comparison;
856
857   if (TARGET_SHMEDIA)
858     {
859       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
860                                              operands[2], operands[3]));
861       DONE;
862     }
863
864   else if (!TARGET_CBRANCHDI4)
865     {
866       sh_emit_compare_and_branch (operands, DImode);
867       DONE;
868     }
869
870   else
871     {
872       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
873         DONE;
874
875       comparison = prepare_cbranch_operands (operands, DImode,
876                                              LAST_AND_UNUSED_RTX_CODE);
877       if (comparison != GET_CODE (operands[0]))
878         operands[0]
879           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
880        operands[4] = gen_rtx_SCRATCH (SImode);
881     }
882 }")
883
884 (define_insn_and_split "cbranchdi4_i"
885   [(set (pc)
886         (if_then_else (match_operator 0 "comparison_operator"
887                         [(match_operand:DI 1 "arith_operand" "r,r")
888                          (match_operand:DI 2 "arith_operand" "rN,I08")])
889                       (label_ref (match_operand 3 "" ""))
890                       (pc)))
891    (clobber (match_scratch:SI 4 "=X,&r"))
892    (clobber (reg:SI T_REG))]
893   "TARGET_CBRANCHDI4"
894   "#"
895   "&& reload_completed"
896   [(pc)]
897   "
898 {
899   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
900     FAIL;
901   DONE;
902 }")
903
904 ;; -------------------------------------------------------------------------
905 ;; DImode signed integer comparisons
906 ;; -------------------------------------------------------------------------
907
908 (define_insn ""
909   [(set (reg:SI T_REG)
910         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
911                        (match_operand:DI 1 "arith_operand" "r"))
912                (const_int 0)))]
913   "TARGET_SH1"
914   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
915                                  insn, operands);"
916   [(set_attr "length" "6")
917    (set_attr "type" "arith3b")])
918
919 (define_insn "cmpeqdi_t"
920   [(set (reg:SI T_REG)
921         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
922                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
923   "TARGET_SH1"
924   "@
925         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
926         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
927   [(set_attr "length" "6")
928    (set_attr "type" "arith3b")])
929
930 (define_split
931   [(set (reg:SI T_REG)
932         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
933                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
934 ;; If we applied this split when not optimizing, it would only be
935 ;; applied during the machine-dependent reorg, when no new basic blocks
936 ;; may be created.
937   "TARGET_SH1 && reload_completed && optimize"
938   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
939    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
940                            (label_ref (match_dup 6))
941                            (pc)))
942    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
943    (match_dup 6)]
944   "
945 {
946   operands[2]
947     = gen_rtx_REG (SImode,
948                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
949   operands[3]
950     = (operands[1] == const0_rtx
951        ? const0_rtx
952        : gen_rtx_REG (SImode,
953                       true_regnum (operands[1])
954                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
955   operands[4] = gen_lowpart (SImode, operands[0]);
956   operands[5] = gen_lowpart (SImode, operands[1]);
957   operands[6] = gen_label_rtx ();
958 }")
959
960 (define_insn "cmpgtdi_t"
961   [(set (reg:SI T_REG)
962         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
963                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
964   "TARGET_SH2"
965   "@
966         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
967         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
968   [(set_attr "length" "8")
969    (set_attr "type" "arith3")])
970
971 (define_insn "cmpgedi_t"
972   [(set (reg:SI T_REG)
973         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
974                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
975   "TARGET_SH2"
976   "@
977         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
978         cmp/pz\\t%S0"
979   [(set_attr "length" "8,2")
980    (set_attr "type" "arith3,mt_group")])
981 \f
982 ;; -------------------------------------------------------------------------
983 ;; DImode unsigned integer comparisons
984 ;; -------------------------------------------------------------------------
985
986 (define_insn "cmpgeudi_t"
987   [(set (reg:SI T_REG)
988         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
989                 (match_operand:DI 1 "arith_reg_operand" "r")))]
990   "TARGET_SH2"
991   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
992   [(set_attr "length" "8")
993    (set_attr "type" "arith3")])
994
995 (define_insn "cmpgtudi_t"
996   [(set (reg:SI T_REG)
997         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
998                 (match_operand:DI 1 "arith_reg_operand" "r")))]
999   "TARGET_SH2"
1000   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
1001   [(set_attr "length" "8")
1002    (set_attr "type" "arith3")])
1003
1004 (define_insn "cmpeqsi_media"
1005   [(set (match_operand:SI 0 "register_operand" "=r")
1006         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1007                (match_operand:SI 2 "cmp_operand" "Nr")))]
1008   "TARGET_SHMEDIA"
1009   "cmpeq        %1, %N2, %0"
1010   [(set_attr "type" "cmp_media")])
1011
1012 (define_insn "cmpeqdi_media"
1013   [(set (match_operand:SI 0 "register_operand" "=r")
1014         (eq:SI (match_operand:DI 1 "register_operand" "%r")
1015                (match_operand:DI 2 "cmp_operand" "Nr")))]
1016   "TARGET_SHMEDIA"
1017   "cmpeq        %1, %N2, %0"
1018   [(set_attr "type" "cmp_media")])
1019
1020 (define_insn "cmpgtsi_media"
1021   [(set (match_operand:SI 0 "register_operand" "=r")
1022         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1023                (match_operand:SI 2 "cmp_operand" "rN")))]
1024   "TARGET_SHMEDIA"
1025   "cmpgt        %N1, %N2, %0"
1026   [(set_attr "type" "cmp_media")])
1027
1028 (define_insn "cmpgtdi_media"
1029   [(set (match_operand:SI 0 "register_operand" "=r")
1030         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1031                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1032   "TARGET_SHMEDIA"
1033   "cmpgt        %N1, %N2, %0"
1034   [(set_attr "type" "cmp_media")])
1035
1036 (define_insn "cmpgtusi_media"
1037   [(set (match_operand:SI 0 "register_operand" "=r")
1038         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1039                 (match_operand:SI 2 "cmp_operand" "rN")))]
1040   "TARGET_SHMEDIA"
1041   "cmpgtu       %N1, %N2, %0"
1042   [(set_attr "type" "cmp_media")])
1043
1044 (define_insn "cmpgtudi_media"
1045   [(set (match_operand:SI 0 "register_operand" "=r")
1046         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1047                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1048   "TARGET_SHMEDIA"
1049   "cmpgtu       %N1, %N2, %0"
1050   [(set_attr "type" "cmp_media")])
1051
1052 ; These two patterns are for combine.
1053 (define_insn "*cmpne0sisi_media"
1054   [(set (match_operand:SI 0 "register_operand" "=r")
1055         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1056   "TARGET_SHMEDIA"
1057   "cmpgtu       %1,r63,%0"
1058   [(set_attr "type" "cmp_media")])
1059
1060 ;; -------------------------------------------------------------------------
1061 ;; Conditional move instructions
1062 ;; -------------------------------------------------------------------------
1063
1064 ;; The insn names may seem reversed, but note that cmveq performs the move
1065 ;; if op1 == 0, and cmvne does it if op1 != 0.
1066
1067 (define_insn "movdicc_false"
1068   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1069         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1070                              (const_int 0))
1071          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1072          (match_operand:DI 3 "arith_reg_operand" "0")))]
1073   "TARGET_SHMEDIA"
1074   "cmveq        %1, %N2, %0"
1075   [(set_attr "type" "arith_media")])
1076
1077 (define_insn "movdicc_true"
1078   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1079         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1080                              (const_int 0))
1081          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1082          (match_operand:DI 3 "arith_reg_operand" "0")))]
1083   "TARGET_SHMEDIA"
1084   "cmvne        %1, %N2, %0"
1085   [(set_attr "type" "arith_media")])
1086
1087 (define_peephole2
1088   [(set (match_operand:DI 0 "arith_reg_dest" "")
1089         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1090                            [(match_operand:DI 1 "arith_reg_operand" "")
1091                             (const_int 0)])
1092          (match_operand:DI 2 "arith_reg_dest" "")
1093          (match_dup 0)))
1094    (set (match_dup 2) (match_dup 0))]
1095   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1096   [(set (match_dup 2)
1097         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1098   "
1099 {
1100   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1101                                 VOIDmode, operands[1], CONST0_RTX (DImode));
1102 }")
1103
1104 (define_peephole2
1105   [(set (match_operand:DI 0 "general_movdst_operand" "")
1106         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1107    (set (match_operand:DI 2 "arith_reg_dest" "")
1108         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1109                            [(match_operand:DI 3 "arith_reg_operand" "")
1110                             (const_int 0)])
1111          (match_dup 0)
1112          (match_dup 2)))]
1113   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1114   [(set (match_dup 2)
1115         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1116   "")
1117
1118 (define_expand "movdicc"
1119   [(set (match_operand:DI 0 "register_operand" "")
1120         (if_then_else:DI (match_operand 1 "comparison_operator" "")
1121                          (match_operand:DI 2 "register_operand" "")
1122                          (match_operand:DI 3 "register_operand" "")))]
1123   "TARGET_SHMEDIA"
1124   "
1125 {
1126   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1127       && GET_MODE (XEXP (operands[1], 0)) == DImode
1128       && XEXP (operands[1], 1) == const0_rtx)
1129     ;
1130   else
1131     {
1132       if (!can_create_pseudo_p ())
1133         FAIL;
1134
1135       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1136                                               GET_CODE (operands[1]),
1137                                               XEXP (operands[1], 0),
1138                                               XEXP (operands[1], 1));
1139       if (!operands[1])
1140         FAIL;
1141     }
1142 }")
1143
1144 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1145 ;; SImode to DImode.
1146 (define_insn "movsicc_false"
1147   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1148         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1149                           (const_int 0))
1150          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1151          (match_operand:SI 3 "arith_reg_operand" "0")))]
1152   "TARGET_SHMEDIA"
1153   "cmveq        %1, %N2, %0"
1154   [(set_attr "type" "arith_media")])
1155
1156 (define_insn "movsicc_true"
1157   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1158         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1159                           (const_int 0))
1160          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1161          (match_operand:SI 3 "arith_reg_operand" "0")))]
1162   "TARGET_SHMEDIA"
1163   "cmvne        %1, %N2, %0"
1164   [(set_attr "type" "arith_media")])
1165
1166 (define_peephole2
1167   [(set (match_operand:SI 0 "arith_reg_dest" "")
1168         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1169                            [(match_operand:SI 1 "arith_reg_operand" "")
1170                             (const_int 0)])
1171          (match_operand:SI 2 "arith_reg_dest" "")
1172          (match_dup 0)))
1173    (set (match_dup 2) (match_dup 0))]
1174   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1175   [(set (match_dup 2)
1176         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1177   "
1178 {
1179   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1180                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1181 }")
1182
1183 (define_peephole2
1184   [(set (match_operand:SI 0 "general_movdst_operand" "")
1185         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1186    (set (match_operand:SI 2 "arith_reg_dest" "")
1187         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1188                            [(match_operand:SI 3 "arith_reg_operand" "")
1189                             (const_int 0)])
1190          (match_dup 0)
1191          (match_dup 2)))]
1192   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1193    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1194   [(set (match_dup 2)
1195         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1196   "
1197 {
1198   replace_rtx (operands[4], operands[0], operands[1]);
1199 }")
1200
1201 (define_peephole2
1202   [(set (match_operand 0 "any_register_operand" "")
1203         (match_operand 1 "any_register_operand" ""))
1204    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1205    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1206   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1207     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1208    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1209    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1210    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1211    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1212    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1213    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1214    && (REGNO_REG_CLASS (REGNO (operands[0]))
1215        == REGNO_REG_CLASS (REGNO (operands[2])))
1216    && (REGNO_REG_CLASS (REGNO (operands[1]))
1217        == REGNO_REG_CLASS (REGNO (operands[0])))"
1218   [(set (match_dup 0) (match_dup 3))
1219    (set (match_dup 4) (match_dup 5))]
1220   "
1221 {
1222   rtx set1, set2, insn2;
1223   rtx replacements[4];
1224
1225   /* We want to replace occurrences of operands[0] with operands[1] and
1226      operands[2] with operands[0] in operands[4]/operands[5].
1227      Doing just two replace_rtx calls naively would result in the second
1228      replacement undoing all that the first did if operands[1] and operands[2]
1229      are identical, so we must do this simultaneously.  */
1230   replacements[0] = operands[0];
1231   replacements[1] = operands[1];
1232   replacements[2] = operands[2];
1233   replacements[3] = operands[0];
1234   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1235       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1236       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1237     FAIL;
1238
1239   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1240   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1241   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1242   /* The operands array is aliased to recog_data.operand, which gets
1243      clobbered by extract_insn, so finish with it now.  */
1244   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1245   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1246   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1247      always uses emit_insn.  */
1248   /* Check that we don't violate matching constraints or earlyclobbers.  */
1249   extract_insn (emit_insn (set1));
1250   if (! constrain_operands (1))
1251     goto failure;
1252   insn2 = emit (set2);
1253   if (GET_CODE (insn2) == BARRIER)
1254     goto failure;
1255   extract_insn (insn2);
1256   if (! constrain_operands (1))
1257     {
1258       rtx tmp;
1259     failure:
1260       tmp = replacements[0];
1261       replacements[0] = replacements[1];
1262       replacements[1] = tmp;
1263       tmp = replacements[2];
1264       replacements[2] = replacements[3];
1265       replacements[3] = tmp;
1266       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1267       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1268       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1269       FAIL;
1270     }
1271   DONE;
1272 }")
1273
1274 ;; The register allocator is rather clumsy in handling multi-way conditional
1275 ;; moves, so allow the combiner to make them, and we split them up after
1276 ;; reload.  */
1277 (define_insn_and_split "*movsicc_umin"
1278   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1279         (umin:SI (if_then_else:SI
1280                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1281                        (const_int 0))
1282                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1283                    (match_operand:SI 3 "register_operand" "0"))
1284                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1285    (clobber (match_scratch:SI 5 "=&r"))]
1286   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1287   "#"
1288   "TARGET_SHMEDIA && reload_completed"
1289   [(pc)]
1290   "
1291 {
1292   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1293                                 operands[3]));
1294   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1295   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1296                                 operands[0]));
1297   DONE;
1298 }")
1299
1300 (define_insn "*movsicc_t_false"
1301   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1302         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1303                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1304                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1305   "TARGET_PRETEND_CMOVE
1306    && (arith_reg_operand (operands[1], SImode)
1307        || (immediate_operand (operands[1], SImode)
1308            && satisfies_constraint_I08 (operands[1])))"
1309   "bt   0f\;mov %1,%0\\n0:"
1310   [(set_attr "type" "mt_group,arith") ;; poor approximation
1311    (set_attr "length" "4")])
1312
1313 (define_insn "*movsicc_t_true"
1314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1315         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1316                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1317                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1318   "TARGET_PRETEND_CMOVE
1319    && (arith_reg_operand (operands[1], SImode)
1320        || (immediate_operand (operands[1], SImode)
1321            && satisfies_constraint_I08 (operands[1])))"
1322   "bf   0f\;mov %1,%0\\n0:"
1323   [(set_attr "type" "mt_group,arith") ;; poor approximation
1324    (set_attr "length" "4")])
1325
1326 (define_expand "movsicc"
1327   [(set (match_operand:SI 0 "arith_reg_dest" "")
1328         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1329                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1330                          (match_operand:SI 3 "arith_reg_operand" "")))]
1331   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1332   "
1333 {
1334   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1335       && GET_MODE (XEXP (operands[1], 0)) == SImode
1336       && (TARGET_SHMEDIA
1337           || (REG_P (XEXP (operands[1], 0))
1338               && REGNO (XEXP (operands[1], 0)) == T_REG))
1339       && XEXP (operands[1], 1) == const0_rtx)
1340     ;
1341
1342   else if (TARGET_PRETEND_CMOVE)
1343     {
1344       enum rtx_code code = GET_CODE (operands[1]);
1345       enum rtx_code new_code = code;
1346       rtx op0 = XEXP (operands[1], 0);
1347       rtx op1 = XEXP (operands[1], 1);
1348
1349       if (! currently_expanding_to_rtl)
1350         FAIL;
1351       switch (code)
1352         {
1353         case LT: case LE: case LEU: case LTU:
1354           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1355             break;
1356         case NE:
1357           new_code = reverse_condition (code);
1358           break;
1359         case EQ: case GT: case GE: case GEU: case GTU:
1360           break;
1361         default:
1362           FAIL;
1363         }
1364       sh_emit_scc_to_t (new_code, op0, op1);
1365       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1366                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1367     }
1368   else
1369     {
1370       if (!can_create_pseudo_p ())
1371         FAIL;
1372
1373       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1374                                               GET_CODE (operands[1]),
1375                                               XEXP (operands[1], 0),
1376                                               XEXP (operands[1], 1));
1377       if (!operands[1])
1378         FAIL;
1379     }
1380 }")
1381
1382 (define_expand "movqicc"
1383   [(set (match_operand:QI 0 "register_operand" "")
1384         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1385                          (match_operand:QI 2 "register_operand" "")
1386                          (match_operand:QI 3 "register_operand" "")))]
1387   "TARGET_SHMEDIA"
1388   "
1389 {
1390   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1391   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1392   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1393   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1394   DONE;
1395 }")
1396 \f
1397 ;; -------------------------------------------------------------------------
1398 ;; Addition instructions
1399 ;; -------------------------------------------------------------------------
1400
1401 (define_expand "adddi3"
1402   [(set (match_operand:DI 0 "arith_reg_operand" "")
1403         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1404                  (match_operand:DI 2 "arith_operand" "")))]
1405   ""
1406   "
1407 {
1408   if (TARGET_SH1)
1409     {
1410       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1411         FAIL;
1412       operands[2] = force_reg (DImode, operands[2]);
1413       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1414       DONE;
1415     }
1416 }")
1417
1418 (define_insn "*adddi3_media"
1419   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1420         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1422   "TARGET_SHMEDIA"
1423   "@
1424         add     %1, %2, %0
1425         addi    %1, %2, %0"
1426   [(set_attr "type" "arith_media")])
1427
1428 (define_insn "*adddisi3_media"
1429   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1430         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1431                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1432   "TARGET_SHMEDIA"
1433   "@
1434         add.l   %1, %2, %0
1435         addi.l  %1, %2, %0"
1436   [(set_attr "type" "arith_media")
1437    (set_attr "highpart" "ignore")])
1438
1439 (define_insn "adddi3z_media"
1440   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1441         (zero_extend:DI
1442          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1443                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1444   "TARGET_SHMEDIA"
1445   "addz.l       %1, %N2, %0"
1446   [(set_attr "type" "arith_media")
1447    (set_attr "highpart" "ignore")])
1448
1449 (define_insn "adddi3_compact"
1450   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1451         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1452                  (match_operand:DI 2 "arith_reg_operand" "r")))
1453    (clobber (reg:SI T_REG))]
1454   "TARGET_SH1"
1455   "#"
1456   [(set_attr "length" "6")])
1457
1458 (define_split
1459   [(set (match_operand:DI 0 "arith_reg_dest" "")
1460         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1461                  (match_operand:DI 2 "arith_reg_operand" "")))
1462    (clobber (reg:SI T_REG))]
1463   "TARGET_SH1 && reload_completed"
1464   [(const_int 0)]
1465   "
1466 {
1467   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1468   high0 = gen_rtx_REG (SImode,
1469                        true_regnum (operands[0])
1470                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1471   high2 = gen_rtx_REG (SImode,
1472                        true_regnum (operands[2])
1473                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1474   emit_insn (gen_clrt ());
1475   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1476   emit_insn (gen_addc1 (high0, high0, high2));
1477   DONE;
1478 }")
1479
1480 (define_insn "addc"
1481   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1482         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1483                           (match_operand:SI 2 "arith_reg_operand" "r"))
1484                  (reg:SI T_REG)))
1485    (set (reg:SI T_REG)
1486         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1487   "TARGET_SH1"
1488   "addc %2,%0"
1489   [(set_attr "type" "arith")])
1490
1491 (define_insn "addc1"
1492   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1494                           (match_operand:SI 2 "arith_reg_operand" "r"))
1495                  (reg:SI T_REG)))
1496    (clobber (reg:SI T_REG))]
1497   "TARGET_SH1"
1498   "addc %2,%0"
1499   [(set_attr "type" "arith")])
1500
1501 (define_expand "addsi3"
1502   [(set (match_operand:SI 0 "arith_reg_operand" "")
1503         (plus:SI (match_operand:SI 1 "arith_operand" "")
1504                  (match_operand:SI 2 "arith_operand" "")))]
1505   ""
1506   "
1507 {
1508   if (TARGET_SHMEDIA)
1509     operands[1] = force_reg (SImode, operands[1]);
1510 }")
1511
1512 (define_insn "addsi3_media"
1513   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1514         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1515                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1516   "TARGET_SHMEDIA"
1517   "@
1518         add.l   %1, %2, %0
1519         addi.l  %1, %2, %0"
1520   [(set_attr "type" "arith_media")
1521    (set_attr "highpart" "ignore")])
1522
1523 (define_insn "addsidi3_media"
1524   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1525         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1526                                   "%r,r")
1527                                  (match_operand:SI 2 "arith_operand"
1528                                   "r,I10"))))]
1529   "TARGET_SHMEDIA"
1530   "@
1531         add.l   %1, %2, %0
1532         addi.l  %1, %2, %0"
1533   [(set_attr "type" "arith_media")
1534    (set_attr "highpart" "ignore")])
1535
1536 (define_insn "*addsi3_compact"
1537   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1538         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1539                  (match_operand:SI 2 "arith_operand" "rI08")))]
1540   "TARGET_SH1"
1541   "add  %2,%0"
1542   [(set_attr "type" "arith")])
1543
1544 ;; -------------------------------------------------------------------------
1545 ;; Subtraction instructions
1546 ;; -------------------------------------------------------------------------
1547
1548 (define_expand "subdi3"
1549   [(set (match_operand:DI 0 "arith_reg_operand" "")
1550         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1551                   (match_operand:DI 2 "arith_reg_operand" "")))]
1552   ""
1553   "
1554 {
1555   if (TARGET_SH1)
1556     {
1557       operands[1] = force_reg (DImode, operands[1]);
1558       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1559       DONE;
1560     }
1561 }")
1562
1563 (define_insn "*subdi3_media"
1564   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1565         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1566                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1567   "TARGET_SHMEDIA"
1568   "sub  %N1, %2, %0"
1569   [(set_attr "type" "arith_media")])
1570   
1571 (define_insn "subdisi3_media"
1572   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1573         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1574                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1575   "TARGET_SHMEDIA"
1576   "sub.l        %N1, %2, %0"
1577   [(set_attr "type" "arith_media")
1578    (set_attr "highpart" "ignore")])
1579
1580 (define_insn "subdi3_compact"
1581   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1582         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1583                  (match_operand:DI 2 "arith_reg_operand" "r")))
1584    (clobber (reg:SI T_REG))]
1585   "TARGET_SH1"
1586   "#"
1587   [(set_attr "length" "6")])
1588
1589 (define_split
1590   [(set (match_operand:DI 0 "arith_reg_dest" "")
1591         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1592                   (match_operand:DI 2 "arith_reg_operand" "")))
1593    (clobber (reg:SI T_REG))]
1594   "TARGET_SH1 && reload_completed"
1595   [(const_int 0)]
1596   "
1597 {
1598   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1599   high0 = gen_rtx_REG (SImode,
1600                        true_regnum (operands[0])
1601                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1602   high2 = gen_rtx_REG (SImode,
1603                        true_regnum (operands[2])
1604                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1605   emit_insn (gen_clrt ());
1606   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1607   emit_insn (gen_subc1 (high0, high0, high2));
1608   DONE;
1609 }")
1610
1611 (define_insn "subc"
1612   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1613         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1614                             (match_operand:SI 2 "arith_reg_operand" "r"))
1615                   (reg:SI T_REG)))
1616    (set (reg:SI T_REG)
1617         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1618                           (reg:SI T_REG))
1619                 (match_dup 1)))]
1620   "TARGET_SH1"
1621   "subc %2,%0"
1622   [(set_attr "type" "arith")])
1623
1624 (define_insn "subc1"
1625   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627                             (match_operand:SI 2 "arith_reg_operand" "r"))
1628                   (reg:SI T_REG)))
1629    (clobber (reg:SI T_REG))]
1630   "TARGET_SH1"
1631   "subc %2,%0"
1632   [(set_attr "type" "arith")])
1633
1634 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1635 ;; pattern for this case.  This helps multimedia applications that compute
1636 ;; the sum of absolute differences.
1637 (define_insn "mov_neg_si_t"
1638   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1639   "TARGET_SH1"
1640   "subc %0,%0"
1641   [(set_attr "type" "arith")])
1642
1643 (define_insn "*subsi3_internal"
1644   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1645         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1646                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1647   "TARGET_SH1"
1648   "sub  %2,%0"
1649   [(set_attr "type" "arith")])
1650
1651 (define_insn_and_split "*subsi3_media"
1652   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1653         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1654                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1655   "TARGET_SHMEDIA
1656    && (operands[1] != constm1_rtx
1657        || (GET_CODE (operands[2]) != TRUNCATE
1658            && GET_CODE (operands[2]) != SUBREG))"
1659   "sub.l        %N1, %2, %0"
1660   "operands[1] == constm1_rtx"
1661   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1662   ""
1663   [(set_attr "type" "arith_media")
1664    (set_attr "highpart" "ignore")])
1665
1666 (define_split
1667   [(set (match_operand:SI 0 "arith_reg_dest" "")
1668         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669                                                        "general_extend_operand"
1670                                                        "") 0)) 0)))]
1671   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1672   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1674   "")
1675
1676 (define_split
1677   [(set (match_operand:SI 0 "arith_reg_dest" "")
1678         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1679                                                        "general_extend_operand"
1680                                                        "") 0)) 3)))]
1681   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1682   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1683    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1684   "")
1685 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1686 ;; will sometimes save one instruction.  Otherwise we might get
1687 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1688 ;; are the same.
1689
1690 (define_expand "subsi3"
1691   [(set (match_operand:SI 0 "arith_reg_operand" "")
1692         (minus:SI (match_operand:SI 1 "arith_operand" "")
1693                   (match_operand:SI 2 "arith_reg_operand" "")))]
1694   ""
1695   "
1696 {
1697   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1698     {
1699       emit_insn (gen_negsi2 (operands[0], operands[2]));
1700       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1701       DONE;
1702     }
1703   if (TARGET_SHMEDIA)
1704     {
1705       if (!can_create_pseudo_p ()
1706           && ! arith_reg_or_0_operand (operands[1], SImode))
1707         FAIL;
1708       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1709         operands[1] = force_reg (SImode, operands[1]);
1710     }
1711 }")
1712 \f
1713 ;; -------------------------------------------------------------------------
1714 ;; Division instructions
1715 ;; -------------------------------------------------------------------------
1716
1717 ;; We take advantage of the library routines which don't clobber as many
1718 ;; registers as a normal function call would.
1719
1720 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1721 ;; also has an effect on the register that holds the address of the sfunc.
1722 ;; To make this work, we have an extra dummy insn that shows the use
1723 ;; of this register for reorg.
1724
1725 (define_insn "use_sfunc_addr"
1726   [(set (reg:SI PR_REG)
1727         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1728   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1729   ""
1730   [(set_attr "length" "0")])
1731
1732 (define_insn "udivsi3_sh2a"
1733   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1734         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1735                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1736   "TARGET_SH2A"
1737   "divu %2,%1"
1738   [(set_attr "type" "arith")
1739    (set_attr "in_delay_slot" "no")])
1740
1741 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1742 ;; hard register 0.  If we used hard register 0, then the next instruction
1743 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1744 ;; gets allocated to a stack slot that needs its address reloaded, then
1745 ;; there is nothing to prevent reload from using r0 to reload the address.
1746 ;; This reload would clobber the value in r0 we are trying to store.
1747 ;; If we let reload allocate r0, then this problem can never happen.
1748
1749 (define_insn "udivsi3_i1"
1750   [(set (match_operand:SI 0 "register_operand" "=z")
1751         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1752    (clobber (reg:SI T_REG))
1753    (clobber (reg:SI PR_REG))
1754    (clobber (reg:SI R4_REG))
1755    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1756   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1757   "jsr  @%1%#"
1758   [(set_attr "type" "sfunc")
1759    (set_attr "needs_delay_slot" "yes")])
1760
1761 ; Since shmedia-nofpu code could be linked against shcompact code, and
1762 ; the udivsi3 libcall has the same name, we must consider all registers
1763 ; clobbered that are in the union of the registers clobbered by the
1764 ; shmedia and the shcompact implementation.  Note, if the shcompact
1765 ; implementation actually used shcompact code, we'd need to clobber
1766 ; also r23 and fr23.
1767 (define_insn "udivsi3_i1_media"
1768   [(set (match_operand:SI 0 "register_operand" "=z")
1769         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1770    (clobber (reg:SI T_MEDIA_REG))
1771    (clobber (reg:SI PR_MEDIA_REG))
1772    (clobber (reg:SI R20_REG))
1773    (clobber (reg:SI R21_REG))
1774    (clobber (reg:SI R22_REG))
1775    (clobber (reg:DI TR0_REG))
1776    (clobber (reg:DI TR1_REG))
1777    (clobber (reg:DI TR2_REG))
1778    (use (match_operand 1 "target_reg_operand" "b"))]
1779   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1780   "blink        %1, r18"
1781   [(set_attr "type" "sfunc")
1782    (set_attr "needs_delay_slot" "yes")])
1783
1784 (define_expand "udivsi3_i4_media"
1785   [(set (match_dup 3)
1786         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1787    (set (match_dup 4)
1788         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1789    (set (match_dup 5) (float:DF (match_dup 3)))
1790    (set (match_dup 6) (float:DF (match_dup 4)))
1791    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1792    (set (match_dup 8) (fix:DI (match_dup 7)))
1793    (set (match_operand:SI 0 "register_operand" "")
1794         (truncate:SI (match_dup 8)))]
1795   "TARGET_SHMEDIA_FPU"
1796   "
1797 {
1798   operands[3] = gen_reg_rtx (DImode);
1799   operands[4] = gen_reg_rtx (DImode);
1800   operands[5] = gen_reg_rtx (DFmode);
1801   operands[6] = gen_reg_rtx (DFmode);
1802   operands[7] = gen_reg_rtx (DFmode);
1803   operands[8] = gen_reg_rtx (DImode);
1804 }")
1805
1806 (define_insn "udivsi3_i4"
1807   [(set (match_operand:SI 0 "register_operand" "=y")
1808         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809    (clobber (reg:SI T_REG))
1810    (clobber (reg:SI PR_REG))
1811    (clobber (reg:DF DR0_REG))
1812    (clobber (reg:DF DR2_REG))
1813    (clobber (reg:DF DR4_REG))
1814    (clobber (reg:SI R0_REG))
1815    (clobber (reg:SI R1_REG))
1816    (clobber (reg:SI R4_REG))
1817    (clobber (reg:SI R5_REG))
1818    (use (reg:PSI FPSCR_REG))
1819    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1820   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1821   "jsr  @%1%#"
1822   [(set_attr "type" "sfunc")
1823    (set_attr "fp_mode" "double")
1824    (set_attr "needs_delay_slot" "yes")])
1825
1826 (define_insn "udivsi3_i4_single"
1827   [(set (match_operand:SI 0 "register_operand" "=y")
1828         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829    (clobber (reg:SI T_REG))
1830    (clobber (reg:SI PR_REG))
1831    (clobber (reg:DF DR0_REG))
1832    (clobber (reg:DF DR2_REG))
1833    (clobber (reg:DF DR4_REG))
1834    (clobber (reg:SI R0_REG))
1835    (clobber (reg:SI R1_REG))
1836    (clobber (reg:SI R4_REG))
1837    (clobber (reg:SI R5_REG))
1838    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1839   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1840   "jsr  @%1%#"
1841   [(set_attr "type" "sfunc")
1842    (set_attr "needs_delay_slot" "yes")])
1843
1844 (define_insn "udivsi3_i4_int"
1845   [(set (match_operand:SI 0 "register_operand" "=z")
1846         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1847    (clobber (reg:SI T_REG))
1848    (clobber (reg:SI R1_REG))
1849    (clobber (reg:SI PR_REG))
1850    (clobber (reg:SI MACH_REG))
1851    (clobber (reg:SI MACL_REG))
1852    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1853   "TARGET_SH1"
1854   "jsr  @%1%#"
1855   [(set_attr "type" "sfunc")
1856    (set_attr "needs_delay_slot" "yes")])
1857
1858
1859 (define_expand "udivsi3"
1860   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1861    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1862    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1863    (parallel [(set (match_operand:SI 0 "register_operand" "")
1864                    (udiv:SI (reg:SI R4_REG)
1865                             (reg:SI R5_REG)))
1866               (clobber (reg:SI T_REG))
1867               (clobber (reg:SI PR_REG))
1868               (clobber (reg:SI R4_REG))
1869               (use (match_dup 3))])]
1870   ""
1871   "
1872 {
1873   rtx last;
1874
1875   operands[3] = gen_reg_rtx (Pmode);
1876   /* Emit the move of the address to a pseudo outside of the libcall.  */
1877   if (TARGET_DIVIDE_CALL_TABLE)
1878     {
1879       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1880          that causes problems when the divide code is supposed to come from a
1881          separate library.  Division by zero is undefined, so dividing 1 can be
1882          implemented by comparing with the divisor.  */
1883       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1884         {
1885           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1886           emit_insn (gen_cstoresi4 (operands[0], test,
1887                                     operands[1], operands[2]));
1888           DONE;
1889         }
1890       else if (operands[2] == const0_rtx)
1891         {
1892           emit_move_insn (operands[0], operands[2]);
1893           DONE;
1894         }
1895       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1896       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1897     }
1898   else if (TARGET_DIVIDE_CALL_FP)
1899     {
1900       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1901       if (TARGET_FPU_SINGLE)
1902         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1903       else
1904         last = gen_udivsi3_i4 (operands[0], operands[3]);
1905     }
1906   else if (TARGET_SHMEDIA_FPU)
1907     {
1908       operands[1] = force_reg (SImode, operands[1]);
1909       operands[2] = force_reg (SImode, operands[2]);
1910       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1911       DONE;
1912     }
1913   else if (TARGET_SH2A)
1914     {
1915       operands[1] = force_reg (SImode, operands[1]);
1916       operands[2] = force_reg (SImode, operands[2]);
1917       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1918       DONE;
1919     }
1920   else if (TARGET_SH5)
1921     {
1922       function_symbol (operands[3],
1923                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1924                        SFUNC_STATIC);
1925
1926       if (TARGET_SHMEDIA)
1927         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1928       else if (TARGET_FPU_ANY)
1929         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1930       else
1931         last = gen_udivsi3_i1 (operands[0], operands[3]);
1932     }
1933   else
1934     {
1935       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1936       last = gen_udivsi3_i1 (operands[0], operands[3]);
1937     }
1938   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1939   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1940   emit_insn (last);
1941   DONE;
1942 }")
1943
1944 (define_insn "divsi3_sh2a"
1945   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1946         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1947                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1948   "TARGET_SH2A"
1949   "divs %2,%1"
1950   [(set_attr "type" "arith")
1951    (set_attr "in_delay_slot" "no")])
1952
1953 (define_insn "divsi3_i1"
1954   [(set (match_operand:SI 0 "register_operand" "=z")
1955         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956    (clobber (reg:SI T_REG))
1957    (clobber (reg:SI PR_REG))
1958    (clobber (reg:SI R1_REG))
1959    (clobber (reg:SI R2_REG))
1960    (clobber (reg:SI R3_REG))
1961    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1963   "jsr  @%1%#"
1964   [(set_attr "type" "sfunc")
1965    (set_attr "needs_delay_slot" "yes")])
1966
1967 (define_insn "divsi3_i1_media"
1968   [(set (match_operand:SI 0 "register_operand" "=z")
1969         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970    (clobber (reg:SI T_MEDIA_REG))
1971    (clobber (reg:SI PR_MEDIA_REG))
1972    (clobber (reg:SI R1_REG))
1973    (clobber (reg:SI R20_REG))
1974    (clobber (reg:SI R21_REG))
1975    (clobber (reg:SI TR0_REG))
1976    (use (match_operand 1 "target_reg_operand" "b"))]
1977   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1978   "blink        %1, r18"
1979   [(set_attr "type" "sfunc")])
1980
1981 (define_insn "divsi3_media_2"
1982   [(set (match_operand:SI 0 "register_operand" "=z")
1983         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1984    (clobber (reg:SI T_MEDIA_REG))
1985    (clobber (reg:SI PR_MEDIA_REG))
1986    (clobber (reg:SI R1_REG))
1987    (clobber (reg:SI R21_REG))
1988    (clobber (reg:SI TR0_REG))
1989    (use (reg:SI R20_REG))
1990    (use (match_operand 1 "target_reg_operand" "b"))]
1991   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1992   "blink        %1, r18"
1993   [(set_attr "type" "sfunc")])
1994
1995 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1996 ;; hard reg clobbers and data dependencies that we need when we want
1997 ;; to rematerialize the division into a call.
1998 (define_insn_and_split "divsi_inv_call"
1999   [(set (match_operand:SI 0 "register_operand" "=r")
2000         (div:SI (match_operand:SI 1 "register_operand" "r")
2001                 (match_operand:SI 2 "register_operand" "r")))
2002    (clobber (reg:SI R4_REG))
2003    (clobber (reg:SI R5_REG))
2004    (clobber (reg:SI T_MEDIA_REG))
2005    (clobber (reg:SI PR_MEDIA_REG))
2006    (clobber (reg:SI R1_REG))
2007    (clobber (reg:SI R21_REG))
2008    (clobber (reg:SI TR0_REG))
2009    (clobber (reg:SI R20_REG))
2010    (use (match_operand:SI 3 "register_operand" "r"))]
2011   "TARGET_SHMEDIA"
2012   "#"
2013   "&& (high_life_started || reload_completed)"
2014   [(set (match_dup 0) (match_dup 3))]
2015   ""
2016   [(set_attr "highpart" "must_split")])
2017
2018 ;; This is the combiner pattern for -mdiv=inv:call .
2019 (define_insn_and_split "*divsi_inv_call_combine"
2020   [(set (match_operand:SI 0 "register_operand" "=z")
2021         (div:SI (match_operand:SI 1 "register_operand" "r")
2022                 (match_operand:SI 2 "register_operand" "r")))
2023    (clobber (reg:SI R4_REG))
2024    (clobber (reg:SI R5_REG))
2025    (clobber (reg:SI T_MEDIA_REG))
2026    (clobber (reg:SI PR_MEDIA_REG))
2027    (clobber (reg:SI R1_REG))
2028    (clobber (reg:SI R21_REG))
2029    (clobber (reg:SI TR0_REG))
2030    (clobber (reg:SI R20_REG))
2031    (use (unspec:SI [(match_dup 1)
2032                     (match_operand:SI 3 "" "")
2033                     (unspec:SI [(match_operand:SI 4 "" "")
2034                                 (match_dup 3)
2035                                 (match_operand:DI 5 "" "")]
2036                      UNSPEC_DIV_INV_M2)
2037                     (match_operand:DI 6 "" "")
2038                     (const_int 0)
2039                     (const_int 0)]
2040          UNSPEC_DIV_INV_M3))]
2041   "TARGET_SHMEDIA"
2042   "#"
2043   "&& (high_life_started || reload_completed)"
2044   [(pc)]
2045   "
2046 {
2047   const char *name = sh_divsi3_libfunc;
2048   enum sh_function_kind kind = SFUNC_GOT;
2049   rtx sym;
2050
2051   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2052   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2053   while (TARGET_DIVIDE_INV_CALL2)
2054     {
2055       rtx x = operands[3];
2056
2057       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2058         break;
2059       x = XVECEXP (x, 0, 0);
2060       name = \"__sdivsi3_2\";
2061       kind = SFUNC_STATIC;
2062       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2063       break;
2064     }
2065   sym = function_symbol (NULL, name, kind);
2066   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2067   DONE;
2068 }"
2069   [(set_attr "highpart" "must_split")])
2070
2071 (define_expand "divsi3_i4_media"
2072   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2073    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2074    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2075    (set (match_operand:SI 0 "register_operand" "=r")
2076         (fix:SI (match_dup 5)))]
2077   "TARGET_SHMEDIA_FPU"
2078   "
2079 {
2080   operands[3] = gen_reg_rtx (DFmode);
2081   operands[4] = gen_reg_rtx (DFmode);
2082   operands[5] = gen_reg_rtx (DFmode);
2083 }")
2084
2085 (define_insn "divsi3_i4"
2086   [(set (match_operand:SI 0 "register_operand" "=y")
2087         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2088    (clobber (reg:SI PR_REG))
2089    (clobber (reg:DF DR0_REG))
2090    (clobber (reg:DF DR2_REG))
2091    (use (reg:PSI FPSCR_REG))
2092    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2094   "jsr  @%1%#"
2095   [(set_attr "type" "sfunc")
2096    (set_attr "fp_mode" "double")
2097    (set_attr "needs_delay_slot" "yes")])
2098
2099 (define_insn "divsi3_i4_single"
2100   [(set (match_operand:SI 0 "register_operand" "=y")
2101         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2102    (clobber (reg:SI PR_REG))
2103    (clobber (reg:DF DR0_REG))
2104    (clobber (reg:DF DR2_REG))
2105    (clobber (reg:SI R2_REG))
2106    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2107   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2108   "jsr  @%1%#"
2109   [(set_attr "type" "sfunc")
2110    (set_attr "needs_delay_slot" "yes")])
2111
2112 (define_insn "divsi3_i4_int"
2113   [(set (match_operand:SI 0 "register_operand" "=z")
2114         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2115    (clobber (reg:SI T_REG))
2116    (clobber (reg:SI PR_REG))
2117    (clobber (reg:SI R1_REG))
2118    (clobber (reg:SI MACH_REG))
2119    (clobber (reg:SI MACL_REG))
2120    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2121   "TARGET_SH1"
2122   "jsr  @%1%#"
2123   [(set_attr "type" "sfunc")
2124    (set_attr "needs_delay_slot" "yes")])
2125
2126 (define_expand "divsi3"
2127   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2128    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2129    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2130    (parallel [(set (match_operand:SI 0 "register_operand" "")
2131                    (div:SI (reg:SI R4_REG)
2132                            (reg:SI R5_REG)))
2133               (clobber (reg:SI T_REG))
2134               (clobber (reg:SI PR_REG))
2135               (clobber (reg:SI R1_REG))
2136               (clobber (reg:SI R2_REG))
2137               (clobber (reg:SI R3_REG))
2138               (use (match_dup 3))])]
2139   ""
2140   "
2141 {
2142   rtx last;
2143
2144   operands[3] = gen_reg_rtx (Pmode);
2145   /* Emit the move of the address to a pseudo outside of the libcall.  */
2146   if (TARGET_DIVIDE_CALL_TABLE)
2147     {
2148       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2149       last = gen_divsi3_i4_int (operands[0], operands[3]);
2150     }
2151   else if (TARGET_DIVIDE_CALL_FP)
2152     {
2153       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2154       if (TARGET_FPU_SINGLE)
2155         last = gen_divsi3_i4_single (operands[0], operands[3]);
2156       else
2157         last = gen_divsi3_i4 (operands[0], operands[3]);
2158     }
2159   else if (TARGET_SH2A)
2160     {
2161       operands[1] = force_reg (SImode, operands[1]);
2162       operands[2] = force_reg (SImode, operands[2]);
2163       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2164       DONE;
2165     }
2166   else if (TARGET_DIVIDE_INV)
2167     {
2168       rtx dividend = operands[1];
2169       rtx divisor = operands[2];
2170       rtx tab_base;
2171       rtx nsb_res = gen_reg_rtx (DImode);
2172       rtx norm64 = gen_reg_rtx (DImode);
2173       rtx tab_ix = gen_reg_rtx (DImode);
2174       rtx norm32 = gen_reg_rtx (SImode);
2175       rtx i92 = force_reg (DImode, GEN_INT (92));
2176       rtx scratch0a = gen_reg_rtx (DImode);
2177       rtx scratch0b = gen_reg_rtx (DImode);
2178       rtx inv0 = gen_reg_rtx (SImode);
2179       rtx scratch1a = gen_reg_rtx (DImode);
2180       rtx scratch1b = gen_reg_rtx (DImode);
2181       rtx shift = gen_reg_rtx (DImode);
2182       rtx i2p27, i43;
2183       rtx inv1 = gen_reg_rtx (SImode);
2184       rtx scratch2a = gen_reg_rtx (DImode);
2185       rtx scratch2b = gen_reg_rtx (SImode);
2186       rtx inv2 = gen_reg_rtx (SImode);
2187       rtx scratch3a = gen_reg_rtx (DImode);
2188       rtx scratch3b = gen_reg_rtx (DImode);
2189       rtx scratch3c = gen_reg_rtx (DImode);
2190       rtx scratch3d = gen_reg_rtx (SImode);
2191       rtx scratch3e = gen_reg_rtx (DImode);
2192       rtx result = gen_reg_rtx (SImode);
2193
2194       if (! arith_reg_or_0_operand (dividend, SImode))
2195         dividend = force_reg (SImode, dividend);
2196       if (! arith_reg_operand (divisor, SImode))
2197         divisor = force_reg (SImode, divisor);
2198       if (flag_pic && Pmode != DImode)
2199         {
2200           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2201           tab_base = gen_datalabel_ref (tab_base);
2202           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2203         }
2204       else
2205         {
2206           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2207           tab_base = gen_datalabel_ref (tab_base);
2208           tab_base = force_reg (DImode, tab_base);
2209         }
2210       if (TARGET_DIVIDE_INV20U)
2211         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2212       else
2213         i2p27 = GEN_INT (0);
2214       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2215         i43 = force_reg (DImode, GEN_INT (43));
2216       else
2217         i43 = GEN_INT (0);
2218       emit_insn (gen_nsbdi (nsb_res,
2219                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2220       emit_insn (gen_ashldi3_media (norm64,
2221                                     gen_rtx_SUBREG (DImode, divisor, 0),
2222                                     nsb_res));
2223       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2224       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2225       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2226                                    inv0, scratch0a, scratch0b,
2227                                    scratch1a, scratch1b));
2228       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2229       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2230                                    scratch2a));
2231       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2232                                    i2p27, i43,
2233                                    scratch3a, scratch3b, scratch3c,
2234                                    scratch2a, scratch2b, scratch3d, scratch3e));
2235       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2236         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2237       else if (TARGET_DIVIDE_INV_FP)
2238         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2239                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2240                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2241                                      gen_reg_rtx (DFmode)));
2242       else
2243         emit_move_insn (operands[0], result);
2244       DONE;
2245     }
2246   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2247     {
2248       operands[1] = force_reg (SImode, operands[1]);
2249       operands[2] = force_reg (SImode, operands[2]);
2250       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2251       DONE;
2252     }
2253   else if (TARGET_SH5)
2254     {
2255       if (TARGET_DIVIDE_CALL2)
2256         {
2257           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2258           tab_base = gen_datalabel_ref (tab_base);
2259           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2260         }
2261       if (TARGET_FPU_ANY && TARGET_SH1)
2262         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2263       else if (TARGET_DIVIDE_CALL2)
2264         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2265       else
2266         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2267
2268       if (TARGET_SHMEDIA)
2269         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2270                 (operands[0], operands[3]));
2271       else if (TARGET_FPU_ANY)
2272         last = gen_divsi3_i4_single (operands[0], operands[3]);
2273       else
2274         last = gen_divsi3_i1 (operands[0], operands[3]);
2275     }
2276   else
2277     {
2278       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2279       last = gen_divsi3_i1 (operands[0], operands[3]);
2280     }
2281   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2282   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2283   emit_insn (last);
2284   DONE;
2285 }")
2286
2287 ;; operands: scratch, tab_base, tab_ix
2288 ;; These are unspecs because we could generate an indexed addressing mode
2289 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2290 ;; confuse reload.  See PR27117.
2291
2292 (define_insn "divsi_inv_qitable"
2293   [(set (match_operand:DI 0 "register_operand" "=r")
2294         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2295                                     (match_operand:DI 2 "register_operand" "r")]
2296                          UNSPEC_DIV_INV_TABLE)))]
2297   "TARGET_SHMEDIA"
2298   "@
2299         ldx.ub  %1, %2, %0"
2300   [(set_attr "type" "load_media")
2301    (set_attr "highpart" "user")])
2302
2303 ;; operands: scratch, tab_base, tab_ix
2304 (define_insn "divsi_inv_hitable"
2305   [(set (match_operand:DI 0 "register_operand" "=r")
2306         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2307                                     (match_operand:DI 2 "register_operand" "r")]
2308                          UNSPEC_DIV_INV_TABLE)))]
2309   "TARGET_SHMEDIA"
2310   "@
2311         ldx.w   %1, %2, %0"
2312   [(set_attr "type" "load_media")
2313    (set_attr "highpart" "user")])
2314
2315 ;; operands: inv0, tab_base, tab_ix, norm32
2316 ;; scratch equiv in sdivsi3_2: r19, r21
2317 (define_expand "divsi_inv_m0"
2318   [(set (match_operand:SI 0 "register_operand" "=r")
2319         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2320                     (match_operand:DI 2 "register_operand" "r")
2321                     (match_operand:SI 3 "register_operand" "r")]
2322          UNSPEC_DIV_INV_M0))
2323    (clobber (match_operand:DI 4 "register_operand" "=r"))
2324    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2325   "TARGET_SHMEDIA"
2326   "
2327 {
2328 /*
2329 tab_base: r20
2330 tab_ix: r21
2331 norm32: r25
2332  ldx.ub r20, r21, r19 // u0.8
2333  shlli r21, 1, r21
2334  muls.l r25, r19, r19 // s2.38
2335  ldx.w r20, r21, r21  // s2.14
2336  shari r19, 24, r19   // truncate to s2.14
2337  sub r21, r19, r19    // some 11 bit inverse in s1.14
2338 */
2339
2340   rtx inv0 = operands[0];
2341   rtx tab_base = operands[1];
2342   rtx tab_ix = operands[2];
2343   rtx norm32 = operands[3];
2344   rtx scratch0 = operands[4];
2345   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2346   rtx scratch1 = operands[5];
2347
2348   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2349   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2350   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2351   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2352   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2353   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2354   DONE;
2355 }")
2356
2357 ;; operands: inv1, tab_base, tab_ix, norm32
2358 (define_insn_and_split "divsi_inv_m1"
2359   [(set (match_operand:SI 0 "register_operand" "=r")
2360         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2361                     (match_operand:DI 2 "register_operand" "r")
2362                     (match_operand:SI 3 "register_operand" "r")]
2363          UNSPEC_DIV_INV_M1))
2364    (clobber (match_operand:SI 4 "register_operand" "=r"))
2365    (clobber (match_operand:DI 5 "register_operand" "=r"))
2366    (clobber (match_operand:DI 6 "register_operand" "=r"))
2367    (clobber (match_operand:DI 7 "register_operand" "=r"))
2368    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2369   "TARGET_SHMEDIA"
2370   "#"
2371   "&& !can_create_pseudo_p ()"
2372   [(pc)]
2373   "
2374 {
2375 /* inv0: r19
2376  muls.l r19, r19, r18 // u0.28
2377  muls.l r25, r18, r18 // s2.58
2378  shlli r19, 45, r0    // multiply by two and convert to s2.58
2379  sub r0, r18, r18
2380  shari r18, 28, r18   // some 18 bit inverse in s1.30
2381 */
2382
2383   rtx inv1 = operands[0];
2384   rtx tab_base = operands[1];
2385   rtx tab_ix = operands[2];
2386   rtx norm32 = operands[3];
2387   rtx inv0 = operands[4];
2388   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2389   rtx scratch0a = operands[5];
2390   rtx scratch0b = operands[6];
2391   rtx scratch0 = operands[7];
2392   rtx scratch1 = operands[8];
2393   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2394
2395   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2396                                scratch0a, scratch0b));
2397   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2398   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2399   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2400   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2401   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2402   DONE;
2403 }")
2404
2405 ;; operands: inv2, norm32, inv1, i92
2406 (define_insn_and_split "divsi_inv_m2"
2407   [(set (match_operand:SI 0 "register_operand" "=r")
2408         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2409                     (match_operand:SI 2 "register_operand" "r")
2410                     (match_operand:DI 3 "register_operand" "r")]
2411          UNSPEC_DIV_INV_M2))
2412    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2413   "TARGET_SHMEDIA"
2414   "#"
2415   "&& !can_create_pseudo_p ()"
2416   [(pc)]
2417   "
2418 {
2419 /*
2420  muls.l r18, r25, r0  // s2.60
2421  shari r0, 16, r0     // s-16.44
2422   sub
2423  muls.l r0, r18, r19  // s-16.74
2424  shari r19, 30, r19   // s-16.44
2425 */
2426   rtx inv2 = operands[0];
2427   rtx norm32 = operands[1];
2428   rtx inv1 = operands[2];
2429   rtx i92 = operands[3];
2430   rtx scratch0 = operands[4];
2431   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2432
2433   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2434   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2435   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2436   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2437   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2438   DONE;
2439 }")
2440
2441 (define_insn_and_split "divsi_inv_m3"
2442   [(set (match_operand:SI 0 "register_operand" "=r")
2443         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2444                     (match_operand:SI 2 "register_operand" "r")
2445                     (match_operand:SI 3 "register_operand" "r")
2446                     (match_operand:DI 4 "register_operand" "r")
2447                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2448                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2449          UNSPEC_DIV_INV_M3))
2450    (clobber (match_operand:DI 7 "register_operand" "=r"))
2451    (clobber (match_operand:DI 8 "register_operand" "=r"))
2452    (clobber (match_operand:DI 9 "register_operand" "=r"))
2453    (clobber (match_operand:DI 10 "register_operand" "=r"))
2454    (clobber (match_operand:SI 11 "register_operand" "=r"))
2455    (clobber (match_operand:SI 12 "register_operand" "=r"))
2456    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2457   "TARGET_SHMEDIA"
2458   "#"
2459   "&& !can_create_pseudo_p ()"
2460   [(pc)]
2461   "
2462 {
2463 /*
2464   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2465   r0: scratch0  r19: scratch1 r21: scratch2
2466
2467   muls.l r18, r4, r25 // s32.30
2468  muls.l r19, r4, r19  // s15.30
2469  shari r25, 63, r21
2470   shari r19, 14, r19  // s18.-14
2471  sub r25, r19, r0
2472  shard r0, r1, r0
2473  sub r0, r21, r0
2474 */
2475
2476   rtx result = operands[0];
2477   rtx dividend = operands[1];
2478   rtx inv1 = operands[2];
2479   rtx inv2 = operands[3];
2480   rtx shift = operands[4];
2481   rtx scratch0 = operands[7];
2482   rtx scratch1 = operands[8];
2483   rtx scratch2 = operands[9];
2484
2485   if (satisfies_constraint_N (dividend))
2486     {
2487       emit_move_insn (result, dividend);
2488       DONE;
2489     }
2490
2491   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2492   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2493   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2494   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2495   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2496   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2497   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2498   DONE;
2499 }")
2500
2501 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2502 ;; inv1: tab_base, tab_ix, norm32
2503 ;; inv2: norm32, inv1, i92
2504 (define_insn_and_split "divsi_inv_m1_3"
2505   [(set (match_operand:SI 0 "register_operand" "=r")
2506         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2507                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2508                                 (match_operand:DI 3 "register_operand" "r")
2509                                 (match_operand:SI 4 "register_operand" "r")]
2510                      UNSPEC_DIV_INV_M1)
2511                     (unspec:SI [(match_dup 4)
2512                                 (unspec:SI [(match_dup 2)
2513                                             (match_dup 3)
2514                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2515                                 (match_operand:SI 5 "" "")]
2516                      UNSPEC_DIV_INV_M2)
2517                     (match_operand:DI 6 "register_operand" "r")
2518                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2519                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2520          UNSPEC_DIV_INV_M3))
2521    (clobber (match_operand:DI 9 "register_operand" "=r"))
2522    (clobber (match_operand:DI 10 "register_operand" "=r"))
2523    (clobber (match_operand:DI 11 "register_operand" "=r"))
2524    (clobber (match_operand:DI 12 "register_operand" "=r"))
2525    (clobber (match_operand:SI 13 "register_operand" "=r"))
2526    (clobber (match_operand:SI 14 "register_operand" "=r"))
2527    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2528   "TARGET_SHMEDIA
2529    && (TARGET_DIVIDE_INV_MINLAT
2530        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2531   "#"
2532   "&& !can_create_pseudo_p ()"
2533   [(pc)]
2534   "
2535 {
2536   rtx result = operands[0];
2537   rtx dividend = operands[1];
2538   rtx tab_base = operands[2];
2539   rtx tab_ix = operands[3];
2540   rtx norm32 = operands[4];
2541   /* rtx i92 = operands[5]; */
2542   rtx shift = operands[6];
2543   rtx i2p27 = operands[7];
2544   rtx i43 = operands[8];
2545   rtx scratch0 = operands[9];
2546   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2547   rtx scratch1 = operands[10];
2548   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2549   rtx scratch2 = operands[11];
2550   rtx scratch3 = operands[12];
2551   rtx scratch4 = operands[13];
2552   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2553   rtx scratch5 = operands[14];
2554   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2555   rtx scratch6 = operands[15];
2556
2557   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2558                                scratch0, scratch1));
2559   /* inv0 == scratch4 */
2560   if (! TARGET_DIVIDE_INV20U)
2561     {
2562       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2563       i2p27 = scratch0;
2564       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2565     }
2566   else
2567     {
2568       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2569       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2570     }
2571   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2572   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2573   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2574   /* inv1 == scratch4 */
2575
2576   if (TARGET_DIVIDE_INV_MINLAT)
2577     {
2578       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2579       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2580       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2581       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2582       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2583       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2584       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2585       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2586       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2587       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2588       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2589     }
2590   else
2591     {
2592       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2593       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2594       emit_insn (gen_nsbdi (scratch6,
2595                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2596       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2597       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2598       emit_insn (gen_divsi_inv20 (scratch2,
2599                                   norm32, scratch4, dividend,
2600                                   scratch6, scratch3, i43,
2601                                   /* scratch0 may be shared with i2p27.  */
2602                                   scratch0, scratch1, scratch5,
2603                                   label, label, i2p27));
2604     }
2605   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2606   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2607   DONE;
2608 }")
2609
2610 (define_insn "divsi_inv20"
2611   [(set (match_operand:DI 0 "register_operand" "=&r")
2612         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2613                     (match_operand:SI 2 "register_operand" "r")
2614                     (match_operand:SI 3 "register_operand" "r")
2615                     (match_operand:DI 4 "register_operand" "r")
2616                     (match_operand:DI 5 "register_operand" "r")
2617                     (match_operand:DI 6 "register_operand" "r")
2618                     (match_operand:DI 12 "register_operand" "r")
2619                     (match_operand 10 "target_operand" "b")
2620                     (match_operand 11 "immediate_operand" "i")]
2621          UNSPEC_DIV_INV20))
2622    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2623    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2624    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2625   "TARGET_SHMEDIA
2626    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2627   "*
2628 {
2629 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2630              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2631              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2632              %10 label (tr), %11 label (imm)
2633
2634  muls.l inv1, norm32, scratch0  // s2.60
2635   muls.l inv1, dividend, result // s32.30
2636   xor i2p27, result_sign, round_scratch
2637  bge/u dividend_nsb, i43, tr.. (label)
2638  shari scratch0, 16, scratch0   // s-16.44
2639  muls.l sratch0_si, inv1, scratch0 // s-16.74
2640   sub result, round_scratch, result
2641   shari dividend, 14, scratch1   // s19.-14
2642  shari scratch0, 30, scratch0   // s-16.44
2643  muls.l scratch0, scratch1, round_scratch // s15.30
2644 label:
2645  sub result, round_scratch, result */
2646
2647   int likely = TARGET_DIVIDE_INV20L;
2648
2649   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2650   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2651   output_asm_insn (likely
2652                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2653                    : \"bge/u\t%4, %6, %10\", operands);
2654   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2655   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2656   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2657   return (likely
2658           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2659           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2660 }")
2661
2662 (define_insn_and_split "divsi_inv_fp"
2663   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2664         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2665                 (match_operand:SI 2 "register_operand" "rf")))
2666    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2667    (clobber (match_operand:SI 4 "register_operand" "=r"))
2668    (clobber (match_operand:SI 5 "register_operand" "=r"))
2669    (clobber (match_operand:DF 6 "register_operand" "=r"))
2670    (clobber (match_operand:DF 7 "register_operand" "=r"))
2671    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2672   "TARGET_SHMEDIA_FPU"
2673   "#"
2674   "&& (high_life_started || reload_completed)"
2675   [(set (match_dup 0) (match_dup 3))]
2676   ""
2677   [(set_attr "highpart" "must_split")])
2678
2679 ;; If a matching group of divide-by-inverse instructions is in the same
2680 ;; basic block after gcse & loop optimizations, we want to transform them
2681 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2682 (define_insn_and_split "*divsi_inv_fp_combine"
2683   [(set (match_operand:SI 0 "register_operand" "=f")
2684         (div:SI (match_operand:SI 1 "register_operand" "f")
2685                 (match_operand:SI 2 "register_operand" "f")))
2686    (use (unspec:SI [(match_dup 1)
2687                     (match_operand:SI 3 "" "")
2688                     (unspec:SI [(match_operand:SI 4 "" "")
2689                                 (match_dup 3)
2690                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2691                     (match_operand:DI 6 "" "")
2692                     (const_int 0)
2693                     (const_int 0)] UNSPEC_DIV_INV_M3))
2694    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2695    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2696    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2697    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2698    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2699   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2700   "#"
2701   "&& 1"
2702   [(set (match_dup 9) (float:DF (match_dup 1)))
2703    (set (match_dup 10) (float:DF (match_dup 2)))
2704    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2705    (set (match_dup 8)
2706         (fix:SI (match_dup 11)))
2707    (set (match_dup 0) (match_dup 8))]
2708   "
2709 {
2710   if (! fp_arith_reg_operand (operands[1], SImode))
2711     {
2712       emit_move_insn (operands[7], operands[1]);
2713       operands[1] = operands[7];
2714     }
2715   if (! fp_arith_reg_operand (operands[2], SImode))
2716     {
2717       emit_move_insn (operands[8], operands[2]);
2718       operands[2] = operands[8];
2719     }
2720 }"
2721   [(set_attr "highpart" "must_split")])
2722 \f
2723 ;; -------------------------------------------------------------------------
2724 ;; Multiplication instructions
2725 ;; -------------------------------------------------------------------------
2726
2727 (define_insn "umulhisi3_i"
2728   [(set (reg:SI MACL_REG)
2729         (mult:SI (zero_extend:SI
2730                   (match_operand:HI 0 "arith_reg_operand" "r"))
2731                  (zero_extend:SI
2732                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2733   "TARGET_SH1"
2734   "mulu.w       %1,%0"
2735   [(set_attr "type" "smpy")])
2736
2737 (define_insn "mulhisi3_i"
2738   [(set (reg:SI MACL_REG)
2739         (mult:SI (sign_extend:SI
2740                   (match_operand:HI 0 "arith_reg_operand" "r"))
2741                  (sign_extend:SI
2742                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2743   "TARGET_SH1"
2744   "muls.w       %1,%0"
2745   [(set_attr "type" "smpy")])
2746
2747 (define_expand "mulhisi3"
2748   [(set (reg:SI MACL_REG)
2749         (mult:SI (sign_extend:SI
2750                   (match_operand:HI 1 "arith_reg_operand" ""))
2751                  (sign_extend:SI
2752                   (match_operand:HI 2 "arith_reg_operand" ""))))
2753    (set (match_operand:SI 0 "arith_reg_operand" "")
2754         (reg:SI MACL_REG))]
2755   "TARGET_SH1"
2756   "
2757 {
2758   rtx insn, macl;
2759
2760   macl = gen_rtx_REG (SImode, MACL_REG);
2761   start_sequence ();
2762   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2763   insn = get_insns ();  
2764   end_sequence ();
2765   /* expand_binop can't find a suitable code in umul_widen_optab to
2766      make a REG_EQUAL note from, so make one here.
2767      See also smulsi3_highpart.
2768      ??? Alternatively, we could put this at the calling site of expand_binop,
2769      i.e. expand_expr.  */
2770   /* Use emit_libcall_block for loop invariant code motion and to make
2771      a REG_EQUAL note.  */
2772   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2773
2774   DONE;
2775 }")
2776
2777 (define_expand "umulhisi3"
2778   [(set (reg:SI MACL_REG)
2779         (mult:SI (zero_extend:SI
2780                   (match_operand:HI 1 "arith_reg_operand" ""))
2781                  (zero_extend:SI
2782                   (match_operand:HI 2 "arith_reg_operand" ""))))
2783    (set (match_operand:SI 0 "arith_reg_operand" "")
2784         (reg:SI MACL_REG))]
2785   "TARGET_SH1"
2786   "
2787 {
2788   rtx insn, macl;
2789
2790   macl = gen_rtx_REG (SImode, MACL_REG);
2791   start_sequence ();
2792   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2793   insn = get_insns ();  
2794   end_sequence ();
2795   /* expand_binop can't find a suitable code in umul_widen_optab to
2796      make a REG_EQUAL note from, so make one here.
2797      See also smulsi3_highpart.
2798      ??? Alternatively, we could put this at the calling site of expand_binop,
2799      i.e. expand_expr.  */
2800   /* Use emit_libcall_block for loop invariant code motion and to make
2801      a REG_EQUAL note.  */
2802   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2803
2804   DONE;
2805 }")
2806
2807 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2808 ;; a call to a routine which clobbers known registers.
2809
2810 (define_insn ""
2811   [(set (match_operand:SI 1 "register_operand" "=z")
2812         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2813    (clobber (reg:SI MACL_REG))
2814    (clobber (reg:SI T_REG))
2815    (clobber (reg:SI PR_REG))
2816    (clobber (reg:SI R3_REG))
2817    (clobber (reg:SI R2_REG))
2818    (clobber (reg:SI R1_REG))
2819    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2820   "TARGET_SH1"
2821   "jsr  @%0%#"
2822   [(set_attr "type" "sfunc")
2823    (set_attr "needs_delay_slot" "yes")])
2824
2825 (define_expand "mulsi3_call"
2826   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2827    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2828    (parallel[(set (match_operand:SI 0 "register_operand" "")
2829                   (mult:SI (reg:SI R4_REG)
2830                            (reg:SI R5_REG)))
2831              (clobber (reg:SI MACL_REG))
2832              (clobber (reg:SI T_REG))
2833              (clobber (reg:SI PR_REG))
2834              (clobber (reg:SI R3_REG))
2835              (clobber (reg:SI R2_REG))
2836              (clobber (reg:SI R1_REG))
2837              (use (match_operand:SI 3 "register_operand" ""))])]
2838   "TARGET_SH1"
2839   "")
2840
2841 (define_insn "mul_r"
2842   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2843         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2844                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2845   "TARGET_SH2A"
2846   "mulr %2,%0"
2847   [(set_attr "type" "dmpy")])
2848
2849 (define_insn "mul_l"
2850   [(set (reg:SI MACL_REG)
2851         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2852                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2853   "TARGET_SH2"
2854   "mul.l        %1,%0"
2855   [(set_attr "type" "dmpy")])
2856
2857 (define_expand "mulsi3"
2858   [(set (reg:SI MACL_REG)
2859         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2860                   (match_operand:SI 2 "arith_reg_operand" "")))
2861    (set (match_operand:SI 0 "arith_reg_operand" "")
2862         (reg:SI MACL_REG))]
2863   "TARGET_SH1"
2864   "
2865 {
2866   if (!TARGET_SH2)
2867     {
2868       /* The address must be set outside the libcall,
2869          since it goes into a pseudo.  */
2870       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2871       rtx addr = force_reg (SImode, sym);
2872       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2873                                    operands[2], addr);
2874       emit_insn (insns);
2875     }
2876   else
2877     {
2878       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2879
2880       emit_insn (gen_mul_l (operands[1], operands[2]));
2881       /* consec_sets_giv can only recognize the first insn that sets a
2882          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2883          note.  */
2884       emit_insn (gen_movsi_i ((operands[0]), macl));
2885     }
2886   DONE;
2887 }")
2888
2889 (define_insn "mulsidi3_i"
2890   [(set (reg:SI MACH_REG)
2891         (truncate:SI
2892          (lshiftrt:DI
2893           (mult:DI
2894            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2895            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2896           (const_int 32))))
2897    (set (reg:SI MACL_REG)
2898         (mult:SI (match_dup 0)
2899                  (match_dup 1)))]
2900   "TARGET_SH2"
2901   "dmuls.l      %1,%0"
2902   [(set_attr "type" "dmpy")])
2903
2904 (define_expand "mulsidi3"
2905   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2906         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2907                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2908   "TARGET_SH2 || TARGET_SHMEDIA"
2909   "
2910 {
2911   if (TARGET_SH2)
2912     {
2913        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2914                                         operands[2]));
2915        DONE;
2916     }
2917 }")
2918
2919 (define_insn "mulsidi3_media"
2920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2922                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2923   "TARGET_SHMEDIA"
2924   "muls.l       %1, %2, %0"
2925   [(set_attr "type" "dmpy_media")
2926    (set_attr "highpart" "ignore")])
2927
2928 (define_insn "mulsidi3_compact"
2929   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2930         (mult:DI
2931          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2932          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2933    (clobber (reg:SI MACH_REG))
2934    (clobber (reg:SI MACL_REG))]
2935   "TARGET_SH2"
2936   "#")
2937
2938 (define_split
2939   [(set (match_operand:DI 0 "arith_reg_dest" "")
2940         (mult:DI
2941          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2942          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2943    (clobber (reg:SI MACH_REG))
2944    (clobber (reg:SI MACL_REG))]
2945   "TARGET_SH2"
2946   [(const_int 0)]
2947   "
2948 {
2949   rtx low_dst = gen_lowpart (SImode, operands[0]);
2950   rtx high_dst = gen_highpart (SImode, operands[0]);
2951
2952   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2953
2954   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2955   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2956   /* We need something to tag the possible REG_EQUAL notes on to.  */
2957   emit_move_insn (operands[0], operands[0]);
2958   DONE;
2959 }")
2960
2961 (define_insn "umulsidi3_i"
2962   [(set (reg:SI MACH_REG)
2963         (truncate:SI
2964          (lshiftrt:DI
2965           (mult:DI
2966            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2967            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2968           (const_int 32))))
2969    (set (reg:SI MACL_REG)
2970         (mult:SI (match_dup 0)
2971                  (match_dup 1)))]
2972   "TARGET_SH2"
2973   "dmulu.l      %1,%0"
2974   [(set_attr "type" "dmpy")])
2975
2976 (define_expand "umulsidi3"
2977   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2978         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2979                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2980   "TARGET_SH2 || TARGET_SHMEDIA"
2981   "
2982 {
2983   if (TARGET_SH2)
2984     {
2985        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2986                                          operands[2]));
2987        DONE;
2988     }
2989 }")
2990
2991 (define_insn "umulsidi3_media"
2992   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2993         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2994                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2995   "TARGET_SHMEDIA"
2996   "mulu.l       %1, %2, %0"
2997   [(set_attr "type" "dmpy_media")
2998    (set_attr "highpart" "ignore")])
2999
3000 (define_insn "umulsidi3_compact"
3001   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3002         (mult:DI
3003          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3004          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3005    (clobber (reg:SI MACH_REG))
3006    (clobber (reg:SI MACL_REG))]
3007   "TARGET_SH2"
3008   "#")
3009
3010 (define_split
3011   [(set (match_operand:DI 0 "arith_reg_dest" "")
3012         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3013                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3014    (clobber (reg:SI MACH_REG))
3015    (clobber (reg:SI MACL_REG))]
3016   "TARGET_SH2"
3017   [(const_int 0)]
3018   "
3019 {
3020   rtx low_dst = gen_lowpart (SImode, operands[0]);
3021   rtx high_dst = gen_highpart (SImode, operands[0]);
3022
3023   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3024
3025   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3026   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3027   /* We need something to tag the possible REG_EQUAL notes on to.  */
3028   emit_move_insn (operands[0], operands[0]);
3029   DONE;
3030 }")
3031
3032 (define_insn "smulsi3_highpart_i"
3033   [(set (reg:SI MACH_REG)
3034         (truncate:SI
3035          (lshiftrt:DI
3036           (mult:DI
3037            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3038            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3039           (const_int 32))))
3040    (clobber (reg:SI MACL_REG))]
3041   "TARGET_SH2"
3042   "dmuls.l      %1,%0"
3043   [(set_attr "type" "dmpy")])
3044
3045 (define_expand "smulsi3_highpart"
3046   [(parallel
3047     [(set (reg:SI MACH_REG)
3048           (truncate:SI
3049            (lshiftrt:DI
3050             (mult:DI
3051              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3052              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3053             (const_int 32))))
3054     (clobber (reg:SI MACL_REG))])
3055    (set (match_operand:SI 0 "arith_reg_operand" "")
3056         (reg:SI MACH_REG))]
3057   "TARGET_SH2"
3058   "
3059 {
3060   rtx insn, mach;
3061
3062   mach = gen_rtx_REG (SImode, MACH_REG);
3063   start_sequence ();
3064   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3065   insn = get_insns ();  
3066   end_sequence ();
3067   /* expand_binop can't find a suitable code in mul_highpart_optab to
3068      make a REG_EQUAL note from, so make one here.
3069      See also {,u}mulhisi.
3070      ??? Alternatively, we could put this at the calling site of expand_binop,
3071      i.e. expand_mult_highpart.  */
3072   /* Use emit_libcall_block for loop invariant code motion and to make
3073      a REG_EQUAL note.  */
3074   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3075
3076   DONE;
3077 }")
3078
3079 (define_insn "umulsi3_highpart_i"
3080   [(set (reg:SI MACH_REG)
3081         (truncate:SI
3082          (lshiftrt:DI
3083           (mult:DI
3084            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3085            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3086           (const_int 32))))
3087    (clobber (reg:SI MACL_REG))]
3088   "TARGET_SH2"
3089   "dmulu.l      %1,%0"
3090   [(set_attr "type" "dmpy")])
3091
3092 (define_expand "umulsi3_highpart"
3093   [(parallel
3094     [(set (reg:SI MACH_REG)
3095           (truncate:SI
3096            (lshiftrt:DI
3097             (mult:DI
3098              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3099              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3100             (const_int 32))))
3101     (clobber (reg:SI MACL_REG))])
3102    (set (match_operand:SI 0 "arith_reg_operand" "")
3103         (reg:SI MACH_REG))]
3104   "TARGET_SH2"
3105   "
3106 {
3107   rtx insn, mach;
3108
3109   mach = gen_rtx_REG (SImode, MACH_REG);
3110   start_sequence ();
3111   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3112   insn = get_insns ();  
3113   end_sequence ();
3114   /* Use emit_libcall_block for loop invariant code motion and to make
3115      a REG_EQUAL note.  */
3116   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3117
3118   DONE;
3119 }")
3120
3121 (define_insn_and_split "muldi3"
3122   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3123         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3124                  (match_operand:DI 2 "arith_reg_operand" "r")))
3125    (clobber (match_scratch:DI 3 "=&r"))
3126    (clobber (match_scratch:DI 4 "=r"))]
3127   "TARGET_SHMEDIA"
3128   "#"
3129   "reload_completed"
3130   [(const_int 0)]
3131   "
3132 {
3133   rtx op3_v2si, op2_v2si;
3134
3135   op3_v2si = operands[3];
3136   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3137     {
3138       op3_v2si = XEXP (op3_v2si, 0);
3139       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3140     }
3141   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3142   op2_v2si = operands[2];
3143   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3144     {
3145       op2_v2si = XEXP (op2_v2si, 0);
3146       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3147     }
3148   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3149   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3150   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3151   emit_insn (gen_umulsidi3_media (operands[4],
3152                                  sh_gen_truncate (SImode, operands[1], 0),
3153                                  sh_gen_truncate (SImode, operands[2], 0)));
3154   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3155   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3156   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3157   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3158   DONE;
3159 }")
3160
3161 \f
3162 ;; -------------------------------------------------------------------------
3163 ;; Logical operations
3164 ;; -------------------------------------------------------------------------
3165
3166 (define_insn "*andsi3_compact"
3167   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3168         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3169                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3170   "TARGET_SH1"
3171   "and  %2,%0"
3172   [(set_attr "type" "arith")])
3173
3174 (define_insn "*andsi3_media"
3175   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3176         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3177                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3178   "TARGET_SHMEDIA"
3179   "@
3180         and     %1, %2, %0
3181         andi    %1, %2, %0"
3182   [(set_attr "type" "arith_media")])
3183
3184 (define_insn "*andsi3_bclr"
3185   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3187                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3188   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3189   "bclr\\t%W2,%0"
3190   [(set_attr "type" "arith")])
3191
3192 ;; If the constant is 255, then emit an extu.b instruction instead of an
3193 ;; and, since that will give better code.
3194
3195 (define_expand "andsi3"
3196   [(set (match_operand:SI 0 "arith_reg_operand" "")
3197         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3198                 (match_operand:SI 2 "logical_operand" "")))]
3199   ""
3200   "
3201 {
3202   if (TARGET_SH1
3203       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3204     {
3205       emit_insn (gen_zero_extendqisi2 (operands[0],
3206                                        gen_lowpart (QImode, operands[1])));
3207       DONE;
3208     }
3209 }")
3210
3211 (define_insn_and_split "anddi3"
3212   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3213         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3214                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3215   "TARGET_SHMEDIA"
3216   "@
3217         and     %1, %2, %0
3218         andi    %1, %2, %0
3219         #"
3220   "reload_completed
3221    && ! logical_operand (operands[2], DImode)"
3222   [(const_int 0)]
3223   "
3224 {
3225   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3226     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3227   else
3228     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3229   DONE;
3230 }"
3231   [(set_attr "type" "arith_media")])
3232
3233 (define_insn "andcsi3"
3234   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3235         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3236                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3237   "TARGET_SHMEDIA"
3238   "andc %1,%2,%0"
3239   [(set_attr "type" "arith_media")])
3240
3241 (define_insn "andcdi3"
3242   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3243         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3244                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3245   "TARGET_SHMEDIA"
3246   "andc %1,%2,%0"
3247   [(set_attr "type" "arith_media")])
3248
3249 (define_expand "iorsi3"
3250   [(set (match_operand:SI 0 "arith_reg_operand" "")
3251         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3252                 (match_operand:SI 2 "logical_operand" "")))]
3253   ""
3254   "")
3255
3256 (define_insn "*iorsi3_compact"
3257   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3258         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3259                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3260   "TARGET_SH1
3261    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3262   "or   %2,%0"
3263   [(set_attr "type" "arith")])
3264
3265 (define_insn "*iorsi3_media"
3266   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3267         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3268                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3269   "TARGET_SHMEDIA"
3270   "@
3271         or      %1, %2, %0
3272         ori     %1, %2, %0"
3273   [(set_attr "type" "arith_media")])
3274
3275 (define_insn "*iorsi3_bset"
3276   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3277         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3278         (match_operand:SI 2 "const_int_operand" "Pso")))]
3279   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3280   "bset\\t%V2,%0"
3281   [(set_attr "type" "arith")])
3282
3283 (define_insn "iordi3"
3284   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3285         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3286                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3287   "TARGET_SHMEDIA"
3288   "@
3289         or      %1, %2, %0
3290         ori     %1, %2, %0"
3291   [(set_attr "type" "arith_media")])
3292
3293 (define_insn_and_split "*logical_sidi3"
3294   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3296                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3297                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3298   "TARGET_SHMEDIA"
3299   "#"
3300   "&& reload_completed"
3301   [(set (match_dup 0) (match_dup 3))]
3302   "
3303 {
3304   operands[3]
3305     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3306                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3307                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3308 }")
3309
3310 (define_insn_and_split "*logical_sidisi3"
3311   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3312         (truncate:SI (sign_extend:DI
3313                         (match_operator:SI 3 "logical_operator"
3314                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3315                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3316   "TARGET_SHMEDIA"
3317   "#"
3318   "&& 1"
3319   [(set (match_dup 0) (match_dup 3))])
3320
3321 (define_insn_and_split "*logical_sidi3_2"
3322   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3323         (sign_extend:DI (truncate:SI (sign_extend:DI
3324                         (match_operator:SI 3 "logical_operator"
3325                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3326                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3327   "TARGET_SHMEDIA"
3328   "#"
3329   "&& 1"
3330   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3331
3332 (define_expand "xorsi3"
3333   [(set (match_operand:SI 0 "arith_reg_operand" "")
3334         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3335                 (match_operand:SI 2 "xor_operand" "")))]
3336   ""
3337   "")
3338
3339 (define_insn "*xorsi3_compact"
3340   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3341         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3342                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3343   "TARGET_SH1"
3344   "xor  %2,%0"
3345   [(set_attr "type" "arith")])
3346
3347 (define_insn "*xorsi3_media"
3348   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3349         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3350                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3351   "TARGET_SHMEDIA"
3352   "@
3353         xor     %1, %2, %0
3354         xori    %1, %2, %0"
3355   [(set_attr "type" "arith_media")])
3356
3357 ;; Store the complements of the T bit in a register.
3358 (define_insn "xorsi3_movrt"
3359   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3360         (xor:SI (reg:SI T_REG)
3361                 (const_int 1)))]
3362   "TARGET_SH2A"
3363   "movrt\\t%0"
3364   [(set_attr "type" "arith")])
3365
3366 (define_insn "xordi3"
3367   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3368         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3369                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3370   "TARGET_SHMEDIA"
3371   "@
3372         xor     %1, %2, %0
3373         xori    %1, %2, %0"
3374   [(set_attr "type" "arith_media")])
3375
3376 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3377 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3378 (define_split
3379   [(set (match_operand:DI 0 "arith_reg_dest" "")
3380         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3381                           [(match_operand 1 "any_register_operand" "")
3382                            (match_operand 2 "any_register_operand" "")])))]
3383   "TARGET_SHMEDIA"
3384   [(set (match_dup 5) (match_dup 4))
3385    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3386 "
3387 {
3388   enum machine_mode inmode = GET_MODE (operands[1]);
3389   int offset = 0;
3390
3391   if (GET_CODE (operands[0]) == SUBREG)
3392     {
3393       offset = SUBREG_BYTE (operands[0]);
3394       operands[0] = SUBREG_REG (operands[0]);
3395     }
3396   gcc_assert (REG_P (operands[0]));
3397   if (! TARGET_LITTLE_ENDIAN)
3398     offset += 8 - GET_MODE_SIZE (inmode);
3399   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3400 }")
3401 \f
3402 ;; -------------------------------------------------------------------------
3403 ;; Shifts and rotates
3404 ;; -------------------------------------------------------------------------
3405
3406 (define_expand "rotldi3"
3407   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3408         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3409                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3410   "TARGET_SHMEDIA"
3411   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3412
3413 (define_insn "rotldi3_mextr"
3414   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3415         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3416                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3417   "TARGET_SHMEDIA"
3418   "*
3419 {
3420   static char templ[16];
3421
3422   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3423            8 - (int) (INTVAL (operands[2]) >> 3));
3424   return templ;
3425 }"
3426   [(set_attr "type" "arith_media")])
3427
3428 (define_expand "rotrdi3"
3429   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3430         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3431                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3432   "TARGET_SHMEDIA"
3433   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3434
3435 (define_insn "rotrdi3_mextr"
3436   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3437         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3438                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3439   "TARGET_SHMEDIA"
3440   "*
3441 {
3442   static char templ[16];
3443
3444   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3445   return templ;
3446 }"
3447   [(set_attr "type" "arith_media")])
3448
3449 (define_split
3450   [(set (match_operand:DI 0 "arith_reg_dest" "")
3451         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3452                                          "ua_address_operand" "")))
3453                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3454                            (const_int 8))))
3455    (clobber (match_operand:DI 3 "register_operand" ""))]
3456   "TARGET_SHMEDIA"
3457   [(match_dup 4) (match_dup 5)]
3458   "
3459 {
3460   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3461                  (operands[3], operands[1]));
3462   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3463                               GEN_INT (56), GEN_INT (8));
3464 }")
3465
3466 (define_insn "rotlsi3_1"
3467   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3468         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3469                    (const_int 1)))
3470    (set (reg:SI T_REG)
3471         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3472   "TARGET_SH1"
3473   "rotl %0"
3474   [(set_attr "type" "arith")])
3475
3476 (define_insn "rotlsi3_31"
3477   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3478         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3479                    (const_int 31)))
3480    (clobber (reg:SI T_REG))]
3481   "TARGET_SH1"
3482   "rotr %0"
3483   [(set_attr "type" "arith")])
3484
3485 (define_insn "rotlsi3_16"
3486   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3487         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3488                    (const_int 16)))]
3489   "TARGET_SH1"
3490   "swap.w       %1,%0"
3491   [(set_attr "type" "arith")])
3492
3493 (define_expand "rotlsi3"
3494   [(set (match_operand:SI 0 "arith_reg_dest" "")
3495         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3496                    (match_operand:SI 2 "immediate_operand" "")))]
3497   "TARGET_SH1"
3498   "
3499 {
3500   static const char rot_tab[] = {
3501     000, 000, 000, 000, 000, 000, 010, 001,
3502     001, 001, 011, 013, 003, 003, 003, 003,
3503     003, 003, 003, 003, 003, 013, 012, 002,
3504     002, 002, 010, 000, 000, 000, 000, 000,
3505   };
3506
3507   int count, choice;
3508
3509   if (!CONST_INT_P (operands[2]))
3510     FAIL;
3511   count = INTVAL (operands[2]);
3512   choice = rot_tab[count];
3513   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3514     FAIL;
3515   choice &= 7;
3516   switch (choice)
3517     {
3518     case 0:
3519       emit_move_insn (operands[0], operands[1]);
3520       count -= (count & 16) * 2;
3521       break;
3522     case 3:
3523      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3524      count -= 16;
3525      break;
3526     case 1:
3527     case 2:
3528       {
3529         rtx parts[2];
3530         parts[0] = gen_reg_rtx (SImode);
3531         parts[1] = gen_reg_rtx (SImode);
3532         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3533         emit_move_insn (parts[choice-1], operands[1]);
3534         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3535         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3536         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3537         count = (count & ~16) - 8;
3538       }
3539     }
3540
3541   for (; count > 0; count--)
3542     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3543   for (; count < 0; count++)
3544     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3545
3546   DONE;
3547 }")
3548
3549 (define_insn "*rotlhi3_8"
3550   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3551         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3552                    (const_int 8)))]
3553   "TARGET_SH1"
3554   "swap.b       %1,%0"
3555   [(set_attr "type" "arith")])
3556
3557 (define_expand "rotlhi3"
3558   [(set (match_operand:HI 0 "arith_reg_operand" "")
3559         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3560                    (match_operand:HI 2 "immediate_operand" "")))]
3561   "TARGET_SH1"
3562   "
3563 {
3564   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3565     FAIL;
3566 }")
3567
3568 ;;
3569 ;; shift left
3570
3571 (define_insn "ashlsi3_sh2a"
3572   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3573         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3574                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3575   "TARGET_SH2A"
3576   "shad %2,%0"
3577   [(set_attr "type" "arith")
3578    (set_attr "length" "4")])
3579
3580 ;; This pattern is used by init_expmed for computing the costs of shift
3581 ;; insns.
3582
3583 (define_insn_and_split "ashlsi3_std"
3584   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3585         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3586                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3587    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3588   "TARGET_SH3
3589    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3590   "@
3591    shld %2,%0
3592    add  %0,%0
3593    shll%O2      %0
3594    #"
3595   "TARGET_SH3
3596    && reload_completed
3597    && CONST_INT_P (operands[2])
3598    && ! satisfies_constraint_P27 (operands[2])"
3599   [(set (match_dup 3) (match_dup 2))
3600    (parallel
3601     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3602      (clobber (match_dup 4))])]
3603   "operands[4] = gen_rtx_SCRATCH (SImode);"
3604   [(set_attr "length" "*,*,*,4")
3605    (set_attr "type" "dyn_shift,arith,arith,arith")])
3606
3607 (define_insn "ashlhi3_k"
3608   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3609         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3610                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3611   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3612   "@
3613         add     %0,%0
3614         shll%O2 %0"
3615   [(set_attr "type" "arith")])
3616
3617 (define_insn "ashlsi3_n"
3618   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3619         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3620                    (match_operand:SI 2 "const_int_operand" "n")))
3621    (clobber (reg:SI T_REG))]
3622   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3623   "#"
3624   [(set (attr "length")
3625         (cond [(match_test "shift_insns_rtx (insn)")
3626                (const_string "2")
3627                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3628                (const_string "4")
3629                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3630                (const_string "6")]
3631               (const_string "8")))
3632    (set_attr "type" "arith")])
3633
3634 (define_split
3635   [(set (match_operand:SI 0 "arith_reg_dest" "")
3636         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3637                    (match_operand:SI 2 "const_int_operand" "")))
3638    (clobber (reg:SI T_REG))]
3639   "TARGET_SH1 && reload_completed"
3640   [(use (reg:SI R0_REG))]
3641   "
3642 {
3643   gen_shifty_op (ASHIFT, operands);
3644   DONE;
3645 }")
3646
3647 (define_insn "ashlsi3_media"
3648   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3649         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3650                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3651   "TARGET_SHMEDIA"
3652   "@
3653         shlld.l %1, %2, %0
3654         shlli.l %1, %2, %0"
3655   [(set_attr "type" "arith_media")
3656    (set_attr "highpart" "ignore")])
3657
3658 (define_expand "ashlsi3"
3659   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3660                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3661                               (match_operand:SI 2 "nonmemory_operand" "")))
3662               (clobber (reg:SI T_REG))])]
3663   ""
3664   "
3665 {
3666   if (TARGET_SHMEDIA)
3667     {
3668       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3669       DONE;
3670     }
3671   if (CONST_INT_P (operands[2])
3672       && sh_dynamicalize_shift_p (operands[2]))
3673     operands[2] = force_reg (SImode, operands[2]);
3674   if (TARGET_SH3)
3675     {
3676       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3677       DONE;
3678     }
3679   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3680     FAIL;
3681 }")
3682
3683 (define_insn "*ashlhi3_n"
3684   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3685         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3686                    (match_operand:HI 2 "const_int_operand" "n")))
3687    (clobber (reg:SI T_REG))]
3688   "TARGET_SH1"
3689   "#"
3690   [(set (attr "length")
3691         (cond [(match_test "shift_insns_rtx (insn)")
3692                (const_string "2")
3693                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3694                (const_string "4")]
3695               (const_string "6")))
3696    (set_attr "type" "arith")])
3697
3698 (define_expand "ashlhi3"
3699   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3700                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3701                               (match_operand:SI 2 "nonmemory_operand" "")))
3702               (clobber (reg:SI T_REG))])]
3703   "TARGET_SH1"
3704   "
3705 {
3706   if (!CONST_INT_P (operands[2]))
3707     FAIL;
3708   /* It may be possible to call gen_ashlhi3 directly with more generic
3709      operands.  Make sure operands[1] is a HImode register here.  */
3710   if (!arith_reg_operand (operands[1], HImode))
3711     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3712 }")
3713
3714 (define_split
3715   [(set (match_operand:HI 0 "arith_reg_dest" "")
3716         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3717                    (match_operand:HI 2 "const_int_operand" "")))
3718    (clobber (reg:SI T_REG))]
3719   "TARGET_SH1 && reload_completed"
3720   [(use (reg:SI R0_REG))]
3721   "
3722 {
3723   gen_shifty_hi_op (ASHIFT, operands);
3724   DONE;
3725 }")
3726
3727 ;
3728 ; arithmetic shift right
3729 ;
3730
3731 (define_insn "ashrsi3_sh2a"
3732   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3733         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3734                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3735   "TARGET_SH2A"
3736   "shad %2,%0"
3737   [(set_attr "type" "dyn_shift")
3738    (set_attr "length" "4")])
3739
3740 (define_insn "ashrsi3_k"
3741   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3742         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3743                      (match_operand:SI 2 "const_int_operand" "M")))
3744    (clobber (reg:SI T_REG))]
3745   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3746   "shar %0"
3747   [(set_attr "type" "arith")])
3748
3749 ;; We can't do HImode right shifts correctly unless we start out with an
3750 ;; explicit zero / sign extension; doing that would result in worse overall
3751 ;; code, so just let the machine independent code widen the mode.
3752 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3753
3754
3755 ;; ??? This should be a define expand.
3756
3757 (define_insn "ashrsi2_16"
3758   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3759         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3760                      (const_int 16)))]
3761   "TARGET_SH1"
3762   "#"
3763   [(set_attr "length" "4")])
3764
3765 (define_split
3766   [(set (match_operand:SI 0 "arith_reg_dest" "")
3767         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3768                      (const_int 16)))]
3769   "TARGET_SH1"
3770   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3771    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3772   "operands[2] = gen_lowpart (HImode, operands[0]);")
3773
3774 ;; ??? This should be a define expand.
3775
3776 (define_insn "ashrsi2_31"
3777   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3778         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3779                      (const_int 31)))
3780    (clobber (reg:SI T_REG))]
3781   "TARGET_SH1"
3782   "#"
3783   [(set_attr "length" "4")])
3784
3785 (define_split
3786   [(set (match_operand:SI 0 "arith_reg_dest" "")
3787         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3788                      (const_int 31)))
3789    (clobber (reg:SI T_REG))]
3790   "TARGET_SH1"
3791   [(const_int 0)]
3792   "
3793 {
3794   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3795   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3796   DONE;
3797 }")
3798
3799 (define_peephole2
3800   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3801    (set (reg:SI T_REG)
3802         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3803   "TARGET_SH1
3804    && peep2_reg_dead_p (2, operands[0])
3805    && peep2_reg_dead_p (2, operands[1])"
3806   [(const_int 0)]
3807   "
3808 {
3809   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3810   DONE;
3811 }")
3812
3813 (define_insn "ashlsi_c"
3814   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3815         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3816    (set (reg:SI T_REG)
3817         (lt:SI (match_dup 1) (const_int 0)))]
3818   "TARGET_SH1"
3819   "shll %0"
3820   [(set_attr "type" "arith")])
3821
3822 (define_insn "*ashlsi_c_void"
3823   [(set (reg:SI T_REG)
3824         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3825    (clobber (match_scratch:SI 1 "=0"))]
3826   "TARGET_SH1 && cse_not_expected"
3827   "shll %0"
3828   [(set_attr "type" "arith")])
3829
3830 (define_insn "ashrsi3_d"
3831   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3832         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3833                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3834   "TARGET_SH3"
3835   "shad %2,%0"
3836   [(set_attr "type" "dyn_shift")])
3837
3838 (define_insn "ashrsi3_n"
3839   [(set (reg:SI R4_REG)
3840         (ashiftrt:SI (reg:SI R4_REG)
3841                      (match_operand:SI 0 "const_int_operand" "i")))
3842    (clobber (reg:SI T_REG))
3843    (clobber (reg:SI PR_REG))
3844    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3845   "TARGET_SH1"
3846   "jsr  @%1%#"
3847   [(set_attr "type" "sfunc")
3848    (set_attr "needs_delay_slot" "yes")])
3849
3850 (define_insn "ashrsi3_media"
3851   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3852         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3853                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3854   "TARGET_SHMEDIA"
3855   "@
3856         shard.l %1, %2, %0
3857         shari.l %1, %2, %0"
3858   [(set_attr "type" "arith_media")
3859    (set_attr "highpart" "ignore")])
3860
3861 (define_expand "ashrsi3"
3862   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3863                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3864                                 (match_operand:SI 2 "nonmemory_operand" "")))
3865               (clobber (reg:SI T_REG))])]
3866   ""
3867   "
3868 {
3869   if (TARGET_SHMEDIA)
3870     {
3871       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3872       DONE;
3873     }
3874   if (expand_ashiftrt (operands))
3875     DONE;
3876   else
3877     FAIL;
3878 }")
3879
3880 ;; logical shift right
3881
3882 (define_insn "lshrsi3_sh2a"
3883   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3884         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3885                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3886   "TARGET_SH2A"
3887   "shld %2,%0"
3888   [(set_attr "type" "dyn_shift")
3889    (set_attr "length" "4")])
3890
3891 (define_insn "lshrsi3_d"
3892   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3893         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3894                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3895   "TARGET_SH3"
3896   "shld %2,%0"
3897   [(set_attr "type" "dyn_shift")])
3898
3899 ;;  Only the single bit shift clobbers the T bit.
3900
3901 (define_insn "lshrsi3_m"
3902   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3903         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3904                      (match_operand:SI 2 "const_int_operand" "M")))
3905    (clobber (reg:SI T_REG))]
3906   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3907   "shlr %0"
3908   [(set_attr "type" "arith")])
3909
3910 (define_insn "lshrsi3_k"
3911   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3912         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3913                      (match_operand:SI 2 "const_int_operand" "P27")))]
3914   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3915    && ! satisfies_constraint_M (operands[2])"
3916   "shlr%O2      %0"
3917   [(set_attr "type" "arith")])
3918
3919 (define_insn "lshrsi3_n"
3920   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3922                      (match_operand:SI 2 "const_int_operand" "n")))
3923    (clobber (reg:SI T_REG))]
3924   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3925   "#"
3926   [(set (attr "length")
3927         (cond [(match_test "shift_insns_rtx (insn)")
3928                (const_string "2")
3929                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3930                (const_string "4")
3931                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3932                (const_string "6")]
3933               (const_string "8")))
3934    (set_attr "type" "arith")])
3935
3936 (define_split
3937   [(set (match_operand:SI 0 "arith_reg_dest" "")
3938         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3939                      (match_operand:SI 2 "const_int_operand" "")))
3940    (clobber (reg:SI T_REG))]
3941   "TARGET_SH1 && reload_completed"
3942   [(use (reg:SI R0_REG))]
3943   "
3944 {
3945   gen_shifty_op (LSHIFTRT, operands);
3946   DONE;
3947 }")
3948
3949 (define_insn "lshrsi3_media"
3950   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3951         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3952                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3953   "TARGET_SHMEDIA"
3954   "@
3955         shlrd.l %1, %2, %0
3956         shlri.l %1, %2, %0"
3957   [(set_attr "type" "arith_media")
3958    (set_attr "highpart" "ignore")])
3959
3960 (define_expand "lshrsi3"
3961   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3962                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3963                                 (match_operand:SI 2 "nonmemory_operand" "")))
3964               (clobber (reg:SI T_REG))])]
3965   ""
3966   "
3967 {
3968   if (TARGET_SHMEDIA)
3969     {
3970       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3971       DONE;
3972     }
3973   if (CONST_INT_P (operands[2])
3974       && sh_dynamicalize_shift_p (operands[2]))
3975     operands[2] = force_reg (SImode, operands[2]);
3976   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3977     {
3978       rtx count = copy_to_mode_reg (SImode, operands[2]);
3979       emit_insn (gen_negsi2 (count, count));
3980       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3981       DONE;
3982     }
3983   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3984     FAIL;
3985 }")
3986
3987 ;; ??? This should be a define expand.
3988
3989 (define_insn "ashldi3_k"
3990   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3991         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3992                    (const_int 1)))
3993    (clobber (reg:SI T_REG))]
3994   "TARGET_SH1"
3995   "shll %R0\;rotcl      %S0"
3996   [(set_attr "length" "4")
3997    (set_attr "type" "arith")])
3998
3999 ;; Expander for DImode shift left with SImode operations.
4000
4001 (define_expand "ashldi3_std"
4002   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4003         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004                    (match_operand:DI 2 "const_int_operand" "n")))]
4005   "TARGET_SH1 && INTVAL (operands[2]) < 32"
4006   "
4007 {
4008   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4009   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4010   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4011   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4012   rtx dst = gen_reg_rtx (DImode);
4013   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
4014   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
4015   rtx tmp0, tmp1;
4016
4017   tmp0 = gen_reg_rtx (SImode);
4018   tmp1 = gen_reg_rtx (SImode);
4019   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4020   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
4021   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
4022   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4023   emit_move_insn (operands[0], dst);
4024   DONE;
4025 }")
4026
4027 (define_insn "ashldi3_media"
4028   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4029         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4030                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
4031   "TARGET_SHMEDIA"
4032   "@
4033         shlld   %1, %2, %0
4034         shlli   %1, %2, %0"
4035   [(set_attr "type" "arith_media")])
4036
4037 (define_insn "*ashldisi3_media"
4038   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4039         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4040                    (match_operand:DI 2 "const_int_operand" "n")))]
4041   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4042   "shlli.l      %1, %2, %0"
4043   [(set_attr "type" "arith_media")
4044    (set_attr "highpart" "ignore")])
4045
4046 (define_expand "ashldi3"
4047   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4048                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4049                               (match_operand:DI 2 "immediate_operand" "")))
4050               (clobber (reg:SI T_REG))])]
4051   ""
4052   "
4053 {
4054   if (TARGET_SHMEDIA)
4055     {
4056       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4057       DONE;
4058     }
4059   if (CONST_INT_P (operands[2])
4060       && INTVAL (operands[2]) == 1)
4061     {
4062       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4063       DONE;
4064     }
4065   else if (CONST_INT_P (operands[2])
4066       && INTVAL (operands[2]) < 32)
4067     {
4068       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4069       DONE;
4070     }
4071   else
4072     FAIL;
4073 }")
4074
4075 ;; ??? This should be a define expand.
4076
4077 (define_insn "lshrdi3_k"
4078   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4079         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4080                      (const_int 1)))
4081    (clobber (reg:SI T_REG))]
4082   "TARGET_SH1"
4083   "shlr %S0\;rotcr      %R0"
4084   [(set_attr "length" "4")
4085    (set_attr "type" "arith")])
4086
4087 (define_insn "lshrdi3_media"
4088   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4089         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4090                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4091   "TARGET_SHMEDIA
4092    && (arith_reg_dest (operands[0], DImode)
4093        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4094   "@
4095         shlrd   %1, %2, %0
4096         shlri   %1, %2, %0"
4097   [(set_attr "type" "arith_media")])
4098
4099 (define_insn "*lshrdisi3_media"
4100   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4101         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4102                      (match_operand:DI 2 "const_int_operand" "n")))]
4103   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4104   "shlri.l      %1, %2, %0"
4105   [(set_attr "type" "arith_media")
4106    (set_attr "highpart" "ignore")])
4107
4108 (define_expand "lshrdi3"
4109   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4110                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4111                                (match_operand:DI 2 "immediate_operand" "")))
4112              (clobber (reg:SI T_REG))])]
4113   ""
4114   "
4115 {
4116   if (TARGET_SHMEDIA)
4117     {
4118       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4119       DONE;
4120     }
4121   if (!CONST_INT_P (operands[2])
4122       || INTVAL (operands[2]) != 1)
4123     FAIL;
4124 }")
4125
4126 ;; ??? This should be a define expand.
4127
4128 (define_insn "ashrdi3_k"
4129   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4130         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4131                      (const_int 1)))
4132    (clobber (reg:SI T_REG))]
4133   "TARGET_SH1"
4134   "shar %S0\;rotcr      %R0"
4135   [(set_attr "length" "4")
4136    (set_attr "type" "arith")])
4137
4138 (define_insn "ashrdi3_media"
4139   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4140         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4141                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4142   "TARGET_SHMEDIA
4143    && (arith_reg_dest (operands[0], DImode)
4144        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4145   "@
4146         shard   %1, %2, %0
4147         shari   %1, %2, %0"
4148   [(set_attr "type" "arith_media")])
4149
4150 (define_insn "*ashrdisi3_media"
4151   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4152         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4153                      (match_operand:DI 2 "const_int_operand" "n")))]
4154   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4155   "shari.l      %1, %2, %0"
4156   [(set_attr "type" "arith_media")
4157    (set_attr "highpart" "ignore")])
4158
4159 (define_insn "ashrdisi3_media_high"
4160   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4161         (truncate:SI
4162            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4163                         (match_operand:DI 2 "const_int_operand" "n"))))]
4164   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4165   "shari        %1, %2, %0"
4166   [(set_attr "type" "arith_media")])
4167
4168 (define_insn "ashrdisi3_media_opaque"
4169   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4170         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4171                     (match_operand:DI 2 "const_int_operand" "n")]
4172          UNSPEC_ASHIFTRT))]
4173   "TARGET_SHMEDIA"
4174   "shari        %1, %2, %0"
4175   [(set_attr "type" "arith_media")])
4176
4177 (define_expand "ashrdi3"
4178   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4179                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4180                                 (match_operand:DI 2 "immediate_operand" "")))
4181               (clobber (reg:SI T_REG))])]
4182   ""
4183   "
4184 {
4185   if (TARGET_SHMEDIA)
4186     {
4187       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4188       DONE;
4189     }
4190   if (!CONST_INT_P (operands[2])
4191       || INTVAL (operands[2]) != 1)
4192     FAIL;
4193 }")
4194
4195 ;; combined left/right shift
4196
4197 (define_split
4198   [(set (match_operand:SI 0 "register_operand" "")
4199         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4200                            (match_operand:SI 2 "const_int_operand" ""))
4201                 (match_operand:SI 3 "const_int_operand" "")))]
4202   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4203   [(use (reg:SI R0_REG))]
4204   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4205    DONE;")
4206
4207 (define_split
4208   [(set (match_operand:SI 0 "register_operand" "")
4209         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4210                            (match_operand:SI 2 "const_int_operand" ""))
4211                 (match_operand:SI 3 "const_int_operand" "")))
4212    (clobber (reg:SI T_REG))]
4213   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4214   [(use (reg:SI R0_REG))]
4215   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4216    DONE;")
4217
4218 (define_insn ""
4219   [(set (match_operand:SI 0 "register_operand" "=r")
4220         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4221                            (match_operand:SI 2 "const_int_operand" "n"))
4222                 (match_operand:SI 3 "const_int_operand" "n")))
4223    (clobber (reg:SI T_REG))]
4224   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4225  "#"
4226   [(set (attr "length")
4227         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4228                (const_string "4")
4229                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4230                (const_string "6")
4231                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4232                (const_string "8")
4233                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4234                (const_string "10")
4235                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4236                (const_string "12")
4237                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4238                (const_string "14")
4239                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4240                (const_string "16")]
4241               (const_string "18")))
4242    (set_attr "type" "arith")])
4243
4244 (define_insn ""
4245   [(set (match_operand:SI 0 "register_operand" "=z")
4246         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4247                            (match_operand:SI 2 "const_int_operand" "n"))
4248                 (match_operand:SI 3 "const_int_operand" "n")))
4249    (clobber (reg:SI T_REG))]
4250   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4251  "#"
4252   [(set (attr "length")
4253         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4254                (const_string "4")
4255                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4256                (const_string "6")
4257                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4258                (const_string "8")]
4259               (const_string "10")))
4260    (set_attr "type" "arith")])
4261
4262 ;; shift left / and combination with a scratch register: The combine pass
4263 ;; does not accept the individual instructions, even though they are
4264 ;; cheap.  But it needs a precise description so that it is usable after
4265 ;; reload.
4266 (define_insn "and_shl_scratch"
4267   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4268         (lshiftrt:SI
4269          (ashift:SI
4270           (and:SI
4271            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4272                         (match_operand:SI 2 "const_int_operand" "N,n"))
4273            (match_operand:SI 3 "" "0,r"))
4274           (match_operand:SI 4 "const_int_operand" "n,n"))
4275          (match_operand:SI 5 "const_int_operand" "n,n")))
4276    (clobber (reg:SI T_REG))]
4277   "TARGET_SH1"
4278   "#"
4279   [(set (attr "length")
4280         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4281                (const_string "4")
4282                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4283                (const_string "6")
4284                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4285                (const_string "8")
4286                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4287                (const_string "10")]
4288               (const_string "12")))
4289    (set_attr "type" "arith")])
4290
4291 (define_split
4292   [(set (match_operand:SI 0 "register_operand" "")
4293         (lshiftrt:SI
4294          (ashift:SI
4295           (and:SI
4296            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4297                         (match_operand:SI 2 "const_int_operand" ""))
4298            (match_operand:SI 3 "register_operand" ""))
4299           (match_operand:SI 4 "const_int_operand" ""))
4300          (match_operand:SI 5 "const_int_operand" "")))
4301    (clobber (reg:SI T_REG))]
4302   "TARGET_SH1"
4303   [(use (reg:SI R0_REG))]
4304   "
4305 {
4306   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4307
4308   if (INTVAL (operands[2]))
4309     {
4310       gen_shifty_op (LSHIFTRT, operands);
4311     }
4312   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4313   operands[2] = operands[4];
4314   gen_shifty_op (ASHIFT, operands);
4315   if (INTVAL (operands[5]))
4316     {
4317       operands[2] = operands[5];
4318       gen_shifty_op (LSHIFTRT, operands);
4319     }
4320   DONE;
4321 }")
4322
4323 ;; signed left/right shift combination.
4324 (define_split
4325   [(set (match_operand:SI 0 "register_operand" "")
4326         (sign_extract:SI
4327          (ashift:SI (match_operand:SI 1 "register_operand" "")
4328                     (match_operand:SI 2 "const_int_operand" ""))
4329          (match_operand:SI 3 "const_int_operand" "")
4330          (const_int 0)))
4331    (clobber (reg:SI T_REG))]
4332   "TARGET_SH1"
4333   [(use (reg:SI R0_REG))]
4334   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4335    DONE;")
4336
4337 (define_insn "shl_sext_ext"
4338   [(set (match_operand:SI 0 "register_operand" "=r")
4339         (sign_extract:SI
4340          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4341                     (match_operand:SI 2 "const_int_operand" "n"))
4342          (match_operand:SI 3 "const_int_operand" "n")
4343          (const_int 0)))
4344    (clobber (reg:SI T_REG))]
4345   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4346   "#"
4347   [(set (attr "length")
4348         (cond [(match_test "shl_sext_length (insn)")
4349                (const_string "2")
4350                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4351                (const_string "4")
4352                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4353                (const_string "6")
4354                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4355                (const_string "8")
4356                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4357                (const_string "10")
4358                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4359                (const_string "12")
4360                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4361                (const_string "14")
4362                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4363                (const_string "16")]
4364               (const_string "18")))
4365     (set_attr "type" "arith")])
4366
4367 (define_insn "shl_sext_sub"
4368   [(set (match_operand:SI 0 "register_operand" "=z")
4369         (sign_extract:SI
4370          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4371                     (match_operand:SI 2 "const_int_operand" "n"))
4372          (match_operand:SI 3 "const_int_operand" "n")
4373          (const_int 0)))
4374    (clobber (reg:SI T_REG))]
4375   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4376   "#"
4377   [(set (attr "length")
4378         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4379                (const_string "6")
4380                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4381                (const_string "8")
4382                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4383                (const_string "10")
4384                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4385                (const_string "12")]
4386               (const_string "14")))
4387     (set_attr "type" "arith")])
4388
4389 ;; These patterns are found in expansions of DImode shifts by 16, and
4390 ;; allow the xtrct instruction to be generated from C source.
4391
4392 (define_insn "xtrct_left"
4393   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4394         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4395                            (const_int 16))
4396                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4397                              (const_int 16))))]
4398   "TARGET_SH1"
4399   "xtrct        %1,%0"
4400   [(set_attr "type" "arith")])
4401
4402 (define_insn "xtrct_right"
4403   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4404         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4405                              (const_int 16))
4406                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4407                            (const_int 16))))]
4408   "TARGET_SH1"
4409   "xtrct        %2,%0"
4410   [(set_attr "type" "arith")])
4411
4412 ;; -------------------------------------------------------------------------
4413 ;; Unary arithmetic
4414 ;; -------------------------------------------------------------------------
4415
4416 (define_insn "negc"
4417   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4418         (neg:SI (plus:SI (reg:SI T_REG)
4419                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4420    (set (reg:SI T_REG)
4421         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4422                (const_int 0)))]
4423   "TARGET_SH1"
4424   "negc %1,%0"
4425   [(set_attr "type" "arith")])
4426
4427 (define_insn "*negdi_media"
4428   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4429         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4430   "TARGET_SHMEDIA"
4431   "sub  r63, %1, %0"
4432   [(set_attr "type" "arith_media")])
4433
4434
4435
4436 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4437 ;; combined.
4438 (define_expand "negdi2"
4439   [(set (match_operand:DI 0 "arith_reg_dest" "")
4440         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4441    (clobber (reg:SI T_REG))]
4442   ""
4443   "")
4444
4445 (define_insn_and_split "*negdi2"
4446   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4447         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4448   "TARGET_SH1"
4449   "#"
4450   "TARGET_SH1"
4451   [(const_int 0)]
4452   "
4453 {
4454   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4455   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4456
4457   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4458   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4459
4460   rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4461   rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4462
4463   emit_insn (gen_clrt ());
4464   emit_insn (gen_negc (low_dst, low_src));
4465   emit_insn (gen_negc (high_dst, high_src));
4466   DONE;
4467 }")
4468
4469 (define_insn "negsi2"
4470   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4471         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4472   "TARGET_SH1"
4473   "neg  %1,%0"
4474   [(set_attr "type" "arith")])
4475
4476 (define_insn "one_cmplsi2"
4477   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4478         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4479   "TARGET_SH1"
4480   "not  %1,%0"
4481   [(set_attr "type" "arith")])
4482
4483 (define_expand "one_cmpldi2"
4484   [(set (match_operand:DI 0 "arith_reg_dest" "")
4485         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4486                 (const_int -1)))]
4487   "TARGET_SHMEDIA" "")
4488
4489 (define_expand "abssi2"
4490   [(set (match_operand:SI 0 "arith_reg_dest" "")
4491         (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4492    (clobber (reg:SI T_REG))]
4493   ""
4494   "")
4495
4496 (define_insn_and_split "*abssi2"
4497   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4498         (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4499   "TARGET_SH1"
4500   "#"
4501   "TARGET_SH1"
4502   [(const_int 0)]
4503   "
4504 {
4505   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4506   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4507                  const1_rtx));
4508   DONE;
4509 }")
4510
4511 (define_insn_and_split "*negabssi2"
4512   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4513         (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4514   "TARGET_SH1"
4515   "#"
4516   "TARGET_SH1"
4517   [(const_int 0)]
4518   "
4519 {
4520   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4521   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4522                  const0_rtx));
4523   DONE;
4524 }")
4525
4526
4527 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4528 ;; This can be used as some kind of conditional execution, which is useful
4529 ;; for abs.
4530 ;; Actually the instruction scheduling should decide whether to use a
4531 ;; zero-offset branch or not for any generic case involving a single
4532 ;; instruction on SH4 202.
4533
4534 (define_insn_and_split "negsi_cond"
4535   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4536         (if_then_else:SI (eq:SI (reg:SI T_REG)
4537                           (match_operand:SI 3 "const_int_operand" "M,N"))
4538          (match_operand:SI 1 "arith_reg_operand" "0,0")
4539          (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4540   "TARGET_HARD_SH4"
4541   "@
4542         bt\\t0f\;neg\\t%2,%0\\n0:
4543         bf\\t0f\;neg\\t%2,%0\\n0:"
4544   "!TARGET_HARD_SH4"
4545   [(const_int 0)]
4546   "
4547 {
4548   rtx skip_neg_label = gen_label_rtx ();
4549
4550   emit_insn (gen_movsi (operands[0], operands[1]));
4551
4552   emit_jump_insn (INTVAL (operands[3])
4553                   ? gen_branch_true (skip_neg_label)
4554                   : gen_branch_false (skip_neg_label));
4555
4556   emit_label_after (skip_neg_label,
4557                     emit_insn (gen_negsi2 (operands[0], operands[1])));
4558   DONE;
4559 }"
4560   [(set_attr "type" "arith") ;; poor approximation
4561    (set_attr "length" "4")])
4562
4563 \f
4564 ;; -------------------------------------------------------------------------
4565 ;; Zero extension instructions
4566 ;; -------------------------------------------------------------------------
4567
4568 (define_insn "zero_extendsidi2"
4569   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4570         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4571   "TARGET_SHMEDIA"
4572   "addz.l       %1, r63, %0"
4573   [(set_attr "type" "arith_media")
4574    (set_attr "highpart" "extend")])
4575
4576 (define_insn "zero_extendhidi2"
4577   [(set (match_operand:DI 0 "register_operand" "=r,r")
4578         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4579   "TARGET_SHMEDIA"
4580   "@
4581         #
4582         ld%M1.uw        %m1, %0"
4583   [(set_attr "type" "*,load_media")
4584    (set (attr "highpart")
4585         (cond [(match_test "sh_contains_memref_p (insn)")
4586                (const_string "user")]
4587               (const_string "ignore")))])
4588
4589 (define_split
4590   [(set (match_operand:DI 0 "register_operand" "")
4591         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4592   "TARGET_SHMEDIA && reload_completed"
4593   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4594    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4595   "
4596 {
4597   if (GET_CODE (operands[1]) == TRUNCATE)
4598     operands[1] = XEXP (operands[1], 0);
4599 }")
4600
4601 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4602 ;; reload the entire truncate expression.
4603 (define_insn_and_split "*loaddi_trunc"
4604   [(set (match_operand 0 "any_register_operand" "=r")
4605         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4606   "TARGET_SHMEDIA && reload_completed"
4607   "#"
4608   "TARGET_SHMEDIA && reload_completed"
4609   [(set (match_dup 0) (match_dup 1))]
4610   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4611
4612 (define_insn "zero_extendqidi2"
4613   [(set (match_operand:DI 0 "register_operand" "=r,r")
4614         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4615   "TARGET_SHMEDIA"
4616   "@
4617         andi    %1, 255, %0
4618         ld%M1.ub        %m1, %0"
4619   [(set_attr "type" "arith_media,load_media")
4620    (set (attr "highpart")
4621         (cond [(match_test "sh_contains_memref_p (insn)")
4622                (const_string "user")]
4623               (const_string "ignore")))])
4624
4625 (define_expand "zero_extendhisi2"
4626   [(set (match_operand:SI 0 "arith_reg_operand" "")
4627         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4628   ""
4629   "
4630 {
4631   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4632     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4633 }")
4634
4635 (define_insn "*zero_extendhisi2_compact"
4636   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4637         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4638   "TARGET_SH1"
4639   "extu.w       %1,%0"
4640   [(set_attr "type" "arith")])
4641
4642 (define_insn "*zero_extendhisi2_media"
4643   [(set (match_operand:SI 0 "register_operand" "=r,r")
4644         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4645   "TARGET_SHMEDIA"
4646   "@
4647         #
4648         ld%M1.uw        %m1, %0"
4649   [(set_attr "type" "arith_media,load_media")
4650    (set (attr "highpart")
4651         (cond [(match_test "sh_contains_memref_p (insn)")
4652                (const_string "user")]
4653               (const_string "ignore")))])
4654
4655 (define_split
4656   [(set (match_operand:SI 0 "register_operand" "")
4657         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4658   "TARGET_SHMEDIA && reload_completed"
4659   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4660    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4661   "
4662 {
4663   rtx op1 = operands[1];
4664
4665   if (GET_CODE (op1) == TRUNCATE)
4666     op1 = XEXP (op1, 0);
4667   operands[2]
4668     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4669                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4670 }")
4671
4672 (define_expand "zero_extendqisi2"
4673   [(set (match_operand:SI 0 "arith_reg_operand" "")
4674         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4675   ""
4676   "
4677 {
4678   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4679     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4680 }")
4681
4682 (define_insn "*zero_extendqisi2_compact"
4683   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4684         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4685   "TARGET_SH1"
4686   "extu.b       %1,%0"
4687   [(set_attr "type" "arith")])
4688
4689 (define_insn "*zero_extendqisi2_media"
4690   [(set (match_operand:SI 0 "register_operand" "=r,r")
4691         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4692   "TARGET_SHMEDIA"
4693   "@
4694         andi    %1, 255, %0
4695         ld%M1.ub        %m1, %0"
4696   [(set_attr "type" "arith_media,load_media")
4697    (set (attr "highpart")
4698         (cond [(match_test "sh_contains_memref_p (insn)")
4699                (const_string "user")]
4700               (const_string "ignore")))])
4701
4702 (define_insn "zero_extendqihi2"
4703   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4704         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4705   "TARGET_SH1"
4706   "extu.b       %1,%0"
4707   [(set_attr "type" "arith")])
4708
4709 ;; -------------------------------------------------------------------------
4710 ;; Sign extension instructions
4711 ;; -------------------------------------------------------------------------
4712
4713 ;; ??? This should be a define expand.
4714 ;; ??? Or perhaps it should be dropped?
4715
4716 ;; convert_move generates good code for SH[1-4].
4717 (define_insn "extendsidi2"
4718   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4719         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4720   "TARGET_SHMEDIA"
4721   "@
4722         add.l   %1, r63, %0
4723         ld%M1.l %m1, %0
4724         fmov.sl %1, %0"
4725   [(set_attr "type" "arith_media,load_media,fpconv_media")
4726    (set (attr "highpart")
4727         (cond [(match_test "sh_contains_memref_p (insn)")
4728                (const_string "user")]
4729               (const_string "extend")))])
4730
4731 (define_insn "extendhidi2"
4732   [(set (match_operand:DI 0 "register_operand" "=r,r")
4733         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4734   "TARGET_SHMEDIA"
4735   "@
4736         #
4737         ld%M1.w %m1, %0"
4738   [(set_attr "type" "*,load_media")
4739    (set (attr "highpart")
4740         (cond [(match_test "sh_contains_memref_p (insn)")
4741                (const_string "user")]
4742               (const_string "ignore")))])
4743
4744 (define_split
4745   [(set (match_operand:DI 0 "register_operand" "")
4746         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4747   "TARGET_SHMEDIA && reload_completed"
4748   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4749    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4750   "
4751 {
4752   if (GET_CODE (operands[1]) == TRUNCATE)
4753     operands[1] = XEXP (operands[1], 0);
4754 }")
4755
4756 (define_insn "extendqidi2"
4757   [(set (match_operand:DI 0 "register_operand" "=r,r")
4758         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4759   "TARGET_SHMEDIA"
4760   "@
4761         #
4762         ld%M1.b %m1, %0"
4763   [(set_attr "type" "*,load_media")
4764    (set (attr "highpart")
4765         (cond [(match_test "sh_contains_memref_p (insn)")
4766                (const_string "user")]
4767               (const_string "ignore")))])
4768
4769 (define_split
4770   [(set (match_operand:DI 0 "register_operand" "")
4771         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4772   "TARGET_SHMEDIA && reload_completed"
4773   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4774    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4775   "
4776 {
4777   if (GET_CODE (operands[1]) == TRUNCATE)
4778     operands[1] = XEXP (operands[1], 0);
4779 }")
4780
4781 (define_expand "extendhisi2"
4782   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4783         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4784   ""
4785   "")
4786
4787 (define_insn "*extendhisi2_compact"
4788   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4789         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4790   "TARGET_SH1"
4791   "@
4792         exts.w  %1,%0
4793         mov.w   %1,%0"
4794   [(set_attr "type" "arith,load")])
4795
4796 (define_insn "*extendhisi2_media"
4797   [(set (match_operand:SI 0 "register_operand" "=r,r")
4798         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4799   "TARGET_SHMEDIA"
4800   "@
4801         #
4802         ld%M1.w %m1, %0"
4803   [(set_attr "type" "arith_media,load_media")
4804    (set (attr "highpart")
4805         (cond [(match_test "sh_contains_memref_p (insn)")
4806                (const_string "user")]
4807               (const_string "ignore")))])
4808
4809 (define_split
4810   [(set (match_operand:SI 0 "register_operand" "")
4811         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4812   "TARGET_SHMEDIA && reload_completed"
4813   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4814    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4815   "
4816 {
4817   rtx op1 = operands[1];
4818   if (GET_CODE (op1) == TRUNCATE)
4819     op1 = XEXP (op1, 0);
4820   operands[2]
4821     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4822                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4823 }")
4824
4825 (define_expand "extendqisi2"
4826   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4827         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4828   ""
4829   "")
4830
4831 (define_insn "*extendqisi2_compact"
4832   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4833         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4834   "TARGET_SH1"
4835   "@
4836         exts.b  %1,%0
4837         mov.b   %1,%0"
4838   [(set_attr "type" "arith,load")
4839    (set_attr_alternative "length"
4840      [(const_int 2)
4841        (if_then_else
4842         (match_test "TARGET_SH2A")
4843         (const_int 4) (const_int 2))])])
4844
4845 (define_insn "*extendqisi2_media"
4846   [(set (match_operand:SI 0 "register_operand" "=r,r")
4847         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4848   "TARGET_SHMEDIA"
4849   "@
4850         #
4851         ld%M1.b %m1, %0"
4852   [(set_attr "type" "arith_media,load_media")
4853    (set (attr "highpart")
4854         (cond [(match_test "sh_contains_memref_p (insn)")
4855                (const_string "user")]
4856               (const_string "ignore")))])
4857
4858 (define_split
4859   [(set (match_operand:SI 0 "register_operand" "")
4860         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4861   "TARGET_SHMEDIA && reload_completed"
4862   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4863    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4864    "
4865 {
4866   rtx op1 = operands[1];
4867   if (GET_CODE (op1) == TRUNCATE)
4868     op1 = XEXP (op1, 0);
4869   operands[2]
4870     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4871                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4872 }")
4873
4874 (define_insn "extendqihi2"
4875   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4876         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4877   "TARGET_SH1"
4878   "@
4879         exts.b  %1,%0
4880         mov.b   %1,%0"
4881   [(set_attr "type" "arith,load")
4882    (set_attr_alternative "length"
4883      [(const_int 2)
4884        (if_then_else
4885         (match_test "TARGET_SH2A")
4886         (const_int 4) (const_int 2))])])
4887
4888 /* It would seem useful to combine the truncXi patterns into the movXi
4889    patterns, but unary operators are ignored when matching constraints,
4890    so we need separate patterns.  */
4891 (define_insn "truncdisi2"
4892   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4893         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4894   "TARGET_SHMEDIA"
4895   "@
4896         add.l   %1, r63, %0
4897         st%M0.l %m0, %1
4898         fst%M0.s        %m0, %T1
4899         fmov.ls %1, %0
4900         fmov.sl %T1, %0
4901         fmov.s  %T1, %0"
4902   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4903    (set (attr "highpart")
4904         (cond [(match_test "sh_contains_memref_p (insn)")
4905                (const_string "user")]
4906               (const_string "extend")))])
4907
4908 (define_insn "truncdihi2"
4909   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4910         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4911   "TARGET_SHMEDIA"
4912   "@
4913         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4914         st%M0.w %m0, %1"
4915   [(set_attr "type"   "arith_media,store_media")
4916    (set_attr "length" "8,4")
4917    (set (attr "highpart")
4918         (cond [(match_test "sh_contains_memref_p (insn)")
4919                (const_string "user")]
4920               (const_string "extend")))])
4921
4922 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4923 ; Because we use zero extension, we can't provide signed QImode compares
4924 ; using a simple compare or conditional branch insn.
4925 (define_insn "truncdiqi2"
4926   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4927         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4928   "TARGET_SHMEDIA"
4929   "@
4930         andi    %1, 255, %0
4931         st%M0.b %m0, %1"
4932   [(set_attr "type"   "arith_media,store")
4933    (set (attr "highpart")
4934         (cond [(match_test "sh_contains_memref_p (insn)")
4935                (const_string "user")]
4936               (const_string "extend")))])
4937 ;; -------------------------------------------------------------------------
4938 ;; Move instructions
4939 ;; -------------------------------------------------------------------------
4940
4941 ;; define push and pop so it is easy for sh.c
4942 ;; We can't use push and pop on SHcompact because the stack must always
4943 ;; be 8-byte aligned.
4944
4945 (define_expand "push"
4946   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4947         (match_operand:SI 0 "register_operand" "r,l,x"))]
4948   "TARGET_SH1 && ! TARGET_SH5"
4949   "")
4950
4951 (define_expand "pop"
4952   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4953         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4954   "TARGET_SH1 && ! TARGET_SH5"
4955   "")
4956
4957 (define_expand "push_e"
4958   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4959                    (match_operand:SF 0 "" ""))
4960               (use (reg:PSI FPSCR_REG))
4961               (clobber (scratch:SI))])]
4962   "TARGET_SH1 && ! TARGET_SH5"
4963   "")
4964
4965 (define_insn "push_fpul"
4966   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4967   "TARGET_SH2E && ! TARGET_SH5"
4968   "sts.l        fpul,@-r15"
4969   [(set_attr "type" "fstore")
4970    (set_attr "late_fp_use" "yes")
4971    (set_attr "hit_stack" "yes")])
4972
4973 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4974 ;; so use that.
4975 (define_expand "push_4"
4976   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4977                    (match_operand:DF 0 "" ""))
4978               (use (reg:PSI FPSCR_REG))
4979               (clobber (scratch:SI))])]
4980   "TARGET_SH1 && ! TARGET_SH5"
4981   "")
4982
4983 (define_expand "pop_e"
4984   [(parallel [(set (match_operand:SF 0 "" "")
4985               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4986               (use (reg:PSI FPSCR_REG))
4987               (clobber (scratch:SI))])]
4988   "TARGET_SH1 && ! TARGET_SH5"
4989   "")
4990
4991 (define_insn "pop_fpul"
4992   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4993   "TARGET_SH2E && ! TARGET_SH5"
4994   "lds.l        @r15+,fpul"
4995   [(set_attr "type" "load")
4996    (set_attr "hit_stack" "yes")])
4997
4998 (define_expand "pop_4"
4999   [(parallel [(set (match_operand:DF 0 "" "")
5000                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
5001               (use (reg:PSI FPSCR_REG))
5002               (clobber (scratch:SI))])]
5003   "TARGET_SH1 && ! TARGET_SH5"
5004   "")
5005
5006 (define_expand "push_fpscr"
5007   [(const_int 0)]
5008   "TARGET_SH2E"
5009   "
5010 {
5011   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
5012                                                  gen_rtx_PRE_DEC (Pmode,
5013                                                           stack_pointer_rtx)),
5014                                         get_fpscr_rtx ()));
5015   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5016   DONE;
5017 }")
5018
5019 (define_expand "pop_fpscr"
5020   [(const_int 0)]
5021   "TARGET_SH2E"
5022   "
5023 {
5024   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
5025                                         gen_frame_mem (PSImode,
5026                                                  gen_rtx_POST_INC (Pmode,
5027                                                           stack_pointer_rtx))));
5028   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5029   DONE;
5030 }")
5031
5032 ;; These two patterns can happen as the result of optimization, when
5033 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5034 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5035
5036 (define_insn "clrt"
5037   [(set (reg:SI T_REG) (const_int 0))]
5038   "TARGET_SH1"
5039   "clrt")
5040
5041 (define_insn "sett"
5042   [(set (reg:SI T_REG) (const_int 1))]
5043   "TARGET_SH1"
5044   "sett")
5045
5046 ;; Define additional pop for SH1 and SH2 so it does not get 
5047 ;; placed in the delay slot.
5048 (define_insn "*movsi_pop"
5049   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5050         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5051   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5052    && ! TARGET_SH3"
5053   "@
5054    mov.l   %1,%0
5055    lds.l   %1,%0
5056    lds.l   %1,%0"
5057   [(set_attr "type" "load_si,mem_mac,pload")
5058    (set_attr "length" "2,2,2")
5059    (set_attr "in_delay_slot" "no,no,no")])
5060
5061 ;; t/r must come after r/r, lest reload will try to reload stuff like
5062 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5063 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5064 (define_insn "movsi_i"
5065   [(set (match_operand:SI 0 "general_movdst_operand"
5066             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5067         (match_operand:SI 1 "general_movsrc_operand"
5068          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5069   "TARGET_SH1
5070    && ! TARGET_SH2E
5071    && ! TARGET_SH2A
5072    && (register_operand (operands[0], SImode)
5073        || register_operand (operands[1], SImode))"
5074   "@
5075         mov.l   %1,%0
5076         mov     %1,%0
5077         mov     %1,%0
5078         cmp/pl  %1
5079         mov.l   %1,%0
5080         sts     %1,%0
5081         sts     %1,%0
5082         movt    %0
5083         mov.l   %1,%0
5084         sts.l   %1,%0
5085         sts.l   %1,%0
5086         lds     %1,%0
5087         lds     %1,%0
5088         lds.l   %1,%0
5089         lds.l   %1,%0
5090         fake    %1,%0"
5091   [(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")
5092    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5093
5094 ;; t/r must come after r/r, lest reload will try to reload stuff like
5095 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5096 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5097 ;; will require a reload.
5098 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5099 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5100 (define_insn "movsi_ie"
5101   [(set (match_operand:SI 0 "general_movdst_operand"
5102             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5103         (match_operand:SI 1 "general_movsrc_operand"
5104          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5105   "(TARGET_SH2E || TARGET_SH2A)
5106    && (register_operand (operands[0], SImode)
5107        || register_operand (operands[1], SImode))"
5108   "@
5109         mov.l   %1,%0
5110         mov     %1,%0
5111         mov     %1,%0
5112         movi20  %1,%0
5113         movi20s %1,%0
5114         cmp/pl  %1
5115         mov.l   %1,%0
5116         sts     %1,%0
5117         sts     %1,%0
5118         movt    %0
5119         mov.l   %1,%0
5120         sts.l   %1,%0
5121         sts.l   %1,%0
5122         lds     %1,%0
5123         lds     %1,%0
5124         lds.l   %1,%0
5125         lds.l   %1,%0
5126         lds.l   %1,%0
5127         sts.l   %1,%0
5128         fake    %1,%0
5129         lds     %1,%0
5130         sts     %1,%0
5131         fsts    fpul,%0
5132         flds    %1,fpul
5133         fmov    %1,%0
5134         ! move optimized away"
5135   [(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")
5136    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5137    (set_attr_alternative "length"
5138      [(const_int 2)
5139       (const_int 2)
5140       (const_int 2)
5141       (const_int 4)
5142       (const_int 4)
5143       (const_int 2)
5144       (if_then_else
5145         (match_test "TARGET_SH2A")
5146         (const_int 4) (const_int 2))
5147       (const_int 2)
5148       (const_int 2)
5149       (const_int 2)
5150       (if_then_else
5151         (match_test "TARGET_SH2A")
5152         (const_int 4) (const_int 2))
5153       (const_int 2)
5154       (const_int 2)
5155       (const_int 2)
5156       (const_int 2)
5157       (const_int 2)
5158       (const_int 2)
5159       (const_int 2)
5160       (const_int 2)
5161       (const_int 2)
5162       (const_int 2)
5163       (const_int 2)
5164       (const_int 2)
5165       (const_int 2)
5166       (const_int 2)
5167       (const_int 0)])])
5168
5169 (define_insn "movsi_i_lowpart"
5170   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5171         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5172    "TARGET_SH1
5173     && (register_operand (operands[0], SImode)
5174         || register_operand (operands[1], SImode))"
5175   "@
5176         mov.l   %1,%0
5177         mov     %1,%0
5178         mov     %1,%0
5179         mov.l   %1,%0
5180         sts     %1,%0
5181         sts     %1,%0
5182         movt    %0
5183         mov.l   %1,%0
5184         fake    %1,%0"
5185   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5186
5187 (define_insn_and_split "load_ra"
5188   [(set (match_operand:SI 0 "general_movdst_operand" "")
5189         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5190   "TARGET_SH1"
5191   "#"
5192   "&& ! currently_expanding_to_rtl"
5193   [(set (match_dup 0) (match_dup 1))]
5194   "
5195 {
5196   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5197     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5198 }")
5199
5200 ;; The '?'s in the following constraints may not reflect the time taken
5201 ;; to perform the move. They are there to discourage the use of floating-
5202 ;; point registers for storing integer values.
5203 (define_insn "*movsi_media"
5204   [(set (match_operand:SI 0 "general_movdst_operand"
5205                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5206         (match_operand:SI 1 "general_movsrc_operand"
5207          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5208   "TARGET_SHMEDIA_FPU
5209    && (register_operand (operands[0], SImode)
5210        || sh_register_operand (operands[1], SImode)
5211        || GET_CODE (operands[1]) == TRUNCATE)"
5212   "@
5213         add.l   %1, r63, %0
5214         movi    %1, %0
5215         #
5216         ld%M1.l %m1, %0
5217         st%M0.l %m0, %N1
5218         fld%M1.s        %m1, %0
5219         fst%M0.s        %m0, %1
5220         fmov.ls %N1, %0
5221         fmov.sl %1, %0
5222         fmov.s  %1, %0
5223         ptabs   %1, %0
5224         gettr   %1, %0
5225         pt      %1, %0"
5226   [(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")
5227    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5228    (set (attr "highpart")
5229         (cond [(match_test "sh_contains_memref_p (insn)")
5230                (const_string "user")]
5231               (const_string "ignore")))])
5232
5233 (define_insn "*movsi_media_nofpu"
5234   [(set (match_operand:SI 0 "general_movdst_operand"
5235                 "=r,r,r,r,m,*b,r,*b")
5236         (match_operand:SI 1 "general_movsrc_operand"
5237          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5238   "TARGET_SHMEDIA
5239    && (register_operand (operands[0], SImode)
5240        || sh_register_operand (operands[1], SImode)
5241        || GET_CODE (operands[1]) == TRUNCATE)"
5242   "@
5243         add.l   %1, r63, %0
5244         movi    %1, %0
5245         #
5246         ld%M1.l %m1, %0
5247         st%M0.l %m0, %N1
5248         ptabs   %1, %0
5249         gettr   %1, %0
5250         pt      %1, %0"
5251   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5252    (set_attr "length" "4,4,8,4,4,4,4,12")
5253    (set (attr "highpart")
5254         (cond [(match_test "sh_contains_memref_p (insn)")
5255                (const_string "user")]
5256               (const_string "ignore")))])
5257
5258 (define_expand "movsi_const"
5259   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5260         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5261                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5262    (set (match_dup 0)
5263         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5264                 (const:SI (unspec:SI [(match_dup 1)
5265                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5266   "TARGET_SHMEDIA && reload_completed
5267    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5268   "
5269 {
5270   if (GET_CODE (operands[1]) == LABEL_REF
5271       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5272     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5273   else if (GOTOFF_P (operands[1]))
5274     {
5275       rtx unspec = XEXP (operands[1], 0);
5276
5277       if (! UNSPEC_GOTOFF_P (unspec))
5278         {
5279           unspec = XEXP (unspec, 0);
5280           if (! UNSPEC_GOTOFF_P (unspec))
5281             abort ();
5282         }
5283       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5284           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5285         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5286     }
5287 }")
5288
5289 (define_expand "movsi_const_16bit"
5290   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5291         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5292                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5293   "TARGET_SHMEDIA && flag_pic && reload_completed
5294    && GET_CODE (operands[1]) == SYMBOL_REF"
5295   "")
5296
5297 (define_split
5298   [(set (match_operand:SI 0 "arith_reg_dest" "")
5299         (match_operand:SI 1 "immediate_operand" ""))]
5300   "TARGET_SHMEDIA && reload_completed
5301    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5302   [(const_int 0)]
5303   "
5304 {
5305   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5306
5307   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5308
5309   DONE;
5310 }")
5311
5312 (define_split
5313   [(set (match_operand:SI 0 "register_operand" "")
5314         (match_operand:SI 1 "immediate_operand" ""))]
5315   "TARGET_SHMEDIA && reload_completed
5316    && ((CONST_INT_P (operands[1])
5317         && ! satisfies_constraint_I16 (operands[1]))
5318        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5319   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5320
5321 (define_expand "movsi"
5322   [(set (match_operand:SI 0 "general_movdst_operand" "")
5323         (match_operand:SI 1 "general_movsrc_operand" ""))]
5324   ""
5325   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5326
5327 (define_expand "ic_invalidate_line"
5328   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5329                                 (match_dup 1)] UNSPEC_ICACHE)
5330               (clobber (scratch:SI))])]
5331   "TARGET_HARD_SH4 || TARGET_SH5"
5332   "
5333 {
5334   if (TARGET_SHMEDIA)
5335     {
5336       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5337       DONE;
5338     }
5339   else if (TARGET_SHCOMPACT)
5340     {
5341       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5342       operands[1] = force_reg (Pmode, operands[1]);
5343       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5344       DONE;
5345     }
5346   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5347     {
5348       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5349       DONE;
5350     }
5351   operands[0] = force_reg (Pmode, operands[0]);
5352   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5353                                                                Pmode)));
5354 }")
5355
5356 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5357 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5358 ;; the requirement *1*00 for associative address writes.  The alignment of
5359 ;; %0 implies that its least significant bit is cleared,
5360 ;; thus we clear the V bit of a matching entry if there is one.
5361 (define_insn "ic_invalidate_line_i"
5362   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5363                      (match_operand:SI 1 "register_operand" "r")]
5364                      UNSPEC_ICACHE)
5365    (clobber (match_scratch:SI 2 "=&r"))]
5366   "TARGET_HARD_SH4"
5367   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5368   [(set_attr "length" "8")
5369    (set_attr "type" "cwb")])
5370
5371 (define_insn "ic_invalidate_line_sh4a"
5372   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5373                     UNSPEC_ICACHE)]
5374   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5375   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5376   [(set_attr "length" "16")
5377    (set_attr "type" "cwb")])
5378
5379 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5380 ;; an add in the code that calculates the address.
5381 (define_insn "ic_invalidate_line_media"
5382   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5383                     UNSPEC_ICACHE)]
5384   "TARGET_SHMEDIA"
5385   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5386   [(set_attr "length" "16")
5387    (set_attr "type" "invalidate_line_media")])
5388
5389 (define_insn "ic_invalidate_line_compact"
5390   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5391                      (match_operand:SI 1 "register_operand" "r")]
5392                     UNSPEC_ICACHE)
5393    (clobber (reg:SI PR_REG))]
5394   "TARGET_SHCOMPACT"
5395   "jsr @%1%#"
5396   [(set_attr "type" "sfunc")
5397    (set_attr "needs_delay_slot" "yes")])
5398
5399 (define_expand "initialize_trampoline"
5400   [(match_operand:SI 0 "" "")
5401    (match_operand:SI 1 "" "")
5402    (match_operand:SI 2 "" "")]
5403   "TARGET_SHCOMPACT"
5404   "
5405 {
5406   rtx sfun, tramp;
5407
5408   tramp = force_reg (Pmode, operands[0]);
5409   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5410                                             SFUNC_STATIC));
5411   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5412   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5413
5414   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5415   DONE;
5416 }")
5417
5418 (define_insn "initialize_trampoline_compact"
5419   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5420                      (match_operand:SI 1 "register_operand" "r")
5421                      (reg:SI R2_REG) (reg:SI R3_REG)]
5422                     UNSPEC_INIT_TRAMP)
5423
5424    (clobber (reg:SI PR_REG))]
5425   "TARGET_SHCOMPACT"
5426   "jsr @%1%#"
5427   [(set_attr "type" "sfunc")
5428    (set_attr "needs_delay_slot" "yes")])
5429
5430 (define_insn "movqi_i"
5431   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5432         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5433   "TARGET_SH1
5434    && (arith_reg_operand (operands[0], QImode)
5435        || arith_reg_operand (operands[1], QImode))"
5436   "@
5437         mov     %1,%0
5438         mov     %1,%0
5439         mov.b   %1,%0
5440         mov.b   %1,%0
5441         movt    %0
5442         sts     %1,%0
5443         lds     %1,%0"
5444  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5445   (set_attr_alternative "length"
5446      [(const_int 2)
5447       (const_int 2)
5448       (if_then_else
5449         (match_test "TARGET_SH2A")
5450         (const_int 4) (const_int 2))
5451       (if_then_else
5452         (match_test "TARGET_SH2A")
5453         (const_int 4) (const_int 2))
5454       (const_int 2)
5455       (const_int 2)
5456       (const_int 2)])])
5457
5458 (define_insn "*movqi_media"
5459   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5460         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5461   "TARGET_SHMEDIA
5462    && (arith_reg_operand (operands[0], QImode)
5463        || extend_reg_or_0_operand (operands[1], QImode))"
5464   "@
5465         add.l   %1, r63, %0
5466         movi    %1, %0
5467         ld%M1.ub        %m1, %0
5468         st%M0.b %m0, %N1"
5469   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5470    (set (attr "highpart")
5471         (cond [(match_test "sh_contains_memref_p (insn)")
5472                (const_string "user")]
5473               (const_string "ignore")))])
5474
5475 (define_expand "movqi"
5476   [(set (match_operand:QI 0 "general_operand" "")
5477         (match_operand:QI 1 "general_operand"  ""))]
5478   ""
5479   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5480
5481 (define_expand "reload_inqi"
5482   [(set (match_operand:SI 2 "" "=&r")
5483         (match_operand:QI 1 "inqhi_operand" ""))
5484    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5485         (truncate:QI (match_dup 3)))]
5486   "TARGET_SHMEDIA"
5487   "
5488 {
5489   rtx inner = XEXP (operands[1], 0);
5490   int regno = REGNO (inner);
5491
5492   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5493   operands[1] = gen_rtx_REG (SImode, regno);
5494   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5495 }")
5496
5497 /* When storing r0, we have to avoid reg+reg addressing.  */
5498 (define_insn "movhi_i"
5499   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5500         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5501   "TARGET_SH1
5502    && (arith_reg_operand (operands[0], HImode)
5503        || arith_reg_operand (operands[1], HImode))
5504    && (!MEM_P (operands[0])
5505        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5506        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5507        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5508   "@
5509         mov.w   %1,%0
5510         mov     %1,%0
5511         mov.w   %1,%0
5512         movt    %0
5513         mov.w   %1,%0
5514         sts     %1,%0
5515         lds     %1,%0
5516         fake    %1,%0"
5517   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5518
5519 (define_insn "*movhi_media"
5520   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5521         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5522   "TARGET_SHMEDIA
5523    && (arith_reg_operand (operands[0], HImode)
5524        || arith_reg_or_0_operand (operands[1], HImode))"
5525   "@
5526         add.l   %1, r63, %0
5527         movi    %1, %0
5528         #
5529         ld%M1.w %m1, %0
5530         st%M0.w %m0, %N1"
5531   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5532    (set (attr "highpart")
5533         (cond [(match_test "sh_contains_memref_p (insn)")
5534                (const_string "user")]
5535               (const_string "ignore")))])
5536
5537 (define_split
5538   [(set (match_operand:HI 0 "register_operand" "")
5539         (match_operand:HI 1 "immediate_operand" ""))]
5540   "TARGET_SHMEDIA && reload_completed
5541    && ! satisfies_constraint_I16 (operands[1])"
5542   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5543
5544 (define_expand "movhi"
5545   [(set (match_operand:HI 0 "general_movdst_operand" "")
5546         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5547   ""
5548   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5549
5550 (define_expand "reload_inhi"
5551   [(set (match_operand:SI 2 "" "=&r")
5552         (match_operand:HI 1 "inqhi_operand" ""))
5553    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5554         (truncate:HI (match_dup 3)))]
5555   "TARGET_SHMEDIA"
5556   "
5557 {
5558   rtx inner = XEXP (operands[1], 0);
5559   int regno = REGNO (inner);
5560
5561   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5562   operands[1] = gen_rtx_REG (SImode, regno);
5563   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5564 }")
5565
5566 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5567 ;; compiled with -m2 -ml -O3 -funroll-loops
5568 (define_insn "*movdi_i"
5569   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5570         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5571   "TARGET_SH1
5572    && (arith_reg_operand (operands[0], DImode)
5573        || arith_reg_operand (operands[1], DImode))"
5574   "* return output_movedouble (insn, operands, DImode);"
5575   [(set_attr "length" "4")
5576    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5577
5578 ;; If the output is a register and the input is memory or a register, we have
5579 ;; to be careful and see which word needs to be loaded first.
5580
5581 (define_split
5582   [(set (match_operand:DI 0 "general_movdst_operand" "")
5583         (match_operand:DI 1 "general_movsrc_operand" ""))]
5584   "TARGET_SH1 && reload_completed"
5585   [(set (match_dup 2) (match_dup 3))
5586    (set (match_dup 4) (match_dup 5))]
5587   "
5588 {
5589   int regno;
5590
5591   if ((MEM_P (operands[0])
5592        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5593       || (MEM_P (operands[1])
5594           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5595     FAIL;
5596
5597   switch (GET_CODE (operands[0]))
5598     {
5599     case REG:
5600       regno = REGNO (operands[0]);
5601       break;
5602     case SUBREG:
5603       regno = subreg_regno (operands[0]);
5604       break;
5605     case MEM:
5606       regno = -1;
5607       break;
5608     default:
5609       gcc_unreachable ();
5610     }
5611
5612   if (regno == -1
5613       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5614     {
5615       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5616       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5617       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5618       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5619     }
5620   else
5621     {
5622       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5623       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5624       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5625       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5626     }
5627
5628   if (operands[2] == 0 || operands[3] == 0
5629       || operands[4] == 0 || operands[5] == 0)
5630     FAIL;
5631 }")
5632
5633 ;; The '?'s in the following constraints may not reflect the time taken
5634 ;; to perform the move. They are there to discourage the use of floating-
5635 ;; point registers for storing integer values.
5636 (define_insn "*movdi_media"
5637   [(set (match_operand:DI 0 "general_movdst_operand"
5638                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5639         (match_operand:DI 1 "general_movsrc_operand"
5640          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5641   "TARGET_SHMEDIA_FPU
5642    && (register_operand (operands[0], DImode)
5643        || sh_register_operand (operands[1], DImode))"
5644   "@
5645         add     %1, r63, %0
5646         movi    %1, %0
5647         #
5648         ld%M1.q %m1, %0
5649         st%M0.q %m0, %N1
5650         fld%M1.d        %m1, %0
5651         fst%M0.d        %m0, %1
5652         fmov.qd %N1, %0
5653         fmov.dq %1, %0
5654         fmov.d  %1, %0
5655         ptabs   %1, %0
5656         gettr   %1, %0
5657         pt      %1, %0"
5658   [(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")
5659    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5660
5661 (define_insn "*movdi_media_nofpu"
5662   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5663         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5664   "TARGET_SHMEDIA
5665    && (register_operand (operands[0], DImode)
5666        || sh_register_operand (operands[1], DImode))"
5667   "@
5668         add     %1, r63, %0
5669         movi    %1, %0
5670         #
5671         ld%M1.q %m1, %0
5672         st%M0.q %m0, %N1
5673         ptabs   %1, %0
5674         gettr   %1, %0
5675         pt      %1, %0"
5676   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5677    (set_attr "length" "4,4,16,4,4,4,4,*")])
5678
5679 (define_insn "*movdi_media_I16"
5680   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5681         (match_operand:DI 1 "const_int_operand" "I16"))]
5682   "TARGET_SHMEDIA && reload_completed"
5683   "movi %1, %0"
5684   [(set_attr "type" "arith_media")
5685    (set_attr "length" "4")])
5686
5687 (define_split
5688   [(set (match_operand:DI 0 "arith_reg_dest" "")
5689         (match_operand:DI 1 "immediate_operand" ""))]
5690   "TARGET_SHMEDIA && reload_completed
5691    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5692   [(set (match_dup 0) (match_dup 1))]
5693   "
5694 {
5695   rtx insn;
5696
5697   if (TARGET_SHMEDIA64)
5698     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5699   else
5700     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5701
5702   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5703
5704   DONE;
5705 }")
5706
5707 (define_expand "movdi_const"
5708   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5709         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5710                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5711    (set (match_dup 0)
5712         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5713                 (const:DI (unspec:DI [(match_dup 1)
5714                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5715    (set (match_dup 0)
5716         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5717                 (const:DI (unspec:DI [(match_dup 1)
5718                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5719    (set (match_dup 0)
5720         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5721                 (const:DI (unspec:DI [(match_dup 1)
5722                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5723   "TARGET_SHMEDIA64 && reload_completed
5724    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5725   "
5726 {
5727   sh_mark_label (operands[1], 4);
5728 }")
5729
5730 (define_expand "movdi_const_32bit"
5731   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5732         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5733                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5734    (set (match_dup 0)
5735         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5736                 (const:DI (unspec:DI [(match_dup 1)
5737                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5738   "TARGET_SHMEDIA32 && reload_completed
5739    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5740   "
5741 {
5742   sh_mark_label (operands[1], 2);
5743 }")
5744
5745 (define_expand "movdi_const_16bit"
5746   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5747         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5748                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5749   "TARGET_SHMEDIA && flag_pic && reload_completed
5750    && GET_CODE (operands[1]) == SYMBOL_REF"
5751   "")
5752
5753 (define_split
5754   [(set (match_operand:DI 0 "ext_dest_operand" "")
5755         (match_operand:DI 1 "immediate_operand" ""))]
5756   "TARGET_SHMEDIA && reload_completed
5757    && CONST_INT_P (operands[1])
5758    && ! satisfies_constraint_I16 (operands[1])"
5759   [(set (match_dup 0) (match_dup 2))
5760    (match_dup 1)]
5761   "
5762 {
5763   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5764   unsigned HOST_WIDE_INT low = val;
5765   unsigned HOST_WIDE_INT high = val;
5766   unsigned HOST_WIDE_INT sign;
5767   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5768
5769   /* Zero-extend the 16 least-significant bits.  */
5770   low &= 0xffff;
5771
5772   /* Arithmetic shift right the word by 16 bits.  */
5773   high >>= 16;
5774   if (GET_CODE (operands[0]) == SUBREG
5775       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5776     {
5777       high &= 0xffff;
5778       high ^= 0x8000;
5779       high -= 0x8000;
5780     }
5781   else
5782     {
5783       sign = 1;
5784       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5785       high ^= sign;
5786       high -= sign;
5787     }
5788   do
5789     {
5790       /* If we can't generate the constant with a two-insn movi / shori
5791          sequence, try some other strategies.  */
5792       if (! CONST_OK_FOR_I16 (high))
5793         {
5794           /* Try constant load / left shift.  We know VAL != 0.  */
5795           val2 = val ^ (val-1);
5796           if (val2 > 0x1ffff)
5797             {
5798               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5799
5800               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5801                   || (! CONST_OK_FOR_I16 (high >> 16)
5802                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5803                 {
5804                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5805                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5806                                                    GEN_INT (trailing_zeroes));
5807                   break;
5808                 }
5809             }
5810           /* Try constant load / right shift.  */
5811           val2 = (val >> 15) + 1;
5812           if (val2 == (val2 & -val2))
5813             {
5814               int shift = 49 - exact_log2 (val2);
5815
5816               val2 = trunc_int_for_mode (val << shift, DImode);
5817               if (CONST_OK_FOR_I16 (val2))
5818                 {
5819                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5820                                                    GEN_INT (shift));
5821                   break;
5822                 }
5823             }
5824           /* Try mperm.w .  */
5825           val2 = val & 0xffff;
5826           if ((val >> 16 & 0xffff) == val2
5827               && (val >> 32 & 0xffff) == val2
5828               && (val >> 48 & 0xffff) == val2)
5829             {
5830               val2 = (HOST_WIDE_INT) val >> 48;
5831               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5832               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5833               break;
5834             }
5835           /* Try movi / mshflo.l  */
5836           val2 = (HOST_WIDE_INT) val >> 32;
5837           if (val2 == ((unsigned HOST_WIDE_INT)
5838                         trunc_int_for_mode (val, SImode)))
5839             {
5840               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5841                                              operands[0]);
5842               break;
5843             }
5844           /* Try movi / mshflo.l w/ r63.  */
5845           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5846           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5847             {
5848               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5849                                              const0_rtx);
5850               break;
5851             }
5852         }
5853       val2 = high;
5854       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5855     }
5856   while (0);
5857   operands[2] = GEN_INT (val2);
5858 }")
5859
5860 (define_split
5861   [(set (match_operand:DI 0 "ext_dest_operand" "")
5862         (match_operand:DI 1 "immediate_operand" ""))]
5863   "TARGET_SHMEDIA && reload_completed
5864    && GET_CODE (operands[1]) == CONST_DOUBLE"
5865   [(set (match_dup 0) (match_dup 2))
5866   (set (match_dup 0)
5867        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5868   "
5869 {
5870   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5871   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5872   unsigned HOST_WIDE_INT val = low;
5873   unsigned HOST_WIDE_INT sign;
5874
5875   /* Zero-extend the 16 least-significant bits.  */
5876   val &= 0xffff;
5877   operands[1] = GEN_INT (val);
5878
5879   /* Arithmetic shift right the double-word by 16 bits.  */
5880   low >>= 16;
5881   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5882   high >>= 16;
5883   sign = 1;
5884   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5885   high ^= sign;
5886   high -= sign;
5887
5888   /* This will only be true if high is a sign-extension of low, i.e.,
5889      it must be either 0 or (unsigned)-1, and be zero iff the
5890      most-significant bit of low is set.  */
5891   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5892     operands[2] = GEN_INT (low);
5893   else
5894     operands[2] = immed_double_const (low, high, DImode);
5895 }")
5896
5897 (define_insn "shori_media"
5898   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5899         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5900                            (const_int 16))
5901                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5902   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5903   "@
5904         shori   %u2, %0
5905         #"
5906   [(set_attr "type" "arith_media,*")])
5907
5908 (define_insn "*shori_media_si"
5909   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5910         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5911                            (const_int 16))
5912                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5913   "TARGET_SHMEDIA"
5914   "shori        %u2, %0")
5915
5916 (define_expand "movdi"
5917   [(set (match_operand:DI 0 "general_movdst_operand" "")
5918         (match_operand:DI 1 "general_movsrc_operand" ""))]
5919   ""
5920   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5921
5922 (define_insn "movdf_media"
5923   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5924         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5925   "TARGET_SHMEDIA_FPU
5926    && (register_operand (operands[0], DFmode)
5927        || sh_register_operand (operands[1], DFmode))"
5928   "@
5929         fmov.d  %1, %0
5930         fmov.qd %N1, %0
5931         fmov.dq %1, %0
5932         add     %1, r63, %0
5933         #
5934         fld%M1.d        %m1, %0
5935         fst%M0.d        %m0, %1
5936         ld%M1.q %m1, %0
5937         st%M0.q %m0, %N1"
5938   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5939
5940 (define_insn "movdf_media_nofpu"
5941   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5942         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5943   "TARGET_SHMEDIA
5944    && (register_operand (operands[0], DFmode)
5945        || sh_register_operand (operands[1], DFmode))"
5946   "@
5947         add     %1, r63, %0
5948         #
5949         ld%M1.q %m1, %0
5950         st%M0.q %m0, %N1"
5951   [(set_attr "type" "arith_media,*,load_media,store_media")])
5952
5953 (define_split
5954   [(set (match_operand:DF 0 "arith_reg_dest" "")
5955         (match_operand:DF 1 "immediate_operand" ""))]
5956   "TARGET_SHMEDIA && reload_completed"
5957   [(set (match_dup 3) (match_dup 2))]
5958   "
5959 {
5960   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5961   long values[2];
5962   REAL_VALUE_TYPE value;
5963
5964   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5965   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5966
5967   if (HOST_BITS_PER_WIDE_INT >= 64)
5968     operands[2] = immed_double_const ((unsigned long) values[endian]
5969                                       | ((HOST_WIDE_INT) values[1 - endian]
5970                                          << 32), 0, DImode);
5971   else
5972     {
5973       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5974       operands[2] = immed_double_const (values[endian], values[1 - endian],
5975                                         DImode);
5976     }
5977
5978   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5979 }")
5980
5981 ;; ??? This should be a define expand.
5982
5983 (define_insn "movdf_k"
5984   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5985         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5986   "TARGET_SH1
5987    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5988        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5989        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5990        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5991    && (arith_reg_operand (operands[0], DFmode)
5992        || arith_reg_operand (operands[1], DFmode))"
5993   "* return output_movedouble (insn, operands, DFmode);"
5994   [(set_attr "length" "4")
5995    (set_attr "type" "move,pcload,load,store")])
5996
5997 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5998 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5999 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
6000 ;; the d/m/c/X alternative, which is split later into single-precision
6001 ;; instructions.  And when not optimizing, no splits are done before fixing
6002 ;; up pcloads, so we need usable length information for that.
6003 (define_insn "movdf_i4"
6004   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
6005         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
6006    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
6007    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
6008   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6009    && (arith_reg_operand (operands[0], DFmode)
6010        || arith_reg_operand (operands[1], DFmode))"
6011   {
6012     switch (which_alternative)
6013     {
6014     case 0:
6015       if (TARGET_FMOVD)
6016         return "fmov    %1,%0";
6017       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
6018         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
6019       else
6020         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
6021     case 3:
6022     case 4:
6023       return "fmov.d    %1,%0";
6024     default:
6025       return "#";
6026     }
6027   }
6028   [(set_attr_alternative "length"
6029      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6030       (const_int 4)
6031       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6032       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6033       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6034       (const_int 4)
6035       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6036       ;; We can't use 4-byte push/pop on SHcompact, so we have to
6037       ;; increment or decrement r15 explicitly.
6038       (if_then_else
6039        (match_test "TARGET_SHCOMPACT")
6040        (const_int 10) (const_int 8))
6041       (if_then_else
6042        (match_test "TARGET_SHCOMPACT")
6043        (const_int 10) (const_int 8))])
6044    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6045    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6046    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6047                                            (const_string "double")
6048                                            (const_string "none")))])
6049
6050 ;; Moving DFmode between fp/general registers through memory
6051 ;; (the top of the stack) is faster than moving through fpul even for
6052 ;; little endian.  Because the type of an instruction is important for its
6053 ;; scheduling,  it is beneficial to split these operations, rather than
6054 ;; emitting them in one single chunk, even if this will expose a stack
6055 ;; use that will prevent scheduling of other stack accesses beyond this
6056 ;; instruction.
6057 (define_split
6058   [(set (match_operand:DF 0 "register_operand" "")
6059         (match_operand:DF 1 "register_operand" ""))
6060    (use (match_operand:PSI 2 "fpscr_operand" ""))
6061    (clobber (match_scratch:SI 3 "=X"))]
6062   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6063    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6064   [(const_int 0)]
6065   "
6066 {
6067   rtx insn, tos;
6068
6069   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6070     {
6071       emit_move_insn (stack_pointer_rtx,
6072                       plus_constant (stack_pointer_rtx, -8));
6073       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6074     }
6075   else
6076     tos = gen_tmp_stack_mem (DFmode,
6077                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6078   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6079   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6080     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6081   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6082     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6083   else
6084     tos = gen_tmp_stack_mem (DFmode,
6085                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6086   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6087   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6088     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6089   else
6090     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6091   DONE;
6092 }")
6093
6094 ;; local-alloc sometimes allocates scratch registers even when not required,
6095 ;; so we must be prepared to handle these.
6096
6097 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6098 (define_split
6099   [(set (match_operand:DF 0 "general_movdst_operand" "")
6100         (match_operand:DF 1 "general_movsrc_operand"  ""))
6101    (use (match_operand:PSI 2 "fpscr_operand" ""))
6102    (clobber (match_scratch:SI 3 ""))]
6103   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6104    && reload_completed
6105    && true_regnum (operands[0]) < 16
6106    && true_regnum (operands[1]) < 16"
6107   [(set (match_dup 0) (match_dup 1))]
6108   "
6109 {
6110   /* If this was a reg <-> mem operation with base + index reg addressing,
6111      we have to handle this in a special way.  */
6112   rtx mem = operands[0];
6113   int store_p = 1;
6114   if (! memory_operand (mem, DFmode))
6115     {
6116       mem = operands[1];
6117       store_p = 0;
6118     }
6119   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6120     mem = SUBREG_REG (mem);
6121   if (MEM_P (mem))
6122     {
6123       rtx addr = XEXP (mem, 0);
6124       if (GET_CODE (addr) == PLUS
6125           && REG_P (XEXP (addr, 0))
6126           && REG_P (XEXP (addr, 1)))
6127         {
6128           int offset;
6129           rtx reg0 = gen_rtx_REG (Pmode, 0);
6130           rtx regop = operands[store_p], word0 ,word1;
6131
6132           if (GET_CODE (regop) == SUBREG)
6133             alter_subreg (&regop);
6134           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6135             offset = 2;
6136           else
6137             offset = 4;
6138           mem = copy_rtx (mem);
6139           PUT_MODE (mem, SImode);
6140           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6141           alter_subreg (&word0);
6142           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6143           alter_subreg (&word1);
6144           if (store_p || ! refers_to_regno_p (REGNO (word0),
6145                                               REGNO (word0) + 1, addr, 0))
6146             {
6147               emit_insn (store_p
6148                          ? gen_movsi_ie (mem, word0)
6149                          : gen_movsi_ie (word0, mem));
6150               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6151               mem = copy_rtx (mem);
6152               emit_insn (store_p
6153                          ? gen_movsi_ie (mem, word1)
6154                          : gen_movsi_ie (word1, mem));
6155               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6156             }
6157           else
6158             {
6159               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6160               emit_insn (gen_movsi_ie (word1, mem));
6161               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6162               mem = copy_rtx (mem);
6163               emit_insn (gen_movsi_ie (word0, mem));
6164             }
6165           DONE;
6166         }
6167     }
6168 }")
6169
6170 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6171 (define_split
6172   [(set (match_operand:DF 0 "register_operand" "")
6173         (match_operand:DF 1 "memory_operand"  ""))
6174    (use (match_operand:PSI 2 "fpscr_operand" ""))
6175    (clobber (reg:SI R0_REG))]
6176   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6177   [(parallel [(set (match_dup 0) (match_dup 1))
6178               (use (match_dup 2))
6179               (clobber (scratch:SI))])]
6180   "")
6181
6182 (define_expand "reload_indf__frn"
6183   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6184                    (match_operand:DF 1 "immediate_operand" "FQ"))
6185               (use (reg:PSI FPSCR_REG))
6186               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6187   "TARGET_SH1"
6188   "")
6189
6190 (define_expand "reload_outdf__RnFRm"
6191   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6192                    (match_operand:DF 1 "register_operand" "af,r"))
6193               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6194   "TARGET_SH1"
6195   "")
6196
6197 ;; Simplify no-op moves.
6198 (define_split
6199   [(set (match_operand:SF 0 "register_operand" "")
6200         (match_operand:SF 1 "register_operand" ""))
6201    (use (match_operand:PSI 2 "fpscr_operand" ""))
6202    (clobber (match_scratch:SI 3 ""))]
6203   "TARGET_SH2E && reload_completed
6204    && true_regnum (operands[0]) == true_regnum (operands[1])"
6205   [(set (match_dup 0) (match_dup 0))]
6206   "")
6207
6208 ;; fmovd substitute post-reload splits
6209 (define_split
6210   [(set (match_operand:DF 0 "register_operand" "")
6211         (match_operand:DF 1 "register_operand" ""))
6212    (use (match_operand:PSI 2 "fpscr_operand" ""))
6213    (clobber (match_scratch:SI 3 ""))]
6214   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6215    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6216    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6217   [(const_int 0)]
6218   "
6219 {
6220   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6221   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6222                            gen_rtx_REG (SFmode, src), operands[2]));
6223   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6224                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6225   DONE;
6226 }")
6227
6228 (define_split
6229   [(set (match_operand:DF 0 "register_operand" "")
6230         (mem:DF (match_operand:SI 1 "register_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    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6236   [(const_int 0)]
6237   "
6238 {
6239   int regno = true_regnum (operands[0]);
6240   rtx insn;
6241   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6242   rtx mem2
6243     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6244   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6245                                            regno + !! TARGET_LITTLE_ENDIAN),
6246                                   mem2, operands[2]));
6247   add_reg_note (insn, REG_INC, operands[1]);
6248   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6249                                                regno + ! TARGET_LITTLE_ENDIAN),
6250                                   change_address (mem, SFmode, NULL_RTX),
6251                                   operands[2]));
6252   DONE;
6253 }")
6254
6255 (define_split
6256   [(set (match_operand:DF 0 "register_operand" "")
6257         (match_operand:DF 1 "memory_operand" ""))
6258    (use (match_operand:PSI 2 "fpscr_operand" ""))
6259    (clobber (match_scratch:SI 3 ""))]
6260   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6261    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6262   [(const_int 0)]
6263 {
6264   int regno = true_regnum (operands[0]);
6265   rtx addr, insn;
6266   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6267   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6268   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6269
6270   operands[1] = copy_rtx (mem2);
6271   addr = XEXP (mem2, 0);
6272
6273   switch (GET_CODE (addr))
6274     {
6275     case REG:
6276       /* This is complicated.  If the register is an arithmetic register
6277          we can just fall through to the REG+DISP case below.  Otherwise
6278          we have to use a combination of POST_INC and REG addressing...  */
6279       if (! arith_reg_operand (operands[1], SFmode))
6280         {
6281           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6282           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6283           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6284           
6285           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6286
6287           /* If we have modified the stack pointer, the value that we have
6288              read with post-increment might be modified by an interrupt,
6289              so write it back.  */
6290           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6291             emit_insn (gen_push_e (reg0));
6292           else
6293             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6294           break;
6295         }
6296       /* Fall through.  */
6297          
6298     case PLUS:
6299       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6300       operands[1] = copy_rtx (operands[1]);
6301       XEXP (operands[1], 0) = plus_constant (addr, 4);
6302       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6303       break;
6304       
6305     case POST_INC:
6306       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6307       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6308     
6309       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6310       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6311       break;
6312
6313     default:
6314       debug_rtx (addr);
6315       gcc_unreachable ();
6316     }
6317
6318   DONE;
6319 })
6320
6321 (define_split
6322   [(set (match_operand:DF 0 "memory_operand" "")
6323         (match_operand:DF 1 "register_operand" ""))
6324    (use (match_operand:PSI 2 "fpscr_operand" ""))
6325    (clobber (match_scratch:SI 3 ""))]
6326   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6327    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6328   [(const_int 0)]
6329 {
6330   int regno = true_regnum (operands[1]);
6331   rtx insn, addr;
6332   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6333   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6334
6335   operands[0] = copy_rtx (operands[0]);
6336   PUT_MODE (operands[0], SFmode);
6337   addr = XEXP (operands[0], 0);
6338
6339   switch (GET_CODE (addr))
6340     {
6341     case REG:
6342       /* This is complicated.  If the register is an arithmetic register
6343          we can just fall through to the REG+DISP case below.  Otherwise
6344          we have to use a combination of REG and PRE_DEC addressing...  */
6345       if (! arith_reg_operand (operands[0], SFmode))
6346         {
6347           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6348           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6349
6350           operands[0] = copy_rtx (operands[0]);
6351           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6352           
6353           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6354           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6355           break;
6356         }
6357       /* Fall through.  */
6358       
6359     case PLUS:
6360       /* Since REG+DISP addressing has already been decided upon by gcc
6361          we can rely upon it having chosen an arithmetic register as the
6362          register component of the address.  Just emit the lower numbered
6363          register first, to the lower address, then the higher numbered
6364          register to the higher address.  */
6365       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6366
6367       operands[0] = copy_rtx (operands[0]);
6368       XEXP (operands[0], 0) = plus_constant (addr, 4);
6369
6370       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6371       break;
6372       
6373     case PRE_DEC:
6374       /* This is easy.  Output the word to go to the higher address
6375          first (ie the word in the higher numbered register) then the
6376          word to go to the lower address.  */
6377
6378       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6379       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6380
6381       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6382       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6383       break;
6384       
6385     default:
6386       /* FAIL; */
6387       debug_rtx (addr);
6388       gcc_unreachable ();
6389     }
6390
6391   DONE;
6392 })
6393
6394 ;; If the output is a register and the input is memory or a register, we have
6395 ;; to be careful and see which word needs to be loaded first.
6396
6397 (define_split
6398   [(set (match_operand:DF 0 "general_movdst_operand" "")
6399         (match_operand:DF 1 "general_movsrc_operand" ""))]
6400   "TARGET_SH1 && reload_completed"
6401   [(set (match_dup 2) (match_dup 3))
6402    (set (match_dup 4) (match_dup 5))]
6403   "
6404 {
6405   int regno;
6406
6407   if ((MEM_P (operands[0])
6408        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6409       || (MEM_P (operands[1])
6410           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6411     FAIL;
6412
6413   switch (GET_CODE (operands[0]))
6414     {
6415     case REG:
6416       regno = REGNO (operands[0]);
6417       break;
6418     case SUBREG:
6419       regno = subreg_regno (operands[0]);
6420       break;
6421     case MEM:
6422       regno = -1;
6423       break;
6424     default:
6425       gcc_unreachable ();
6426     }
6427
6428   if (regno == -1
6429       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6430     {
6431       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6432       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6433       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6434       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6435     }
6436   else
6437     {
6438       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6439       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6440       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6441       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6442     }
6443
6444   if (operands[2] == 0 || operands[3] == 0
6445       || operands[4] == 0 || operands[5] == 0)
6446     FAIL;
6447 }")
6448
6449 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6450 ;; used only once, let combine add in the index again.
6451
6452 (define_split
6453   [(set (match_operand:SI 0 "register_operand" "")
6454         (match_operand:SI 1 "" ""))
6455    (clobber (match_operand 2 "register_operand" ""))]
6456   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6457    && ALLOW_INDEXED_ADDRESS"
6458   [(use (reg:SI R0_REG))]
6459   "
6460 {
6461   rtx addr, reg, const_int;
6462
6463   if (!MEM_P (operands[1]))
6464     FAIL;
6465   addr = XEXP (operands[1], 0);
6466   if (GET_CODE (addr) != PLUS)
6467     FAIL;
6468   reg = XEXP (addr, 0);
6469   const_int = XEXP (addr, 1);
6470   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6471          && CONST_INT_P (const_int)))
6472     FAIL;
6473   emit_move_insn (operands[2], const_int);
6474   emit_move_insn (operands[0],
6475                   change_address (operands[1], VOIDmode,
6476                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6477   DONE;
6478 }")
6479
6480 (define_split
6481   [(set (match_operand:SI 1 "" "")
6482         (match_operand:SI 0 "register_operand" ""))
6483    (clobber (match_operand 2 "register_operand" ""))]
6484   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6485    && ALLOW_INDEXED_ADDRESS"
6486   [(use (reg:SI R0_REG))]
6487   "
6488 {
6489   rtx addr, reg, const_int;
6490
6491   if (!MEM_P (operands[1]))
6492     FAIL;
6493   addr = XEXP (operands[1], 0);
6494   if (GET_CODE (addr) != PLUS)
6495     FAIL;
6496   reg = XEXP (addr, 0);
6497   const_int = XEXP (addr, 1);
6498   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6499          && CONST_INT_P (const_int)))
6500     FAIL;
6501   emit_move_insn (operands[2], const_int);
6502   emit_move_insn (change_address (operands[1], VOIDmode,
6503                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6504                   operands[0]);
6505   DONE;
6506 }")
6507
6508 (define_expand "movdf"
6509   [(set (match_operand:DF 0 "general_movdst_operand" "")
6510         (match_operand:DF 1 "general_movsrc_operand" ""))]
6511   ""
6512   "
6513 {
6514   if (prepare_move_operands (operands, DFmode)) DONE;
6515   if (TARGET_SHMEDIA)
6516     {
6517       if (TARGET_SHMEDIA_FPU)
6518         emit_insn (gen_movdf_media (operands[0], operands[1]));
6519       else
6520         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6521       DONE;
6522     }
6523   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6524     {
6525       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6526       DONE;
6527     }
6528 }")
6529
6530 ;;This is incompatible with the way gcc uses subregs.
6531 ;;(define_insn "movv2sf_i"
6532 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6533 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6534 ;;  "TARGET_SHMEDIA_FPU
6535 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6536 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6537 ;;  "@
6538 ;;      #
6539 ;;      fld%M1.p        %m1, %0
6540 ;;      fst%M0.p        %m0, %1"
6541 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6542
6543 (define_insn_and_split "movv2sf_i"
6544   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6545         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6546   "TARGET_SHMEDIA_FPU"
6547   "#"
6548   "TARGET_SHMEDIA_FPU && reload_completed"
6549   [(set (match_dup 0) (match_dup 1))]
6550   "
6551 {
6552   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6553   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6554 }")
6555
6556 (define_expand "movv2sf"
6557   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6558         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6559   "TARGET_SHMEDIA_FPU"
6560   "
6561 {
6562   if (prepare_move_operands (operands, V2SFmode))
6563     DONE;
6564 }")
6565
6566 (define_expand "addv2sf3"
6567   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6568    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6569    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6570   "TARGET_SHMEDIA_FPU"
6571   "
6572 {
6573   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6574   DONE;
6575 }")
6576
6577 (define_expand "subv2sf3"
6578   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6579    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6580    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6581   "TARGET_SHMEDIA_FPU"
6582   "
6583 {
6584   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6585   DONE;
6586 }")
6587
6588 (define_expand "mulv2sf3"
6589   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6590    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6591    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6592   "TARGET_SHMEDIA_FPU"
6593   "
6594 {
6595   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6596   DONE;
6597 }")
6598
6599 (define_expand "divv2sf3"
6600   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6601    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6602    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6603   "TARGET_SHMEDIA_FPU"
6604   "
6605 {
6606   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6607   DONE;
6608 }")
6609
6610 (define_insn_and_split "*movv4sf_i"
6611   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6612         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6613   "TARGET_SHMEDIA_FPU"
6614   "#"
6615   "&& reload_completed"
6616   [(const_int 0)]
6617   "
6618 {
6619   int i;
6620
6621   for (i = 0; i < 4/2; i++)
6622     {
6623       rtx x, y;
6624
6625       if (MEM_P (operands[0]))
6626         x = adjust_address (operands[0], V2SFmode,
6627                             i * GET_MODE_SIZE (V2SFmode));
6628       else
6629         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6630
6631       if (MEM_P (operands[1]))
6632         y = adjust_address (operands[1], V2SFmode,
6633                             i * GET_MODE_SIZE (V2SFmode));
6634       else
6635         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6636
6637       emit_insn (gen_movv2sf_i (x, y));
6638     }
6639
6640   DONE;
6641 }"
6642   [(set_attr "length" "8")])
6643
6644 (define_expand "movv4sf"
6645   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6646         (match_operand:V4SF 1 "general_operand" ""))]
6647   "TARGET_SHMEDIA_FPU"
6648   "
6649 {
6650   if (prepare_move_operands (operands, V4SFmode))
6651     DONE;
6652 }")
6653
6654 (define_insn_and_split "*movv16sf_i"
6655   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6656         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6657   "TARGET_SHMEDIA_FPU"
6658   "#"
6659   "&& reload_completed"
6660   [(const_int 0)]
6661   "
6662 {
6663   int i;
6664
6665   for (i = 0; i < 16/2; i++)
6666     {
6667       rtx x,y;
6668
6669       if (MEM_P (operands[0]))
6670         x = adjust_address (operands[0], V2SFmode,
6671                             i * GET_MODE_SIZE (V2SFmode));
6672       else
6673         {
6674           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6675           alter_subreg (&x);
6676         }
6677
6678       if (MEM_P (operands[1]))
6679         y = adjust_address (operands[1], V2SFmode,
6680                             i * GET_MODE_SIZE (V2SFmode));
6681       else
6682         {
6683           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6684           alter_subreg (&y);
6685         }
6686
6687       emit_insn (gen_movv2sf_i (x, y));
6688     }
6689
6690   DONE;
6691 }"
6692   [(set_attr "length" "32")])
6693
6694 (define_expand "movv16sf"
6695   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6696         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6697   "TARGET_SHMEDIA_FPU"
6698   "
6699 {
6700   if (prepare_move_operands (operands, V16SFmode))
6701     DONE;
6702 }")
6703
6704 (define_insn "movsf_media"
6705   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6706         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6707   "TARGET_SHMEDIA_FPU
6708    && (register_operand (operands[0], SFmode)
6709        || sh_register_operand (operands[1], SFmode))"
6710   "@
6711         fmov.s  %1, %0
6712         fmov.ls %N1, %0
6713         fmov.sl %1, %0
6714         add.l   %1, r63, %0
6715         #
6716         fld%M1.s        %m1, %0
6717         fst%M0.s        %m0, %1
6718         ld%M1.l %m1, %0
6719         st%M0.l %m0, %N1"
6720   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6721    (set (attr "highpart")
6722         (cond [(match_test "sh_contains_memref_p (insn)")
6723                (const_string "user")]
6724               (const_string "ignore")))])
6725
6726 (define_insn "movsf_media_nofpu"
6727   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6728         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6729   "TARGET_SHMEDIA
6730    && (register_operand (operands[0], SFmode)
6731        || sh_register_operand (operands[1], SFmode))"
6732   "@
6733         add.l   %1, r63, %0
6734         #
6735         ld%M1.l %m1, %0
6736         st%M0.l %m0, %N1"
6737   [(set_attr "type" "arith_media,*,load_media,store_media")
6738    (set (attr "highpart")
6739         (cond [(match_test "sh_contains_memref_p (insn)")
6740                (const_string "user")]
6741               (const_string "ignore")))])
6742
6743 (define_split
6744   [(set (match_operand:SF 0 "arith_reg_dest" "")
6745         (match_operand:SF 1 "immediate_operand" ""))]
6746   "TARGET_SHMEDIA && reload_completed
6747    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6748   [(set (match_dup 3) (match_dup 2))]
6749   "
6750 {
6751   long values;
6752   REAL_VALUE_TYPE value;
6753
6754   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6755   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6756   operands[2] = GEN_INT (values);
6757
6758   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6759 }")
6760
6761 (define_insn "movsf_i"
6762   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6763         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6764   "TARGET_SH1
6765    && (! TARGET_SH2E
6766        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6767        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6768        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6769    && (arith_reg_operand (operands[0], SFmode)
6770        || arith_reg_operand (operands[1], SFmode))"
6771   "@
6772         mov     %1,%0
6773         mov     #0,%0
6774         mov.l   %1,%0
6775         mov.l   %1,%0
6776         mov.l   %1,%0
6777         lds     %1,%0
6778         sts     %1,%0"
6779   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6780
6781 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6782 ;; update_flow_info would not know where to put REG_EQUAL notes
6783 ;; when the destination changes mode.
6784 (define_insn "movsf_ie"
6785   [(set (match_operand:SF 0 "general_movdst_operand"
6786          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6787         (match_operand:SF 1 "general_movsrc_operand"
6788           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6789    (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"))
6790    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6791
6792   "TARGET_SH2E
6793    && (arith_reg_operand (operands[0], SFmode)
6794        || arith_reg_operand (operands[1], SFmode)
6795        || arith_reg_operand (operands[3], SImode)
6796        || (fpul_operand (operands[0], SFmode)
6797            && memory_operand (operands[1], SFmode)
6798            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6799        || (fpul_operand (operands[1], SFmode)
6800            && memory_operand (operands[0], SFmode)
6801            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6802   "@
6803         fmov    %1,%0
6804         mov     %1,%0
6805         fldi0   %0
6806         fldi1   %0
6807         #
6808         fmov.s  %1,%0
6809         fmov.s  %1,%0
6810         mov.l   %1,%0
6811         mov.l   %1,%0
6812         mov.l   %1,%0
6813         fsts    fpul,%0
6814         flds    %1,fpul
6815         lds.l   %1,%0
6816         #
6817         sts     %1,%0
6818         lds     %1,%0
6819         sts.l   %1,%0
6820         lds.l   %1,%0
6821         ! move optimized away"
6822   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6823    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6824    (set_attr_alternative "length"
6825      [(const_int 2)
6826       (const_int 2)
6827       (const_int 2)
6828       (const_int 2)
6829       (const_int 4)
6830       (if_then_else
6831         (match_test "TARGET_SH2A")
6832         (const_int 4) (const_int 2))
6833       (if_then_else
6834         (match_test "TARGET_SH2A")
6835         (const_int 4) (const_int 2))
6836       (const_int 2)
6837       (if_then_else
6838         (match_test "TARGET_SH2A")
6839         (const_int 4) (const_int 2))
6840       (if_then_else
6841         (match_test "TARGET_SH2A")
6842         (const_int 4) (const_int 2))
6843       (const_int 2)
6844       (const_int 2)
6845       (const_int 2)
6846       (const_int 4)
6847       (const_int 2)
6848       (const_int 2)
6849       (const_int 2)
6850       (const_int 2)
6851       (const_int 0)])
6852    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6853                                            (const_string "single")
6854                                            (const_string "single")))])
6855
6856 (define_split
6857   [(set (match_operand:SF 0 "register_operand" "")
6858         (match_operand:SF 1 "register_operand" ""))
6859    (use (match_operand:PSI 2 "fpscr_operand" ""))
6860    (clobber (reg:SI FPUL_REG))]
6861   "TARGET_SH1"
6862   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6863               (use (match_dup 2))
6864               (clobber (scratch:SI))])
6865    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6866               (use (match_dup 2))
6867               (clobber (scratch:SI))])]
6868   "")
6869
6870 (define_expand "movsf"
6871   [(set (match_operand:SF 0 "general_movdst_operand" "")
6872         (match_operand:SF 1 "general_movsrc_operand" ""))]
6873   ""
6874   "
6875 {
6876   if (prepare_move_operands (operands, SFmode))
6877     DONE;
6878   if (TARGET_SHMEDIA)
6879     {
6880       if (TARGET_SHMEDIA_FPU)
6881         emit_insn (gen_movsf_media (operands[0], operands[1]));
6882       else
6883         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6884       DONE;
6885     }
6886   if (TARGET_SH2E)
6887     {
6888       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6889       DONE;
6890     }
6891 }")
6892
6893 (define_insn "mov_nop"
6894   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6895   "TARGET_SH2E"
6896   ""
6897   [(set_attr "length" "0")
6898    (set_attr "type" "nil")])
6899
6900 (define_expand "reload_insf__frn"
6901   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6902                    (match_operand:SF 1 "immediate_operand" "FQ"))
6903               (use (reg:PSI FPSCR_REG))
6904               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6905   "TARGET_SH1"
6906   "")
6907
6908 (define_expand "reload_insi__i_fpul"
6909   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6910                    (match_operand:SI 1 "immediate_operand" "i"))
6911               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6912   "TARGET_SH1"
6913   "")
6914
6915 (define_expand "ptabs"
6916   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6917   "TARGET_SHMEDIA"
6918   "
6919 {
6920   if (!TARGET_PT_FIXED)
6921     {
6922       rtx eq = operands[1];
6923
6924       /* ??? For canonical RTL we really should remove any CONST from EQ
6925          before wrapping it in the AND, and finally wrap the EQ into a
6926          const if is constant.  However, for reload we must expose the
6927          input register or symbolic constant, and we can't have
6928          different insn structures outside of the operands for different
6929          alternatives of the same pattern.  */
6930       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6931                        GEN_INT (3));
6932       operands[1]
6933         = (gen_rtx_IF_THEN_ELSE
6934             (PDImode,
6935              eq,
6936              gen_rtx_MEM (PDImode, operands[1]),
6937              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6938                             PDImode, operands[1])));
6939     }
6940 }")
6941
6942 ;; expanded by ptabs expander.
6943 (define_insn "*extendsipdi_media"
6944   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6945         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6946                                                           "r,Csy")
6947                                       (const_int 3))
6948                               (const_int 3))
6949                           (mem:PDI (match_dup 1))
6950                           (sign_extend:PDI (match_dup 1))))]
6951   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6952   "@
6953         ptabs   %1, %0
6954         pt      %1, %0"
6955   [(set_attr "type"   "ptabs_media,pt_media")
6956    (set_attr "length" "4,*")])
6957
6958 (define_insn "*truncdipdi_media"
6959   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6960         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6961                                                           "r,Csy")
6962                                       (const_int 3))
6963                               (const_int 3))
6964                           (mem:PDI (match_dup 1))
6965                           (truncate:PDI (match_dup 1))))]
6966   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6967   "@
6968         ptabs   %1, %0
6969         pt      %1, %0"
6970   [(set_attr "type"   "ptabs_media,pt_media")
6971    (set_attr "length" "4,*")])
6972
6973 (define_insn "*movsi_y"
6974   [(set (match_operand:SI 0 "register_operand" "=y,y")
6975         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6976    (clobber (match_scratch:SI 2 "=&z,r"))]
6977   "TARGET_SH2E
6978    && (reload_in_progress || reload_completed)"
6979   "#"
6980   [(set_attr "length" "4")
6981    (set_attr "type" "pcload,move")])
6982
6983 (define_split
6984   [(set (match_operand:SI 0 "register_operand" "")
6985         (match_operand:SI 1 "immediate_operand" ""))
6986    (clobber (match_operand:SI 2 "register_operand" ""))]
6987   "TARGET_SH1"
6988   [(set (match_dup 2) (match_dup 1))
6989    (set (match_dup 0) (match_dup 2))]
6990   "")
6991
6992 (define_split
6993   [(set (match_operand:SI 0 "register_operand" "")
6994         (match_operand:SI 1 "memory_operand" ""))
6995    (clobber (reg:SI R0_REG))]
6996   "TARGET_SH1"
6997   [(set (match_dup 0) (match_dup 1))]
6998   "")
6999 \f
7000 ;; ------------------------------------------------------------------------
7001 ;; Define the real conditional branch instructions.
7002 ;; ------------------------------------------------------------------------
7003
7004 (define_insn "branch_true"
7005   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
7006                            (label_ref (match_operand 0 "" ""))
7007                            (pc)))]
7008   "TARGET_SH1"
7009   "* return output_branch (1, insn, operands);"
7010   [(set_attr "type" "cbranch")])
7011
7012 (define_insn "branch_false"
7013   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7014                            (label_ref (match_operand 0 "" ""))
7015                            (pc)))]
7016   "TARGET_SH1"
7017   "* return output_branch (0, insn, operands);"
7018   [(set_attr "type" "cbranch")])
7019
7020 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
7021 ;; which destination is too far away.
7022 ;; The const_int_operand is distinct for each branch target; it avoids
7023 ;; unwanted matches with redundant_insn.
7024 (define_insn "block_branch_redirect"
7025   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7026   "TARGET_SH1"
7027   ""
7028   [(set_attr "length" "0")])
7029
7030 ;; This one has the additional purpose to record a possible scratch register
7031 ;; for the following branch.
7032 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7033 ;; because the insn then might be deemed dead and deleted.  And we can't
7034 ;; make the use in the jump insn explicit because that would disable
7035 ;; delay slot scheduling from the target.
7036 (define_insn "indirect_jump_scratch"
7037   [(set (match_operand:SI 0 "register_operand" "=r")
7038         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7039    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7040   "TARGET_SH1"
7041   ""
7042   [(set_attr "length" "0")])
7043
7044 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7045 ;; being pulled into the delay slot of a condbranch that has been made to
7046 ;; jump around the unconditional jump because it was out of range.
7047 (define_insn "stuff_delay_slot"
7048   [(set (pc)
7049         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7050                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7051   "TARGET_SH1"
7052   ""
7053   [(set_attr "length" "0")
7054    (set_attr "cond_delay_slot" "yes")])
7055 \f
7056 ;; Conditional branch insns
7057
7058 (define_expand "cbranchint4_media"
7059   [(set (pc)
7060         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7061                        [(match_operand 1 "" "")
7062                         (match_operand 2 "" "")])
7063                       (match_operand 3 "" "")
7064                       (pc)))]
7065   "TARGET_SHMEDIA"
7066   "
7067 {
7068   enum machine_mode mode = GET_MODE (operands[1]);
7069   if (mode == VOIDmode)
7070     mode = GET_MODE (operands[2]);
7071   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7072     {
7073       operands[1] = force_reg (mode, operands[1]);
7074       if (CONSTANT_P (operands[2])
7075           && (! satisfies_constraint_I06 (operands[2])))
7076         operands[2] = force_reg (mode, operands[2]);
7077     }
7078   else
7079     {
7080       if (operands[1] != const0_rtx)
7081         operands[1] = force_reg (mode, operands[1]);
7082       if (operands[2] != const0_rtx)
7083         operands[2] = force_reg (mode, operands[2]);
7084     }
7085   switch (GET_CODE (operands[0]))
7086     {
7087     case LEU:
7088     case LE:
7089     case LTU:
7090     case LT:
7091       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7092                                     VOIDmode, operands[2], operands[1]);
7093       operands[1] = XEXP (operands[0], 0);
7094       operands[2] = XEXP (operands[0], 1);
7095       break;
7096     default:
7097       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7098                                     VOIDmode, operands[1], operands[2]);
7099       break;
7100     }
7101   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7102 }")
7103
7104 (define_expand "cbranchfp4_media"
7105   [(set (pc)
7106         (if_then_else (match_operator 0 "sh_float_comparison_operator"
7107                        [(match_operand 1 "" "")
7108                         (match_operand 2 "" "")])
7109                       (match_operand 3 "" "")
7110                       (pc)))]
7111   "TARGET_SHMEDIA"
7112   "
7113 {
7114   rtx tmp = gen_reg_rtx (SImode);
7115   rtx cmp;
7116   if (GET_CODE (operands[0]) == NE)
7117     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7118   else
7119     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7120                           operands[1], operands[2]);
7121
7122   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7123
7124   if (GET_CODE (cmp) == GET_CODE (operands[0]))
7125     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7126   else
7127     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7128   operands[1] = tmp;
7129   operands[2] = const0_rtx;
7130   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7131 }")
7132
7133 (define_insn "*beq_media_i"
7134   [(set (pc)
7135         (if_then_else (match_operator 3 "equality_comparison_operator"
7136                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
7137                          (match_operand:DI 2 "arith_operand" "r,I06")])
7138                       (match_operand 0 "target_operand" "b,b")
7139                       (pc)))]
7140   "TARGET_SHMEDIA"
7141   "@
7142         b%o3%'  %1, %2, %0%>
7143         b%o3i%' %1, %2, %0%>"
7144   [(set_attr "type" "cbranch_media")])
7145
7146 (define_insn "*beq_media_i32"
7147   [(set (pc)
7148         (if_then_else (match_operator 3 "equality_comparison_operator"
7149                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
7150                          (match_operand:SI 2 "arith_operand" "r,I06")])
7151                       (match_operand 0 "target_operand" "b,b")
7152                       (pc)))]
7153   "TARGET_SHMEDIA"
7154   "@
7155         b%o3%'  %1, %2, %0%>
7156         b%o3i%' %1, %2, %0%>"
7157   [(set_attr "type" "cbranch_media")])
7158
7159 (define_insn "*bgt_media_i"
7160   [(set (pc)
7161         (if_then_else (match_operator 3 "greater_comparison_operator"
7162                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7163                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7164                       (match_operand 0 "target_operand" "b")
7165                       (pc)))]
7166   "TARGET_SHMEDIA"
7167   "b%o3%'       %N1, %N2, %0%>"
7168   [(set_attr "type" "cbranch_media")])
7169
7170 (define_insn "*bgt_media_i32"
7171   [(set (pc)
7172         (if_then_else (match_operator 3 "greater_comparison_operator"
7173                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7174                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7175                       (match_operand 0 "target_operand" "b")
7176                       (pc)))]
7177   "TARGET_SHMEDIA"
7178   "b%o3%'       %N1, %N2, %0%>"
7179   [(set_attr "type" "cbranch_media")])
7180
7181 ;; These are only needed to make invert_jump() happy - otherwise, jump
7182 ;; optimization will be silently disabled.
7183 (define_insn "*blt_media_i"
7184   [(set (pc)
7185         (if_then_else (match_operator 3 "less_comparison_operator"
7186                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7187                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7188                       (match_operand 0 "target_operand" "b")
7189                       (pc)))]
7190   "TARGET_SHMEDIA"
7191   "b%o3%'       %N2, %N1, %0%>"
7192   [(set_attr "type" "cbranch_media")])
7193
7194 (define_insn "*blt_media_i32"
7195   [(set (pc)
7196         (if_then_else (match_operator 3 "less_comparison_operator"
7197                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7198                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7199                       (match_operand 0 "target_operand" "b")
7200                       (pc)))]
7201   "TARGET_SHMEDIA"
7202   "b%o3%'       %N2, %N1, %0%>"
7203   [(set_attr "type" "cbranch_media")])
7204
7205 ;; combiner splitter for test-and-branch on single bit in register.  This
7206 ;; is endian dependent because the non-paradoxical subreg looks different
7207 ;; on big endian.
7208 (define_split
7209   [(set (pc)
7210         (if_then_else
7211           (match_operator 3 "equality_comparison_operator"
7212             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7213                                                       "extend_reg_operand" "")
7214                                                     0)
7215                                          (const_int 1)
7216                                          (match_operand 2
7217                                           "const_int_operand" "")) 0)
7218              (const_int 0)])
7219           (match_operand 0 "target_operand" "")
7220           (pc)))
7221    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7222   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7223   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7224    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7225
7226   "
7227 {
7228   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7229   operands[6] = (GET_CODE (operands[3]) == EQ
7230                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7231                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7232 }")
7233
7234 ; operand 0 is the loop count pseudo register
7235 ; operand 1 is the number of loop iterations or 0 if it is unknown
7236 ; operand 2 is the maximum number of loop iterations
7237 ; operand 3 is the number of levels of enclosed loops
7238 ; operand 4 is the label to jump to at the top of the loop
7239
7240 (define_expand "doloop_end"
7241   [(parallel [(set (pc) (if_then_else
7242                           (ne:SI (match_operand:SI 0 "" "")
7243                               (const_int 1))
7244                           (label_ref (match_operand 4 "" ""))
7245                           (pc)))
7246               (set (match_dup 0)
7247                    (plus:SI (match_dup 0) (const_int -1)))
7248               (clobber (reg:SI T_REG))])]
7249   "TARGET_SH2"
7250   "
7251 {
7252   if (GET_MODE (operands[0]) != SImode)
7253     FAIL;
7254 }
7255 ")
7256
7257 (define_insn_and_split "doloop_end_split"
7258   [(set (pc)
7259         (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7260                           (const_int 1))
7261                       (label_ref (match_operand 1 "" ""))
7262                       (pc)))
7263    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7264         (plus (match_dup 2) (const_int -1)))
7265    (clobber (reg:SI T_REG))]
7266   "TARGET_SH2"
7267   "#"
7268   ""
7269   [(parallel [(set (reg:SI T_REG)
7270                    (eq:SI (match_dup 2) (const_int 1)))
7271               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7272    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7273                            (label_ref (match_dup 1))
7274                            (pc)))]
7275 ""
7276    [(set_attr "type" "cbranch")])
7277
7278 \f
7279 ;; ------------------------------------------------------------------------
7280 ;; Jump and linkage insns
7281 ;; ------------------------------------------------------------------------
7282
7283 (define_insn "jump_compact"
7284   [(set (pc)
7285         (label_ref (match_operand 0 "" "")))]
7286   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7287   "*
7288 {
7289   /* The length is 16 if the delay slot is unfilled.  */
7290   if (get_attr_length(insn) > 4)
7291     return output_far_jump(insn, operands[0]);
7292   else
7293     return   \"bra      %l0%#\";
7294 }"
7295   [(set_attr "type" "jump")
7296    (set_attr "needs_delay_slot" "yes")])
7297
7298 ;; ??? It would be much saner to explicitly use the scratch register
7299 ;; in the jump insn, and have indirect_jump_scratch only set it,
7300 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7301 ;; from the target then, as it uses simplejump_p.
7302 ;;(define_insn "jump_compact_far"
7303 ;;  [(set (pc)
7304 ;;      (label_ref (match_operand 0 "" "")))
7305 ;;   (use (match_operand 1 "register_operand" "r")]
7306 ;;  "TARGET_SH1"
7307 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7308 ;;  [(set_attr "type" "jump")
7309 ;;   (set_attr "needs_delay_slot" "yes")])
7310
7311 (define_insn "jump_media"
7312   [(set (pc)
7313         (match_operand 0 "target_operand" "b"))]
7314   "TARGET_SHMEDIA"
7315   "blink        %0, r63%>"
7316   [(set_attr "type" "jump_media")])
7317
7318 (define_expand "jump"
7319   [(set (pc)
7320         (label_ref (match_operand 0 "" "")))]
7321   ""
7322   "
7323 {
7324   if (TARGET_SH1)
7325     emit_jump_insn (gen_jump_compact (operands[0]));
7326   else if (TARGET_SHMEDIA)
7327     {
7328       if (reload_in_progress || reload_completed)
7329         FAIL;
7330       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7331                                                          operands[0])));
7332     }
7333   DONE;
7334 }")
7335
7336 (define_insn "force_mode_for_call"
7337   [(use (reg:PSI FPSCR_REG))]
7338   "TARGET_SHCOMPACT"
7339   ""
7340   [(set_attr "length" "0")
7341    (set (attr "fp_mode")
7342         (if_then_else (eq_attr "fpu_single" "yes")
7343                       (const_string "single") (const_string "double")))])
7344
7345 (define_insn "calli"
7346   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7347          (match_operand 1 "" ""))
7348    (use (reg:PSI FPSCR_REG))
7349    (clobber (reg:SI PR_REG))]
7350   "TARGET_SH1"
7351   "*
7352    {
7353      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7354         return \"jsr/n\\t@%0\";
7355      else
7356         return \"jsr\\t@%0%#\";
7357    }"
7358
7359   [(set_attr "type" "call")
7360    (set (attr "fp_mode")
7361         (if_then_else (eq_attr "fpu_single" "yes")
7362                       (const_string "single") (const_string "double")))
7363    (set_attr "needs_delay_slot" "yes")
7364    (set_attr "fp_set" "unknown")])
7365
7366 ;; This is TBR relative jump instruction for SH2A architecture.
7367 ;; Its use is enabled assigning an attribute "function_vector"
7368 ;; and the vector number to a function during its declaration.
7369
7370 (define_insn "calli_tbr_rel"
7371   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7372          (match_operand 1 "" ""))
7373    (use (reg:PSI FPSCR_REG))
7374    (clobber (reg:SI PR_REG))]
7375   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7376   "*
7377 {
7378   unsigned HOST_WIDE_INT vect_num;
7379   vect_num = sh2a_get_function_vector_number (operands[0]);
7380   operands[2] = GEN_INT (vect_num * 4);
7381
7382   return \"jsr/n\\t@@(%O2,tbr)\";
7383 }"
7384   [(set_attr "type" "call")
7385    (set (attr "fp_mode")
7386         (if_then_else (eq_attr "fpu_single" "yes")
7387                       (const_string "single") (const_string "double")))
7388    (set_attr "needs_delay_slot" "no")
7389    (set_attr "fp_set" "unknown")])
7390
7391 ;; This is a pc-rel call, using bsrf, for use with PIC.
7392
7393 (define_insn "calli_pcrel"
7394   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7395          (match_operand 1 "" ""))
7396    (use (reg:PSI FPSCR_REG))
7397    (use (reg:SI PIC_REG))
7398    (use (match_operand 2 "" ""))
7399    (clobber (reg:SI PR_REG))]
7400   "TARGET_SH2"
7401   "bsrf %0\\n%O2:%#"
7402   [(set_attr "type" "call")
7403    (set (attr "fp_mode")
7404         (if_then_else (eq_attr "fpu_single" "yes")
7405                       (const_string "single") (const_string "double")))
7406    (set_attr "needs_delay_slot" "yes")
7407    (set_attr "fp_set" "unknown")])
7408
7409 (define_insn_and_split "call_pcrel"
7410   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7411          (match_operand 1 "" ""))
7412    (use (reg:PSI FPSCR_REG))
7413    (use (reg:SI PIC_REG))
7414    (clobber (reg:SI PR_REG))
7415    (clobber (match_scratch:SI 2 "=r"))]
7416   "TARGET_SH2"
7417   "#"
7418   "reload_completed"
7419   [(const_int 0)]
7420   "
7421 {
7422   rtx lab = PATTERN (gen_call_site ());
7423
7424   if (SYMBOL_REF_LOCAL_P (operands[0]))
7425     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7426   else
7427     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7428   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7429   DONE;
7430 }"
7431   [(set_attr "type" "call")
7432    (set (attr "fp_mode")
7433         (if_then_else (eq_attr "fpu_single" "yes")
7434                       (const_string "single") (const_string "double")))
7435    (set_attr "needs_delay_slot" "yes")
7436    (set_attr "fp_set" "unknown")])
7437
7438 (define_insn "call_compact"
7439   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7440          (match_operand 1 "" ""))
7441    (match_operand 2 "immediate_operand" "n")
7442    (use (reg:SI R0_REG))
7443    (use (reg:SI R1_REG))
7444    (use (reg:PSI FPSCR_REG))
7445    (clobber (reg:SI PR_REG))]
7446   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7447   "jsr  @%0%#"
7448   [(set_attr "type" "call")
7449    (set (attr "fp_mode")
7450         (if_then_else (eq_attr "fpu_single" "yes")
7451                       (const_string "single") (const_string "double")))
7452    (set_attr "needs_delay_slot" "yes")])
7453
7454 (define_insn "call_compact_rettramp"
7455   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7456          (match_operand 1 "" ""))
7457    (match_operand 2 "immediate_operand" "n")
7458    (use (reg:SI R0_REG))
7459    (use (reg:SI R1_REG))
7460    (use (reg:PSI FPSCR_REG))
7461    (clobber (reg:SI R10_REG))
7462    (clobber (reg:SI PR_REG))]
7463   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7464   "jsr  @%0%#"
7465   [(set_attr "type" "call")
7466    (set (attr "fp_mode")
7467         (if_then_else (eq_attr "fpu_single" "yes")
7468                       (const_string "single") (const_string "double")))
7469    (set_attr "needs_delay_slot" "yes")])
7470
7471 (define_insn "call_media"
7472   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7473          (match_operand 1 "" ""))
7474    (clobber (reg:DI PR_MEDIA_REG))]
7475   "TARGET_SHMEDIA"
7476   "blink        %0, r18"
7477   [(set_attr "type" "jump_media")])
7478
7479 (define_insn "call_valuei"
7480   [(set (match_operand 0 "" "=rf")
7481         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7482               (match_operand 2 "" "")))
7483    (use (reg:PSI FPSCR_REG))
7484    (clobber (reg:SI PR_REG))]
7485   "TARGET_SH1"
7486   "*
7487    {
7488      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7489         return \"jsr/n\\t@%1\";
7490      else
7491         return \"jsr\\t@%1%#\";
7492    }"
7493   [(set_attr "type" "call")
7494    (set (attr "fp_mode")
7495         (if_then_else (eq_attr "fpu_single" "yes")
7496                       (const_string "single") (const_string "double")))
7497    (set_attr "needs_delay_slot" "yes")
7498    (set_attr "fp_set" "unknown")])
7499
7500 ;; This is TBR relative jump instruction for SH2A architecture.
7501 ;; Its use is enabled assigning an attribute "function_vector"
7502 ;; and the vector number to a function during its declaration.
7503
7504 (define_insn "call_valuei_tbr_rel"
7505   [(set (match_operand 0 "" "=rf")
7506         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7507               (match_operand 2 "" "")))
7508    (use (reg:PSI FPSCR_REG))
7509    (clobber (reg:SI PR_REG))]
7510   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7511   "*
7512 {
7513   unsigned HOST_WIDE_INT vect_num;
7514   vect_num = sh2a_get_function_vector_number (operands[1]);
7515   operands[3] = GEN_INT (vect_num * 4);
7516
7517   return \"jsr/n\\t@@(%O3,tbr)\";
7518 }"
7519   [(set_attr "type" "call")
7520    (set (attr "fp_mode")
7521         (if_then_else (eq_attr "fpu_single" "yes")
7522                       (const_string "single") (const_string "double")))
7523    (set_attr "needs_delay_slot" "no")
7524    (set_attr "fp_set" "unknown")])
7525
7526 (define_insn "call_valuei_pcrel"
7527   [(set (match_operand 0 "" "=rf")
7528         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7529               (match_operand 2 "" "")))
7530    (use (reg:PSI FPSCR_REG))
7531    (use (reg:SI PIC_REG))
7532    (use (match_operand 3 "" ""))
7533    (clobber (reg:SI PR_REG))]
7534   "TARGET_SH2"
7535   "bsrf %1\\n%O3:%#"
7536   [(set_attr "type" "call")
7537    (set (attr "fp_mode")
7538         (if_then_else (eq_attr "fpu_single" "yes")
7539                       (const_string "single") (const_string "double")))
7540    (set_attr "needs_delay_slot" "yes")
7541    (set_attr "fp_set" "unknown")])
7542
7543 (define_insn_and_split "call_value_pcrel"
7544   [(set (match_operand 0 "" "=rf")
7545         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7546               (match_operand 2 "" "")))
7547    (use (reg:PSI FPSCR_REG))
7548    (use (reg:SI PIC_REG))
7549    (clobber (reg:SI PR_REG))
7550    (clobber (match_scratch:SI 3 "=r"))]
7551   "TARGET_SH2"
7552   "#"
7553   "reload_completed"
7554   [(const_int 0)]
7555   "
7556 {
7557   rtx lab = PATTERN (gen_call_site ());
7558
7559   if (SYMBOL_REF_LOCAL_P (operands[1]))
7560     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7561   else
7562     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7563   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7564                                          operands[2], copy_rtx (lab)));
7565   DONE;
7566 }"
7567   [(set_attr "type" "call")
7568    (set (attr "fp_mode")
7569         (if_then_else (eq_attr "fpu_single" "yes")
7570                       (const_string "single") (const_string "double")))
7571    (set_attr "needs_delay_slot" "yes")
7572    (set_attr "fp_set" "unknown")])
7573
7574 (define_insn "call_value_compact"
7575   [(set (match_operand 0 "" "=rf")
7576         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7577               (match_operand 2 "" "")))
7578    (match_operand 3 "immediate_operand" "n")
7579    (use (reg:SI R0_REG))
7580    (use (reg:SI R1_REG))
7581    (use (reg:PSI FPSCR_REG))
7582    (clobber (reg:SI PR_REG))]
7583   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7584   "jsr  @%1%#"
7585   [(set_attr "type" "call")
7586    (set (attr "fp_mode")
7587         (if_then_else (eq_attr "fpu_single" "yes")
7588                       (const_string "single") (const_string "double")))
7589    (set_attr "needs_delay_slot" "yes")])
7590
7591 (define_insn "call_value_compact_rettramp"
7592   [(set (match_operand 0 "" "=rf")
7593         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7594               (match_operand 2 "" "")))
7595    (match_operand 3 "immediate_operand" "n")
7596    (use (reg:SI R0_REG))
7597    (use (reg:SI R1_REG))
7598    (use (reg:PSI FPSCR_REG))
7599    (clobber (reg:SI R10_REG))
7600    (clobber (reg:SI PR_REG))]
7601   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7602   "jsr  @%1%#"
7603   [(set_attr "type" "call")
7604    (set (attr "fp_mode")
7605         (if_then_else (eq_attr "fpu_single" "yes")
7606                       (const_string "single") (const_string "double")))
7607    (set_attr "needs_delay_slot" "yes")])
7608
7609 (define_insn "call_value_media"
7610   [(set (match_operand 0 "" "=rf")
7611         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7612               (match_operand 2 "" "")))
7613    (clobber (reg:DI PR_MEDIA_REG))]
7614   "TARGET_SHMEDIA"
7615   "blink        %1, r18"
7616   [(set_attr "type" "jump_media")])
7617
7618 (define_expand "call"
7619   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7620                             (match_operand 1 "" ""))
7621               (match_operand 2 "" "")
7622               (use (reg:PSI FPSCR_REG))
7623               (clobber (reg:SI PR_REG))])]
7624   ""
7625   "
7626 {
7627   if (TARGET_SHMEDIA)
7628     {
7629       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7630       emit_call_insn (gen_call_media (operands[0], operands[1]));
7631       DONE;
7632     }
7633   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7634     {
7635       rtx cookie_rtx = operands[2];
7636       long cookie = INTVAL (cookie_rtx);
7637       rtx func = XEXP (operands[0], 0);
7638       rtx r0, r1;
7639
7640       if (flag_pic)
7641         {
7642           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7643             {
7644               rtx reg = gen_reg_rtx (Pmode);
7645
7646               emit_insn (gen_symGOTPLT2reg (reg, func));
7647               func = reg;
7648             }
7649           else
7650             func = legitimize_pic_address (func, Pmode, 0);
7651         }
7652
7653       r0 = gen_rtx_REG (SImode, R0_REG);
7654       r1 = gen_rtx_REG (SImode, R1_REG);
7655
7656       /* Since such a call function may use all call-clobbered
7657          registers, we force a mode switch earlier, so that we don't
7658          run out of registers when adjusting fpscr for the call.  */
7659       emit_insn (gen_force_mode_for_call ());
7660
7661       operands[0]
7662         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7663                            SFUNC_GOT);
7664       operands[0] = force_reg (SImode, operands[0]);
7665
7666       emit_move_insn (r0, func);
7667       emit_move_insn (r1, cookie_rtx);
7668
7669       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7670         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7671                                                    operands[2]));
7672       else
7673         emit_call_insn (gen_call_compact (operands[0], operands[1],
7674                                           operands[2]));
7675
7676       DONE;
7677     }
7678   else if (TARGET_SHCOMPACT && flag_pic
7679            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7680            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7681     {
7682       rtx reg = gen_reg_rtx (Pmode);
7683
7684       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7685       XEXP (operands[0], 0) = reg;
7686     }
7687   if (!flag_pic && TARGET_SH2A
7688       && MEM_P (operands[0])
7689       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7690     {
7691       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7692         {
7693           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7694                                              operands[1]));
7695           DONE;
7696         }
7697     }
7698   if (flag_pic && TARGET_SH2
7699       && MEM_P (operands[0])
7700       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7701     {
7702       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7703       DONE;
7704     }
7705   else
7706   {
7707     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7708     operands[1] = operands[2];
7709   }
7710
7711   emit_call_insn (gen_calli (operands[0], operands[1]));
7712   DONE;
7713 }")
7714
7715 (define_insn "call_pop_compact"
7716   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7717          (match_operand 1 "" ""))
7718    (match_operand 2 "immediate_operand" "n")
7719    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7720                                  (match_operand 3 "immediate_operand" "n")))
7721    (use (reg:SI R0_REG))
7722    (use (reg:SI R1_REG))
7723    (use (reg:PSI FPSCR_REG))
7724    (clobber (reg:SI PR_REG))]
7725   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7726   "jsr  @%0%#"
7727   [(set_attr "type" "call")
7728    (set (attr "fp_mode")
7729         (if_then_else (eq_attr "fpu_single" "yes")
7730                       (const_string "single") (const_string "double")))
7731    (set_attr "needs_delay_slot" "yes")])
7732
7733 (define_insn "call_pop_compact_rettramp"
7734   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7735          (match_operand 1 "" ""))
7736    (match_operand 2 "immediate_operand" "n")
7737    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7738                                  (match_operand 3 "immediate_operand" "n")))
7739    (use (reg:SI R0_REG))
7740    (use (reg:SI R1_REG))
7741    (use (reg:PSI FPSCR_REG))
7742    (clobber (reg:SI R10_REG))
7743    (clobber (reg:SI PR_REG))]
7744   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7745   "jsr  @%0%#"
7746   [(set_attr "type" "call")
7747    (set (attr "fp_mode")
7748         (if_then_else (eq_attr "fpu_single" "yes")
7749                       (const_string "single") (const_string "double")))
7750    (set_attr "needs_delay_slot" "yes")])
7751
7752 (define_expand "call_pop"
7753   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7754                     (match_operand 1 "" ""))
7755              (match_operand 2 "" "")
7756              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7757                                            (match_operand 3 "" "")))])]
7758   "TARGET_SHCOMPACT"
7759   "
7760 {
7761   rtx cookie_rtx;
7762   long cookie;
7763   rtx func;
7764   rtx r0, r1;
7765
7766   gcc_assert (operands[2] && INTVAL (operands[2]));
7767   cookie_rtx = operands[2];
7768   cookie = INTVAL (cookie_rtx);
7769   func = XEXP (operands[0], 0);
7770
7771   if (flag_pic)
7772     {
7773       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7774         {
7775           rtx reg = gen_reg_rtx (Pmode);
7776           emit_insn (gen_symGOTPLT2reg (reg, func));
7777           func = reg;
7778         }
7779       else
7780         func = legitimize_pic_address (func, Pmode, 0);
7781     }
7782
7783   r0 = gen_rtx_REG (SImode, R0_REG);
7784   r1 = gen_rtx_REG (SImode, R1_REG);
7785
7786   /* Since such a call function may use all call-clobbered
7787      registers, we force a mode switch earlier, so that we don't
7788      run out of registers when adjusting fpscr for the call.  */
7789   emit_insn (gen_force_mode_for_call ());
7790
7791   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7792                                  SFUNC_GOT);
7793   operands[0] = force_reg (SImode, operands[0]);
7794
7795   emit_move_insn (r0, func);
7796   emit_move_insn (r1, cookie_rtx);
7797
7798   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7799     emit_call_insn (gen_call_pop_compact_rettramp
7800                      (operands[0], operands[1], operands[2], operands[3]));
7801   else
7802     emit_call_insn (gen_call_pop_compact
7803                      (operands[0], operands[1], operands[2], operands[3]));
7804
7805   DONE;
7806 }")
7807
7808 (define_expand "call_value"
7809   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7810                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7811                                  (match_operand 2 "" "")))
7812               (match_operand 3 "" "")
7813               (use (reg:PSI FPSCR_REG))
7814               (clobber (reg:SI PR_REG))])]
7815   ""
7816   "
7817 {
7818   if (TARGET_SHMEDIA)
7819     {
7820       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7821       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7822                                             operands[2]));
7823       DONE;
7824     }
7825   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7826     {
7827       rtx cookie_rtx = operands[3];
7828       long cookie = INTVAL (cookie_rtx);
7829       rtx func = XEXP (operands[1], 0);
7830       rtx r0, r1;
7831
7832       if (flag_pic)
7833         {
7834           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7835             {
7836               rtx reg = gen_reg_rtx (Pmode);
7837
7838               emit_insn (gen_symGOTPLT2reg (reg, func));
7839               func = reg;
7840             }
7841           else
7842             func = legitimize_pic_address (func, Pmode, 0);
7843         }
7844
7845       r0 = gen_rtx_REG (SImode, R0_REG);
7846       r1 = gen_rtx_REG (SImode, R1_REG);
7847
7848       /* Since such a call function may use all call-clobbered
7849          registers, we force a mode switch earlier, so that we don't
7850          run out of registers when adjusting fpscr for the call.  */
7851       emit_insn (gen_force_mode_for_call ());
7852
7853       operands[1]
7854         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7855                            SFUNC_GOT);
7856       operands[1] = force_reg (SImode, operands[1]);
7857
7858       emit_move_insn (r0, func);
7859       emit_move_insn (r1, cookie_rtx);
7860
7861       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7862         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7863                                                          operands[1],
7864                                                          operands[2],
7865                                                          operands[3]));
7866       else
7867         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7868                                                 operands[2], operands[3]));
7869
7870       DONE;
7871     }
7872   else if (TARGET_SHCOMPACT && flag_pic
7873            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7874            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7875     {
7876       rtx reg = gen_reg_rtx (Pmode);
7877
7878       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7879       XEXP (operands[1], 0) = reg;
7880     }
7881   if (!flag_pic && TARGET_SH2A
7882       && MEM_P (operands[1])
7883       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7884     {
7885       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7886         {
7887           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7888                                  XEXP (operands[1], 0), operands[2]));
7889           DONE;
7890         }
7891     }
7892   if (flag_pic && TARGET_SH2
7893       && MEM_P (operands[1])
7894       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7895     {
7896       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7897                                             operands[2]));
7898       DONE;
7899     }
7900   else
7901     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7902
7903   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7904   DONE;
7905 }")
7906
7907 (define_insn "sibcalli"
7908   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7909          (match_operand 1 "" ""))
7910    (use (reg:PSI FPSCR_REG))
7911    (return)]
7912   "TARGET_SH1"
7913   "jmp  @%0%#"
7914   [(set_attr "needs_delay_slot" "yes")
7915    (set (attr "fp_mode")
7916         (if_then_else (eq_attr "fpu_single" "yes")
7917                       (const_string "single") (const_string "double")))
7918    (set_attr "type" "jump_ind")])
7919
7920 (define_insn "sibcalli_pcrel"
7921   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7922          (match_operand 1 "" ""))
7923    (use (match_operand 2 "" ""))
7924    (use (reg:PSI FPSCR_REG))
7925    (return)]
7926   "TARGET_SH2"
7927   "braf %0\\n%O2:%#"
7928   [(set_attr "needs_delay_slot" "yes")
7929    (set (attr "fp_mode")
7930         (if_then_else (eq_attr "fpu_single" "yes")
7931                       (const_string "single") (const_string "double")))
7932    (set_attr "type" "jump_ind")])
7933
7934 ;; This uses an unspec to describe that the symbol_ref is very close.
7935 (define_insn "sibcalli_thunk"
7936   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7937                              UNSPEC_THUNK))
7938          (match_operand 1 "" ""))
7939    (use (reg:PSI FPSCR_REG))
7940    (return)]
7941   "TARGET_SH1"
7942   "bra  %O0"
7943   [(set_attr "needs_delay_slot" "yes")
7944    (set (attr "fp_mode")
7945         (if_then_else (eq_attr "fpu_single" "yes")
7946                       (const_string "single") (const_string "double")))
7947    (set_attr "type" "jump")
7948    (set_attr "length" "2")])
7949
7950 (define_insn_and_split "sibcall_pcrel"
7951   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7952          (match_operand 1 "" ""))
7953    (use (reg:PSI FPSCR_REG))
7954    (clobber (match_scratch:SI 2 "=k"))
7955    (return)]
7956   "TARGET_SH2"
7957   "#"
7958   "reload_completed"
7959   [(const_int 0)]
7960   "
7961 {
7962   rtx lab = PATTERN (gen_call_site ());
7963   rtx call_insn;
7964
7965   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7966   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7967                                                   copy_rtx (lab)));
7968   SIBLING_CALL_P (call_insn) = 1;
7969   DONE;
7970 }"
7971   [(set_attr "needs_delay_slot" "yes")
7972    (set (attr "fp_mode")
7973         (if_then_else (eq_attr "fpu_single" "yes")
7974                       (const_string "single") (const_string "double")))
7975    (set_attr "type" "jump_ind")])
7976
7977 (define_insn "sibcall_compact"
7978   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7979          (match_operand 1 "" ""))
7980    (return)
7981    (use (match_operand:SI 2 "register_operand" "z,x"))
7982    (use (reg:SI R1_REG))
7983    (use (reg:PSI FPSCR_REG))
7984    ;; We want to make sure the `x' above will only match MACH_REG
7985    ;; because sibcall_epilogue may clobber MACL_REG.
7986    (clobber (reg:SI MACL_REG))]
7987   "TARGET_SHCOMPACT"
7988   "@
7989         jmp     @%0%#
7990         jmp     @%0\\n  sts     %2, r0"
7991   [(set_attr "needs_delay_slot" "yes,no")
7992    (set_attr "length" "2,4")
7993    (set (attr "fp_mode") (const_string "single"))
7994    (set_attr "type" "jump_ind")])
7995
7996 (define_insn "sibcall_media"
7997   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7998          (match_operand 1 "" ""))
7999    (use (reg:SI PR_MEDIA_REG))
8000    (return)]
8001   "TARGET_SHMEDIA"
8002   "blink        %0, r63"
8003   [(set_attr "type" "jump_media")])
8004
8005 (define_expand "sibcall"
8006   [(parallel
8007     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8008            (match_operand 1 "" ""))
8009      (match_operand 2 "" "")
8010      (use (reg:PSI FPSCR_REG))
8011      (return)])]
8012   ""
8013   "
8014 {
8015   if (TARGET_SHMEDIA)
8016     {
8017       operands[0] = shmedia_prepare_call_address (operands[0], 1);
8018       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8019       DONE;
8020     }
8021   else if (TARGET_SHCOMPACT && operands[2]
8022            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8023     {
8024       rtx cookie_rtx = operands[2];
8025       long cookie = INTVAL (cookie_rtx);
8026       rtx func = XEXP (operands[0], 0);
8027       rtx mach, r1;
8028
8029       if (flag_pic)
8030         {
8031           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8032             {
8033               rtx reg = gen_reg_rtx (Pmode);
8034
8035               emit_insn (gen_symGOT2reg (reg, func));
8036               func = reg;
8037             }
8038           else
8039             func = legitimize_pic_address (func, Pmode, 0);
8040         }
8041
8042       /* FIXME: if we could tell whether all argument registers are
8043          already taken, we could decide whether to force the use of
8044          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8045          simple way to tell.  We could use the CALL_COOKIE, but we
8046          can't currently tell a register used for regular argument
8047          passing from one that is unused.  If we leave it up to reload
8048          to decide which register to use, it seems to always choose
8049          R0_REG, which leaves no available registers in SIBCALL_REGS
8050          to hold the address of the trampoline.  */
8051       mach = gen_rtx_REG (SImode, MACH_REG);
8052       r1 = gen_rtx_REG (SImode, R1_REG);
8053
8054       /* Since such a call function may use all call-clobbered
8055          registers, we force a mode switch earlier, so that we don't
8056          run out of registers when adjusting fpscr for the call.  */
8057       emit_insn (gen_force_mode_for_call ());
8058
8059       operands[0]
8060         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8061                            SFUNC_GOT);
8062       operands[0] = force_reg (SImode, operands[0]);
8063
8064       /* We don't need a return trampoline, since the callee will
8065          return directly to the upper caller.  */
8066       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8067         {
8068           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8069           cookie_rtx = GEN_INT (cookie);
8070         }
8071
8072       emit_move_insn (mach, func);
8073       emit_move_insn (r1, cookie_rtx);
8074
8075       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8076       DONE;
8077     }
8078   else if (TARGET_SHCOMPACT && flag_pic
8079            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8080            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8081     {
8082       rtx reg = gen_reg_rtx (Pmode);
8083
8084       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8085       XEXP (operands[0], 0) = reg;
8086     }
8087   if (flag_pic && TARGET_SH2
8088       && MEM_P (operands[0])
8089       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8090       /* The PLT needs the PIC register, but the epilogue would have
8091          to restore it, so we can only use PC-relative PIC calls for
8092          static functions.  */
8093       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8094     {
8095       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8096       DONE;
8097     }
8098   else
8099     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8100
8101   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8102   DONE;
8103 }")
8104
8105 (define_insn "sibcall_valuei"
8106   [(set (match_operand 0 "" "=rf")
8107         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8108               (match_operand 2 "" "")))
8109    (use (reg:PSI FPSCR_REG))
8110    (return)]
8111   "TARGET_SH1"
8112   "jmp  @%1%#"
8113   [(set_attr "needs_delay_slot" "yes")
8114    (set (attr "fp_mode")
8115         (if_then_else (eq_attr "fpu_single" "yes")
8116                       (const_string "single") (const_string "double")))
8117    (set_attr "type" "jump_ind")])
8118
8119 (define_insn "sibcall_valuei_pcrel"
8120   [(set (match_operand 0 "" "=rf")
8121         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8122               (match_operand 2 "" "")))
8123    (use (match_operand 3 "" ""))
8124    (use (reg:PSI FPSCR_REG))
8125    (return)]
8126   "TARGET_SH2"
8127   "braf %1\\n%O3:%#"
8128   [(set_attr "needs_delay_slot" "yes")
8129    (set (attr "fp_mode")
8130         (if_then_else (eq_attr "fpu_single" "yes")
8131                       (const_string "single") (const_string "double")))
8132    (set_attr "type" "jump_ind")])
8133
8134 (define_insn_and_split "sibcall_value_pcrel"
8135   [(set (match_operand 0 "" "=rf")
8136         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8137               (match_operand 2 "" "")))
8138    (use (reg:PSI FPSCR_REG))
8139    (clobber (match_scratch:SI 3 "=k"))
8140    (return)]
8141   "TARGET_SH2"
8142   "#"
8143   "reload_completed"
8144   [(const_int 0)]
8145   "
8146 {
8147   rtx lab = PATTERN (gen_call_site ());
8148   rtx call_insn;
8149
8150   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8151   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8152                                                         operands[3],
8153                                                         operands[2],
8154                                                         copy_rtx (lab)));
8155   SIBLING_CALL_P (call_insn) = 1;
8156   DONE;
8157 }"
8158   [(set_attr "needs_delay_slot" "yes")
8159    (set (attr "fp_mode")
8160         (if_then_else (eq_attr "fpu_single" "yes")
8161                       (const_string "single") (const_string "double")))
8162    (set_attr "type" "jump_ind")])
8163
8164 (define_insn "sibcall_value_compact"
8165   [(set (match_operand 0 "" "=rf,rf")
8166         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8167               (match_operand 2 "" "")))
8168    (return)
8169    (use (match_operand:SI 3 "register_operand" "z,x"))
8170    (use (reg:SI R1_REG))
8171    (use (reg:PSI FPSCR_REG))
8172    ;; We want to make sure the `x' above will only match MACH_REG
8173    ;; because sibcall_epilogue may clobber MACL_REG.
8174    (clobber (reg:SI MACL_REG))]
8175   "TARGET_SHCOMPACT"
8176   "@
8177         jmp     @%1%#
8178         jmp     @%1\\n  sts     %3, r0"
8179   [(set_attr "needs_delay_slot" "yes,no")
8180    (set_attr "length" "2,4")
8181    (set (attr "fp_mode") (const_string "single"))
8182    (set_attr "type" "jump_ind")])
8183
8184 (define_insn "sibcall_value_media"
8185   [(set (match_operand 0 "" "=rf")
8186         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8187               (match_operand 2 "" "")))
8188    (use (reg:SI PR_MEDIA_REG))
8189    (return)]
8190   "TARGET_SHMEDIA"
8191   "blink        %1, r63"
8192   [(set_attr "type" "jump_media")])
8193
8194 (define_expand "sibcall_value"
8195   [(parallel
8196     [(set (match_operand 0 "arith_reg_operand" "")
8197           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8198                 (match_operand 2 "" "")))
8199      (match_operand 3 "" "")
8200      (use (reg:PSI FPSCR_REG))
8201      (return)])]
8202   ""
8203   "
8204 {
8205   if (TARGET_SHMEDIA)
8206     {
8207       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8208       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8209                                                operands[2]));
8210       DONE;
8211     }
8212   else if (TARGET_SHCOMPACT && operands[3]
8213            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8214     {
8215       rtx cookie_rtx = operands[3];
8216       long cookie = INTVAL (cookie_rtx);
8217       rtx func = XEXP (operands[1], 0);
8218       rtx mach, r1;
8219
8220       if (flag_pic)
8221         {
8222           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8223             {
8224               rtx reg = gen_reg_rtx (Pmode);
8225
8226               emit_insn (gen_symGOT2reg (reg, func));
8227               func = reg;
8228             }
8229           else
8230             func = legitimize_pic_address (func, Pmode, 0);
8231         }
8232
8233       /* FIXME: if we could tell whether all argument registers are
8234          already taken, we could decide whether to force the use of
8235          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8236          simple way to tell.  We could use the CALL_COOKIE, but we
8237          can't currently tell a register used for regular argument
8238          passing from one that is unused.  If we leave it up to reload
8239          to decide which register to use, it seems to always choose
8240          R0_REG, which leaves no available registers in SIBCALL_REGS
8241          to hold the address of the trampoline.  */
8242       mach = gen_rtx_REG (SImode, MACH_REG);
8243       r1 = gen_rtx_REG (SImode, R1_REG);
8244
8245       /* Since such a call function may use all call-clobbered
8246          registers, we force a mode switch earlier, so that we don't
8247          run out of registers when adjusting fpscr for the call.  */
8248       emit_insn (gen_force_mode_for_call ());
8249
8250       operands[1]
8251         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8252                            SFUNC_GOT);
8253       operands[1] = force_reg (SImode, operands[1]);
8254
8255       /* We don't need a return trampoline, since the callee will
8256          return directly to the upper caller.  */
8257       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8258         {
8259           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8260           cookie_rtx = GEN_INT (cookie);
8261         }
8262
8263       emit_move_insn (mach, func);
8264       emit_move_insn (r1, cookie_rtx);
8265
8266       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8267                                                  operands[2], mach));
8268       DONE;
8269     }
8270   else if (TARGET_SHCOMPACT && flag_pic
8271            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8272            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8273     {
8274       rtx reg = gen_reg_rtx (Pmode);
8275
8276       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8277       XEXP (operands[1], 0) = reg;
8278     }
8279   if (flag_pic && TARGET_SH2
8280       && MEM_P (operands[1])
8281       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8282       /* The PLT needs the PIC register, but the epilogue would have
8283          to restore it, so we can only use PC-relative PIC calls for
8284          static functions.  */
8285       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8286     {
8287       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8288                                                XEXP (operands[1], 0),
8289                                                operands[2]));
8290       DONE;
8291     }
8292   else
8293     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8294
8295   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8296   DONE;
8297 }")
8298
8299 (define_insn "call_value_pop_compact"
8300   [(set (match_operand 0 "" "=rf")
8301         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8302               (match_operand 2 "" "")))
8303    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8304                                  (match_operand 4 "immediate_operand" "n")))
8305    (match_operand 3 "immediate_operand" "n")
8306    (use (reg:SI R0_REG))
8307    (use (reg:SI R1_REG))
8308    (use (reg:PSI FPSCR_REG))
8309    (clobber (reg:SI PR_REG))]
8310   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8311   "jsr  @%1%#"
8312   [(set_attr "type" "call")
8313    (set (attr "fp_mode")
8314         (if_then_else (eq_attr "fpu_single" "yes")
8315                       (const_string "single") (const_string "double")))
8316    (set_attr "needs_delay_slot" "yes")])
8317
8318 (define_insn "call_value_pop_compact_rettramp"
8319   [(set (match_operand 0 "" "=rf")
8320         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8321               (match_operand 2 "" "")))
8322    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8323                                  (match_operand 4 "immediate_operand" "n")))
8324    (match_operand 3 "immediate_operand" "n")
8325    (use (reg:SI R0_REG))
8326    (use (reg:SI R1_REG))
8327    (use (reg:PSI FPSCR_REG))
8328    (clobber (reg:SI R10_REG))
8329    (clobber (reg:SI PR_REG))]
8330   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8331   "jsr  @%1%#"
8332   [(set_attr "type" "call")
8333    (set (attr "fp_mode")
8334         (if_then_else (eq_attr "fpu_single" "yes")
8335                       (const_string "single") (const_string "double")))
8336    (set_attr "needs_delay_slot" "yes")])
8337
8338 (define_expand "call_value_pop"
8339   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8340                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8341                                  (match_operand 2 "" "")))
8342               (match_operand 3 "" "")
8343               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8344                                             (match_operand 4 "" "")))])]
8345   "TARGET_SHCOMPACT"
8346   "
8347 {
8348   rtx cookie_rtx;
8349   long cookie;
8350   rtx func;
8351   rtx r0, r1;
8352
8353   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8354   cookie_rtx = operands[3];
8355   cookie = INTVAL (cookie_rtx);
8356   func = XEXP (operands[1], 0);
8357
8358   if (flag_pic)
8359     {
8360       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8361         {
8362           rtx reg = gen_reg_rtx (Pmode);
8363
8364           emit_insn (gen_symGOTPLT2reg (reg, func));
8365           func = reg;
8366         }
8367       else
8368         func = legitimize_pic_address (func, Pmode, 0);
8369     }
8370
8371   r0 = gen_rtx_REG (SImode, R0_REG);
8372   r1 = gen_rtx_REG (SImode, R1_REG);
8373
8374   /* Since such a call function may use all call-clobbered
8375      registers, we force a mode switch earlier, so that we don't
8376      run out of registers when adjusting fpscr for the call.  */
8377   emit_insn (gen_force_mode_for_call ());
8378
8379   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8380                                  SFUNC_GOT);
8381   operands[1] = force_reg (SImode, operands[1]);
8382
8383   emit_move_insn (r0, func);
8384   emit_move_insn (r1, cookie_rtx);
8385
8386   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8387     emit_call_insn (gen_call_value_pop_compact_rettramp
8388                         (operands[0], operands[1], operands[2],
8389                          operands[3], operands[4]));
8390   else
8391     emit_call_insn (gen_call_value_pop_compact
8392                         (operands[0], operands[1], operands[2],
8393                          operands[3], operands[4]));
8394
8395   DONE;
8396 }")
8397
8398 (define_expand "sibcall_epilogue"
8399   [(return)]
8400   ""
8401   "
8402 {
8403   sh_expand_epilogue (1);
8404   if (TARGET_SHCOMPACT)
8405     {
8406       rtx insn, set;
8407
8408       /* If epilogue clobbers r0, preserve it in macl.  */
8409       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8410         if ((set = single_set (insn))
8411             && REG_P (SET_DEST (set))
8412             && REGNO (SET_DEST (set)) == R0_REG)
8413           {
8414             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8415             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8416
8417             /* We can't tell at this point whether the sibcall is a
8418                sibcall_compact and, if it is, whether it uses r0 or
8419                mach as operand 2, so let the instructions that
8420                preserve r0 be optimized away if r0 turns out to be
8421                dead.  */
8422             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8423             emit_move_insn (r0, tmp);
8424             break;
8425           }
8426     }
8427   DONE;
8428 }")
8429
8430 (define_insn "indirect_jump_compact"
8431   [(set (pc)
8432         (match_operand:SI 0 "arith_reg_operand" "r"))]
8433   "TARGET_SH1"
8434   "jmp  @%0%#"
8435   [(set_attr "needs_delay_slot" "yes")
8436    (set_attr "type" "jump_ind")])
8437
8438 (define_expand "indirect_jump"
8439   [(set (pc)
8440         (match_operand 0 "register_operand" ""))]
8441   ""
8442   "
8443 {
8444   if (GET_MODE (operands[0]) != Pmode)
8445     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8446 }")
8447
8448 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8449 ;; which can be present in structured code from indirect jumps which can not
8450 ;; be present in structured code.  This allows -fprofile-arcs to work.
8451
8452 ;; For SH1 processors.
8453 (define_insn "casesi_jump_1"
8454   [(set (pc)
8455         (match_operand:SI 0 "register_operand" "r"))
8456    (use (label_ref (match_operand 1 "" "")))]
8457   "TARGET_SH1"
8458   "jmp  @%0%#"
8459   [(set_attr "needs_delay_slot" "yes")
8460    (set_attr "type" "jump_ind")])
8461
8462 ;; For all later processors.
8463 (define_insn "casesi_jump_2"
8464   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8465                       (label_ref (match_operand 1 "" ""))))
8466    (use (label_ref (match_operand 2 "" "")))]
8467   "TARGET_SH2
8468    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8469   "braf %0%#"
8470   [(set_attr "needs_delay_slot" "yes")
8471    (set_attr "type" "jump_ind")])
8472
8473 (define_insn "casesi_jump_media"
8474   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8475    (use (label_ref (match_operand 1 "" "")))]
8476   "TARGET_SHMEDIA"
8477   "blink        %0, r63"
8478   [(set_attr "type" "jump_media")])
8479
8480 ;; Call subroutine returning any type.
8481 ;; ??? This probably doesn't work.
8482
8483 (define_expand "untyped_call"
8484   [(parallel [(call (match_operand 0 "" "")
8485                     (const_int 0))
8486               (match_operand 1 "" "")
8487               (match_operand 2 "" "")])]
8488   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8489   "
8490 {
8491   int i;
8492
8493   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8494
8495   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8496     {
8497       rtx set = XVECEXP (operands[2], 0, i);
8498       emit_move_insn (SET_DEST (set), SET_SRC (set));
8499     }
8500
8501   /* The optimizer does not know that the call sets the function value
8502      registers we stored in the result block.  We avoid problems by
8503      claiming that all hard registers are used and clobbered at this
8504      point.  */
8505   emit_insn (gen_blockage ());
8506
8507   DONE;
8508 }")
8509 \f
8510 ;; ------------------------------------------------------------------------
8511 ;; Misc insns
8512 ;; ------------------------------------------------------------------------
8513
8514 (define_insn "dect"
8515   [(set (reg:SI T_REG)
8516         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8517    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8518         (plus:SI (match_dup 1) (const_int -1)))]
8519   "TARGET_SH2"
8520   "dt   %0"
8521   [(set_attr "type" "arith")])
8522
8523 (define_insn "nop"
8524   [(const_int 0)]
8525   ""
8526   "nop")
8527
8528 ;; Load address of a label. This is only generated by the casesi expand,
8529 ;; and by machine_dependent_reorg (fixing up fp moves).
8530 ;; This must use unspec, because this only works for labels that are
8531 ;; within range,
8532
8533 (define_insn "mova"
8534   [(set (reg:SI R0_REG)
8535         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8536   "TARGET_SH1"
8537   "mova %O0,r0"
8538   [(set_attr "in_delay_slot" "no")
8539    (set_attr "type" "arith")])
8540
8541 ;; machine_dependent_reorg will make this a `mova'.
8542 (define_insn "mova_const"
8543   [(set (reg:SI R0_REG)
8544         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8545   "TARGET_SH1"
8546   "#"
8547   [(set_attr "in_delay_slot" "no")
8548    (set_attr "type" "arith")])
8549
8550 (define_expand "GOTaddr2picreg"
8551   [(set (reg:SI R0_REG)
8552         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8553                    UNSPEC_MOVA))
8554    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8555    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8556   "" "
8557 {
8558   if (TARGET_VXWORKS_RTP)
8559     {
8560       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8561       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8562       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8563       DONE;
8564     }
8565
8566   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8567   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8568
8569   if (TARGET_SHMEDIA)
8570     {
8571       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8572       rtx pic = operands[0];
8573       rtx lab = PATTERN (gen_call_site ());
8574       rtx insn, equiv;
8575
8576       equiv = operands[1];
8577       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8578                                     UNSPEC_PCREL_SYMOFF);
8579       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8580
8581       if (Pmode == SImode)
8582         {
8583           emit_insn (gen_movsi_const (pic, operands[1]));
8584           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8585         }
8586       else
8587         {
8588           emit_insn (gen_movdi_const (pic, operands[1]));
8589           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8590         }
8591
8592       insn = emit_move_insn (operands[0], tr);
8593
8594       set_unique_reg_note (insn, REG_EQUAL, equiv);
8595
8596       DONE;
8597     }
8598 }
8599 ")
8600
8601 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8602 ;; PIC register.
8603
8604 (define_expand "vxworks_picreg"
8605   [(set (reg:SI PIC_REG)
8606         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8607    (set (reg:SI R0_REG)
8608         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8609    (set (reg:SI PIC_REG)
8610         (mem:SI (reg:SI PIC_REG)))
8611    (set (reg:SI PIC_REG)
8612         (mem:SI (plus:SI (reg:SI PIC_REG)
8613                          (reg:SI R0_REG))))]
8614   "TARGET_VXWORKS_RTP")
8615
8616 (define_insn "*ptb"
8617   [(set (match_operand 0 "target_reg_operand" "=b")
8618         (const (unspec [(match_operand 1 "" "Csy")]
8619                              UNSPEC_DATALABEL)))]
8620   "TARGET_SHMEDIA && flag_pic
8621    && satisfies_constraint_Csy (operands[1])"
8622   "ptb/u        datalabel %1, %0"
8623   [(set_attr "type" "ptabs_media")
8624    (set_attr "length" "*")])
8625
8626 (define_insn "ptrel_si"
8627   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8628         (plus:SI (match_operand:SI 1 "register_operand" "r")
8629               (pc)))
8630    (match_operand:SI 2 "" "")]
8631   "TARGET_SHMEDIA"
8632   "%O2: ptrel/u %1, %0"
8633   [(set_attr "type" "ptabs_media")])
8634
8635 (define_insn "ptrel_di"
8636   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8637         (plus:DI (match_operand:DI 1 "register_operand" "r")
8638               (pc)))
8639    (match_operand:DI 2 "" "")]
8640   "TARGET_SHMEDIA"
8641   "%O2: ptrel/u %1, %0"
8642   [(set_attr "type" "ptabs_media")])
8643
8644 (define_expand "builtin_setjmp_receiver"
8645   [(match_operand 0 "" "")]
8646   "flag_pic"
8647   "
8648 {
8649   emit_insn (gen_GOTaddr2picreg ());
8650   DONE;
8651 }")
8652
8653 (define_expand "call_site"
8654   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8655   "TARGET_SH1"
8656   "
8657 {
8658   static HOST_WIDE_INT i = 0;
8659   operands[0] = GEN_INT (i);
8660   i++;
8661 }")
8662
8663 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8664 ;; in symGOT_load expand.
8665
8666 (define_insn_and_split "chk_guard_add"
8667   [(set (match_operand:SI 0 "register_operand" "=&r")
8668         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8669                     (reg:SI PIC_REG)]
8670                    UNSPEC_CHKADD))]
8671   "TARGET_SH1"
8672   "#"
8673   "TARGET_SH1 && reload_completed"
8674   [(set (match_dup 0) (reg:SI PIC_REG))
8675    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8676   ""
8677   [(set_attr "type" "arith")])
8678
8679 (define_expand "sym_label2reg"
8680   [(set (match_operand:SI 0 "" "")
8681         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8682                               (const (plus:SI (match_operand:SI 2 "" "")
8683                                               (const_int 2)))]
8684                              UNSPEC_SYMOFF)))]
8685   "TARGET_SH1" "")
8686
8687 (define_expand "symGOT_load"
8688   [(set (match_dup 2) (match_operand 1 "" ""))
8689    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8690    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8691   ""
8692   "
8693 {
8694   rtx mem;
8695
8696   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8697   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8698
8699   if (TARGET_SHMEDIA)
8700     {
8701       rtx reg = operands[2];
8702
8703       if (Pmode == DImode)
8704         {      
8705           if (flag_pic > 1)
8706             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8707           else
8708             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8709         }
8710       else
8711         {
8712           if (flag_pic > 1)
8713             emit_insn (gen_movsi_const (reg, operands[1]));
8714           else
8715             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8716         }
8717     }
8718   else
8719     emit_move_insn (operands[2], operands[1]);
8720
8721   /* When stack protector inserts codes after the result is set to
8722      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8723      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8724      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8725      matter because this is a rare situation.  */
8726   if (!TARGET_SHMEDIA
8727       && flag_stack_protect
8728       && GET_CODE (operands[1]) == CONST
8729       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8730       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8731       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8732                  \"__stack_chk_guard\") == 0)
8733     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8734   else
8735     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8736                                                gen_rtx_REG (Pmode, PIC_REG)));
8737
8738   /* N.B. This is not constant for a GOTPLT relocation.  */
8739   mem = gen_rtx_MEM (Pmode, operands[3]);
8740   MEM_NOTRAP_P (mem) = 1;
8741   /* ??? Should we have a special alias set for the GOT?  */
8742   emit_move_insn (operands[0], mem);
8743
8744   DONE;
8745 }")
8746
8747 (define_expand "sym2GOT"
8748   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8749   ""
8750   "")
8751
8752 (define_expand "symGOT2reg"
8753   [(match_operand 0 "" "") (match_operand 1 "" "")]
8754   ""
8755   "
8756 {
8757   rtx gotsym, insn;
8758
8759   gotsym = gen_sym2GOT (operands[1]);
8760   PUT_MODE (gotsym, Pmode);
8761   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8762
8763   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8764
8765   DONE;
8766 }")
8767
8768 (define_expand "symGOTPLT2reg"
8769   [(match_operand 0 "" "") (match_operand 1 "" "")]
8770   ""
8771   "
8772 {
8773   rtx pltsym = gen_rtx_CONST (Pmode,
8774                               gen_rtx_UNSPEC (Pmode,
8775                                               gen_rtvec (1, operands[1]),
8776                                               UNSPEC_GOTPLT));
8777   emit_insn (gen_symGOT_load (operands[0], pltsym));
8778   DONE;
8779 }")
8780
8781 (define_expand "sym2GOTOFF"
8782   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8783   ""
8784   "")
8785
8786 (define_expand "symGOTOFF2reg"
8787   [(match_operand 0 "" "") (match_operand 1 "" "")]
8788   ""
8789   "
8790 {
8791   rtx gotoffsym, insn;
8792   rtx t = (!can_create_pseudo_p ()
8793            ? operands[0]
8794            : gen_reg_rtx (GET_MODE (operands[0])));
8795
8796   gotoffsym = gen_sym2GOTOFF (operands[1]);
8797   PUT_MODE (gotoffsym, Pmode);
8798   emit_move_insn (t, gotoffsym);
8799   insn = emit_move_insn (operands[0],
8800                          gen_rtx_PLUS (Pmode, t,
8801                                        gen_rtx_REG (Pmode, PIC_REG)));
8802
8803   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8804
8805   DONE;
8806 }")
8807
8808 (define_expand "symPLT_label2reg"
8809   [(set (match_operand:SI 0 "" "")
8810         (const:SI
8811          (unspec:SI
8812           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8813            (const:SI (plus:SI (match_operand:SI 2 "" "")
8814                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8815    ;; Even though the PIC register is not really used by the call
8816    ;; sequence in which this is expanded, the PLT code assumes the PIC
8817    ;; register is set, so we must not skip its initialization.  Since
8818    ;; we only use this expand as part of calling sequences, and never
8819    ;; to take the address of a function, this is the best point to
8820    ;; insert the (use).  Using the PLT to take the address of a
8821    ;; function would be wrong, not only because the PLT entry could
8822    ;; then be called from a function that doesn't initialize the PIC
8823    ;; register to the proper GOT, but also because pointers to the
8824    ;; same function might not compare equal, should they be set by
8825    ;; different shared libraries.
8826    (use (reg:SI PIC_REG))]
8827   "TARGET_SH1"
8828   "")
8829
8830 (define_expand "sym2PIC"
8831   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8832   ""
8833   "")
8834
8835 ;; TLS code generation.
8836 ;; ??? this should be a define_insn_and_split
8837 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8838 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8839 ;; for details.
8840
8841 (define_insn "tls_global_dynamic"
8842   [(set (match_operand:SI 0 "register_operand" "=&z")
8843         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8844                                   UNSPEC_TLSGD))
8845               (const_int 0)))
8846    (use (reg:PSI FPSCR_REG))
8847    (use (reg:SI PIC_REG))
8848    (clobber (reg:SI PR_REG))
8849    (clobber (scratch:SI))]
8850   "TARGET_SH1"
8851   "*
8852 {
8853   return \"\\
8854 mov.l\\t1f,r4\\n\\
8855 \\tmova\\t2f,r0\\n\\
8856 \\tmov.l\\t2f,r1\\n\\
8857 \\tadd\\tr0,r1\\n\\
8858 \\tjsr\\t@r1\\n\\
8859 \\tadd\\tr12,r4\\n\\
8860 \\tbra\\t3f\\n\\
8861 \\tnop\\n\\
8862 \\t.align\\t2\\n\\
8863 1:\\t.long\\t%a1@TLSGD\\n\\
8864 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8865 3:\";
8866 }"
8867   [(set_attr "type" "tls_load")
8868    (set_attr "length" "26")])
8869
8870 (define_insn "tls_local_dynamic"
8871   [(set (match_operand:SI 0 "register_operand" "=&z")
8872         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8873                                   UNSPEC_TLSLDM))
8874               (const_int 0)))
8875    (use (reg:PSI FPSCR_REG))
8876    (use (reg:SI PIC_REG))
8877    (clobber (reg:SI PR_REG))
8878    (clobber (scratch:SI))]
8879   "TARGET_SH1"
8880   "*
8881 {
8882   return \"\\
8883 mov.l\\t1f,r4\\n\\
8884 \\tmova\\t2f,r0\\n\\
8885 \\tmov.l\\t2f,r1\\n\\
8886 \\tadd\\tr0,r1\\n\\
8887 \\tjsr\\t@r1\\n\\
8888 \\tadd\\tr12,r4\\n\\
8889 \\tbra\\t3f\\n\\
8890 \\tnop\\n\\
8891 \\t.align\\t2\\n\\
8892 1:\\t.long\\t%a1@TLSLDM\\n\\
8893 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8894 3:\";
8895 }"
8896   [(set_attr "type" "tls_load")
8897    (set_attr "length" "26")])
8898
8899 (define_expand "sym2DTPOFF"
8900   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8901   ""
8902   "")
8903
8904 (define_expand "symDTPOFF2reg"
8905   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8906   ""
8907   "
8908 {
8909   rtx dtpoffsym;
8910   rtx t = (!can_create_pseudo_p ()
8911            ? operands[0]
8912            : gen_reg_rtx (GET_MODE (operands[0])));
8913
8914   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8915   PUT_MODE (dtpoffsym, Pmode);
8916   emit_move_insn (t, dtpoffsym);
8917   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8918   DONE;
8919 }")
8920
8921 (define_expand "sym2GOTTPOFF"
8922   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8923   ""
8924   "")
8925
8926 (define_insn "tls_initial_exec"
8927   [(set (match_operand:SI 0 "register_operand" "=&r")
8928         (unspec:SI [(match_operand:SI 1 "" "")]
8929                     UNSPEC_TLSIE))
8930    (use (reg:SI GBR_REG))
8931    (use (reg:SI PIC_REG))
8932    (clobber (reg:SI R0_REG))]
8933   ""
8934   "*
8935 {
8936   return \"\\
8937 mov.l\\t1f,r0\\n\\
8938 \\tstc\\tgbr,%0\\n\\
8939 \\tmov.l\\t@(r0,r12),r0\\n\\
8940 \\tbra\\t2f\\n\\
8941 \\tadd\\tr0,%0\\n\\
8942 \\t.align\\t2\\n\\
8943 1:\\t.long\\t%a1\\n\\
8944 2:\";
8945 }"
8946   [(set_attr "type" "tls_load")
8947    (set_attr "length" "16")])
8948
8949 (define_expand "sym2TPOFF"
8950   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8951   ""
8952   "")
8953
8954 (define_expand "symTPOFF2reg"
8955   [(match_operand 0 "" "") (match_operand 1 "" "")]
8956   ""
8957   "
8958 {
8959   rtx tpoffsym;
8960
8961   tpoffsym = gen_sym2TPOFF (operands[1]);
8962   PUT_MODE (tpoffsym, Pmode);
8963   emit_move_insn (operands[0], tpoffsym);
8964   DONE;
8965 }")
8966
8967 (define_insn "load_gbr"
8968   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8969    (use (reg:SI GBR_REG))]
8970   ""
8971   "stc  gbr,%0"
8972   [(set_attr "type" "tls_load")])
8973
8974 ;; case instruction for switch statements.
8975
8976 ;; Operand 0 is index
8977 ;; operand 1 is the minimum bound
8978 ;; operand 2 is the maximum bound - minimum bound + 1
8979 ;; operand 3 is CODE_LABEL for the table;
8980 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8981
8982 (define_expand "casesi"
8983   [(match_operand:SI 0 "arith_reg_operand" "")
8984    (match_operand:SI 1 "arith_reg_operand" "")
8985    (match_operand:SI 2 "arith_reg_operand" "")
8986    (match_operand 3 "" "") (match_operand 4 "" "")]
8987   ""
8988   "
8989 {
8990   rtx reg = gen_reg_rtx (SImode);
8991   rtx reg2 = gen_reg_rtx (SImode);
8992   if (TARGET_SHMEDIA)
8993     {
8994       rtx reg = gen_reg_rtx (DImode);
8995       rtx reg2 = gen_reg_rtx (DImode);
8996       rtx reg3 = gen_reg_rtx (Pmode);
8997       rtx reg4 = gen_reg_rtx (Pmode);
8998       rtx reg5 = gen_reg_rtx (Pmode);
8999       rtx load, test;
9000
9001       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9002       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9003       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9004
9005       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
9006       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
9007       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9008       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
9009       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
9010       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9011       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9012                                                (Pmode, operands[3])));
9013       /* Messy: can we subreg to clean this up? */
9014       if (Pmode == DImode)
9015         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9016       else
9017         load = gen_casesi_load_media (reg4,
9018                                       gen_rtx_SUBREG (DImode, reg3, 0),
9019                                       reg2, operands[3]);
9020       PUT_MODE (SET_SRC (load), Pmode);
9021       emit_insn (load);
9022       /* ??? The following add could be eliminated if we used ptrel.  */
9023       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9024       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9025       emit_barrier ();
9026       DONE;
9027     }
9028   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9029   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9030   /* If optimizing, casesi_worker depends on the mode of the instruction
9031      before label it 'uses' - operands[3].  */
9032   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9033                            reg));
9034   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9035   if (TARGET_SH2)
9036     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9037   else
9038     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9039   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9040      operands[3], but to lab.  We will fix this up in
9041      machine_dependent_reorg.  */
9042   emit_barrier ();
9043   DONE;
9044 }")
9045
9046 (define_expand "casesi_0"
9047   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9048    (set (match_dup 4) (minus:SI (match_dup 4)
9049                                 (match_operand:SI 1 "arith_operand" "")))
9050    (set (reg:SI T_REG)
9051         (gtu:SI (match_dup 4)
9052                 (match_operand:SI 2 "arith_reg_operand" "")))
9053    (set (pc)
9054         (if_then_else (ne (reg:SI T_REG)
9055                           (const_int 0))
9056                       (label_ref (match_operand 3 "" ""))
9057                       (pc)))]
9058   "TARGET_SH1"
9059   "")
9060
9061 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9062 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9063 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9064
9065 (define_insn "casesi_worker_0"
9066   [(set (match_operand:SI 0 "register_operand" "=r,r")
9067         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9068                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9069    (clobber (match_scratch:SI 3 "=X,1"))
9070    (clobber (match_scratch:SI 4 "=&z,z"))]
9071   "TARGET_SH1"
9072   "#")
9073
9074 (define_split
9075   [(set (match_operand:SI 0 "register_operand" "")
9076         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9077                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9078    (clobber (match_scratch:SI 3 ""))
9079    (clobber (match_scratch:SI 4 ""))]
9080   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9081   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9082    (parallel [(set (match_dup 0)
9083               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9084                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9085               (clobber (match_dup 3))])
9086    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9087   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9088
9089 (define_split
9090   [(set (match_operand:SI 0 "register_operand" "")
9091         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9092                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9093    (clobber (match_scratch:SI 3 ""))
9094    (clobber (match_scratch:SI 4 ""))]
9095   "TARGET_SH2 && reload_completed"
9096   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9097    (parallel [(set (match_dup 0)
9098               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9099                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9100               (clobber (match_dup 3))])]
9101   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9102
9103 (define_insn "casesi_worker_1"
9104   [(set (match_operand:SI 0 "register_operand" "=r,r")
9105         (unspec:SI [(reg:SI R0_REG)
9106                     (match_operand:SI 1 "register_operand" "0,r")
9107                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9108    (clobber (match_scratch:SI 3 "=X,1"))]
9109   "TARGET_SH1"
9110   "*
9111 {
9112   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9113
9114   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9115
9116   switch (GET_MODE (diff_vec))
9117     {
9118     case SImode:
9119       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9120     case HImode:
9121       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9122     case QImode:
9123       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9124         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9125       return \"mov.b    @(r0,%1),%0\";
9126     default:
9127       gcc_unreachable ();
9128     }
9129 }"
9130   [(set_attr "length" "4")])
9131
9132 (define_insn "casesi_worker_2"
9133   [(set (match_operand:SI 0 "register_operand" "=r,r")
9134         (unspec:SI [(reg:SI R0_REG)
9135                     (match_operand:SI 1 "register_operand" "0,r")
9136                     (label_ref (match_operand 2 "" ""))
9137                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9138    (clobber (match_operand:SI 4 "" "=X,1"))]
9139   "TARGET_SH2 && reload_completed && flag_pic"
9140   "*
9141 {
9142   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9143   const char *load;
9144
9145   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9146
9147   switch (GET_MODE (diff_vec))
9148     {
9149     case SImode:
9150       output_asm_insn (\"shll2    %1\", operands);
9151       load = \"mov.l    @(r0,%1),%0\"; break;
9152     case HImode:
9153       output_asm_insn (\"add    %1,%1\", operands);
9154       load = \"mov.w    @(r0,%1),%0\"; break;
9155     case QImode:
9156       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9157         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9158       else
9159         load = \"mov.b  @(r0,%1),%0\";
9160       break;
9161     default:
9162       gcc_unreachable ();
9163     }
9164   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9165   return load;
9166 }"
9167   [(set_attr "length" "8")])
9168
9169 (define_insn "casesi_shift_media"
9170   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9171         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9172                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9173                     UNSPEC_CASESI)))]
9174   "TARGET_SHMEDIA"
9175   "*
9176 {
9177   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9178
9179   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9180
9181   switch (GET_MODE (diff_vec))
9182     {
9183     case SImode:
9184       return \"shlli    %1, 2, %0\";
9185     case HImode:
9186       return \"shlli    %1, 1, %0\";
9187     case QImode:
9188       if (rtx_equal_p (operands[0], operands[1]))
9189         return \"\";
9190       return \"add      %1, r63, %0\";
9191     default:
9192       gcc_unreachable ();
9193     }
9194 }"
9195   [(set_attr "type" "arith_media")])
9196
9197 (define_insn "casesi_load_media"
9198   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9199         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9200                          (match_operand:DI 2 "arith_reg_operand" "r")
9201                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9202   "TARGET_SHMEDIA"
9203   "*
9204 {
9205   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9206
9207   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9208
9209   switch (GET_MODE (diff_vec))
9210     {
9211     case SImode:
9212       return \"ldx.l    %1, %2, %0\";
9213     case HImode:
9214 #if 0
9215       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9216         return \"ldx.uw %1, %2, %0\";
9217 #endif
9218       return \"ldx.w    %1, %2, %0\";
9219     case QImode:
9220       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9221         return \"ldx.ub %1, %2, %0\";
9222       return \"ldx.b    %1, %2, %0\";
9223     default:
9224       gcc_unreachable ();
9225     }
9226 }"
9227   [(set_attr "type" "load_media")])
9228
9229 (define_expand "return"
9230   [(return)]
9231   "reload_completed && ! sh_need_epilogue ()"
9232   "
9233 {
9234   if (TARGET_SHMEDIA)
9235     {
9236       emit_jump_insn (gen_return_media ());
9237       DONE;
9238     }
9239
9240   if (TARGET_SHCOMPACT
9241       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9242     {
9243       emit_jump_insn (gen_shcompact_return_tramp ());
9244       DONE;
9245     }
9246 }")
9247
9248 (define_insn "*return_i"
9249   [(return)]
9250   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9251                     && (crtl->args.info.call_cookie
9252                         & CALL_COOKIE_RET_TRAMP (1)))
9253    && reload_completed
9254    && lookup_attribute (\"trap_exit\",
9255                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9256   "*
9257   {
9258     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9259                         && !current_function_interrupt)
9260        return \"rts/n\";
9261     else
9262        return \"%@      %#\";
9263   }"
9264   [(set_attr "type" "return")
9265    (set_attr "needs_delay_slot" "yes")])
9266
9267 ;; trapa has no delay slot.
9268 (define_insn "*return_trapa"
9269   [(return)]
9270   "TARGET_SH1 && !TARGET_SHCOMPACT
9271    && reload_completed"
9272   "%@"
9273   [(set_attr "type" "return")])
9274
9275 (define_expand "shcompact_return_tramp"
9276   [(return)]
9277   "TARGET_SHCOMPACT
9278    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9279   "
9280 {
9281   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9282
9283   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9284   emit_jump_insn (gen_shcompact_return_tramp_i ());
9285   DONE;
9286 }")
9287
9288 (define_insn "shcompact_return_tramp_i"
9289   [(parallel [(return) (use (reg:SI R0_REG))])]
9290   "TARGET_SHCOMPACT
9291    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9292   "jmp  @r0%#"
9293   [(set_attr "type" "jump_ind")
9294    (set_attr "needs_delay_slot" "yes")])
9295
9296 (define_insn "return_media_i"
9297   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9298   "TARGET_SHMEDIA && reload_completed"
9299   "blink        %0, r63"
9300   [(set_attr "type" "jump_media")])
9301
9302 (define_insn "return_media_rte"
9303   [(return)]
9304   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9305   "rte"
9306   [(set_attr "type" "jump_media")])
9307
9308 (define_expand "return_media"
9309   [(return)]
9310   "TARGET_SHMEDIA && reload_completed"
9311   "
9312 {
9313   int tr_regno = sh_media_register_for_return ();
9314   rtx tr;
9315
9316   if (current_function_interrupt)
9317     {
9318       emit_jump_insn (gen_return_media_rte ());
9319       DONE;
9320     }
9321   if (tr_regno < 0)
9322     {
9323       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9324
9325       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9326       tr_regno = TR0_REG;
9327       tr = gen_rtx_REG (Pmode, tr_regno);
9328       emit_move_insn (tr, r18);
9329     }
9330   else
9331     tr = gen_rtx_REG (Pmode, tr_regno);
9332
9333   emit_jump_insn (gen_return_media_i (tr));
9334   DONE;
9335 }")
9336
9337 (define_insn "shcompact_preserve_incoming_args"
9338   [(set (match_operand:SI 0 "register_operand" "+r")
9339         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9340   "TARGET_SHCOMPACT"
9341   ""
9342   [(set_attr "length" "0")])
9343
9344 (define_insn "shcompact_incoming_args"
9345   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9346    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9347    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9348    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9349    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9350    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9351    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9352    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9353    (set (mem:BLK (reg:SI MACL_REG))
9354         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9355    (use (reg:SI R0_REG))
9356    (clobber (reg:SI R0_REG))
9357    (clobber (reg:SI MACL_REG))
9358    (clobber (reg:SI MACH_REG))
9359    (clobber (reg:SI PR_REG))]
9360   "TARGET_SHCOMPACT"
9361   "jsr  @r0%#"
9362   [(set_attr "needs_delay_slot" "yes")])
9363
9364 (define_insn "shmedia_save_restore_regs_compact"
9365   [(set (reg:SI SP_REG)
9366         (plus:SI (reg:SI SP_REG)
9367                  (match_operand:SI 0 "immediate_operand" "i")))
9368    (use (reg:SI R0_REG))
9369    (clobber (reg:SI PR_REG))]
9370   "TARGET_SHCOMPACT
9371    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9372        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9373   "jsr @r0%#"
9374   [(set_attr "needs_delay_slot" "yes")])
9375
9376 (define_expand "prologue"
9377   [(const_int 0)]
9378   ""
9379   "sh_expand_prologue (); DONE;")
9380
9381 (define_expand "epilogue"
9382   [(return)]
9383   ""
9384   "
9385 {
9386   sh_expand_epilogue (0);
9387   emit_jump_insn (gen_return ());
9388   DONE;
9389 }")
9390
9391 (define_expand "eh_return"
9392   [(use (match_operand 0 "register_operand" ""))]
9393   ""
9394 {
9395   rtx ra = operands[0];
9396
9397   if (TARGET_SHMEDIA64)
9398     emit_insn (gen_eh_set_ra_di (ra));
9399   else
9400     emit_insn (gen_eh_set_ra_si (ra));
9401
9402   DONE;
9403 })
9404
9405 ;; Clobber the return address on the stack.  We can't expand this
9406 ;; until we know where it will be put in the stack frame.
9407
9408 (define_insn "eh_set_ra_si"
9409   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9410       UNSPECV_EH_RETURN)
9411    (clobber (match_scratch:SI 1 "=&r"))]
9412   "! TARGET_SHMEDIA64"
9413   "#")
9414
9415 (define_insn "eh_set_ra_di"
9416   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9417       UNSPECV_EH_RETURN)
9418    (clobber (match_scratch:DI 1 "=&r"))]
9419   "TARGET_SHMEDIA64"
9420   "#")
9421
9422 (define_split
9423   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9424       UNSPECV_EH_RETURN)
9425    (clobber (match_scratch 1 ""))]
9426   "reload_completed"
9427   [(const_int 0)]
9428   "
9429 {
9430   sh_set_return_address (operands[0], operands[1]);
9431   DONE;
9432 }")
9433
9434 (define_insn "blockage"
9435   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9436   ""
9437   ""
9438   [(set_attr "length" "0")])
9439 \f
9440 ;; Define movml instructions for SH2A target.  Currently they are
9441 ;; used to push and pop all banked registers only.
9442
9443 (define_insn "movml_push_banked"
9444   [(set (match_operand:SI 0 "register_operand" "=r")
9445           (plus (match_dup 0) (const_int -32)))
9446    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9447    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9448    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9449    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9450    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9451    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9452    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9453    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9454   "TARGET_SH2A && REGNO (operands[0]) == 15"
9455   "movml.l\tr7,@-r15"
9456   [(set_attr "in_delay_slot" "no")])
9457
9458 (define_insn "movml_pop_banked"
9459   [(set (match_operand:SI 0 "register_operand" "=r")
9460           (plus (match_dup 0) (const_int 32)))
9461    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9462    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9463    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9464    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9465    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9466    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9467    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9468    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9469   "TARGET_SH2A && REGNO (operands[0]) == 15"
9470   "movml.l\t@r15+,r7"
9471   [(set_attr "in_delay_slot" "no")])
9472 \f
9473 ;; ------------------------------------------------------------------------
9474 ;; Scc instructions
9475 ;; ------------------------------------------------------------------------
9476
9477 (define_insn "movt"
9478   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9479         (eq:SI (reg:SI T_REG) (const_int 1)))]
9480   "TARGET_SH1"
9481   "movt %0"
9482   [(set_attr "type" "arith")])
9483
9484 (define_expand "cstore4_media"
9485   [(set (match_operand:SI 0 "register_operand" "=r")
9486         (match_operator:SI 1 "sh_float_comparison_operator"
9487          [(match_operand 2 "logical_operand" "")
9488           (match_operand 3 "cmp_operand" "")]))]
9489   "TARGET_SHMEDIA"
9490   "
9491 {
9492   enum machine_mode mode = GET_MODE (operands[2]);
9493   enum rtx_code code = GET_CODE (operands[1]);
9494   bool invert, swap;
9495   if (mode == VOIDmode)
9496     mode = GET_MODE (operands[3]);
9497   if (operands[2] == const0_rtx)
9498     {
9499       if (code == EQ || code == NE)
9500         operands[2] = operands[3], operands[3] = const0_rtx;
9501     }
9502   else
9503     operands[2] = force_reg (mode, operands[2]);
9504   if (operands[3] != const0_rtx)
9505     operands[3] = force_reg (mode, operands[3]);
9506
9507   switch (code)
9508     {
9509     case GEU:
9510     case GE:
9511       swap = invert = !FLOAT_MODE_P (mode);
9512       break;
9513
9514     case LEU:
9515     case LE:
9516       swap = FLOAT_MODE_P (mode), invert = !swap;
9517       break;
9518
9519     case LTU:
9520     case LT:
9521       swap = true, invert = false;
9522       break;
9523
9524     case GTU:
9525     case GT:
9526     case EQ:
9527     case UNORDERED:
9528       swap = invert = false;
9529       break;
9530
9531     case NE:
9532       swap = invert = true;
9533       break;
9534
9535     default:
9536       gcc_unreachable ();
9537   }
9538
9539   if (swap)
9540     {
9541       rtx tem = operands[2];
9542       operands[2] = operands[3];
9543       operands[3] = tem;
9544       code = swap_condition (code);
9545     }
9546
9547   if (invert)
9548     {
9549       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9550       code = reverse_condition (code);
9551       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9552       emit_insn (gen_cstore4_media (tem, operands[1],
9553                                     operands[2], operands[3]));
9554       code = EQ;
9555       operands[2] = tem;
9556       operands[3] = const0_rtx;
9557     }
9558
9559   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9560 }")
9561
9562 (define_expand "cstoresi4"
9563   [(set (match_operand:SI 0 "register_operand" "=r")
9564         (match_operator:SI 1 "comparison_operator"
9565          [(match_operand:SI 2 "cmpsi_operand" "")
9566           (match_operand:SI 3 "arith_operand" "")]))]
9567   "TARGET_SH1 || TARGET_SHMEDIA"
9568   "if (TARGET_SHMEDIA)
9569     {
9570       emit_insn (gen_cstore4_media (operands[0], operands[1],
9571                                     operands[2], operands[3]));
9572       DONE;
9573     }
9574
9575    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9576        && sh_expand_t_scc (operands))
9577      DONE;
9578
9579    if (! currently_expanding_to_rtl)
9580      FAIL;
9581    
9582    sh_emit_compare_and_set (operands, SImode);
9583    DONE;
9584 ")
9585
9586 (define_expand "cstoredi4"
9587   [(set (match_operand:SI 0 "register_operand" "=r")
9588         (match_operator:SI 1 "comparison_operator"
9589          [(match_operand:DI 2 "arith_operand" "")
9590           (match_operand:DI 3 "arith_operand" "")]))]
9591   "TARGET_SH2 || TARGET_SHMEDIA"
9592   "if (TARGET_SHMEDIA)
9593     {
9594       emit_insn (gen_cstore4_media (operands[0], operands[1],
9595                                     operands[2], operands[3]));
9596       DONE;
9597     }
9598
9599    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9600        && sh_expand_t_scc (operands))
9601      DONE;
9602
9603    if (! currently_expanding_to_rtl)
9604      FAIL;
9605    
9606    sh_emit_compare_and_set (operands, DImode);
9607    DONE;
9608 ")
9609
9610
9611
9612 ;; sne moves the complement of the T reg to DEST like this:
9613 ;;      cmp/eq ...
9614 ;;      mov    #-1,temp
9615 ;;      negc   temp,dest
9616 ;;   This is better than xoring compare result with 1 because it does
9617 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9618 ;;   loop.
9619
9620 (define_expand "movnegt"
9621   [(set (match_dup 1) (const_int -1))
9622    (parallel [(set (match_operand:SI 0 "" "")
9623                    (neg:SI (plus:SI (reg:SI T_REG)
9624                                     (match_dup 1))))
9625               (set (reg:SI T_REG)
9626                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9627                           (const_int 0)))])]
9628   ""
9629   "
9630 {
9631   operands[1] = gen_reg_rtx (SImode);
9632 }")
9633
9634
9635 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9636 ;; This prevents a regression that occurred when we switched from xor to
9637 ;; mov/neg for sne.
9638
9639 (define_split
9640   [(set (match_operand:SI 0 "arith_reg_dest" "")
9641         (plus:SI (reg:SI T_REG)
9642                  (const_int -1)))]
9643   "TARGET_SH1"
9644   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9645    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9646   "")
9647
9648 (define_expand "cstoresf4"
9649   [(set (match_operand:SI 0 "register_operand" "=r")
9650         (match_operator:SI 1 "sh_float_comparison_operator"
9651          [(match_operand:SF 2 "arith_operand" "")
9652           (match_operand:SF 3 "arith_operand" "")]))]
9653   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9654   "if (TARGET_SHMEDIA)
9655      {
9656        emit_insn (gen_cstore4_media (operands[0], operands[1],
9657                                      operands[2], operands[3]));
9658        DONE;
9659      }
9660
9661    if (! currently_expanding_to_rtl)
9662      FAIL;
9663    
9664    sh_emit_compare_and_set (operands, SFmode);
9665    DONE;
9666 ")
9667
9668 (define_expand "cstoredf4"
9669   [(set (match_operand:SI 0 "register_operand" "=r")
9670         (match_operator:SI 1 "sh_float_comparison_operator"
9671          [(match_operand:DF 2 "arith_operand" "")
9672           (match_operand:DF 3 "arith_operand" "")]))]
9673   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9674   "if (TARGET_SHMEDIA)
9675      {
9676        emit_insn (gen_cstore4_media (operands[0], operands[1],
9677                                      operands[2], operands[3]));
9678        DONE;
9679      }
9680
9681     if (! currently_expanding_to_rtl)
9682       FAIL;
9683    
9684    sh_emit_compare_and_set (operands, DFmode);
9685    DONE;
9686 ")
9687
9688
9689 ;; -------------------------------------------------------------------------
9690 ;; Instructions to cope with inline literal tables
9691 ;; -------------------------------------------------------------------------
9692
9693 ; 2 byte integer in line
9694
9695 (define_insn "consttable_2"
9696  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9697                     (match_operand 1 "" "")]
9698                    UNSPECV_CONST2)]
9699  ""
9700  "*
9701 {
9702   if (operands[1] != const0_rtx)
9703     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9704   return \"\";
9705 }"
9706  [(set_attr "length" "2")
9707  (set_attr "in_delay_slot" "no")])
9708
9709 ; 4 byte integer in line
9710
9711 (define_insn "consttable_4"
9712  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9713                     (match_operand 1 "" "")]
9714                    UNSPECV_CONST4)]
9715  ""
9716  "*
9717 {
9718   if (operands[1] != const0_rtx)
9719     {
9720       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9721       mark_symbol_refs_as_used (operands[0]);
9722     }
9723   return \"\";
9724 }"
9725  [(set_attr "length" "4")
9726   (set_attr "in_delay_slot" "no")])
9727
9728 ; 8 byte integer in line
9729
9730 (define_insn "consttable_8"
9731  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9732                     (match_operand 1 "" "")]
9733                    UNSPECV_CONST8)]
9734  ""
9735  "*
9736 {
9737   if (operands[1] != const0_rtx)
9738     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9739   return \"\";
9740 }"
9741  [(set_attr "length" "8")
9742   (set_attr "in_delay_slot" "no")])
9743
9744 ; 4 byte floating point
9745
9746 (define_insn "consttable_sf"
9747  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9748                     (match_operand 1 "" "")]
9749                    UNSPECV_CONST4)]
9750  ""
9751  "*
9752 {
9753   if (operands[1] != const0_rtx)
9754     {
9755       REAL_VALUE_TYPE d;
9756       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9757       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9758     }
9759   return \"\";
9760 }"
9761  [(set_attr "length" "4")
9762   (set_attr "in_delay_slot" "no")])
9763
9764 ; 8 byte floating point
9765
9766 (define_insn "consttable_df"
9767  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9768                     (match_operand 1 "" "")]
9769                    UNSPECV_CONST8)]
9770  ""
9771  "*
9772 {
9773   if (operands[1] != const0_rtx)
9774     {
9775       REAL_VALUE_TYPE d;
9776       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9777       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9778     }
9779   return \"\";
9780 }"
9781  [(set_attr "length" "8")
9782   (set_attr "in_delay_slot" "no")])
9783
9784 ;; Alignment is needed for some constant tables; it may also be added for
9785 ;; Instructions at the start of loops, or after unconditional branches.
9786 ;; ??? We would get more accurate lengths if we did instruction
9787 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9788 ;; here is too conservative.
9789
9790 ; align to a two byte boundary
9791
9792 (define_expand "align_2"
9793  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9794  ""
9795  "")
9796
9797 ; align to a four byte boundary
9798 ;; align_4 and align_log are instructions for the starts of loops, or
9799 ;; after unconditional branches, which may take up extra room.
9800
9801 (define_expand "align_4"
9802  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9803  ""
9804  "")
9805
9806 ; align to a cache line boundary
9807
9808 (define_insn "align_log"
9809  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9810  ""
9811  ""
9812  [(set_attr "length" "0")
9813   (set_attr "in_delay_slot" "no")])
9814
9815 ; emitted at the end of the literal table, used to emit the
9816 ; 32bit branch labels if needed.
9817
9818 (define_insn "consttable_end"
9819   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9820   ""
9821   "* return output_jump_label_table ();"
9822   [(set_attr "in_delay_slot" "no")])
9823
9824 ; emitted at the end of the window in the literal table.
9825
9826 (define_insn "consttable_window_end"
9827   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9828   ""
9829   ""
9830   [(set_attr "length" "0")
9831    (set_attr "in_delay_slot" "no")])
9832
9833 ;; -------------------------------------------------------------------------
9834 ;; Misc
9835 ;; -------------------------------------------------------------------------
9836
9837 ;; String/block move insn.
9838
9839 (define_expand "movmemsi"
9840   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9841                    (mem:BLK (match_operand:BLK 1 "" "")))
9842               (use (match_operand:SI 2 "nonmemory_operand" ""))
9843               (use (match_operand:SI 3 "immediate_operand" ""))
9844               (clobber (reg:SI PR_REG))
9845               (clobber (reg:SI R4_REG))
9846               (clobber (reg:SI R5_REG))
9847               (clobber (reg:SI R0_REG))])]
9848   "TARGET_SH1 && ! TARGET_SH5"
9849   "
9850 {
9851   if(expand_block_move (operands))
9852      DONE;
9853   else FAIL;
9854 }")
9855
9856 (define_insn "block_move_real"
9857   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9858                    (mem:BLK (reg:SI R5_REG)))
9859               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9860               (clobber (reg:SI PR_REG))
9861               (clobber (reg:SI R0_REG))])]
9862   "TARGET_SH1 && ! TARGET_HARD_SH4"
9863   "jsr  @%0%#"
9864   [(set_attr "type" "sfunc")
9865    (set_attr "needs_delay_slot" "yes")])
9866
9867 (define_insn "block_lump_real"
9868   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9869                    (mem:BLK (reg:SI R5_REG)))
9870               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9871               (use (reg:SI R6_REG))
9872               (clobber (reg:SI PR_REG))
9873               (clobber (reg:SI T_REG))
9874               (clobber (reg:SI R4_REG))
9875               (clobber (reg:SI R5_REG))
9876               (clobber (reg:SI R6_REG))
9877               (clobber (reg:SI R0_REG))])]
9878   "TARGET_SH1 && ! TARGET_HARD_SH4"
9879   "jsr  @%0%#"
9880   [(set_attr "type" "sfunc")
9881    (set_attr "needs_delay_slot" "yes")])
9882
9883 (define_insn "block_move_real_i4"
9884   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9885                    (mem:BLK (reg:SI R5_REG)))
9886               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9887               (clobber (reg:SI PR_REG))
9888               (clobber (reg:SI R0_REG))
9889               (clobber (reg:SI R1_REG))
9890               (clobber (reg:SI R2_REG))])]
9891   "TARGET_HARD_SH4"
9892   "jsr  @%0%#"
9893   [(set_attr "type" "sfunc")
9894    (set_attr "needs_delay_slot" "yes")])
9895
9896 (define_insn "block_lump_real_i4"
9897   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9898                    (mem:BLK (reg:SI R5_REG)))
9899               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9900               (use (reg:SI R6_REG))
9901               (clobber (reg:SI PR_REG))
9902               (clobber (reg:SI T_REG))
9903               (clobber (reg:SI R4_REG))
9904               (clobber (reg:SI R5_REG))
9905               (clobber (reg:SI R6_REG))
9906               (clobber (reg:SI R0_REG))
9907               (clobber (reg:SI R1_REG))
9908               (clobber (reg:SI R2_REG))
9909               (clobber (reg:SI R3_REG))])]
9910   "TARGET_HARD_SH4"
9911   "jsr  @%0%#"
9912   [(set_attr "type" "sfunc")
9913    (set_attr "needs_delay_slot" "yes")])
9914 \f
9915 ;; -------------------------------------------------------------------------
9916 ;; Floating point instructions.
9917 ;; -------------------------------------------------------------------------
9918
9919 ;; ??? All patterns should have a type attribute.
9920
9921 (define_expand "movpsi"
9922   [(set (match_operand:PSI 0 "register_operand" "")
9923         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9924   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9925   "")
9926
9927 ;; The c / m alternative is a fake to guide reload to load directly into
9928 ;; fpscr, since reload doesn't know how to use post-increment.
9929 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9930 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9931 ;; predicate after reload.
9932 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9933 ;; like a mac -> gpr move.
9934 (define_insn "fpu_switch"
9935   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9936         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9937   "TARGET_SH2E
9938    && (! reload_completed
9939        || true_regnum (operands[0]) != FPSCR_REG
9940        || !MEM_P (operands[1])
9941        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9942   "@
9943         ! precision stays the same
9944         lds.l   %1,fpscr
9945         mov.l   %1,%0
9946         #
9947         lds     %1,fpscr
9948         mov     %1,%0
9949         mov.l   %1,%0
9950         sts     fpscr,%0
9951         sts.l   fpscr,%0"
9952   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9953    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9954
9955 (define_peephole2
9956   [(set (reg:PSI FPSCR_REG)
9957         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9958   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9959   [(const_int 0)]
9960 {
9961   rtx fpscr, mem, new_insn;
9962
9963   fpscr = SET_DEST (PATTERN (curr_insn));
9964   mem = SET_SRC (PATTERN (curr_insn));
9965   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9966
9967   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9968   add_reg_note (new_insn, REG_INC, operands[0]);
9969   DONE;
9970 })
9971
9972 (define_split
9973   [(set (reg:PSI FPSCR_REG)
9974         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9975   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9976    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9977   [(const_int 0)]
9978 {
9979   rtx fpscr, mem, new_insn;
9980
9981   fpscr = SET_DEST (PATTERN (curr_insn));
9982   mem = SET_SRC (PATTERN (curr_insn));
9983   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9984
9985   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9986   add_reg_note (new_insn, REG_INC, operands[0]);
9987
9988   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9989     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9990   DONE;
9991 })
9992
9993 ;; ??? This uses the fp unit, but has no type indicating that.
9994 ;; If we did that, this would either give a bogus latency or introduce
9995 ;; a bogus FIFO constraint.
9996 ;; Since this insn is currently only used for prologues/epilogues,
9997 ;; it is probably best to claim no function unit, which matches the
9998 ;; current setting.
9999 (define_insn "toggle_sz"
10000   [(set (reg:PSI FPSCR_REG)
10001         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10002   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10003   "fschg"
10004   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10005
10006 ;; There's no way we can use it today, since optimize mode switching
10007 ;; doesn't enable us to know from which mode we're switching to the
10008 ;; mode it requests, to tell whether we can use a relative mode switch
10009 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10010 ;; memory).
10011 (define_insn "toggle_pr"
10012   [(set (reg:PSI FPSCR_REG)
10013         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10014   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10015   "fpchg"
10016   [(set_attr "type" "fpscr_toggle")])
10017
10018 (define_expand "addsf3"
10019   [(set (match_operand:SF 0 "arith_reg_operand" "")
10020         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10021                  (match_operand:SF 2 "arith_reg_operand" "")))]
10022   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10023   "
10024 {
10025   if (TARGET_SH2E)
10026     {
10027       expand_sf_binop (&gen_addsf3_i, operands);
10028       DONE;
10029     }
10030 }")
10031
10032 (define_insn "*addsf3_media"
10033   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10034         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10035                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10036   "TARGET_SHMEDIA_FPU"
10037   "fadd.s       %1, %2, %0"
10038   [(set_attr "type" "fparith_media")])
10039
10040 (define_insn_and_split "unary_sf_op"
10041   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10042         (vec_select:V2SF
10043          (vec_concat:V2SF
10044           (vec_select:SF
10045            (match_dup 0)
10046            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10047           (match_operator:SF 2 "unary_float_operator"
10048             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10049                             (parallel [(match_operand 4
10050                                         "const_int_operand" "n")]))]))
10051          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10052   "TARGET_SHMEDIA_FPU"
10053   "#"
10054   "TARGET_SHMEDIA_FPU && reload_completed"
10055   [(set (match_dup 5) (match_dup 6))]
10056   "
10057 {
10058   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10059   rtx op1 = gen_rtx_REG (SFmode,
10060                          (true_regnum (operands[1])
10061                           + (INTVAL (operands[4]) ^ endian)));
10062
10063   operands[7] = gen_rtx_REG (SFmode,
10064                              (true_regnum (operands[0])
10065                               + (INTVAL (operands[3]) ^ endian)));
10066   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10067 }"
10068   [(set_attr "type" "fparith_media")])
10069
10070 (define_insn_and_split "binary_sf_op0"
10071   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10072         (vec_concat:V2SF
10073           (match_operator:SF 3 "binary_float_operator"
10074             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10075                             (parallel [(const_int 0)]))
10076              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10077                             (parallel [(const_int 0)]))])
10078           (vec_select:SF
10079            (match_dup 0)
10080            (parallel [(const_int 1)]))))]
10081   "TARGET_SHMEDIA_FPU"
10082   "#"
10083   "&& reload_completed"
10084   [(set (match_dup 4) (match_dup 5))]
10085   "
10086 {
10087   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10088   rtx op1 = gen_rtx_REG (SFmode,
10089                          true_regnum (operands[1]) + endian);
10090   rtx op2 = gen_rtx_REG (SFmode,
10091                          true_regnum (operands[2]) + endian);
10092
10093   operands[4] = gen_rtx_REG (SFmode,
10094                              true_regnum (operands[0]) + endian);
10095   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10096 }"
10097   [(set_attr "type" "fparith_media")])
10098
10099 (define_insn_and_split "binary_sf_op1"
10100   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10101         (vec_concat:V2SF
10102           (vec_select:SF
10103            (match_dup 0)
10104            (parallel [(const_int 0)]))
10105           (match_operator:SF 3 "binary_float_operator"
10106             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10107                             (parallel [(const_int 1)]))
10108              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10109                             (parallel [(const_int 1)]))])))]
10110   "TARGET_SHMEDIA_FPU"
10111   "#"
10112   "&& reload_completed"
10113   [(set (match_dup 4) (match_dup 5))]
10114   "
10115 {
10116   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10117   rtx op1 = gen_rtx_REG (SFmode,
10118                          true_regnum (operands[1]) + (1 ^ endian));
10119   rtx op2 = gen_rtx_REG (SFmode,
10120                          true_regnum (operands[2]) + (1 ^ endian));
10121
10122   operands[4] = gen_rtx_REG (SFmode,
10123                              true_regnum (operands[0]) + (1 ^ endian));
10124   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10125 }"
10126   [(set_attr "type" "fparith_media")])
10127
10128 (define_insn "addsf3_i"
10129   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10130         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10131                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10132    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10133   "TARGET_SH2E"
10134   "fadd %2,%0"
10135   [(set_attr "type" "fp")
10136    (set_attr "fp_mode" "single")])
10137
10138 (define_expand "subsf3"
10139   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10140         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10141                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10142   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10143   "
10144 {
10145   if (TARGET_SH2E)
10146     {
10147       expand_sf_binop (&gen_subsf3_i, operands);
10148       DONE;
10149     }
10150 }")
10151
10152 (define_insn "*subsf3_media"
10153   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10154         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10155                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10156   "TARGET_SHMEDIA_FPU"
10157   "fsub.s       %1, %2, %0"
10158   [(set_attr "type" "fparith_media")])
10159
10160 (define_insn "subsf3_i"
10161   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10162         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10163                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10164    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10165   "TARGET_SH2E"
10166   "fsub %2,%0"
10167   [(set_attr "type" "fp")
10168    (set_attr "fp_mode" "single")])
10169
10170 (define_expand "mulsf3"
10171   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10172         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10173                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10174   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10175   "")
10176
10177 (define_insn "*mulsf3_media"
10178   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10179         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10180                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10181   "TARGET_SHMEDIA_FPU"
10182   "fmul.s       %1, %2, %0"
10183   [(set_attr "type" "fparith_media")])
10184
10185 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10186 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10187 ;; we start out with a mulsf pattern that does not depend on fpscr.
10188 ;; This is split after combine to introduce the dependency, in order to
10189 ;; get mode switching and scheduling right.
10190 (define_insn_and_split "mulsf3_ie"
10191   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10192         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10193                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10194   "TARGET_SH2E"
10195   "fmul %2,%0"
10196   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10197   [(const_int 0)]
10198   "
10199 {
10200   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10201              get_fpscr_rtx ()));
10202   DONE;
10203 }"
10204   [(set_attr "type" "fp")])
10205
10206 (define_insn "mulsf3_i4"
10207   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10208         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10209                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10210    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10211   "TARGET_SH2E"
10212   "fmul %2,%0"
10213   [(set_attr "type" "fp")
10214    (set_attr "fp_mode" "single")])
10215
10216 (define_insn "mac_media"
10217   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10218         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10219                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10220                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10221   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10222   "fmac.s %1, %2, %0"
10223   [(set_attr "type" "fparith_media")])
10224
10225 (define_insn "*macsf3"
10226   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10227         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10228                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10229                  (match_operand:SF 3 "arith_reg_operand" "0")))
10230    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10231   "TARGET_SH2E && TARGET_FMAC"
10232   "fmac fr0,%2,%0"
10233   [(set_attr "type" "fp")
10234    (set_attr "fp_mode" "single")])
10235
10236 (define_expand "divsf3"
10237   [(set (match_operand:SF 0 "arith_reg_operand" "")
10238         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10239                 (match_operand:SF 2 "arith_reg_operand" "")))]
10240   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10241   "
10242 {
10243   if (TARGET_SH2E)
10244     {
10245       expand_sf_binop (&gen_divsf3_i, operands);
10246       DONE;
10247     }
10248 }")
10249
10250 (define_insn "*divsf3_media"
10251   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10252         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10253                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10254   "TARGET_SHMEDIA_FPU"
10255   "fdiv.s       %1, %2, %0"
10256   [(set_attr "type" "fdiv_media")])
10257
10258 (define_insn "divsf3_i"
10259   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10260         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10261                  (match_operand:SF 2 "arith_reg_operand" "f")))
10262    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10263   "TARGET_SH2E"
10264   "fdiv %2,%0"
10265   [(set_attr "type" "fdiv")
10266    (set_attr "fp_mode" "single")])
10267
10268 (define_insn "floatdisf2"
10269   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10270         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10271   "TARGET_SHMEDIA_FPU"
10272   "float.qs %1, %0"
10273   [(set_attr "type" "fpconv_media")])
10274
10275 (define_expand "floatsisf2"
10276   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10277         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10278   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10279   "
10280 {
10281   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10282     {
10283       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10284       DONE;
10285     }
10286 }")
10287
10288 (define_insn "*floatsisf2_media"
10289   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10290         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10291   "TARGET_SHMEDIA_FPU"
10292   "float.ls     %1, %0"
10293   [(set_attr "type" "fpconv_media")])
10294
10295 (define_insn "floatsisf2_i4"
10296   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10297         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10298    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10299   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10300   "float        %1,%0"
10301   [(set_attr "type" "fp")
10302    (set_attr "fp_mode" "single")])
10303
10304 (define_insn "*floatsisf2_ie"
10305   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10307   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10308   "float        %1,%0"
10309   [(set_attr "type" "fp")])
10310
10311 (define_insn "fix_truncsfdi2"
10312   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10313         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10314   "TARGET_SHMEDIA_FPU"
10315   "ftrc.sq %1, %0"
10316   [(set_attr "type" "fpconv_media")])
10317
10318 (define_expand "fix_truncsfsi2"
10319   [(set (match_operand:SI 0 "fpul_operand" "=y")
10320         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10321   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10322   "
10323 {
10324   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10325     {
10326       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10327       DONE;
10328     }
10329 }")
10330
10331 (define_insn "*fix_truncsfsi2_media"
10332   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10333         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10334   "TARGET_SHMEDIA_FPU"
10335   "ftrc.sl      %1, %0"
10336   [(set_attr "type" "fpconv_media")])
10337
10338 (define_insn "fix_truncsfsi2_i4"
10339   [(set (match_operand:SI 0 "fpul_operand" "=y")
10340         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10341    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10342   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10343   "ftrc %1,%0"
10344   [(set_attr "type" "ftrc_s")
10345    (set_attr "fp_mode" "single")])
10346
10347 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10348 ;; fix_truncsfsi2_i4.
10349 ;; (define_insn "fix_truncsfsi2_i4_2"
10350 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10351 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10352 ;;   (use (reg:PSI FPSCR_REG))
10353 ;;   (clobber (reg:SI FPUL_REG))]
10354 ;;  "TARGET_SH4"
10355 ;;  "#"
10356 ;;  [(set_attr "length" "4")
10357 ;;   (set_attr "fp_mode" "single")])
10358
10359 ;;(define_split
10360 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10361 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10362 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10363 ;;   (clobber (reg:SI FPUL_REG))]
10364 ;;  "TARGET_SH4"
10365 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10366 ;;            (use (match_dup 2))])
10367 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10368
10369 (define_insn "*fixsfsi"
10370   [(set (match_operand:SI 0 "fpul_operand" "=y")
10371         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10372   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10373   "ftrc %1,%0"
10374   [(set_attr "type" "fp")])
10375
10376 (define_insn "cmpgtsf_t"
10377   [(set (reg:SI T_REG)
10378         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10379                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10380   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10381   "fcmp/gt      %1,%0"
10382   [(set_attr "type" "fp_cmp")
10383    (set_attr "fp_mode" "single")])
10384
10385 (define_insn "cmpeqsf_t"
10386   [(set (reg:SI T_REG)
10387         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10388                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10389   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10390   "fcmp/eq      %1,%0"
10391   [(set_attr "type" "fp_cmp")
10392    (set_attr "fp_mode" "single")])
10393
10394 (define_insn "ieee_ccmpeqsf_t"
10395   [(set (reg:SI T_REG)
10396         (ior:SI (reg:SI T_REG)
10397                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10398                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10399   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10400   "* return output_ieee_ccmpeq (insn, operands);"
10401   [(set_attr "length" "4")])
10402
10403
10404 (define_insn "cmpgtsf_t_i4"
10405   [(set (reg:SI T_REG)
10406         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10407                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10408    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10409   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10410   "fcmp/gt      %1,%0"
10411   [(set_attr "type" "fp_cmp")
10412    (set_attr "fp_mode" "single")])
10413
10414 (define_insn "cmpeqsf_t_i4"
10415   [(set (reg:SI T_REG)
10416         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10417                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10418    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10419   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10420   "fcmp/eq      %1,%0"
10421   [(set_attr "type" "fp_cmp")
10422    (set_attr "fp_mode" "single")])
10423
10424 (define_insn "*ieee_ccmpeqsf_t_4"
10425   [(set (reg:SI T_REG)
10426         (ior:SI (reg:SI T_REG)
10427                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10428                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10429    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10430   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10431   "* return output_ieee_ccmpeq (insn, operands);"
10432   [(set_attr "length" "4")
10433    (set_attr "fp_mode" "single")])
10434
10435 (define_insn "cmpeqsf_media"
10436   [(set (match_operand:SI 0 "register_operand" "=r")
10437         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10438                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10439   "TARGET_SHMEDIA_FPU"
10440   "fcmpeq.s     %1, %2, %0"
10441   [(set_attr "type" "fcmp_media")])
10442
10443 (define_insn "cmpgtsf_media"
10444   [(set (match_operand:SI 0 "register_operand" "=r")
10445         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10446                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10447   "TARGET_SHMEDIA_FPU"
10448   "fcmpgt.s     %1, %2, %0"
10449   [(set_attr "type" "fcmp_media")])
10450
10451 (define_insn "cmpgesf_media"
10452   [(set (match_operand:SI 0 "register_operand" "=r")
10453         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10454                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10455   "TARGET_SHMEDIA_FPU"
10456   "fcmpge.s     %1, %2, %0"
10457   [(set_attr "type" "fcmp_media")])
10458
10459 (define_insn "cmpunsf_media"
10460   [(set (match_operand:SI 0 "register_operand" "=r")
10461         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10462                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10463   "TARGET_SHMEDIA_FPU"
10464   "fcmpun.s     %1, %2, %0"
10465   [(set_attr "type" "fcmp_media")])
10466
10467 (define_expand "cbranchsf4"
10468   [(set (pc)
10469         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10470                        [(match_operand:SF 1 "arith_operand" "")
10471                         (match_operand:SF 2 "arith_operand" "")])
10472                       (match_operand 3 "" "")
10473                       (pc)))]
10474   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10475   "
10476 {
10477   if (TARGET_SHMEDIA)
10478     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10479                                           operands[3]));
10480   else
10481     sh_emit_compare_and_branch (operands, SFmode);
10482   DONE;
10483 }")
10484
10485 (define_expand "negsf2"
10486   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10487         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10488   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10489   "
10490 {
10491   if (TARGET_SH2E)
10492     {
10493       expand_sf_unop (&gen_negsf2_i, operands);
10494       DONE;
10495     }
10496 }")
10497
10498 (define_insn "*negsf2_media"
10499   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10500         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10501   "TARGET_SHMEDIA_FPU"
10502   "fneg.s       %1, %0"
10503   [(set_attr "type" "fmove_media")])
10504
10505 (define_insn "negsf2_i"
10506   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10507         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10508    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10509   "TARGET_SH2E"
10510   "fneg %0"
10511   [(set_attr "type" "fmove")
10512    (set_attr "fp_mode" "single")])
10513
10514 (define_expand "sqrtsf2"
10515   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10516         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10517   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10518   "
10519 {
10520   if (TARGET_SH3E)
10521     {
10522       expand_sf_unop (&gen_sqrtsf2_i, operands);
10523       DONE;
10524     }
10525 }")
10526
10527 (define_insn "*sqrtsf2_media"
10528   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10529         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10530   "TARGET_SHMEDIA_FPU"
10531   "fsqrt.s      %1, %0"
10532   [(set_attr "type" "fdiv_media")])
10533
10534 (define_insn "sqrtsf2_i"
10535   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10537    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10538   "TARGET_SH3E"
10539   "fsqrt        %0"
10540   [(set_attr "type" "fdiv")
10541    (set_attr "fp_mode" "single")])
10542
10543 (define_insn "rsqrtsf2"
10544   [(set (match_operand:SF 0 "register_operand" "=f")
10545         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10546                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10547    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10548   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10549    && operands[1] == CONST1_RTX (SFmode)"
10550   "fsrra        %0"
10551   [(set_attr "type" "fsrra")
10552    (set_attr "fp_mode" "single")])
10553
10554 (define_insn "fsca"
10555   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10556         (vec_concat:V2SF
10557          (unspec:SF [(mult:SF
10558                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10559                       (match_operand:SF 2 "immediate_operand" "i"))
10560                     ] UNSPEC_FSINA)
10561          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10562                     ] UNSPEC_FCOSA)))
10563    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10564   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10565    && operands[2] == sh_fsca_int2sf ()"
10566   "fsca fpul,%d0"
10567   [(set_attr "type" "fsca")
10568    (set_attr "fp_mode" "single")])
10569
10570 (define_expand "sinsf2"
10571   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10572         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10573                    UNSPEC_FSINA))]
10574   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10575   "
10576 {
10577   rtx scaled = gen_reg_rtx (SFmode);
10578   rtx truncated = gen_reg_rtx (SImode);
10579   rtx fsca = gen_reg_rtx (V2SFmode);
10580   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10581
10582   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10583   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10584   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10585                           get_fpscr_rtx ()));
10586   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10587   DONE;
10588 }")
10589
10590 (define_expand "cossf2"
10591   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10592         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10593                    UNSPEC_FCOSA))]
10594   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10595   "
10596 {
10597   rtx scaled = gen_reg_rtx (SFmode);
10598   rtx truncated = gen_reg_rtx (SImode);
10599   rtx fsca = gen_reg_rtx (V2SFmode);
10600   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10601
10602   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10603   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10604   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10605                           get_fpscr_rtx ()));
10606   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10607   DONE;
10608 }")
10609
10610 (define_expand "sindf2"
10611   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10612         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10613                    UNSPEC_FSINA))]
10614   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10615   "
10616 {
10617   rtx scaled = gen_reg_rtx (DFmode);
10618   rtx truncated = gen_reg_rtx (SImode);
10619   rtx fsca = gen_reg_rtx (V2SFmode);
10620   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10621   rtx sfresult = gen_reg_rtx (SFmode);
10622
10623   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10624   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10625   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10626                           get_fpscr_rtx ()));
10627   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10628   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10629   DONE;
10630 }")
10631
10632 (define_expand "cosdf2"
10633   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10634         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10635                    UNSPEC_FCOSA))]
10636   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10637   "
10638 {
10639   rtx scaled = gen_reg_rtx (DFmode);
10640   rtx truncated = gen_reg_rtx (SImode);
10641   rtx fsca = gen_reg_rtx (V2SFmode);
10642   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10643   rtx sfresult = gen_reg_rtx (SFmode);
10644
10645   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10646   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10647   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10648                           get_fpscr_rtx ()));
10649   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10650   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10651   DONE;
10652 }")
10653
10654 (define_expand "abssf2"
10655   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10656         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10657   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10658   "
10659 {
10660   if (TARGET_SH2E)
10661     {
10662       expand_sf_unop (&gen_abssf2_i, operands);
10663       DONE;
10664     }
10665 }")
10666
10667 (define_insn "*abssf2_media"
10668   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10669         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10670   "TARGET_SHMEDIA_FPU"
10671   "fabs.s       %1, %0"
10672   [(set_attr "type" "fmove_media")])
10673
10674 (define_insn "abssf2_i"
10675   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10676         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10677    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10678   "TARGET_SH2E"
10679   "fabs %0"
10680   [(set_attr "type" "fmove")
10681    (set_attr "fp_mode" "single")])
10682
10683 (define_expand "adddf3"
10684   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10685         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10686                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10687   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10688   "
10689 {
10690   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10691     {
10692       expand_df_binop (&gen_adddf3_i, operands);
10693       DONE;
10694     }
10695 }")
10696
10697 (define_insn "*adddf3_media"
10698   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10699         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10700                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701   "TARGET_SHMEDIA_FPU"
10702   "fadd.d       %1, %2, %0"
10703   [(set_attr "type" "dfparith_media")])
10704
10705 (define_insn "adddf3_i"
10706   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10707         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10708                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10709    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10710   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10711   "fadd %2,%0"
10712   [(set_attr "type" "dfp_arith")
10713    (set_attr "fp_mode" "double")])
10714
10715 (define_expand "subdf3"
10716   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10717         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10718                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10719   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10720   "
10721 {
10722   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10723     {
10724       expand_df_binop (&gen_subdf3_i, operands);
10725       DONE;
10726     }
10727 }")
10728
10729 (define_insn "*subdf3_media"
10730   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10731         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10732                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10733   "TARGET_SHMEDIA_FPU"
10734   "fsub.d       %1, %2, %0"
10735   [(set_attr "type" "dfparith_media")])
10736
10737 (define_insn "subdf3_i"
10738   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10739         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10740                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10741    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10742   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10743   "fsub %2,%0"
10744   [(set_attr "type" "dfp_arith")
10745    (set_attr "fp_mode" "double")])
10746
10747 (define_expand "muldf3"
10748   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10749         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10750                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10751   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10752   "
10753 {
10754   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10755     {
10756       expand_df_binop (&gen_muldf3_i, operands);
10757       DONE;
10758     }
10759 }")
10760
10761 (define_insn "*muldf3_media"
10762   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10763         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10764                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10765   "TARGET_SHMEDIA_FPU"
10766   "fmul.d       %1, %2, %0"
10767   [(set_attr "type" "dfmul_media")])
10768
10769 (define_insn "muldf3_i"
10770   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10771         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10772                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10773    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10774   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10775   "fmul %2,%0"
10776   [(set_attr "type" "dfp_mul")
10777    (set_attr "fp_mode" "double")])
10778
10779 (define_expand "divdf3"
10780   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10781         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10782                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10783   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10784   "
10785 {
10786   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10787     {
10788       expand_df_binop (&gen_divdf3_i, operands);
10789       DONE;
10790     }
10791 }")
10792
10793 (define_insn "*divdf3_media"
10794   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10795         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10796                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10797   "TARGET_SHMEDIA_FPU"
10798   "fdiv.d       %1, %2, %0"
10799   [(set_attr "type" "dfdiv_media")])
10800
10801 (define_insn "divdf3_i"
10802   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10803         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10804                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10805    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10806   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10807   "fdiv %2,%0"
10808   [(set_attr "type" "dfdiv")
10809    (set_attr "fp_mode" "double")])
10810
10811 (define_insn "floatdidf2"
10812   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10813         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10814   "TARGET_SHMEDIA_FPU"
10815   "float.qd     %1, %0"
10816   [(set_attr "type" "dfpconv_media")])
10817
10818 (define_expand "floatsidf2"
10819   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10820         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10821   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10822   "
10823 {
10824   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10825     {
10826       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10827                                       get_fpscr_rtx ()));
10828       DONE;
10829     }
10830 }")
10831
10832 (define_insn "*floatsidf2_media"
10833   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10834         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10835   "TARGET_SHMEDIA_FPU"
10836   "float.ld     %1, %0"
10837   [(set_attr "type" "dfpconv_media")])
10838
10839 (define_insn "floatsidf2_i"
10840   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10841         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10842    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10843   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10844   "float        %1,%0"
10845   [(set_attr "type" "dfp_conv")
10846    (set_attr "fp_mode" "double")])
10847
10848 (define_insn "fix_truncdfdi2"
10849   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10850         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10851   "TARGET_SHMEDIA_FPU"
10852   "ftrc.dq      %1, %0"
10853   [(set_attr "type" "dfpconv_media")])
10854
10855 (define_expand "fix_truncdfsi2"
10856   [(set (match_operand:SI 0 "fpul_operand" "")
10857         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10858   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10859   "
10860 {
10861   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10862     {
10863       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10864                                           get_fpscr_rtx ()));
10865       DONE;
10866     }
10867 }")
10868
10869 (define_insn "*fix_truncdfsi2_media"
10870   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10871         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872   "TARGET_SHMEDIA_FPU"
10873   "ftrc.dl      %1, %0"
10874   [(set_attr "type" "dfpconv_media")])
10875
10876 (define_insn "fix_truncdfsi2_i"
10877   [(set (match_operand:SI 0 "fpul_operand" "=y")
10878         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10879    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881   "ftrc %1,%0"
10882   [(set_attr "type" "dfp_conv")
10883    (set_attr "dfp_comp" "no")
10884    (set_attr "fp_mode" "double")])
10885
10886 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10887 ;; fix_truncdfsi2_i.
10888 ;; (define_insn "fix_truncdfsi2_i4"
10889 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10890 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10891 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10892 ;;    (clobber (reg:SI FPUL_REG))]
10893 ;;   "TARGET_SH4"
10894 ;;   "#"
10895 ;;   [(set_attr "length" "4")
10896 ;;    (set_attr "fp_mode" "double")])
10897 ;;
10898 ;; (define_split
10899 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10900 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10901 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10902 ;;    (clobber (reg:SI FPUL_REG))]
10903 ;;   "TARGET_SH4"
10904 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10905 ;;            (use (match_dup 2))])
10906 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10907
10908 (define_insn "cmpgtdf_t"
10909   [(set (reg:SI T_REG)
10910         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10911                (match_operand:DF 1 "arith_reg_operand" "f")))
10912    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10913   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10914   "fcmp/gt      %1,%0"
10915   [(set_attr "type" "dfp_cmp")
10916    (set_attr "fp_mode" "double")])
10917
10918 (define_insn "cmpeqdf_t"
10919   [(set (reg:SI T_REG)
10920         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10921                (match_operand:DF 1 "arith_reg_operand" "f")))
10922    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10924   "fcmp/eq      %1,%0"
10925   [(set_attr "type" "dfp_cmp")
10926    (set_attr "fp_mode" "double")])
10927
10928 (define_insn "*ieee_ccmpeqdf_t"
10929   [(set (reg:SI T_REG)
10930         (ior:SI (reg:SI T_REG)
10931                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10932                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10933    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10934   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10935   "* return output_ieee_ccmpeq (insn, operands);"
10936   [(set_attr "length" "4")
10937    (set_attr "fp_mode" "double")])
10938
10939 (define_insn "cmpeqdf_media"
10940   [(set (match_operand:SI 0 "register_operand" "=r")
10941         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10942                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10943   "TARGET_SHMEDIA_FPU"
10944   "fcmpeq.d     %1,%2,%0"
10945   [(set_attr "type" "fcmp_media")])
10946
10947 (define_insn "cmpgtdf_media"
10948   [(set (match_operand:SI 0 "register_operand" "=r")
10949         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10950                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10951   "TARGET_SHMEDIA_FPU"
10952   "fcmpgt.d     %1,%2,%0"
10953   [(set_attr "type" "fcmp_media")])
10954
10955 (define_insn "cmpgedf_media"
10956   [(set (match_operand:SI 0 "register_operand" "=r")
10957         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10958                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10959   "TARGET_SHMEDIA_FPU"
10960   "fcmpge.d     %1,%2,%0"
10961   [(set_attr "type" "fcmp_media")])
10962
10963 (define_insn "cmpundf_media"
10964   [(set (match_operand:SI 0 "register_operand" "=r")
10965         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10966                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10967   "TARGET_SHMEDIA_FPU"
10968   "fcmpun.d     %1,%2,%0"
10969   [(set_attr "type" "fcmp_media")])
10970
10971 (define_expand "cbranchdf4"
10972   [(set (pc)
10973         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10974                        [(match_operand:DF 1 "arith_operand" "")
10975                         (match_operand:DF 2 "arith_operand" "")])
10976                       (match_operand 3 "" "")
10977                       (pc)))]
10978   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10979   "
10980 {
10981   if (TARGET_SHMEDIA)
10982     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10983                                           operands[3]));
10984   else
10985     sh_emit_compare_and_branch (operands, DFmode);
10986   DONE;
10987 }")
10988
10989
10990 (define_expand "negdf2"
10991   [(set (match_operand:DF 0 "arith_reg_operand" "")
10992         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10993   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10994   "
10995 {
10996   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10997     {
10998       expand_df_unop (&gen_negdf2_i, operands);
10999       DONE;
11000     }
11001 }")
11002
11003 (define_insn "*negdf2_media"
11004   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11006   "TARGET_SHMEDIA_FPU"
11007   "fneg.d       %1, %0"
11008   [(set_attr "type" "fmove_media")])
11009
11010 (define_insn "negdf2_i"
11011   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11012         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11013    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11014   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11015   "fneg %0"
11016   [(set_attr "type" "fmove")
11017    (set_attr "fp_mode" "double")])
11018
11019 (define_expand "sqrtdf2"
11020   [(set (match_operand:DF 0 "arith_reg_operand" "")
11021         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11022   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11023   "
11024 {
11025   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11026     {
11027       expand_df_unop (&gen_sqrtdf2_i, operands);
11028       DONE;
11029     }
11030 }")
11031
11032 (define_insn "*sqrtdf2_media"
11033   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11034         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11035   "TARGET_SHMEDIA_FPU"
11036   "fsqrt.d      %1, %0"
11037   [(set_attr "type" "dfdiv_media")])
11038
11039 (define_insn "sqrtdf2_i"
11040   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11041         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11042    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11043   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11044   "fsqrt        %0"
11045   [(set_attr "type" "dfdiv")
11046    (set_attr "fp_mode" "double")])
11047
11048 (define_expand "absdf2"
11049   [(set (match_operand:DF 0 "arith_reg_operand" "")
11050         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11051   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11052   "
11053 {
11054   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11055     {
11056       expand_df_unop (&gen_absdf2_i, operands);
11057       DONE;
11058     }
11059 }")
11060
11061 (define_insn "*absdf2_media"
11062   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11063         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11064   "TARGET_SHMEDIA_FPU"
11065   "fabs.d       %1, %0"
11066   [(set_attr "type" "fmove_media")])
11067
11068 (define_insn "absdf2_i"
11069   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11070         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11071    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11072   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11073   "fabs %0"
11074   [(set_attr "type" "fmove")
11075    (set_attr "fp_mode" "double")])
11076
11077 (define_expand "extendsfdf2"
11078   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11079         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11080   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11081   "
11082 {
11083   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11084     {
11085       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11086                                         get_fpscr_rtx ()));
11087       DONE;
11088     }
11089 }")
11090
11091 (define_insn "*extendsfdf2_media"
11092   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11093         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11094   "TARGET_SHMEDIA_FPU"
11095   "fcnv.sd      %1, %0"
11096   [(set_attr "type" "dfpconv_media")])
11097
11098 (define_insn "extendsfdf2_i4"
11099   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11100         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11101    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11102   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11103   "fcnvsd  %1,%0"
11104   [(set_attr "type" "fp")
11105    (set_attr "fp_mode" "double")])
11106
11107 (define_expand "truncdfsf2"
11108   [(set (match_operand:SF 0 "fpul_operand" "")
11109         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11110   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11111   "
11112 {
11113   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11114     {
11115       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11116                                        get_fpscr_rtx ()));
11117       DONE;
11118     }
11119 }")
11120
11121 (define_insn "*truncdfsf2_media"
11122   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11123         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11124   "TARGET_SHMEDIA_FPU"
11125   "fcnv.ds      %1, %0"
11126   [(set_attr "type" "dfpconv_media")])
11127
11128 (define_insn "truncdfsf2_i4"
11129   [(set (match_operand:SF 0 "fpul_operand" "=y")
11130         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11131    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11132   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11133   "fcnvds  %1,%0"
11134   [(set_attr "type" "fp")
11135    (set_attr "fp_mode" "double")])
11136 \f
11137 ;; Bit field extract patterns.  These give better code for packed bitfields,
11138 ;; because they allow auto-increment addresses to be generated.
11139
11140 (define_expand "insv"
11141   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11142                          (match_operand:SI 1 "immediate_operand" "")
11143                          (match_operand:SI 2 "immediate_operand" ""))
11144         (match_operand:SI 3 "general_operand" ""))]
11145   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11146   "
11147 {
11148   rtx addr_target, orig_address, shift_reg, qi_val;
11149   HOST_WIDE_INT bitsize, size, v = 0;
11150   rtx x = operands[3];
11151
11152   if (TARGET_SH2A && TARGET_BITOPS
11153       && (satisfies_constraint_Sbw (operands[0])
11154           || satisfies_constraint_Sbv (operands[0]))
11155       && satisfies_constraint_M (operands[1])
11156       && satisfies_constraint_K03 (operands[2]))
11157     {
11158       if (satisfies_constraint_N (operands[3]))
11159         {
11160           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11161           DONE;
11162         }
11163       else if (satisfies_constraint_M (operands[3]))
11164         {
11165           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11166           DONE;
11167         }
11168       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11169                 && satisfies_constraint_M (operands[1]))
11170         {
11171           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11172           DONE;
11173         }
11174       else if (REG_P (operands[3])
11175                && satisfies_constraint_M (operands[1]))
11176         {
11177           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11178           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11179           DONE;
11180         }
11181     }
11182   /* ??? expmed doesn't care for non-register predicates.  */
11183   if (! memory_operand (operands[0], VOIDmode)
11184       || ! immediate_operand (operands[1], VOIDmode)
11185       || ! immediate_operand (operands[2], VOIDmode)
11186       || ! general_operand (x, VOIDmode))
11187     FAIL;
11188   /* If this isn't a 16 / 24 / 32 bit field, or if
11189      it doesn't start on a byte boundary, then fail.  */
11190   bitsize = INTVAL (operands[1]);
11191   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11192       || (INTVAL (operands[2]) % 8) != 0)
11193     FAIL;
11194
11195   size = bitsize / 8;
11196   orig_address = XEXP (operands[0], 0);
11197   shift_reg = gen_reg_rtx (SImode);
11198   if (CONST_INT_P (x))
11199     {
11200       v = INTVAL (x);
11201       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11202     }
11203   else
11204     {
11205       emit_insn (gen_movsi (shift_reg, operands[3]));
11206       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11207     }
11208   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11209
11210   operands[0] = replace_equiv_address (operands[0], addr_target);
11211   emit_insn (gen_movqi (operands[0], qi_val));
11212
11213   while (size -= 1)
11214     {
11215       if (CONST_INT_P (x))
11216         qi_val
11217           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11218       else
11219         {
11220           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11221           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11222         }
11223       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11224       emit_insn (gen_movqi (operands[0], qi_val));
11225     }
11226
11227   DONE;
11228 }")
11229
11230 (define_insn "movua"
11231   [(set (match_operand:SI 0 "register_operand" "=z")
11232         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11233                    UNSPEC_MOVUA))]
11234   "TARGET_SH4A_ARCH"
11235   "movua.l      %1,%0"
11236   [(set_attr "type" "movua")])
11237
11238 ;; We shouldn't need this, but cse replaces increments with references
11239 ;; to other regs before flow has a chance to create post_inc
11240 ;; addressing modes, and only postreload's cse_move2add brings the
11241 ;; increments back to a usable form.
11242 (define_peephole2
11243   [(set (match_operand:SI 0 "register_operand" "")
11244         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11245                          (const_int 32) (const_int 0)))
11246    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11247   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11248   [(set (match_operand:SI 0 "register_operand" "")
11249         (sign_extract:SI (mem:SI (post_inc:SI
11250                                   (match_operand:SI 1 "register_operand" "")))
11251                          (const_int 32) (const_int 0)))]
11252   "")
11253
11254 (define_expand "extv"
11255   [(set (match_operand:SI 0 "register_operand" "")
11256         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11257                          (match_operand 2 "const_int_operand" "")
11258                          (match_operand 3 "const_int_operand" "")))]
11259   "TARGET_SH4A_ARCH || TARGET_SH2A"
11260 {
11261   if (TARGET_SH2A && TARGET_BITOPS
11262       && (satisfies_constraint_Sbw (operands[1])
11263           || satisfies_constraint_Sbv (operands[1]))
11264       && satisfies_constraint_M (operands[2])
11265       && satisfies_constraint_K03 (operands[3]))
11266    {
11267       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11268       if (REGNO (operands[0]) != T_REG)
11269         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11270       DONE;
11271    }
11272   if (TARGET_SH4A_ARCH
11273       && INTVAL (operands[2]) == 32
11274       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11275       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11276     {
11277       rtx src = adjust_address (operands[1], BLKmode, 0);
11278       set_mem_size (src, 4);
11279       emit_insn (gen_movua (operands[0], src));
11280       DONE;
11281     }
11282
11283   FAIL;
11284 })
11285
11286 (define_expand "extzv"
11287   [(set (match_operand:SI 0 "register_operand" "")
11288         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11289                          (match_operand 2 "const_int_operand" "")
11290                          (match_operand 3 "const_int_operand" "")))]
11291   "TARGET_SH4A_ARCH || TARGET_SH2A"
11292 {
11293   if (TARGET_SH2A && TARGET_BITOPS
11294       && (satisfies_constraint_Sbw (operands[1])
11295           || satisfies_constraint_Sbv (operands[1]))
11296       && satisfies_constraint_M (operands[2])
11297       && satisfies_constraint_K03 (operands[3]))
11298     {
11299       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11300       if (REGNO (operands[0]) != T_REG)
11301         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11302       DONE;
11303     }
11304   if (TARGET_SH4A_ARCH
11305       && INTVAL (operands[2]) == 32
11306       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11307       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11308     {
11309       rtx src = adjust_address (operands[1], BLKmode, 0);
11310       set_mem_size (src, 4);
11311       emit_insn (gen_movua (operands[0], src));
11312       DONE;
11313     }
11314
11315   FAIL;
11316 })
11317
11318 ;; SH2A instructions for bitwise operations.
11319
11320 ;; Clear a bit in a memory location.
11321 (define_insn "bclr_m2a"
11322   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11323         (and:QI
11324             (not:QI (ashift:QI (const_int 1)
11325                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11326             (match_dup 0)))]
11327   "TARGET_SH2A && TARGET_BITOPS"
11328   "@
11329         bclr.b\\t%1,%0
11330         bclr.b\\t%1,@(0,%t0)"
11331 [(set_attr "length" "4,4")])
11332
11333 (define_insn "bclrmem_m2a"
11334   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11335         (and:QI (match_dup 0)
11336                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11337   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11338   "@
11339         bclr.b\\t%W1,%0
11340         bclr.b\\t%W1,@(0,%t0)"
11341   [(set_attr "length" "4,4")])
11342
11343 ;; Set a bit in a memory location.
11344 (define_insn "bset_m2a"
11345   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11346         (ior:QI
11347             (ashift:QI (const_int 1)
11348                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11349             (match_dup 0)))]
11350   "TARGET_SH2A && TARGET_BITOPS"
11351   "@
11352         bset.b\\t%1,%0
11353         bset.b\\t%1,@(0,%t0)"
11354   [(set_attr "length" "4,4")])
11355
11356 (define_insn "bsetmem_m2a"
11357   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11358         (ior:QI (match_dup 0)
11359                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11360   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11361   "@
11362         bset.b\\t%V1,%0
11363         bset.b\\t%V1,@(0,%t0)"
11364   [(set_attr "length" "4,4")])
11365
11366 ;;; Transfer the contents of the T bit to a specified bit of memory.
11367 (define_insn "bst_m2a"
11368   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11369         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11370             (and:QI
11371                 (not:QI (ashift:QI (const_int 1)
11372                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11373                 (match_dup 0))
11374             (ior:QI
11375                 (ashift:QI (const_int 1) (match_dup 1))
11376                 (match_dup 0))))]
11377   "TARGET_SH2A && TARGET_BITOPS"
11378   "@
11379         bst.b\\t%1,%0
11380         bst.b\\t%1,@(0,%t0)"
11381   [(set_attr "length" "4")])
11382
11383 ;; Store a specified bit of memory in the T bit.
11384 (define_insn "bld_m2a"
11385   [(set (reg:SI T_REG)
11386         (zero_extract:SI
11387             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11388             (const_int 1)
11389             (match_operand 1 "const_int_operand" "K03,K03")))]
11390   "TARGET_SH2A && TARGET_BITOPS"
11391   "@
11392         bld.b\\t%1,%0
11393         bld.b\\t%1,@(0,%t0)"
11394   [(set_attr "length" "4,4")])
11395
11396 ;; Store a specified bit of memory in the T bit.
11397 (define_insn "bldsign_m2a"
11398   [(set (reg:SI T_REG)
11399         (sign_extract:SI
11400             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11401             (const_int 1)
11402             (match_operand 1 "const_int_operand" "K03,K03")))]
11403   "TARGET_SH2A && TARGET_BITOPS"
11404   "@
11405         bld.b\\t%1,%0
11406         bld.b\\t%1,@(0,%t0)"
11407   [(set_attr "length" "4,4")])
11408
11409 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11410 (define_insn "bld_reg"
11411   [(set (reg:SI T_REG)
11412         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11413                          (const_int 1)
11414                          (match_operand 1 "const_int_operand" "K03")))]
11415   "TARGET_SH2A"
11416   "bld\\t%1,%0")
11417
11418 (define_insn "*bld_regqi"
11419   [(set (reg:SI T_REG)
11420         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11421                          (const_int 1)
11422                          (match_operand 1 "const_int_operand" "K03")))]
11423   "TARGET_SH2A"
11424   "bld\\t%1,%0")
11425
11426 ;; Take logical and of a specified bit of memory with the T bit and
11427 ;; store its result in the T bit.
11428 (define_insn "band_m2a"
11429   [(set (reg:SI T_REG)
11430         (and:SI (reg:SI T_REG)
11431                 (zero_extract:SI
11432                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11433                     (const_int 1)
11434                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11435   "TARGET_SH2A && TARGET_BITOPS"
11436   "@
11437         band.b\\t%1,%0
11438         band.b\\t%1,@(0,%t0)"
11439   [(set_attr "length" "4,4")])
11440
11441 (define_insn "bandreg_m2a"
11442   [(set (match_operand:SI 0 "register_operand" "=r,r")
11443         (and:SI (zero_extract:SI
11444                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11445                     (const_int 1)
11446                     (match_operand 2 "const_int_operand" "K03,K03"))
11447                 (match_operand:SI 3 "register_operand" "r,r")))]
11448   "TARGET_SH2A && TARGET_BITOPS"
11449   "@
11450         band.b\\t%2,%1\;movt\\t%0
11451         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11452   [(set_attr "length" "6,6")])
11453
11454 ;; Take logical or of a specified bit of memory with the T bit and
11455 ;; store its result in the T bit.
11456 (define_insn "bor_m2a"
11457   [(set (reg:SI T_REG)
11458         (ior:SI (reg:SI T_REG)
11459                 (zero_extract:SI
11460                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11461                     (const_int 1)
11462                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11463   "TARGET_SH2A && TARGET_BITOPS"
11464   "@
11465         bor.b\\t%1,%0
11466         bor.b\\t%1,@(0,%t0)"
11467   [(set_attr "length" "4,4")])
11468
11469 (define_insn "borreg_m2a"
11470   [(set (match_operand:SI 0 "register_operand" "=r,r")
11471         (ior:SI (zero_extract:SI
11472                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11473                     (const_int 1)
11474                     (match_operand 2 "const_int_operand" "K03,K03"))
11475                 (match_operand:SI 3 "register_operand" "=r,r")))]
11476   "TARGET_SH2A && TARGET_BITOPS"
11477   "@
11478         bor.b\\t%2,%1\;movt\\t%0
11479         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11480   [(set_attr "length" "6,6")])
11481
11482 ;; Take exclusive or of a specified bit of memory with the T bit and
11483 ;; store its result in the T bit.
11484 (define_insn "bxor_m2a"
11485   [(set (reg:SI T_REG)
11486         (xor:SI (reg:SI T_REG)
11487                 (zero_extract:SI
11488                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11489                     (const_int 1)
11490                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11491   "TARGET_SH2A && TARGET_BITOPS"
11492   "@
11493         bxor.b\\t%1,%0
11494         bxor.b\\t%1,@(0,%t0)"
11495   [(set_attr "length" "4,4")])
11496
11497 (define_insn "bxorreg_m2a"
11498   [(set (match_operand:SI 0 "register_operand" "=r,r")
11499         (xor:SI (zero_extract:SI
11500                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11501                     (const_int 1)
11502                     (match_operand 2 "const_int_operand" "K03,K03"))
11503                 (match_operand:SI 3 "register_operand" "=r,r")))]
11504   "TARGET_SH2A && TARGET_BITOPS"
11505   "@
11506         bxor.b\\t%2,%1\;movt\\t%0
11507         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11508   [(set_attr "length" "6,6")])
11509
11510 \f
11511 ;; -------------------------------------------------------------------------
11512 ;; Peepholes
11513 ;; -------------------------------------------------------------------------
11514 ;; This matches cases where the bit in a memory location is set.
11515 (define_peephole2
11516   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11517         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11518    (set (match_dup 0)
11519         (ior:SI (match_dup 0)
11520         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11521    (set (match_dup 1)
11522         (match_operand 3 "arith_reg_operand" "r,r"))]
11523   "TARGET_SH2A && TARGET_BITOPS
11524    && satisfies_constraint_Pso (operands[2])
11525    && REGNO (operands[0]) == REGNO (operands[3])"
11526   [(set (match_dup 1)
11527         (ior:QI (match_dup 1)
11528                 (match_dup 2)))]
11529   "")
11530
11531 ;; This matches cases where the bit in a memory location is cleared.
11532 (define_peephole2
11533   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11534         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11535    (set (match_dup 0)
11536         (and:SI (match_dup 0)
11537         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11538    (set (match_dup 1)
11539         (match_operand 3 "arith_reg_operand" "r,r"))]
11540   "TARGET_SH2A && TARGET_BITOPS
11541    && satisfies_constraint_Psz (operands[2])
11542    && REGNO (operands[0]) == REGNO (operands[3])"
11543   [(set (match_dup 1)
11544         (and:QI (match_dup 1)
11545                 (match_dup 2)))]
11546   "")
11547
11548 ;; This matches cases where a stack pointer increment at the start of the
11549 ;; epilogue combines with a stack slot read loading the return value.
11550
11551 (define_peephole
11552   [(set (match_operand:SI 0 "arith_reg_operand" "")
11553         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11554    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11555   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11556   "mov.l        @%1+,%0")
11557
11558 ;; See the comment on the dt combiner pattern above.
11559
11560 (define_peephole
11561   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11562         (plus:SI (match_dup 0)
11563                  (const_int -1)))
11564    (set (reg:SI T_REG)
11565         (eq:SI (match_dup 0)
11566                (const_int 0)))]
11567   "TARGET_SH2"
11568   "dt   %0")
11569
11570 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11571 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11572 ;; reload when the constant is too large for a reg+offset address.
11573
11574 ;; ??? We would get much better code if this was done in reload.  This would
11575 ;; require modifying find_reloads_address to recognize that if the constant
11576 ;; is out-of-range for an immediate add, then we get better code by reloading
11577 ;; the constant into a register than by reloading the sum into a register,
11578 ;; since the former is one instruction shorter if the address does not need
11579 ;; to be offsettable.  Unfortunately this does not work, because there is
11580 ;; only one register, r0, that can be used as an index register.  This register
11581 ;; is also the function return value register.  So, if we try to force reload
11582 ;; to use double-reg addresses, then we end up with some instructions that
11583 ;; need to use r0 twice.  The only way to fix this is to change the calling
11584 ;; convention so that r0 is not used to return values.
11585
11586 (define_peephole
11587   [(set (match_operand:SI 0 "register_operand" "=r")
11588         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11589    (set (mem:SI (match_dup 0))
11590         (match_operand:SI 2 "general_movsrc_operand" ""))]
11591   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11592   "mov.l        %2,@(%0,%1)")
11593
11594 (define_peephole
11595   [(set (match_operand:SI 0 "register_operand" "=r")
11596         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11597    (set (match_operand:SI 2 "general_movdst_operand" "")
11598         (mem:SI (match_dup 0)))]
11599   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11600   "mov.l        @(%0,%1),%2")
11601
11602 (define_peephole
11603   [(set (match_operand:SI 0 "register_operand" "=r")
11604         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11605    (set (mem:HI (match_dup 0))
11606         (match_operand:HI 2 "general_movsrc_operand" ""))]
11607   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11608   "mov.w        %2,@(%0,%1)")
11609
11610 (define_peephole
11611   [(set (match_operand:SI 0 "register_operand" "=r")
11612         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11613    (set (match_operand:HI 2 "general_movdst_operand" "")
11614         (mem:HI (match_dup 0)))]
11615   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11616   "mov.w        @(%0,%1),%2")
11617
11618 (define_peephole
11619   [(set (match_operand:SI 0 "register_operand" "=r")
11620         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11621    (set (mem:QI (match_dup 0))
11622         (match_operand:QI 2 "general_movsrc_operand" ""))]
11623   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11624   "mov.b        %2,@(%0,%1)")
11625
11626 (define_peephole
11627   [(set (match_operand:SI 0 "register_operand" "=r")
11628         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11629    (set (match_operand:QI 2 "general_movdst_operand" "")
11630         (mem:QI (match_dup 0)))]
11631   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11632   "mov.b        @(%0,%1),%2")
11633
11634 (define_peephole
11635   [(set (match_operand:SI 0 "register_operand" "=r")
11636         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11637    (set (mem:SF (match_dup 0))
11638         (match_operand:SF 2 "general_movsrc_operand" ""))]
11639   "TARGET_SH1 && REGNO (operands[0]) == 0
11640    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11641        || (GET_CODE (operands[2]) == SUBREG
11642            && REGNO (SUBREG_REG (operands[2])) < 16))
11643    && reg_unused_after (operands[0], insn)"
11644   "mov.l        %2,@(%0,%1)")
11645
11646 (define_peephole
11647   [(set (match_operand:SI 0 "register_operand" "=r")
11648         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11649    (set (match_operand:SF 2 "general_movdst_operand" "")
11650
11651         (mem:SF (match_dup 0)))]
11652   "TARGET_SH1 && REGNO (operands[0]) == 0
11653    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11654        || (GET_CODE (operands[2]) == SUBREG
11655            && REGNO (SUBREG_REG (operands[2])) < 16))
11656    && reg_unused_after (operands[0], insn)"
11657   "mov.l        @(%0,%1),%2")
11658
11659 (define_peephole
11660   [(set (match_operand:SI 0 "register_operand" "=r")
11661         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11662    (set (mem:SF (match_dup 0))
11663         (match_operand:SF 2 "general_movsrc_operand" ""))]
11664   "TARGET_SH2E && REGNO (operands[0]) == 0
11665    && ((REG_P (operands[2])
11666         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11667        || (GET_CODE (operands[2]) == SUBREG
11668            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11669    && reg_unused_after (operands[0], insn)"
11670   "fmov{.s|}    %2,@(%0,%1)")
11671
11672 (define_peephole
11673   [(set (match_operand:SI 0 "register_operand" "=r")
11674         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11675    (set (match_operand:SF 2 "general_movdst_operand" "")
11676
11677         (mem:SF (match_dup 0)))]
11678   "TARGET_SH2E && REGNO (operands[0]) == 0
11679    && ((REG_P (operands[2])
11680         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11681        || (GET_CODE (operands[2]) == SUBREG
11682            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11683    && reg_unused_after (operands[0], insn)"
11684   "fmov{.s|}    @(%0,%1),%2")
11685
11686 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11687 (define_insn "sp_switch_1"
11688   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11689   "TARGET_SH1"
11690   "*
11691 {
11692   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11693   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11694   return \"mov r0,r15\";
11695 }"
11696   [(set_attr "length" "10")])
11697
11698 ;; Switch back to the original stack for interrupt functions with the
11699 ;; sp_switch attribute.  */
11700 (define_insn "sp_switch_2"
11701   [(const_int 2)]
11702   "TARGET_SH1"
11703   "mov.l @r15+,r15\;mov.l @r15+,r0"
11704   [(set_attr "length" "4")])
11705
11706 ;; Integer vector moves
11707
11708 (define_expand "movv8qi"
11709   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11710         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11711   "TARGET_SHMEDIA"
11712   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11713
11714 (define_insn "movv8qi_i"
11715   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11716         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11717   "TARGET_SHMEDIA
11718    && (register_operand (operands[0], V8QImode)
11719        || sh_register_operand (operands[1], V8QImode))"
11720   "@
11721         add     %1, r63, %0
11722         movi    %1, %0
11723         #
11724         ld%M1.q %m1, %0
11725         st%M0.q %m0, %N1"
11726   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11727    (set_attr "length" "4,4,16,4,4")])
11728
11729 (define_split
11730   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11731         (subreg:V8QI (const_int 0) 0))]
11732   "TARGET_SHMEDIA"
11733   [(set (match_dup 0)
11734         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11735                             (const_int 0) (const_int 0) (const_int 0)
11736                             (const_int 0) (const_int 0)]))])
11737
11738 (define_split
11739   [(set (match_operand 0 "arith_reg_dest" "")
11740         (match_operand 1 "sh_rep_vec" ""))]
11741   "TARGET_SHMEDIA && reload_completed
11742    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11743    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11744    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11745    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11746        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11747    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11748        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11749   [(set (match_dup 0) (match_dup 1))
11750    (match_dup 2)]
11751   "
11752 {
11753   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11754   rtx elt1 = XVECEXP (operands[1], 0, 1);
11755
11756   if (unit_size > 2)
11757     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11758   else
11759     {
11760       if (unit_size < 2)
11761         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11762       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11763     }
11764   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11765   operands[1] = XVECEXP (operands[1], 0, 0);
11766   if (unit_size < 2)
11767     {
11768       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11769         operands[1]
11770           = GEN_INT (TARGET_LITTLE_ENDIAN
11771                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11772                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11773       else
11774         {
11775           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11776           operands[1]
11777             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11778         }
11779     }
11780 }")
11781
11782 (define_split
11783   [(set (match_operand 0 "arith_reg_dest" "")
11784         (match_operand 1 "sh_const_vec" ""))]
11785   "TARGET_SHMEDIA && reload_completed
11786    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11787    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11788   [(set (match_dup 0) (match_dup 1))]
11789   "
11790 {
11791   rtx v = operands[1];
11792   enum machine_mode new_mode
11793     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11794
11795   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11796   operands[1]
11797     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11798 }")
11799
11800 (define_expand "movv2hi"
11801   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11802         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11803   "TARGET_SHMEDIA"
11804   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11805
11806 (define_insn "movv2hi_i"
11807   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11808         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11809   "TARGET_SHMEDIA
11810    && (register_operand (operands[0], V2HImode)
11811        || sh_register_operand (operands[1], V2HImode))"
11812   "@
11813         add.l   %1, r63, %0
11814         movi    %1, %0
11815         #
11816         ld%M1.l %m1, %0
11817         st%M0.l %m0, %N1"
11818   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11819    (set_attr "length" "4,4,16,4,4")
11820    (set (attr "highpart")
11821         (cond [(match_test "sh_contains_memref_p (insn)")
11822                (const_string "user")]
11823               (const_string "ignore")))])
11824
11825 (define_expand "movv4hi"
11826   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11827         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11828   "TARGET_SHMEDIA"
11829   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11830
11831 (define_insn "movv4hi_i"
11832   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11833         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11834   "TARGET_SHMEDIA
11835    && (register_operand (operands[0], V4HImode)
11836        || sh_register_operand (operands[1], V4HImode))"
11837   "@
11838         add     %1, r63, %0
11839         movi    %1, %0
11840         #
11841         ld%M1.q %m1, %0
11842         st%M0.q %m0, %N1"
11843   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11844    (set_attr "length" "4,4,16,4,4")
11845    (set_attr "highpart" "depend")])
11846
11847 (define_expand "movv2si"
11848   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11849         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11850   "TARGET_SHMEDIA"
11851   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11852
11853 (define_insn "movv2si_i"
11854   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11855         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11856   "TARGET_SHMEDIA
11857    && (register_operand (operands[0], V2SImode)
11858        || sh_register_operand (operands[1], V2SImode))"
11859   "@
11860         add     %1, r63, %0
11861         #
11862         #
11863         ld%M1.q %m1, %0
11864         st%M0.q %m0, %N1"
11865   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11866    (set_attr "length" "4,4,16,4,4")
11867    (set_attr "highpart" "depend")])
11868
11869 ;; Multimedia Intrinsics
11870
11871 (define_insn "absv2si2"
11872   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11873         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11874   "TARGET_SHMEDIA"
11875   "mabs.l       %1, %0"
11876   [(set_attr "type" "mcmp_media")
11877    (set_attr "highpart" "depend")])
11878
11879 (define_insn "absv4hi2"
11880   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11881         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11882   "TARGET_SHMEDIA"
11883   "mabs.w       %1, %0"
11884   [(set_attr "type" "mcmp_media")
11885    (set_attr "highpart" "depend")])
11886
11887 (define_insn "addv2si3"
11888   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11889         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11890                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11891   "TARGET_SHMEDIA"
11892   "madd.l       %1, %2, %0"
11893   [(set_attr "type" "arith_media")
11894    (set_attr "highpart" "depend")])
11895
11896 (define_insn "addv4hi3"
11897   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11898         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11899                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11900   "TARGET_SHMEDIA"
11901   "madd.w       %1, %2, %0"
11902   [(set_attr "type" "arith_media")
11903    (set_attr "highpart" "depend")])
11904
11905 (define_insn_and_split "addv2hi3"
11906   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11907         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11908                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11909   "TARGET_SHMEDIA"
11910   "#"
11911   "TARGET_SHMEDIA"
11912   [(const_int 0)]
11913   "
11914 {
11915   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11916   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11917   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11918   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11919   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11920
11921   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11922   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11923   DONE;
11924 }"
11925   [(set_attr "highpart" "must_split")])
11926
11927 (define_insn "ssaddv2si3"
11928   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11929         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11930                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11931   "TARGET_SHMEDIA"
11932   "madds.l      %1, %2, %0"
11933   [(set_attr "type" "mcmp_media")
11934    (set_attr "highpart" "depend")])
11935
11936 (define_insn "usaddv8qi3"
11937   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11938         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11939                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11940   "TARGET_SHMEDIA"
11941   "madds.ub     %1, %2, %0"
11942   [(set_attr "type" "mcmp_media")
11943    (set_attr "highpart" "depend")])
11944
11945 (define_insn "ssaddv4hi3"
11946   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11947         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11948                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11949   "TARGET_SHMEDIA"
11950   "madds.w      %1, %2, %0"
11951   [(set_attr "type" "mcmp_media")
11952    (set_attr "highpart" "depend")])
11953
11954 (define_insn "negcmpeqv8qi"
11955   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11956         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11957                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11958   "TARGET_SHMEDIA"
11959   "mcmpeq.b     %N1, %N2, %0"
11960   [(set_attr "type" "mcmp_media")
11961    (set_attr "highpart" "depend")])
11962
11963 (define_insn "negcmpeqv2si"
11964   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11965         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11966                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11967   "TARGET_SHMEDIA"
11968   "mcmpeq.l     %N1, %N2, %0"
11969   [(set_attr "type" "mcmp_media")
11970    (set_attr "highpart" "depend")])
11971
11972 (define_insn "negcmpeqv4hi"
11973   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11974         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11975                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11976   "TARGET_SHMEDIA"
11977   "mcmpeq.w     %N1, %N2, %0"
11978   [(set_attr "type" "mcmp_media")
11979    (set_attr "highpart" "depend")])
11980
11981 (define_insn "negcmpgtuv8qi"
11982   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11983         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11984                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11985   "TARGET_SHMEDIA"
11986   "mcmpgt.ub    %N1, %N2, %0"
11987   [(set_attr "type" "mcmp_media")
11988    (set_attr "highpart" "depend")])
11989
11990 (define_insn "negcmpgtv2si"
11991   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11992         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11993                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11994   "TARGET_SHMEDIA"
11995   "mcmpgt.l     %N1, %N2, %0"
11996   [(set_attr "type" "mcmp_media")
11997    (set_attr "highpart" "depend")])
11998
11999 (define_insn "negcmpgtv4hi"
12000   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12001         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12002                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12003   "TARGET_SHMEDIA"
12004   "mcmpgt.w     %N1, %N2, %0"
12005   [(set_attr "type" "mcmp_media")
12006    (set_attr "highpart" "depend")])
12007
12008 (define_insn "mcmv"
12009   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12010         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12011                         (match_operand:DI 2 "arith_reg_operand" "r"))
12012                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12013                         (not:DI (match_dup 2)))))]
12014   "TARGET_SHMEDIA"
12015   "mcmv %N1, %2, %0"
12016   [(set_attr "type" "arith_media")
12017    (set_attr "highpart" "depend")])
12018
12019 (define_insn "mcnvs_lw"
12020   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12021         (vec_concat:V4HI
12022          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12023          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12024   "TARGET_SHMEDIA"
12025   "mcnvs.lw     %N1, %N2, %0"
12026   [(set_attr "type" "mcmp_media")])
12027
12028 (define_insn "mcnvs_wb"
12029   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12030         (vec_concat:V8QI
12031          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12032          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12033   "TARGET_SHMEDIA"
12034   "mcnvs.wb     %N1, %N2, %0"
12035   [(set_attr "type" "mcmp_media")])
12036
12037 (define_insn "mcnvs_wub"
12038   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12039         (vec_concat:V8QI
12040          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12041          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12042   "TARGET_SHMEDIA"
12043   "mcnvs.wub    %N1, %N2, %0"
12044   [(set_attr "type" "mcmp_media")])
12045
12046 (define_insn "mextr_rl"
12047   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12048         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12049                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12050                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12051                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12052   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12053   "*
12054 {
12055   static char templ[21];
12056
12057   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12058            (int) INTVAL (operands[3]) >> 3);
12059   return templ;
12060 }"
12061   [(set_attr "type" "arith_media")])
12062
12063 (define_insn "*mextr_lr"
12064   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12065         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12066                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12067                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12068                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12069   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12070   "*
12071 {
12072   static char templ[21];
12073
12074   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12075            (int) INTVAL (operands[4]) >> 3);
12076   return templ;
12077 }"
12078   [(set_attr "type" "arith_media")])
12079
12080 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12081 ; vector then varies depending on endianness.
12082 (define_expand "mextr1"
12083   [(match_operand:DI 0 "arith_reg_dest" "")
12084    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12085    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12086   "TARGET_SHMEDIA"
12087   "
12088 {
12089   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12090                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12091   DONE;
12092 }")
12093
12094 (define_expand "mextr2"
12095   [(match_operand:DI 0 "arith_reg_dest" "")
12096    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12097    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12098   "TARGET_SHMEDIA"
12099   "
12100 {
12101   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12102                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12103   DONE;
12104 }")
12105
12106 (define_expand "mextr3"
12107   [(match_operand:DI 0 "arith_reg_dest" "")
12108    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12109    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12110   "TARGET_SHMEDIA"
12111   "
12112 {
12113   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12114                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12115   DONE;
12116 }")
12117
12118 (define_expand "mextr4"
12119   [(match_operand:DI 0 "arith_reg_dest" "")
12120    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12121    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12122   "TARGET_SHMEDIA"
12123   "
12124 {
12125   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12126                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12127   DONE;
12128 }")
12129
12130 (define_expand "mextr5"
12131   [(match_operand:DI 0 "arith_reg_dest" "")
12132    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12133    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12134   "TARGET_SHMEDIA"
12135   "
12136 {
12137   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12138                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12139   DONE;
12140 }")
12141
12142 (define_expand "mextr6"
12143   [(match_operand:DI 0 "arith_reg_dest" "")
12144    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12145    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12146   "TARGET_SHMEDIA"
12147   "
12148 {
12149   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12150                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12151   DONE;
12152 }")
12153
12154 (define_expand "mextr7"
12155   [(match_operand:DI 0 "arith_reg_dest" "")
12156    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12157    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12158   "TARGET_SHMEDIA"
12159   "
12160 {
12161   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12162                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12163   DONE;
12164 }")
12165
12166 (define_expand "mmacfx_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_mmacfx_wl_i (operands[0], operands[3],
12175                               operands[1], operands[2]));
12176   DONE;
12177 }")
12178
12179 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12180 ;; is depend
12181 (define_insn "mmacfx_wl_i"
12182   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12183         (ss_plus:V2SI
12184          (match_operand:V2SI 1 "arith_reg_operand" "0")
12185          (ss_truncate:V2SI
12186           (ashift:V2DI
12187            (sign_extend:V2DI
12188             (mult:V2SI
12189              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12190              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12191            (const_int 1)))))]
12192   "TARGET_SHMEDIA"
12193   "mmacfx.wl    %2, %3, %0"
12194   [(set_attr "type" "mac_media")
12195    (set_attr "highpart" "depend")])
12196
12197 (define_expand "mmacnfx_wl"
12198   [(match_operand:V2SI 0 "arith_reg_dest" "")
12199    (match_operand:V2HI 1 "extend_reg_operand" "")
12200    (match_operand:V2HI 2 "extend_reg_operand" "")
12201    (match_operand:V2SI 3 "arith_reg_operand" "")]
12202   "TARGET_SHMEDIA"
12203   "
12204 {
12205   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12206                                operands[1], operands[2]));
12207   DONE;
12208 }")
12209
12210 (define_insn "mmacnfx_wl_i"
12211   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12212         (ss_minus:V2SI
12213          (match_operand:V2SI 1 "arith_reg_operand" "0")
12214          (ss_truncate:V2SI
12215           (ashift:V2DI
12216            (sign_extend:V2DI
12217             (mult:V2SI
12218              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12219              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12220            (const_int 1)))))]
12221   "TARGET_SHMEDIA"
12222   "mmacnfx.wl   %2, %3, %0"
12223   [(set_attr "type" "mac_media")
12224    (set_attr "highpart" "depend")])
12225
12226 (define_insn "mulv2si3"
12227   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12228         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12229                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12230   "TARGET_SHMEDIA"
12231   "mmul.l       %1, %2, %0"
12232   [(set_attr "type" "d2mpy_media")
12233    (set_attr "highpart" "depend")])
12234
12235 (define_insn "mulv4hi3"
12236   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12237         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12238                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12239   "TARGET_SHMEDIA"
12240   "mmul.w       %1, %2, %0"
12241   [(set_attr "type" "dmpy_media")
12242    (set_attr "highpart" "depend")])
12243
12244 (define_insn "mmulfx_l"
12245   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12246         (ss_truncate:V2SI
12247          (ashiftrt:V2DI
12248           (mult:V2DI
12249            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12250            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12251           (const_int 31))))]
12252   "TARGET_SHMEDIA"
12253   "mmulfx.l     %1, %2, %0"
12254   [(set_attr "type" "d2mpy_media")
12255    (set_attr "highpart" "depend")])
12256
12257 (define_insn "mmulfx_w"
12258   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12259         (ss_truncate:V4HI
12260          (ashiftrt:V4SI
12261           (mult:V4SI
12262            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12263            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12264           (const_int 15))))]
12265   "TARGET_SHMEDIA"
12266   "mmulfx.w     %1, %2, %0"
12267   [(set_attr "type" "dmpy_media")
12268    (set_attr "highpart" "depend")])
12269
12270 (define_insn "mmulfxrp_w"
12271   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12272         (ss_truncate:V4HI
12273          (ashiftrt:V4SI
12274           (plus:V4SI
12275            (mult:V4SI
12276             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12277             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12278            (const_int 16384))
12279           (const_int 15))))]
12280   "TARGET_SHMEDIA"
12281   "mmulfxrp.w   %1, %2, %0"
12282   [(set_attr "type" "dmpy_media")
12283    (set_attr "highpart" "depend")])
12284
12285
12286 (define_expand "mmulhi_wl"
12287   [(match_operand:V2SI 0 "arith_reg_dest" "")
12288    (match_operand:V4HI 1 "arith_reg_operand" "")
12289    (match_operand:V4HI 2 "arith_reg_operand" "")]
12290   "TARGET_SHMEDIA"
12291   "
12292 {
12293   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12294              (operands[0], operands[1], operands[2]));
12295   DONE;
12296 }")
12297
12298 (define_expand "mmullo_wl"
12299   [(match_operand:V2SI 0 "arith_reg_dest" "")
12300    (match_operand:V4HI 1 "arith_reg_operand" "")
12301    (match_operand:V4HI 2 "arith_reg_operand" "")]
12302   "TARGET_SHMEDIA"
12303   "
12304 {
12305   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12306              (operands[0], operands[1], operands[2]));
12307   DONE;
12308 }")
12309
12310 (define_insn "mmul23_wl"
12311   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12312         (vec_select:V2SI
12313          (mult:V4SI
12314           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12315           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12316          (parallel [(const_int 2) (const_int 3)])))]
12317   "TARGET_SHMEDIA"
12318   "* return (TARGET_LITTLE_ENDIAN
12319              ? \"mmulhi.wl      %1, %2, %0\"
12320              : \"mmullo.wl      %1, %2, %0\");"
12321   [(set_attr "type" "dmpy_media")
12322    (set (attr "highpart")
12323         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12324          (const_string "user")))])
12325
12326 (define_insn "mmul01_wl"
12327   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12328         (vec_select:V2SI
12329          (mult:V4SI
12330           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12331           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12332          (parallel [(const_int 0) (const_int 1)])))]
12333   "TARGET_SHMEDIA"
12334   "* return (TARGET_LITTLE_ENDIAN
12335              ? \"mmullo.wl      %1, %2, %0\"
12336              : \"mmulhi.wl      %1, %2, %0\");"
12337   [(set_attr "type" "dmpy_media")
12338    (set (attr "highpart")
12339         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12340          (const_string "user")))])
12341
12342
12343 (define_expand "mmulsum_wq"
12344   [(match_operand:DI 0 "arith_reg_dest" "")
12345    (match_operand:V4HI 1 "arith_reg_operand" "")
12346    (match_operand:V4HI 2 "arith_reg_operand" "")
12347    (match_operand:DI 3 "arith_reg_operand" "")]
12348   "TARGET_SHMEDIA"
12349   "
12350 {
12351   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12352                                operands[1], operands[2]));
12353   DONE;
12354 }")
12355
12356 (define_insn "mmulsum_wq_i"
12357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12358         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12359          (plus:DI
12360           (plus:DI
12361            (vec_select:DI
12362             (mult:V4DI
12363              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12364              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12365             (parallel [(const_int 0)]))
12366            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12367                                      (sign_extend:V4DI (match_dup 3)))
12368                           (parallel [(const_int 1)])))
12369           (plus:DI
12370            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12371                                      (sign_extend:V4DI (match_dup 3)))
12372                           (parallel [(const_int 2)]))
12373            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12374                                      (sign_extend:V4DI (match_dup 3)))
12375                           (parallel [(const_int 3)]))))))]
12376   "TARGET_SHMEDIA"
12377   "mmulsum.wq   %2, %3, %0"
12378   [(set_attr "type" "mac_media")])
12379
12380 (define_expand "mperm_w"
12381   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12382    (match_operand:V4HI 1 "arith_reg_operand" "r")
12383    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12384   "TARGET_SHMEDIA"
12385   "
12386 {
12387   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12388              (operands[0], operands[1], operands[2]));
12389   DONE;
12390 }")
12391
12392 ; This use of vec_select isn't exactly correct according to rtl.texi
12393 ; (because not constant), but it seems a straightforward extension.
12394 (define_insn "mperm_w_little"
12395   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12396         (vec_select:V4HI
12397          (match_operand:V4HI 1 "arith_reg_operand" "r")
12398          (parallel
12399           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12400                             (const_int 2) (const_int 0))
12401            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12402            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12403            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12404   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12405   "mperm.w      %1, %N2, %0"
12406   [(set_attr "type" "arith_media")])
12407
12408 (define_insn "mperm_w_big"
12409   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12410         (vec_select:V4HI
12411          (match_operand:V4HI 1 "arith_reg_operand" "r")
12412          (parallel
12413           [(zero_extract:QI (not:QI (match_operand:QI 2
12414                                      "extend_reg_or_0_operand" "rZ"))
12415                             (const_int 2) (const_int 0))
12416            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12417            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12418            (zero_extract:QI (not:QI (match_dup 2))
12419                             (const_int 2) (const_int 6))])))]
12420   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12421   "mperm.w      %1, %N2, %0"
12422   [(set_attr "type" "arith_media")])
12423
12424 (define_insn "mperm_w0"
12425   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12426         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12427                                           "trunc_hi_operand" "r"))))]
12428   "TARGET_SHMEDIA"
12429   "mperm.w      %1, r63, %0"
12430   [(set_attr "type" "arith_media")
12431    (set_attr "highpart" "ignore")])
12432
12433 (define_expand "msad_ubq"
12434   [(match_operand:DI 0 "arith_reg_dest" "")
12435    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12436    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12437    (match_operand:DI 3 "arith_reg_operand" "")]
12438   "TARGET_SHMEDIA"
12439   "
12440 {
12441   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12442                              operands[1], operands[2]));
12443   DONE;
12444 }")
12445
12446 (define_insn "msad_ubq_i"
12447   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12448         (plus:DI
12449          (plus:DI
12450           (plus:DI
12451            (plus:DI
12452             (match_operand:DI 1 "arith_reg_operand" "0")
12453             (abs:DI (vec_select:DI
12454                      (minus:V8DI
12455                       (zero_extend:V8DI
12456                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12457                       (zero_extend:V8DI
12458                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12459                      (parallel [(const_int 0)]))))
12460            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12461                                               (zero_extend:V8DI (match_dup 3)))
12462                                   (parallel [(const_int 1)]))))
12463           (plus:DI
12464            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12465                                               (zero_extend:V8DI (match_dup 3)))
12466                                   (parallel [(const_int 2)])))
12467            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12468                                               (zero_extend:V8DI (match_dup 3)))
12469                                   (parallel [(const_int 3)])))))
12470          (plus:DI
12471           (plus:DI
12472            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12473                                               (zero_extend:V8DI (match_dup 3)))
12474                                   (parallel [(const_int 4)])))
12475            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12476                                               (zero_extend:V8DI (match_dup 3)))
12477                                   (parallel [(const_int 5)]))))
12478           (plus:DI
12479            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12480                                               (zero_extend:V8DI (match_dup 3)))
12481                                   (parallel [(const_int 6)])))
12482            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12483                                               (zero_extend:V8DI (match_dup 3)))
12484                                   (parallel [(const_int 7)])))))))]
12485   "TARGET_SHMEDIA"
12486   "msad.ubq     %N2, %N3, %0"
12487   [(set_attr "type" "mac_media")])
12488
12489 (define_insn "mshalds_l"
12490   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12491         (ss_truncate:V2SI
12492          (ashift:V2DI
12493           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12494           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12495                   (const_int 31)))))]
12496   "TARGET_SHMEDIA"
12497   "mshalds.l    %1, %2, %0"
12498   [(set_attr "type" "mcmp_media")
12499    (set_attr "highpart" "depend")])
12500
12501 (define_insn "mshalds_w"
12502   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12503         (ss_truncate:V4HI
12504          (ashift:V4SI
12505           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12506           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12507                   (const_int 15)))))]
12508   "TARGET_SHMEDIA"
12509   "mshalds.w    %1, %2, %0"
12510   [(set_attr "type" "mcmp_media")
12511    (set_attr "highpart" "depend")])
12512
12513 (define_insn "ashrv2si3"
12514   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12515         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12516                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12517   "TARGET_SHMEDIA"
12518   "mshard.l     %1, %2, %0"
12519   [(set_attr "type" "arith_media")
12520    (set_attr "highpart" "depend")])
12521
12522 (define_insn "ashrv4hi3"
12523   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12524         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12525                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12526   "TARGET_SHMEDIA"
12527   "mshard.w     %1, %2, %0"
12528   [(set_attr "type" "arith_media")
12529    (set_attr "highpart" "depend")])
12530
12531 (define_insn "mshards_q"
12532   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12533         (ss_truncate:HI
12534          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12535                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12536   "TARGET_SHMEDIA"
12537   "mshards.q    %1, %N2, %0"
12538   [(set_attr "type" "mcmp_media")])
12539
12540 (define_expand "mshfhi_b"
12541   [(match_operand:V8QI 0 "arith_reg_dest" "")
12542    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12543    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12544   "TARGET_SHMEDIA"
12545   "
12546 {
12547   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12548              (operands[0], operands[1], operands[2]));
12549   DONE;
12550 }")
12551
12552 (define_expand "mshflo_b"
12553   [(match_operand:V8QI 0 "arith_reg_dest" "")
12554    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12555    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12556   "TARGET_SHMEDIA"
12557   "
12558 {
12559   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12560              (operands[0], operands[1], operands[2]));
12561   DONE;
12562 }")
12563
12564 (define_insn "mshf4_b"
12565   [(set
12566     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12567     (vec_select:V8QI
12568      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12569                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12570      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12571                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12572   "TARGET_SHMEDIA"
12573   "* return (TARGET_LITTLE_ENDIAN
12574              ? \"mshfhi.b       %N1, %N2, %0\"
12575              : \"mshflo.b       %N1, %N2, %0\");"
12576   [(set_attr "type" "arith_media")
12577    (set (attr "highpart")
12578         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12579          (const_string "user")))])
12580
12581 (define_insn "mshf0_b"
12582   [(set
12583     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12584     (vec_select:V8QI
12585      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12586                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12587      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12588                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12589   "TARGET_SHMEDIA"
12590   "* return (TARGET_LITTLE_ENDIAN
12591              ? \"mshflo.b       %N1, %N2, %0\"
12592              : \"mshfhi.b       %N1, %N2, %0\");"
12593   [(set_attr "type" "arith_media")
12594    (set (attr "highpart")
12595         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12596          (const_string "user")))])
12597
12598 (define_expand "mshfhi_l"
12599   [(match_operand:V2SI 0 "arith_reg_dest" "")
12600    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12601    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12602   "TARGET_SHMEDIA"
12603   "
12604 {
12605   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12606              (operands[0], operands[1], operands[2]));
12607   DONE;
12608 }")
12609
12610 (define_expand "mshflo_l"
12611   [(match_operand:V2SI 0 "arith_reg_dest" "")
12612    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12613    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12614   "TARGET_SHMEDIA"
12615   "
12616 {
12617   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12618              (operands[0], operands[1], operands[2]));
12619   DONE;
12620 }")
12621
12622 (define_insn "mshf4_l"
12623   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12624         (vec_select:V2SI
12625          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12626                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12627          (parallel [(const_int 1) (const_int 3)])))]
12628   "TARGET_SHMEDIA"
12629   "* return (TARGET_LITTLE_ENDIAN
12630              ? \"mshfhi.l       %N1, %N2, %0\"
12631              : \"mshflo.l       %N1, %N2, %0\");"
12632   [(set_attr "type" "arith_media")
12633    (set (attr "highpart")
12634         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12635          (const_string "user")))])
12636
12637 (define_insn "mshf0_l"
12638   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12639         (vec_select:V2SI
12640          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12641                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12642          (parallel [(const_int 0) (const_int 2)])))]
12643   "TARGET_SHMEDIA"
12644   "* return (TARGET_LITTLE_ENDIAN
12645              ? \"mshflo.l       %N1, %N2, %0\"
12646              : \"mshfhi.l       %N1, %N2, %0\");"
12647   [(set_attr "type" "arith_media")
12648    (set (attr "highpart")
12649         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12650          (const_string "user")))])
12651
12652 (define_expand "mshfhi_w"
12653   [(match_operand:V4HI 0 "arith_reg_dest" "")
12654    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12655    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12656   "TARGET_SHMEDIA"
12657   "
12658 {
12659   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12660              (operands[0], operands[1], operands[2]));
12661   DONE;
12662 }")
12663
12664 (define_expand "mshflo_w"
12665   [(match_operand:V4HI 0 "arith_reg_dest" "")
12666    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12667    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12668   "TARGET_SHMEDIA"
12669   "
12670 {
12671   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12672              (operands[0], operands[1], operands[2]));
12673   DONE;
12674 }")
12675
12676 (define_insn "mshf4_w"
12677   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12678         (vec_select:V4HI
12679          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12680                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12681          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12682   "TARGET_SHMEDIA"
12683   "* return (TARGET_LITTLE_ENDIAN
12684              ? \"mshfhi.w       %N1, %N2, %0\"
12685              : \"mshflo.w       %N1, %N2, %0\");"
12686   [(set_attr "type" "arith_media")
12687    (set (attr "highpart")
12688         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12689          (const_string "user")))])
12690
12691 (define_insn "mshf0_w"
12692   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12693         (vec_select:V4HI
12694          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12695                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12696          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12697   "TARGET_SHMEDIA"
12698   "* return (TARGET_LITTLE_ENDIAN
12699              ? \"mshflo.w       %N1, %N2, %0\"
12700              : \"mshfhi.w       %N1, %N2, %0\");"
12701   [(set_attr "type" "arith_media")
12702    (set (attr "highpart")
12703         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12704          (const_string "user")))])
12705
12706 (define_insn "mshflo_w_x"
12707   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12708         (vec_select:V4HI
12709          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12710                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12711          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12712   "TARGET_SHMEDIA"
12713   "mshflo.w     %N1, %N2, %0"
12714   [(set_attr "type" "arith_media")
12715    (set_attr "highpart" "ignore")])
12716
12717 /* These are useful to expand ANDs and as combiner patterns.  */
12718 (define_insn_and_split "mshfhi_l_di"
12719   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12720         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12721                              (const_int 32))
12722                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12723                         (const_int -4294967296))))]
12724   "TARGET_SHMEDIA"
12725   "@
12726         mshfhi.l        %N1, %N2, %0
12727         #"
12728   "TARGET_SHMEDIA && reload_completed
12729    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12730   [(set (match_dup 3) (match_dup 4))
12731    (set (match_dup 5) (match_dup 6))]
12732   "
12733 {
12734   operands[3] = gen_lowpart (SImode, operands[0]);
12735   operands[4] = gen_highpart (SImode, operands[1]);
12736   operands[5] = gen_highpart (SImode, operands[0]);
12737   operands[6] = gen_highpart (SImode, operands[2]);
12738 }"
12739   [(set_attr "type" "arith_media")])
12740
12741 (define_insn "*mshfhi_l_di_rev"
12742   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12743         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12744                         (const_int -4294967296))
12745                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12746                              (const_int 32))))]
12747   "TARGET_SHMEDIA"
12748   "mshfhi.l     %N2, %N1, %0"
12749   [(set_attr "type" "arith_media")])
12750
12751 (define_split
12752   [(set (match_operand:DI 0 "arith_reg_dest" "")
12753         (ior:DI (zero_extend:DI (match_operand:SI 1
12754                                               "extend_reg_or_0_operand" ""))
12755                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12756                         (const_int -4294967296))))
12757    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12758   "TARGET_SHMEDIA"
12759   [(const_int 0)]
12760   "
12761 {
12762   emit_insn (gen_ashldi3_media (operands[3],
12763                                 simplify_gen_subreg (DImode, operands[1],
12764                                                      SImode, 0),
12765                                 GEN_INT (32)));
12766   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12767   DONE;
12768 }")
12769
12770 (define_insn "mshflo_l_di"
12771   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12772         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12773                         (const_int 4294967295))
12774                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12775                            (const_int 32))))]
12776
12777   "TARGET_SHMEDIA"
12778   "mshflo.l     %N1, %N2, %0"
12779   [(set_attr "type" "arith_media")
12780    (set_attr "highpart" "ignore")])
12781
12782 (define_insn "*mshflo_l_di_rev"
12783   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12784         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12785                            (const_int 32))
12786                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12787                         (const_int 4294967295))))]
12788
12789   "TARGET_SHMEDIA"
12790   "mshflo.l     %N2, %N1, %0"
12791   [(set_attr "type" "arith_media")
12792    (set_attr "highpart" "ignore")])
12793
12794 ;; Combiner pattern for trampoline initialization.
12795 (define_insn_and_split "*double_shori"
12796   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12797         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12798                            (const_int 32))
12799                 (match_operand:DI 2 "const_int_operand" "n")))]
12800   "TARGET_SHMEDIA
12801    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12802   "#"
12803   "rtx_equal_p (operands[0], operands[1])"
12804   [(const_int 0)]
12805   "
12806 {
12807   HOST_WIDE_INT v = INTVAL (operands[2]);
12808
12809   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12810   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12811   DONE;
12812 }"
12813   [(set_attr "highpart" "ignore")])
12814
12815
12816 (define_insn "*mshflo_l_di_x"
12817   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12818         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12819                                  "rZ"))
12820                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12821                            (const_int 32))))]
12822
12823   "TARGET_SHMEDIA"
12824   "mshflo.l     %N1, %N2, %0"
12825   [(set_attr "type" "arith_media")
12826    (set_attr "highpart" "ignore")])
12827
12828 (define_insn_and_split "concat_v2sf"
12829   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12830 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12831         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12832                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12833
12834   "TARGET_SHMEDIA"
12835   "@
12836         mshflo.l        %N1, %N2, %0
12837         #
12838         #"
12839   "TARGET_SHMEDIA && reload_completed
12840    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12841   [(set (match_dup 3) (match_dup 1))
12842    (set (match_dup 4) (match_dup 2))]
12843   "
12844 {
12845   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12846   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12847 }"
12848   [(set_attr "type" "arith_media")
12849    (set_attr "highpart" "ignore")])
12850
12851 (define_insn "*mshflo_l_di_x_rev"
12852   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12853         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12854                            (const_int 32))
12855                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12856
12857   "TARGET_SHMEDIA"
12858   "mshflo.l     %N2, %N1, %0"
12859   [(set_attr "type" "arith_media")
12860    (set_attr "highpart" "ignore")])
12861
12862 (define_insn "ashlv2si3"
12863   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12864         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12865                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12866   "TARGET_SHMEDIA"
12867   "mshlld.l     %1, %2, %0"
12868   [(set_attr "type" "arith_media")
12869    (set_attr "highpart" "depend")])
12870
12871 (define_split
12872   [(set (match_operand 0 "any_register_operand" "")
12873         (match_operator 3 "shift_operator"
12874           [(match_operand 1 "any_register_operand" "")
12875            (match_operand 2 "shift_count_reg_operand" "")]))]
12876   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12877   [(set (match_dup 0) (match_dup 3))]
12878   "
12879 {
12880   rtx count = operands[2];
12881   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12882
12883   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12884          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12885          || GET_CODE (count) == TRUNCATE)
12886     count = XEXP (count, 0);
12887   inner_mode = GET_MODE (count);
12888   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12889                                subreg_lowpart_offset (outer_mode, inner_mode));
12890   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12891                                 operands[1], count);
12892 }")
12893
12894 (define_insn "ashlv4hi3"
12895   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12896         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12897                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12898   "TARGET_SHMEDIA"
12899   "mshlld.w     %1, %2, %0"
12900   [(set_attr "type" "arith_media")
12901    (set_attr "highpart" "depend")])
12902
12903 (define_insn "lshrv2si3"
12904   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12905         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12906                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12907   "TARGET_SHMEDIA"
12908   "mshlrd.l     %1, %2, %0"
12909   [(set_attr "type" "arith_media")
12910    (set_attr "highpart" "depend")])
12911
12912 (define_insn "lshrv4hi3"
12913   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12914         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12915                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12916   "TARGET_SHMEDIA"
12917   "mshlrd.w     %1, %2, %0"
12918   [(set_attr "type" "arith_media")
12919    (set_attr "highpart" "depend")])
12920
12921 (define_insn "subv2si3"
12922   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12923         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12924                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12925   "TARGET_SHMEDIA"
12926   "msub.l       %N1, %2, %0"
12927   [(set_attr "type" "arith_media")
12928    (set_attr "highpart" "depend")])
12929
12930 (define_insn "subv4hi3"
12931   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12932         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12933                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12934   "TARGET_SHMEDIA"
12935   "msub.w       %N1, %2, %0"
12936   [(set_attr "type" "arith_media")
12937    (set_attr "highpart" "depend")])
12938
12939 (define_insn_and_split "subv2hi3"
12940   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12941         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12942                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12943   "TARGET_SHMEDIA"
12944   "#"
12945   "TARGET_SHMEDIA"
12946   [(const_int 0)]
12947   "
12948 {
12949   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12950   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12951   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12952   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12953   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12954
12955   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12956   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12957   DONE;
12958 }"
12959   [(set_attr "highpart" "must_split")])
12960
12961 (define_insn "sssubv2si3"
12962   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12963         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12964                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12965   "TARGET_SHMEDIA"
12966   "msubs.l      %N1, %2, %0"
12967   [(set_attr "type" "mcmp_media")
12968    (set_attr "highpart" "depend")])
12969
12970 (define_insn "ussubv8qi3"
12971   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12972         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12973                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12974   "TARGET_SHMEDIA"
12975   "msubs.ub     %N1, %2, %0"
12976   [(set_attr "type" "mcmp_media")
12977    (set_attr "highpart" "depend")])
12978
12979 (define_insn "sssubv4hi3"
12980   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12981         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12982                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12983   "TARGET_SHMEDIA"
12984   "msubs.w      %N1, %2, %0"
12985   [(set_attr "type" "mcmp_media")
12986    (set_attr "highpart" "depend")])
12987
12988 ;; Floating Point Intrinsics
12989
12990 (define_insn "fcosa_s"
12991   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12992         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12993                    UNSPEC_FCOSA))]
12994   "TARGET_SHMEDIA"
12995   "fcosa.s      %1, %0"
12996   [(set_attr "type" "atrans_media")])
12997
12998 (define_insn "fsina_s"
12999   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13000         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13001                    UNSPEC_FSINA))]
13002   "TARGET_SHMEDIA"
13003   "fsina.s      %1, %0"
13004   [(set_attr "type" "atrans_media")])
13005
13006 (define_insn "fipr"
13007   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13008         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13009                                                     "fp_arith_reg_operand" "f")
13010                                                    (match_operand:V4SF 2
13011                                                     "fp_arith_reg_operand" "f"))
13012                                          (parallel [(const_int 0)]))
13013                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13014                                          (parallel [(const_int 1)])))
13015                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13016                                          (parallel [(const_int 2)]))
13017                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13018                                          (parallel [(const_int 3)])))))]
13019   "TARGET_SHMEDIA"
13020   "fipr.s       %1, %2, %0"
13021   [(set_attr "type" "fparith_media")])
13022
13023 (define_insn "fsrra_s"
13024   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13025         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13026                    UNSPEC_FSRRA))]
13027   "TARGET_SHMEDIA"
13028   "fsrra.s      %1, %0"
13029   [(set_attr "type" "atrans_media")])
13030
13031 (define_insn "ftrv"
13032   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13033         (plus:V4SF
13034          (plus:V4SF
13035           (mult:V4SF
13036            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13037                             (parallel [(const_int 0) (const_int 5)
13038                                        (const_int 10) (const_int 15)]))
13039            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13040           (mult:V4SF
13041            (vec_select:V4SF (match_dup 1)
13042                             (parallel [(const_int 4) (const_int 9)
13043                                        (const_int 14) (const_int 3)]))
13044            (vec_select:V4SF (match_dup 2)
13045                             (parallel [(const_int 1) (const_int 2)
13046                                        (const_int 3) (const_int 0)]))))
13047          (plus:V4SF
13048           (mult:V4SF
13049            (vec_select:V4SF (match_dup 1)
13050                             (parallel [(const_int 8) (const_int 13)
13051                                        (const_int 2) (const_int 7)]))
13052            (vec_select:V4SF (match_dup 2)
13053                             (parallel [(const_int 2) (const_int 3)
13054                                        (const_int 0) (const_int 1)])))
13055           (mult:V4SF
13056            (vec_select:V4SF (match_dup 1)
13057                             (parallel [(const_int 12) (const_int 1)
13058                                        (const_int 6) (const_int 11)]))
13059            (vec_select:V4SF (match_dup 2)
13060                             (parallel [(const_int 3) (const_int 0)
13061                                        (const_int 1) (const_int 2)]))))))]
13062   "TARGET_SHMEDIA"
13063   "ftrv.s %1, %2, %0"
13064   [(set_attr "type" "fparith_media")])
13065
13066 (define_insn "ldhi_l"
13067   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13068         (zero_extract:SI
13069          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13070                                   (const_int 3))
13071                           (const_int -3)))
13072          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13073          (const_int 0)))]
13074   "TARGET_SHMEDIA32"
13075   "ldhi.l       %U1, %0"
13076   [(set_attr "type" "load_media")])
13077
13078 (define_insn "ldhi_q"
13079   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13080         (zero_extract:DI
13081          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13082                                   (const_int 7))
13083                           (const_int -7)))
13084          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13085          (const_int 0)))]
13086   "TARGET_SHMEDIA32"
13087   "ldhi.q       %U1, %0"
13088   [(set_attr "type" "load_media")])
13089
13090 (define_insn_and_split "*ldhi_q_comb0"
13091   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13092         (zero_extract:DI
13093          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13094                                             "register_operand" "r")
13095                                            (match_operand:SI 2
13096                                             "ua_offset" "I06"))
13097                                   (const_int 7))
13098                           (const_int -7)))
13099          (plus:SI (and:SI (match_dup 1) (const_int 7))
13100                   (const_int 1))
13101          (const_int 0)))]
13102   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13103   "#"
13104   ""
13105   [(pc)]
13106   "emit_insn (gen_ldhi_q (operands[0],
13107                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13108    DONE;")
13109
13110
13111 (define_insn_and_split "*ldhi_q_comb1"
13112   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13113         (zero_extract:DI
13114          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13115                                             "register_operand" "r")
13116                                            (match_operand:SI 2
13117                                             "ua_offset" "I06"))
13118                                   (const_int 7))
13119                           (const_int -7)))
13120          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13121                                                    "ua_offset" "I06"))
13122                           (const_int 7))
13123                   (const_int 1))
13124          (const_int 0)))]
13125   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13126    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13127   "#"
13128   ""
13129   [(pc)]
13130   "emit_insn (gen_ldhi_q (operands[0],
13131                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13132    DONE;")
13133
13134
13135 (define_insn "ldlo_l"
13136   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13137         (zero_extract:SI
13138          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13139                          (const_int -4)))
13140          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13141          (and:SI (match_dup 1) (const_int 3))))]
13142   "TARGET_SHMEDIA32"
13143   "ldlo.l       %U1, %0"
13144   [(set_attr "type" "load_media")])
13145
13146 (define_insn "ldlo_q"
13147   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13148         (zero_extract:DI
13149          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13150                          (const_int -8)))
13151          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13152          (and:SI (match_dup 1) (const_int 7))))]
13153   "TARGET_SHMEDIA32"
13154   "ldlo.q       %U1, %0"
13155   [(set_attr "type" "load_media")])
13156
13157 (define_insn_and_split "*ldlo_q_comb0"
13158   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13159         (zero_extract:DI
13160          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13161                                   (match_operand:SI 2 "ua_offset" "I06"))
13162                          (const_int -8)))
13163          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13164          (and:SI (match_dup 1) (const_int 7))))]
13165   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13166   "#"
13167   ""
13168   [(pc)]
13169   "emit_insn (gen_ldlo_q (operands[0],
13170                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13171    DONE;")
13172
13173 (define_insn_and_split "*ldlo_q_comb1"
13174   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13175         (zero_extract:DI
13176          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13177                                   (match_operand:SI 2 "ua_offset" "I06"))
13178                          (const_int -8)))
13179          (minus:SI (const_int 8)
13180                    (and:SI (plus:SI (match_dup 1)
13181                                     (match_operand:SI 3 "ua_offset" "I06"))
13182                            (const_int 7)))
13183          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13184   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13185    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13186   "#"
13187   ""
13188   [(pc)]
13189   "emit_insn (gen_ldlo_q (operands[0],
13190                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13191    DONE;")
13192
13193 (define_insn "sthi_l"
13194   [(set (zero_extract:SI
13195          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13196                                   (const_int 3))
13197                           (const_int -3)))
13198          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13199          (const_int 0))
13200         (match_operand:SI 1 "arith_reg_operand" "r"))]
13201   "TARGET_SHMEDIA32"
13202   "sthi.l       %U0, %1"
13203   [(set_attr "type" "ustore_media")])
13204
13205 ;; All unaligned stores are considered to be 'narrow' because they typically
13206 ;; operate on less that a quadword, and when they operate on a full quadword,
13207 ;; the vanilla store high / store low sequence will cause a stall if not
13208 ;; scheduled apart.
13209 (define_insn "sthi_q"
13210   [(set (zero_extract:DI
13211          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13212                                   (const_int 7))
13213                           (const_int -7)))
13214          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13215          (const_int 0))
13216         (match_operand:DI 1 "arith_reg_operand" "r"))]
13217   "TARGET_SHMEDIA32"
13218   "sthi.q       %U0, %1"
13219   [(set_attr "type" "ustore_media")])
13220
13221 (define_insn_and_split "*sthi_q_comb0"
13222   [(set (zero_extract:DI
13223          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13224                                             "register_operand" "r")
13225                                            (match_operand:SI 1 "ua_offset"
13226                                             "I06"))
13227                                   (const_int 7))
13228                           (const_int -7)))
13229          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13230          (const_int 0))
13231         (match_operand:DI 2 "arith_reg_operand" "r"))]
13232   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13233   "#"
13234   ""
13235   [(pc)]
13236   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13237                           operands[2]));
13238    DONE;")
13239
13240 (define_insn_and_split "*sthi_q_comb1"
13241   [(set (zero_extract:DI
13242          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13243                                             "register_operand" "r")
13244                                            (match_operand:SI 1 "ua_offset"
13245                                             "I06"))
13246                                   (const_int 7))
13247                           (const_int -7)))
13248          (plus:SI (and:SI (plus:SI (match_dup 0)
13249                                    (match_operand:SI 2 "ua_offset" "I06"))
13250                           (const_int 7))
13251                   (const_int 1))
13252          (const_int 0))
13253         (match_operand:DI 3 "arith_reg_operand" "r"))]
13254   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13255    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13256   "#"
13257   ""
13258   [(pc)]
13259   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13260                           operands[3]));
13261    DONE;")
13262
13263 ;; This is highpart user because the address is used as full 64 bit.
13264 (define_insn "stlo_l"
13265   [(set (zero_extract:SI
13266          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13267                          (const_int -4)))
13268          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13269          (and:SI (match_dup 0) (const_int 3)))
13270         (match_operand:SI 1 "arith_reg_operand" "r"))]
13271   "TARGET_SHMEDIA32"
13272   "stlo.l       %U0, %1"
13273   [(set_attr "type" "ustore_media")])
13274
13275 (define_insn "stlo_q"
13276   [(set (zero_extract:DI
13277          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13278                          (const_int -8)))
13279          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13280          (and:SI (match_dup 0) (const_int 7)))
13281         (match_operand:DI 1 "arith_reg_operand" "r"))]
13282   "TARGET_SHMEDIA32"
13283   "stlo.q       %U0, %1"
13284   [(set_attr "type" "ustore_media")])
13285
13286 (define_insn_and_split "*stlo_q_comb0"
13287   [(set (zero_extract:DI
13288          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13289                                   (match_operand:SI 1 "ua_offset" "I06"))
13290                          (const_int -8)))
13291          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13292          (and:SI (match_dup 0) (const_int 7)))
13293         (match_operand:DI 2 "arith_reg_operand" "r"))]
13294   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13295   "#"
13296   ""
13297   [(pc)]
13298   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13299                           operands[2]));
13300    DONE;")
13301
13302 (define_insn_and_split "*stlo_q_comb1"
13303   [(set (zero_extract:DI
13304          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13305                                   (match_operand:SI 1 "ua_offset" "I06"))
13306                          (const_int -8)))
13307          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13308                                                   (match_operand:SI 2
13309                                                    "ua_offset" "I06"))
13310                                          (const_int 7)))
13311          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13312         (match_operand:DI 3 "arith_reg_operand" "r"))]
13313   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13314   "#"
13315   ""
13316   [(pc)]
13317   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13318                           operands[3]));
13319    DONE;")
13320
13321 (define_insn "ldhi_l64"
13322   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13323         (zero_extract:SI
13324          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13325                                   (const_int 3))
13326                           (const_int -3)))
13327          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13328          (const_int 0)))]
13329   "TARGET_SHMEDIA64"
13330   "ldhi.l       %U1, %0"
13331   [(set_attr "type" "load_media")])
13332
13333 (define_insn "ldhi_q64"
13334   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13335         (zero_extract:DI
13336          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13337                                   (const_int 7))
13338                           (const_int -7)))
13339          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13340          (const_int 0)))]
13341   "TARGET_SHMEDIA64"
13342   "ldhi.q       %U1, %0"
13343   [(set_attr "type" "load_media")])
13344
13345 (define_insn "ldlo_l64"
13346   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13347         (zero_extract:SI
13348          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13349                          (const_int -4)))
13350          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13351          (and:DI (match_dup 1) (const_int 3))))]
13352   "TARGET_SHMEDIA64"
13353   "ldlo.l       %U1, %0"
13354   [(set_attr "type" "load_media")])
13355
13356 (define_insn "ldlo_q64"
13357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13358         (zero_extract:DI
13359          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13360                          (const_int -8)))
13361          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13362          (and:DI (match_dup 1) (const_int 7))))]
13363   "TARGET_SHMEDIA64"
13364   "ldlo.q       %U1, %0"
13365   [(set_attr "type" "load_media")])
13366
13367 (define_insn "sthi_l64"
13368   [(set (zero_extract:SI
13369          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13370                                   (const_int 3))
13371                           (const_int -3)))
13372          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13373          (const_int 0))
13374         (match_operand:SI 1 "arith_reg_operand" "r"))]
13375   "TARGET_SHMEDIA64"
13376   "sthi.l       %U0, %1"
13377   [(set_attr "type" "ustore_media")])
13378
13379 (define_insn "sthi_q64"
13380   [(set (zero_extract:DI
13381          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13382                                   (const_int 7))
13383                           (const_int -7)))
13384          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13385          (const_int 0))
13386         (match_operand:DI 1 "arith_reg_operand" "r"))]
13387   "TARGET_SHMEDIA64"
13388   "sthi.q       %U0, %1"
13389   [(set_attr "type" "ustore_media")])
13390
13391 (define_insn "stlo_l64"
13392   [(set (zero_extract:SI
13393          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13394                          (const_int -4)))
13395          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13396          (and:DI (match_dup 0) (const_int 3)))
13397         (match_operand:SI 1 "arith_reg_operand" "r"))]
13398   "TARGET_SHMEDIA64"
13399   "stlo.l       %U0, %1"
13400   [(set_attr "type" "ustore_media")])
13401
13402 (define_insn "stlo_q64"
13403   [(set (zero_extract:DI
13404          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13405                          (const_int -8)))
13406          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13407          (and:DI (match_dup 0) (const_int 7)))
13408         (match_operand:DI 1 "arith_reg_operand" "r"))]
13409   "TARGET_SHMEDIA64"
13410   "stlo.q       %U0, %1"
13411   [(set_attr "type" "ustore_media")])
13412
13413 (define_insn "nsb"
13414   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13415         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13416                    UNSPEC_NSB))]
13417   "TARGET_SHMEDIA"
13418   "nsb  %1, %0"
13419   [(set_attr "type" "arith_media")])
13420
13421 (define_insn "nsbsi"
13422   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13423         (zero_extend:SI
13424          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13425                     UNSPEC_NSB)))]
13426   "TARGET_SHMEDIA"
13427   "nsb  %1, %0"
13428   [(set_attr "type" "arith_media")])
13429
13430 (define_insn "nsbdi"
13431   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13432         (zero_extend:DI
13433          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13434                     UNSPEC_NSB)))]
13435   "TARGET_SHMEDIA"
13436   "nsb  %1, %0"
13437   [(set_attr "type" "arith_media")])
13438
13439 (define_expand "ffsdi2"
13440   [(set (match_operand:DI 0 "arith_reg_dest" "")
13441         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13442   "TARGET_SHMEDIA"
13443   "
13444 {
13445   rtx scratch = gen_reg_rtx (DImode);
13446   rtx last;
13447
13448   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13449   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13450   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13451   emit_insn (gen_nsbdi (scratch, scratch));
13452   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13453   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13454   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13455   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13456
13457   DONE;
13458 }")
13459
13460 (define_expand "ffssi2"
13461   [(set (match_operand:SI 0 "arith_reg_dest" "")
13462         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13463   "TARGET_SHMEDIA"
13464   "
13465 {
13466   rtx scratch = gen_reg_rtx (SImode);
13467   rtx discratch = gen_reg_rtx (DImode);
13468   rtx last;
13469
13470   emit_insn (gen_adddi3 (discratch,
13471                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13472                          constm1_rtx));
13473   emit_insn (gen_andcdi3 (discratch,
13474                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13475                           discratch));
13476   emit_insn (gen_nsbsi (scratch, discratch));
13477   last = emit_insn (gen_subsi3 (operands[0],
13478                                 force_reg (SImode, GEN_INT (63)), scratch));
13479   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13480
13481   DONE;
13482 }")
13483
13484 (define_insn "byterev"
13485   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13486         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13487                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13488                                     (const_int 4) (const_int 3) (const_int 2)
13489                                     (const_int 1) (const_int 0)])))]
13490   "TARGET_SHMEDIA"
13491   "byterev      %1, %0"
13492   [(set_attr "type" "arith_media")])
13493
13494 (define_insn "*prefetch_media"
13495   [(prefetch (match_operand:QI 0 "address_operand" "p")
13496              (match_operand:SI 1 "const_int_operand" "n")
13497              (match_operand:SI 2 "const_int_operand" "n"))]
13498   "TARGET_SHMEDIA"
13499   "*
13500 {
13501   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13502   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13503   return \"\";
13504 }"
13505   [(set_attr "type" "other")])
13506
13507 (define_insn "*prefetch_i4"
13508   [(prefetch (match_operand:SI 0 "register_operand" "r")
13509              (match_operand:SI 1 "const_int_operand" "n")
13510              (match_operand:SI 2 "const_int_operand" "n"))]
13511   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13512   "*
13513 {
13514   return \"pref @%0\";
13515 }"
13516   [(set_attr "type" "other")])
13517
13518 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13519 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13520 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13521 (define_expand "prefetch"
13522   [(prefetch (match_operand 0 "address_operand" "p")
13523              (match_operand:SI 1 "const_int_operand" "n")
13524              (match_operand:SI 2 "const_int_operand" "n"))]
13525   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13526    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13527   "
13528 {
13529   if (GET_MODE (operands[0]) != Pmode
13530       || !CONST_INT_P (operands[1])
13531       || !CONST_INT_P (operands[2]))
13532     FAIL;
13533   if (! TARGET_SHMEDIA)
13534     operands[0] = force_reg (Pmode, operands[0]);
13535 }")
13536
13537 (define_insn "prefetch_m2a"
13538   [(prefetch (match_operand:SI 0 "register_operand" "r")
13539              (match_operand:SI 1 "const_int_operand" "n")
13540              (match_operand:SI 2 "const_int_operand" "n"))]
13541   "TARGET_SH2A"
13542   "pref\\t@%0"
13543   [(set_attr "type" "other")])
13544
13545 (define_insn "alloco_i"
13546   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13547         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13548   "TARGET_SHMEDIA32"
13549   "*
13550 {
13551   rtx xops[2];
13552
13553   if (GET_CODE (operands[0]) == PLUS)
13554     {
13555       xops[0] = XEXP (operands[0], 0);
13556       xops[1] = XEXP (operands[0], 1);
13557     }
13558   else
13559     {
13560       xops[0] = operands[0];
13561       xops[1] = const0_rtx;
13562     }
13563   output_asm_insn (\"alloco   %0, %1\", xops);
13564   return \"\";
13565 }"
13566   [(set_attr "type" "other")])
13567
13568 (define_split
13569   [(set (match_operand 0 "any_register_operand" "")
13570         (match_operand 1 "" ""))]
13571   "TARGET_SHMEDIA && reload_completed"
13572   [(set (match_dup 0) (match_dup 1))]
13573   "
13574 {
13575   int n_changes = 0;
13576
13577   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13578   if (!n_changes)
13579     FAIL;
13580 }")
13581
13582 ; Stack Protector Patterns
13583
13584 (define_expand "stack_protect_set"
13585   [(set (match_operand 0 "memory_operand" "")
13586         (match_operand 1 "memory_operand" ""))]
13587   ""
13588 {
13589   if (TARGET_SHMEDIA)
13590     {
13591       if (TARGET_SHMEDIA64)
13592         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13593       else
13594         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13595     }
13596   else
13597     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13598
13599   DONE;
13600 })
13601
13602 (define_insn "stack_protect_set_si"
13603   [(set (match_operand:SI 0 "memory_operand" "=m")
13604         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13605    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13606   "!TARGET_SHMEDIA"
13607   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13608   [(set_attr "type" "other")
13609    (set_attr "length" "6")])
13610
13611 (define_insn "stack_protect_set_si_media"
13612   [(set (match_operand:SI 0 "memory_operand" "=m")
13613         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13614    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13615   "TARGET_SHMEDIA"
13616   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13617   [(set_attr "type" "other")
13618    (set_attr "length" "12")])
13619
13620 (define_insn "stack_protect_set_di_media"
13621   [(set (match_operand:DI 0 "memory_operand" "=m")
13622         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13623    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13624   "TARGET_SHMEDIA64"
13625   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13626   [(set_attr "type" "other")
13627    (set_attr "length" "12")])
13628
13629 (define_expand "stack_protect_test"
13630   [(match_operand 0 "memory_operand" "")
13631    (match_operand 1 "memory_operand" "")
13632    (match_operand 2 "" "")]
13633   ""
13634 {
13635   if (TARGET_SHMEDIA)
13636     {
13637       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13638       rtx test;
13639
13640       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13641       if (TARGET_SHMEDIA64)
13642         {
13643           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13644                                                       operands[1]));
13645           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13646         }
13647       else
13648         {
13649           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13650                                                       operands[1]));
13651           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13652         }
13653     }
13654   else
13655     {
13656       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13657       emit_jump_insn (gen_branch_true (operands[2]));
13658     }
13659
13660   DONE;
13661 })
13662
13663 (define_insn "stack_protect_test_si"
13664   [(set (reg:SI T_REG)
13665         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13666                     (match_operand:SI 1 "memory_operand" "m")]
13667                    UNSPEC_SP_TEST))
13668   (set (match_scratch:SI 2 "=&r") (const_int 0))
13669   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13670   "!TARGET_SHMEDIA"
13671   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13672   [(set_attr "type" "other")
13673    (set_attr "length" "10")])
13674
13675 (define_insn "stack_protect_test_si_media"
13676   [(set (match_operand:SI 0 "register_operand" "=&r")
13677         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13678                     (match_operand:SI 2 "memory_operand" "m")]
13679                    UNSPEC_SP_TEST))
13680   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13681   "TARGET_SHMEDIA"
13682   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13683   [(set_attr "type" "other")
13684    (set_attr "length" "16")])
13685
13686 (define_insn "stack_protect_test_di_media"
13687   [(set (match_operand:DI 0 "register_operand" "=&r")
13688         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13689                     (match_operand:DI 2 "memory_operand" "m")]
13690                    UNSPEC_SP_TEST))
13691   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13692   "TARGET_SHMEDIA64"
13693   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13694   [(set_attr "type" "other")
13695    (set_attr "length" "16")])