OSDN Git Service

Update Copyright years for files modified in 2008 and/or 2009.
[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 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
26
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
29
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
31
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
34
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
37
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
42 ;; Special constraints for SH machine description:
43 ;;
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
48 ;;
49 ;; Special formats used for outputting SH instructions:
50 ;;
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
58 ;;
59 ;; Special predicates:
60 ;;
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
66
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
70
71 (define_constants [
72   (AP_REG       145)
73   (PR_REG       146)
74   (T_REG        147)
75   (GBR_REG      144)
76   (MACH_REG     148)
77   (MACL_REG     149)
78   (FPUL_REG     150)
79   (RAP_REG      152)
80
81   (FPSCR_REG    151)
82
83   (PIC_REG      12)
84   (FP_REG       14)
85   (SP_REG       15)
86
87   (PR_MEDIA_REG 18)
88   (T_MEDIA_REG  19)
89
90   (R0_REG       0)
91   (R1_REG       1)
92   (R2_REG       2)
93   (R3_REG       3)
94   (R4_REG       4)
95   (R5_REG       5)
96   (R6_REG       6)
97   (R7_REG       7)
98   (R8_REG       8)
99   (R9_REG       9)
100   (R10_REG      10)
101   (R20_REG      20)
102   (R21_REG      21)
103   (R22_REG      22)
104   (R23_REG      23)
105
106   (DR0_REG      64)
107   (DR2_REG      66)
108   (DR4_REG      68)
109   (FR23_REG     87)
110
111   (TR0_REG      128)
112   (TR1_REG      129)
113   (TR2_REG      130)
114
115   (XD0_REG      136)
116
117   ;; These are used with unspec.
118   (UNSPEC_COMPACT_ARGS  0)
119   (UNSPEC_MOVA          1)
120   (UNSPEC_CASESI        2)
121   (UNSPEC_DATALABEL     3)
122   (UNSPEC_BBR           4)
123   (UNSPEC_SFUNC         5)
124   (UNSPEC_PIC           6)
125   (UNSPEC_GOT           7)
126   (UNSPEC_GOTOFF        8)
127   (UNSPEC_PLT           9)
128   (UNSPEC_CALLER        10)
129   (UNSPEC_GOTPLT        11)
130   (UNSPEC_ICACHE        12)
131   (UNSPEC_INIT_TRAMP    13)
132   (UNSPEC_FCOSA         14)
133   (UNSPEC_FSRRA         15)
134   (UNSPEC_FSINA         16)
135   (UNSPEC_NSB           17)
136   (UNSPEC_ALLOCO        18)
137   (UNSPEC_TLSGD         20)
138   (UNSPEC_TLSLDM        21)
139   (UNSPEC_TLSIE         22)
140   (UNSPEC_DTPOFF        23)
141   (UNSPEC_GOTTPOFF      24)
142   (UNSPEC_TPOFF         25)
143   (UNSPEC_RA            26)
144   (UNSPEC_DIV_INV_M0    30)
145   (UNSPEC_DIV_INV_M1    31)
146   (UNSPEC_DIV_INV_M2    32)
147   (UNSPEC_DIV_INV_M3    33)
148   (UNSPEC_DIV_INV20     34)
149   (UNSPEC_DIV_INV_TABLE 37)
150   (UNSPEC_ASHIFTRT      35)
151   (UNSPEC_THUNK         36)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
155
156   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158   (UNSPEC_EXTRACT_S16   43)
159   (UNSPEC_EXTRACT_U16   44)
160
161   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
162   (UNSPEC_SYMOFF        45)
163
164   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165   (UNSPEC_PCREL_SYMOFF  46)
166
167   ;; These are used with unspec_volatile.
168   (UNSPECV_BLOCKAGE     0)
169   (UNSPECV_ALIGN        1)
170   (UNSPECV_CONST2       2)
171   (UNSPECV_CONST4       4)
172   (UNSPECV_CONST8       6)
173   (UNSPECV_WINDOW_END   10)
174   (UNSPECV_CONST_END    11)
175   (UNSPECV_EH_RETURN    12)
176 ])
177
178 ;; -------------------------------------------------------------------------
179 ;; Attributes
180 ;; -------------------------------------------------------------------------
181
182 ;; Target CPU.
183
184 (define_attr "cpu"
185  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
186   (const (symbol_ref "sh_cpu_attr")))
187
188 (define_attr "endian" "big,little"
189  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
190                       (const_string "little") (const_string "big"))))
191
192 ;; Indicate if the default fpu mode is single precision.
193 (define_attr "fpu_single" "yes,no"
194   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
195                          (const_string "yes") (const_string "no"))))
196
197 (define_attr "fmovd" "yes,no"
198   (const (if_then_else (symbol_ref "TARGET_FMOVD")
199                        (const_string "yes") (const_string "no"))))
200 ;; pipeline model
201 (define_attr "pipe_model" "sh1,sh4,sh5media"
202   (const
203    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
204           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
205          (const_string "sh1"))))
206
207 ;; cbranch      conditional branch instructions
208 ;; jump         unconditional jumps
209 ;; arith        ordinary arithmetic
210 ;; arith3       a compound insn that behaves similarly to a sequence of
211 ;;              three insns of type arith
212 ;; arith3b      like above, but might end with a redirected branch
213 ;; load         from memory
214 ;; load_si      Likewise, SImode variant for general register.
215 ;; fload        Likewise, but load to fp register.
216 ;; store        to memory
217 ;; fstore       floating point register to memory
218 ;; move         general purpose register to register
219 ;; movi8        8-bit immediate to general purpose register
220 ;; mt_group     other sh4 mt instructions
221 ;; fmove        register to register, floating point
222 ;; smpy         word precision integer multiply
223 ;; dmpy         longword or doublelongword precision integer multiply
224 ;; return       rts
225 ;; pload        load of pr reg, which can't be put into delay slot of rts
226 ;; prset        copy register to pr reg, ditto
227 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
228 ;; prget        copy pr to register, ditto
229 ;; pcload       pc relative load of constant value
230 ;; pcfload      Likewise, but load to fp register.
231 ;; pcload_si    Likewise, SImode variant for general register.
232 ;; rte          return from exception
233 ;; sfunc        special function call with known used registers
234 ;; call         function call
235 ;; fp           floating point
236 ;; fpscr_toggle toggle a bit in the fpscr
237 ;; fdiv         floating point divide (or square root)
238 ;; gp_fpul      move from general purpose register to fpul
239 ;; fpul_gp      move from fpul to general purpose register
240 ;; mac_gp       move from mac[lh] to general purpose register
241 ;; gp_mac       move from general purpose register to mac[lh]
242 ;; mac_mem      move from mac[lh] to memory
243 ;; mem_mac      move from memory to mac[lh]
244 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
245 ;; ftrc_s       fix_truncsfsi2_i4
246 ;; dfdiv        double precision floating point divide (or square root)
247 ;; cwb          ic_invalidate_line_i
248 ;; movua        SH4a unaligned load
249 ;; fsrra        square root reciprocal approximate
250 ;; fsca         sine and cosine approximate
251 ;; tls_load     load TLS related address
252 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
253 ;; cbranch_media SHmedia conditional branch instructions
254 ;; cmp_media    SHmedia compare instructions
255 ;; dfdiv_media  SHmedia double precision divide and square root
256 ;; dfmul_media  SHmedia double precision multiply instruction
257 ;; dfparith_media SHmedia double precision floating point arithmetic
258 ;; dfpconv_media SHmedia double precision floating point conversions
259 ;; dmpy_media   SHmedia longword multiply
260 ;; fcmp_media   SHmedia floating point compare instructions
261 ;; fdiv_media   SHmedia single precision divide and square root
262 ;; fload_media  SHmedia floating point register load instructions
263 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
264 ;; fparith_media SHmedia single precision floating point arithmetic
265 ;; fpconv_media SHmedia single precision floating point conversions
266 ;; fstore_media SHmedia floating point register store instructions
267 ;; gettr_media  SHmedia gettr instruction
268 ;; invalidate_line_media SHmedia invalidate_line sequence
269 ;; jump_media   SHmedia unconditional branch instructions
270 ;; load_media   SHmedia general register load instructions
271 ;; pt_media     SHmedia pt instruction (expanded by assembler)
272 ;; ptabs_media  SHmedia ptabs instruction
273 ;; store_media  SHmedia general register store instructions
274 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
275 ;; mac_media    SHmedia mac-style fixed point operations
276 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
277 ;; atrans_media SHmedia approximate transcendental functions
278 ;; ustore_media SHmedia unaligned stores
279 ;; nil          no-op move, will be deleted.
280
281 (define_attr "type"
282  "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"
283   (const_string "other"))
284
285 ;; We define a new attribute namely "insn_class".We use
286 ;; this for the DFA based pipeline description.
287 ;;
288 ;; mt_group      SH4 "mt" group instructions.
289 ;;
290 ;; ex_group      SH4 "ex" group instructions.
291 ;;
292 ;; ls_group      SH4 "ls" group instructions.
293 ;;
294
295 (define_attr "insn_class"
296   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
297   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
298          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
299          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
300          (eq_attr "type" "cbranch,jump") (const_string "br_group")
301          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
302            (const_string "fe_group")
303          (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")]
304         (const_string "none")))
305 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
306 ;; so these do not belong in an insn group, although they are modeled
307 ;; with their own define_insn_reservations.
308
309 ;; Indicate what precision must be selected in fpscr for this insn, if any.
310
311 (define_attr "fp_mode" "single,double,none" (const_string "none"))
312
313 ;; Indicate if the fpu mode is set by this instruction
314 ;; "unknown" must have the value as "none" in fp_mode, and means
315 ;; that the instruction/abi has left the processor in an unknown
316 ;; state.
317 ;; "none" means that nothing has changed and no mode is set.
318 ;; This attribute is only used for the Renesas ABI.
319 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
320
321 ; If a conditional branch destination is within -252..258 bytes away
322 ; from the instruction it can be 2 bytes long.  Something in the
323 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
324 ; branches are initially assumed to be 16 bytes long.
325 ; In machine_dependent_reorg, we split all branches that are longer than
326 ; 2 bytes.
327
328 ;; The maximum range used for SImode constant pool entries is 1018.  A final
329 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
330 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
331 ;; instruction around the pool table, 2 bytes of alignment before the table,
332 ;; and 30 bytes of alignment after the table.  That gives a maximum total
333 ;; pool size of 1058 bytes.
334 ;; Worst case code/pool content size ratio is 1:2 (using asms).
335 ;; Thus, in the worst case, there is one instruction in front of a maximum
336 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
337 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
338 ;; If we have a forward branch, the initial table will be put after the
339 ;; unconditional branch.
340 ;;
341 ;; ??? We could do much better by keeping track of the actual pcloads within
342 ;; the branch range and in the pcload range in front of the branch range.
343
344 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
345 ;; inside an le.
346 (define_attr "short_cbranch_p" "no,yes"
347   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348          (const_string "no")
349          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
350          (const_string "yes")
351          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
354          (const_string "yes")
355          ] (const_string "no")))
356
357 (define_attr "med_branch_p" "no,yes"
358   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
359               (const_int 1988))
360          (const_string "yes")
361          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
364               (const_int 8186))
365          (const_string "yes")
366          ] (const_string "no")))
367
368 (define_attr "med_cbranch_p" "no,yes"
369   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
370               (const_int 1986))
371          (const_string "yes")
372          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373          (const_string "no")
374          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
375                (const_int 8184))
376          (const_string "yes")
377          ] (const_string "no")))
378
379 (define_attr "braf_branch_p" "no,yes"
380   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
381          (const_string "no")
382          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
383               (const_int 20660))
384          (const_string "yes")
385          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
386          (const_string "no")
387          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
388               (const_int 65530))
389          (const_string "yes")
390          ] (const_string "no")))
391
392 (define_attr "braf_cbranch_p" "no,yes"
393   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
394          (const_string "no")
395          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
396               (const_int 20658))
397          (const_string "yes")
398          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
399          (const_string "no")
400          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
401               (const_int 65528))
402          (const_string "yes")
403          ] (const_string "no")))
404
405 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
406 ; For wider ranges, we need a combination of a code and a data part.
407 ; If we can get a scratch register for a long range jump, the code
408 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
409 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
410 ; long; otherwise, it must be 6 bytes long.
411
412 ; All other instructions are two bytes long by default.
413
414 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
415 ;; but getattrtab doesn't understand this.
416 (define_attr "length" ""
417   (cond [(eq_attr "type" "cbranch")
418          (cond [(eq_attr "short_cbranch_p" "yes")
419                 (const_int 2)
420                 (eq_attr "med_cbranch_p" "yes")
421                 (const_int 6)
422                 (eq_attr "braf_cbranch_p" "yes")
423                 (const_int 12)
424 ;; ??? using pc is not computed transitively.
425                 (ne (match_dup 0) (match_dup 0))
426                 (const_int 14)
427                 (ne (symbol_ref ("flag_pic")) (const_int 0))
428                 (const_int 24)
429                 ] (const_int 16))
430          (eq_attr "type" "jump")
431          (cond [(eq_attr "med_branch_p" "yes")
432                 (const_int 2)
433                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
434                          (const_int 0))
435                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
436                               (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
438                               (symbol_ref "code_for_indirect_jump_scratch"))))
439                 (cond [(eq_attr "braf_branch_p" "yes")
440                        (const_int 6)
441                        (eq (symbol_ref "flag_pic") (const_int 0))
442                        (const_int 10)
443                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
444                        (const_int 10)] (const_int 18))
445                 (eq_attr "braf_branch_p" "yes")
446                 (const_int 10)
447 ;; ??? using pc is not computed transitively.
448                 (ne (match_dup 0) (match_dup 0))
449                 (const_int 12)
450                 (ne (symbol_ref ("flag_pic")) (const_int 0))
451                 (const_int 22)
452                 ] (const_int 14))
453          (eq_attr "type" "pt_media")
454          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
455                        (const_int 20) (const_int 12))
456          (and (eq_attr "type" "jump_media")
457               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
458          (const_int 8)
459          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
460                          (const_int 4)
461                          (const_int 2))))
462
463 ;; DFA descriptions for the pipelines
464
465 (include "sh1.md")
466 (include "shmedia.md")
467 (include "sh4.md")
468
469 (include "predicates.md")
470 (include "constraints.md")
471
472 ;; Definitions for filling delay slots
473
474 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475
476 (define_attr "banked" "yes,no" 
477         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
478                    (const_int 1))
479                (const_string "yes")]
480               (const_string "no")))
481
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
485                    (const_int 0))
486                (const_string "no")]
487               (const_string "yes")))
488
489 (define_attr "interrupt_function" "no,yes"
490   (const (symbol_ref "current_function_interrupt")))
491
492 (define_attr "in_delay_slot" "yes,no"
493   (cond [(eq_attr "type" "cbranch") (const_string "no")
494          (eq_attr "type" "pcload,pcload_si") (const_string "no")
495          (eq_attr "needs_delay_slot" "yes") (const_string "no")
496          (eq_attr "length" "2") (const_string "yes")
497          ] (const_string "no")))
498
499 (define_attr "cond_delay_slot" "yes,no"
500   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
501          ] (const_string "no")))
502
503 (define_attr "is_sfunc" ""
504   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505
506 (define_attr "is_mac_media" ""
507   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508
509 (define_attr "branch_zero" "yes,no"
510   (cond [(eq_attr "type" "!cbranch") (const_string "no")
511          (ne (symbol_ref "(next_active_insn (insn)\
512                            == (prev_active_insn\
513                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
514                           && get_attr_length (next_active_insn (insn)) == 2")
515              (const_int 0))
516          (const_string "yes")]
517         (const_string "no")))
518
519 ;; SH4 Double-precision computation with double-precision result -
520 ;; the two halves are ready at different times.
521 (define_attr "dfp_comp" "yes,no"
522   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
523         (const_string "no")))
524
525 ;; Insns for which the latency of a preceding fp insn is decreased by one.
526 (define_attr "late_fp_use" "yes,no" (const_string "no"))
527 ;; And feeding insns for which this relevant.
528 (define_attr "any_fp_comp" "yes,no"
529   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
530          (const_string "yes")]
531         (const_string "no")))
532
533 (define_attr "any_int_load" "yes,no"
534   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
535          (const_string "yes")]
536         (const_string "no")))
537
538 (define_attr "highpart" "user, ignore, extend, depend, must_split"
539   (const_string "user"))
540
541 (define_delay
542   (eq_attr "needs_delay_slot" "yes")
543   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544
545 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
546 ;; and thus we can't put a pop instruction in its delay slot.
547 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
548 ;; instruction can go in the delay slot.
549
550 ;; Since a normal return (rts) implicitly uses the PR register,
551 ;; we can't allow PR register loads in an rts delay slot.
552
553 (define_delay
554   (eq_attr "type" "return")
555   [(and (eq_attr "in_delay_slot" "yes")
556         (ior (and (eq_attr "interrupt_function" "no")
557                   (eq_attr "type" "!pload,prset"))
558              (and (eq_attr "interrupt_function" "yes")
559                   (ior
560                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
561                    (eq_attr "hit_stack" "no")
562                    (eq_attr "banked" "no"))))) (nil) (nil)])
563
564 ;; Since a call implicitly uses the PR register, we can't allow
565 ;; a PR register store in a jsr delay slot.
566
567 (define_delay
568   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
569   [(and (eq_attr "in_delay_slot" "yes")
570         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
571
572 ;; Say that we have annulled true branches, since this gives smaller and
573 ;; faster code when branches are predicted as not taken.
574
575 ;; ??? The non-annulled condition should really be "in_delay_slot",
576 ;; but insns that can be filled in non-annulled get priority over insns
577 ;; that can only be filled in anulled.
578
579 (define_delay
580   (and (eq_attr "type" "cbranch")
581        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
582   ;; SH2e has a hardware bug that pretty much prohibits the use of
583   ;; annuled delay slots.
584   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
585                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
586 \f
587 ;; -------------------------------------------------------------------------
588 ;; SImode signed integer comparisons
589 ;; -------------------------------------------------------------------------
590
591 (define_insn ""
592   [(set (reg:SI T_REG)
593         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
594                        (match_operand:SI 1 "arith_operand" "K08,r"))
595                (const_int 0)))]
596   "TARGET_SH1"
597   "tst  %1,%0"
598   [(set_attr "type" "mt_group")])
599
600 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
601 ;; That would still allow reload to create cmpi instructions, but would
602 ;; perhaps allow forcing the constant into a register when that is better.
603 ;; Probably should use r0 for mem/imm compares, but force constant into a
604 ;; register for pseudo/imm compares.
605
606 (define_insn "cmpeqsi_t"
607   [(set (reg:SI T_REG)
608         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
609                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
610   "TARGET_SH1"
611   "@
612         tst     %0,%0
613         cmp/eq  %1,%0
614         cmp/eq  %1,%0"
615    [(set_attr "type" "mt_group")])
616
617 (define_insn "cmpgtsi_t"
618   [(set (reg:SI T_REG)
619         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
621   "TARGET_SH1"
622   "@
623         cmp/gt  %1,%0
624         cmp/pl  %0"
625    [(set_attr "type" "mt_group")])
626
627 (define_insn "cmpgesi_t"
628   [(set (reg:SI T_REG)
629         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
630                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
631   "TARGET_SH1"
632   "@
633         cmp/ge  %1,%0
634         cmp/pz  %0"
635    [(set_attr "type" "mt_group")])
636
637 ;; -------------------------------------------------------------------------
638 ;; SImode compare and branch
639 ;; -------------------------------------------------------------------------
640
641 (define_expand "cbranchsi4"
642   [(set (pc)
643         (if_then_else (match_operator 0 "comparison_operator"
644                         [(match_operand:SI 1 "arith_operand" "")
645                          (match_operand:SI 2 "arith_operand" "")])
646                       (label_ref (match_operand 3 "" ""))
647                       (pc)))
648    (clobber (reg:SI T_REG))]
649   "TARGET_CBRANCHDI4"
650   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
651
652 ;; -------------------------------------------------------------------------
653 ;; SImode unsigned integer comparisons
654 ;; -------------------------------------------------------------------------
655
656 (define_insn_and_split "cmpgeusi_t"
657   [(set (reg:SI T_REG)
658         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
659                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
660   "TARGET_SH1"
661   "cmp/hs       %1,%0"
662   "&& operands[1] == CONST0_RTX (SImode)"
663   [(pc)]
664   "
665 {
666   emit_insn (gen_sett ());
667   DONE;
668 }"
669    [(set_attr "type" "mt_group")])
670
671 (define_insn "cmpgtusi_t"
672   [(set (reg:SI T_REG)
673         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
674                 (match_operand:SI 1 "arith_reg_operand" "r")))]
675   "TARGET_SH1"
676   "cmp/hi       %1,%0"
677    [(set_attr "type" "mt_group")])
678
679 ;; We save the compare operands in the cmpxx patterns and use them when
680 ;; we generate the branch.
681
682 (define_expand "cmpsi"
683   [(set (reg:SI T_REG)
684         (compare (match_operand:SI 0 "cmpsi_operand" "")
685                  (match_operand:SI 1 "arith_operand" "")))]
686   "TARGET_SH1 || TARGET_SHMEDIA"
687   "
688 {
689   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
690       && GET_CODE (operands[1]) != CONST_INT)
691     operands[0] = copy_to_mode_reg (SImode, operands[0]);
692   sh_compare_op0 = operands[0];
693   sh_compare_op1 = operands[1];
694   DONE;
695 }")
696 \f
697 ;; -------------------------------------------------------------------------
698 ;; DImode compare and branch
699 ;; -------------------------------------------------------------------------
700
701
702 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
703 ;; Therefore, we aim to have a set of three branches that go straight to the
704 ;; destination, i.e. only one of them is taken at any one time.
705 ;; This mechanism should also be slightly better for the sh4-200.
706
707 (define_expand "cbranchdi4"
708   [(set (pc)
709         (if_then_else (match_operator 0 "comparison_operator"
710                         [(match_operand:DI 1 "arith_operand" "")
711                          (match_operand:DI 2 "arith_operand" "")])
712                       (label_ref (match_operand 3 "" ""))
713                       (pc)))
714    (clobber (match_dup 4))
715    (clobber (reg:SI T_REG))]
716   "TARGET_CBRANCHDI4"
717   "
718 {
719   enum rtx_code comparison;
720
721   if (TARGET_EXPAND_CBRANCHDI4)
722     {
723       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
724         DONE;
725     }
726   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
727   if (comparison != GET_CODE (operands[0]))
728     operands[0]
729       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
730    operands[4] = gen_rtx_SCRATCH (SImode);
731 }")
732
733 (define_insn_and_split "cbranchdi4_i"
734   [(set (pc)
735         (if_then_else (match_operator 0 "comparison_operator"
736                         [(match_operand:DI 1 "arith_operand" "r,r")
737                          (match_operand:DI 2 "arith_operand" "rN,i")])
738                       (label_ref (match_operand 3 "" ""))
739                       (pc)))
740    (clobber (match_scratch:SI 4 "=X,&r"))
741    (clobber (reg:SI T_REG))]
742   "TARGET_CBRANCHDI4"
743   "#"
744   "&& reload_completed"
745   [(pc)]
746   "
747 {
748   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
749     FAIL;
750   DONE;
751 }")
752
753 ;; -------------------------------------------------------------------------
754 ;; DImode signed integer comparisons
755 ;; -------------------------------------------------------------------------
756
757 (define_insn ""
758   [(set (reg:SI T_REG)
759         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
760                        (match_operand:DI 1 "arith_operand" "r"))
761                (const_int 0)))]
762   "TARGET_SH1"
763   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
764                                  insn, operands);"
765   [(set_attr "length" "6")
766    (set_attr "type" "arith3b")])
767
768 (define_insn "cmpeqdi_t"
769   [(set (reg:SI T_REG)
770         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
771                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
772   "TARGET_SH1"
773   "@
774         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
775         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
776   [(set_attr "length" "6")
777    (set_attr "type" "arith3b")])
778
779 (define_split
780   [(set (reg:SI T_REG)
781         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
782                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
783 ;; If we applied this split when not optimizing, it would only be
784 ;; applied during the machine-dependent reorg, when no new basic blocks
785 ;; may be created.
786   "TARGET_SH1 && reload_completed && optimize"
787   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
788    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
789                            (label_ref (match_dup 6))
790                            (pc)))
791    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
792    (match_dup 6)]
793   "
794 {
795   operands[2]
796     = gen_rtx_REG (SImode,
797                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
798   operands[3]
799     = (operands[1] == const0_rtx
800        ? const0_rtx
801        : gen_rtx_REG (SImode,
802                       true_regnum (operands[1])
803                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
804   operands[4] = gen_lowpart (SImode, operands[0]);
805   operands[5] = gen_lowpart (SImode, operands[1]);
806   operands[6] = gen_label_rtx ();
807 }")
808
809 (define_insn "cmpgtdi_t"
810   [(set (reg:SI T_REG)
811         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
813   "TARGET_SH2"
814   "@
815         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
816         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
817   [(set_attr "length" "8")
818    (set_attr "type" "arith3")])
819
820 (define_insn "cmpgedi_t"
821   [(set (reg:SI T_REG)
822         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
823                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
824   "TARGET_SH2"
825   "@
826         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
827         cmp/pz\\t%S0"
828   [(set_attr "length" "8,2")
829    (set_attr "type" "arith3,mt_group")])
830 \f
831 ;; -------------------------------------------------------------------------
832 ;; DImode unsigned integer comparisons
833 ;; -------------------------------------------------------------------------
834
835 (define_insn "cmpgeudi_t"
836   [(set (reg:SI T_REG)
837         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
838                 (match_operand:DI 1 "arith_reg_operand" "r")))]
839   "TARGET_SH2"
840   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
841   [(set_attr "length" "8")
842    (set_attr "type" "arith3")])
843
844 (define_insn "cmpgtudi_t"
845   [(set (reg:SI T_REG)
846         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
847                 (match_operand:DI 1 "arith_reg_operand" "r")))]
848   "TARGET_SH2"
849   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
850   [(set_attr "length" "8")
851    (set_attr "type" "arith3")])
852
853 (define_insn "cmpeqsi_media"
854   [(set (match_operand:SI 0 "register_operand" "=r")
855         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
856                (match_operand:SI 2 "cmp_operand" "Nr")))]
857   "TARGET_SHMEDIA"
858   "cmpeq        %1, %N2, %0"
859   [(set_attr "type" "cmp_media")])
860
861 (define_insn "cmpeqdi_media"
862   [(set (match_operand:SI 0 "register_operand" "=r")
863         (eq:SI (match_operand:DI 1 "register_operand" "%r")
864                (match_operand:DI 2 "cmp_operand" "Nr")))]
865   "TARGET_SHMEDIA"
866   "cmpeq        %1, %N2, %0"
867   [(set_attr "type" "cmp_media")])
868
869 (define_insn "cmpgtsi_media"
870   [(set (match_operand:SI 0 "register_operand" "=r")
871         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
872                (match_operand:SI 2 "cmp_operand" "rN")))]
873   "TARGET_SHMEDIA"
874   "cmpgt        %N1, %N2, %0"
875   [(set_attr "type" "cmp_media")])
876
877 (define_insn "cmpgtdi_media"
878   [(set (match_operand:SI 0 "register_operand" "=r")
879         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
880                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
881   "TARGET_SHMEDIA"
882   "cmpgt        %N1, %N2, %0"
883   [(set_attr "type" "cmp_media")])
884
885 (define_insn "cmpgtusi_media"
886   [(set (match_operand:SI 0 "register_operand" "=r")
887         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
888                 (match_operand:SI 2 "cmp_operand" "rN")))]
889   "TARGET_SHMEDIA"
890   "cmpgtu       %N1, %N2, %0"
891   [(set_attr "type" "cmp_media")])
892
893 (define_insn "cmpgtudi_media"
894   [(set (match_operand:SI 0 "register_operand" "=r")
895         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
896                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
897   "TARGET_SHMEDIA"
898   "cmpgtu       %N1, %N2, %0"
899   [(set_attr "type" "cmp_media")])
900
901 ; These two patterns are for combine.
902 (define_insn "*cmpne0sisi_media"
903   [(set (match_operand:SI 0 "register_operand" "=r")
904         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
905   "TARGET_SHMEDIA"
906   "cmpgtu       %1,r63,%0"
907   [(set_attr "type" "cmp_media")])
908
909 ;; We save the compare operands in the cmpxx patterns and use them when
910 ;; we generate the branch.
911
912 (define_expand "cmpdi"
913   [(set (reg:SI T_REG)
914         (compare (match_operand:DI 0 "arith_operand" "")
915                  (match_operand:DI 1 "arith_operand" "")))]
916   "TARGET_SH2 || TARGET_SHMEDIA"
917   "
918 {
919   sh_compare_op0 = operands[0];
920   sh_compare_op1 = operands[1];
921   DONE;
922 }")
923 ;; -------------------------------------------------------------------------
924 ;; Conditional move instructions
925 ;; -------------------------------------------------------------------------
926
927 ;; The insn names may seem reversed, but note that cmveq performs the move
928 ;; if op1 == 0, and cmvne does it if op1 != 0.
929
930 (define_insn "movdicc_false"
931   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
932         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
933                              (const_int 0))
934          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
935          (match_operand:DI 3 "arith_reg_operand" "0")))]
936   "TARGET_SHMEDIA"
937   "cmveq        %1, %N2, %0"
938   [(set_attr "type" "arith_media")])
939
940 (define_insn "movdicc_true"
941   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
942         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
943                              (const_int 0))
944          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
945          (match_operand:DI 3 "arith_reg_operand" "0")))]
946   "TARGET_SHMEDIA"
947   "cmvne        %1, %N2, %0"
948   [(set_attr "type" "arith_media")])
949
950 (define_peephole2
951   [(set (match_operand:DI 0 "arith_reg_dest" "")
952         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
953                            [(match_operand:DI 1 "arith_reg_operand" "")
954                             (const_int 0)])
955          (match_operand:DI 2 "arith_reg_dest" "")
956          (match_dup 0)))
957    (set (match_dup 2) (match_dup 0))]
958   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
959   [(set (match_dup 2)
960         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
961   "
962 {
963   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
964                                 VOIDmode, operands[1], CONST0_RTX (DImode));
965 }")
966
967 (define_peephole2
968   [(set (match_operand:DI 0 "general_movdst_operand" "")
969         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
970    (set (match_operand:DI 2 "arith_reg_dest" "")
971         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
972                            [(match_operand:DI 3 "arith_reg_operand" "")
973                             (const_int 0)])
974          (match_dup 0)
975          (match_dup 2)))]
976   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
977   [(set (match_dup 2)
978         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
979   "")
980
981 (define_expand "movdicc"
982   [(set (match_operand:DI 0 "register_operand" "")
983         (if_then_else:DI (match_operand 1 "comparison_operator" "")
984                          (match_operand:DI 2 "register_operand" "")
985                          (match_operand:DI 3 "register_operand" "")))]
986   "TARGET_SHMEDIA"
987   "
988 {
989   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
990       && GET_MODE (sh_compare_op0) == DImode
991       && sh_compare_op1 == const0_rtx)
992     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
993                                   sh_compare_op0, sh_compare_op1);
994   else
995     {
996       rtx tmp;
997
998       if (!can_create_pseudo_p ())
999         FAIL;
1000
1001       tmp = gen_reg_rtx (DImode);
1002
1003       switch (GET_CODE (operands[1]))
1004         {
1005         case EQ:
1006           emit_insn (gen_seq (tmp));
1007           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1008           break;
1009
1010         case NE:
1011           emit_insn (gen_seq (tmp));
1012           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1013           break;
1014
1015         case GT:
1016           emit_insn (gen_sgt (tmp));
1017           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1018           break;
1019
1020         case LT:
1021           emit_insn (gen_slt (tmp));
1022           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1023           break;
1024
1025         case GE:
1026           emit_insn (gen_slt (tmp));
1027           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1028           break;
1029
1030         case LE:
1031           emit_insn (gen_sgt (tmp));
1032           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1033           break;
1034
1035         case GTU:
1036           emit_insn (gen_sgtu (tmp));
1037           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1038           break;
1039
1040         case LTU:
1041           emit_insn (gen_sltu (tmp));
1042           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1043           break;
1044
1045         case GEU:
1046           emit_insn (gen_sltu (tmp));
1047           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1048           break;
1049
1050         case LEU:
1051           emit_insn (gen_sgtu (tmp));
1052           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1053           break;
1054
1055         case UNORDERED:
1056           emit_insn (gen_sunordered (tmp));
1057           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1058           break;
1059
1060         case ORDERED:
1061           emit_insn (gen_sunordered (tmp));
1062           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1063           break;
1064
1065         case UNEQ:
1066         case UNGE:
1067         case UNGT:
1068         case UNLE:
1069         case UNLT:
1070         case LTGT:
1071           FAIL;
1072
1073         default:
1074           gcc_unreachable ();
1075         }
1076     }
1077 }")
1078
1079 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1080 ;; SImode to DImode.
1081 (define_insn "movsicc_false"
1082   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1083         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1084                           (const_int 0))
1085          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1086          (match_operand:SI 3 "arith_reg_operand" "0")))]
1087   "TARGET_SHMEDIA"
1088   "cmveq        %1, %N2, %0"
1089   [(set_attr "type" "arith_media")])
1090
1091 (define_insn "movsicc_true"
1092   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1093         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1094                           (const_int 0))
1095          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1096          (match_operand:SI 3 "arith_reg_operand" "0")))]
1097   "TARGET_SHMEDIA"
1098   "cmvne        %1, %N2, %0"
1099   [(set_attr "type" "arith_media")])
1100
1101 (define_peephole2
1102   [(set (match_operand:SI 0 "arith_reg_dest" "")
1103         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1104                            [(match_operand:SI 1 "arith_reg_operand" "")
1105                             (const_int 0)])
1106          (match_operand:SI 2 "arith_reg_dest" "")
1107          (match_dup 0)))
1108    (set (match_dup 2) (match_dup 0))]
1109   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1110   [(set (match_dup 2)
1111         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1112   "
1113 {
1114   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1115                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1116 }")
1117
1118 (define_peephole2
1119   [(set (match_operand:SI 0 "general_movdst_operand" "")
1120         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1121    (set (match_operand:SI 2 "arith_reg_dest" "")
1122         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1123                            [(match_operand:SI 3 "arith_reg_operand" "")
1124                             (const_int 0)])
1125          (match_dup 0)
1126          (match_dup 2)))]
1127   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1128    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1129   [(set (match_dup 2)
1130         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1131   "
1132 {
1133   replace_rtx (operands[4], operands[0], operands[1]);
1134 }")
1135
1136 (define_peephole2
1137   [(set (match_operand 0 "any_register_operand" "")
1138         (match_operand 1 "any_register_operand" ""))
1139    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1140    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1141   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1142     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1143    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1144    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1145    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1146    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1147    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1148    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1149    && (REGNO_REG_CLASS (REGNO (operands[0]))
1150        == REGNO_REG_CLASS (REGNO (operands[2])))
1151    && (REGNO_REG_CLASS (REGNO (operands[1]))
1152        == REGNO_REG_CLASS (REGNO (operands[0])))"
1153   [(set (match_dup 0) (match_dup 3))
1154    (set (match_dup 4) (match_dup 5))]
1155   "
1156 {
1157   rtx set1, set2, insn2;
1158   rtx replacements[4];
1159
1160   /* We want to replace occurrences of operands[0] with operands[1] and
1161      operands[2] with operands[0] in operands[4]/operands[5].
1162      Doing just two replace_rtx calls naively would result in the second
1163      replacement undoing all that the first did if operands[1] and operands[2]
1164      are identical, so we must do this simultaneously.  */
1165   replacements[0] = operands[0];
1166   replacements[1] = operands[1];
1167   replacements[2] = operands[2];
1168   replacements[3] = operands[0];
1169   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1170       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1171       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1172     FAIL;
1173
1174   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1175   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1176   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1177   /* The operands array is aliased to recog_data.operand, which gets
1178      clobbered by extract_insn, so finish with it now.  */
1179   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1180   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1181   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1182      always uses emit_insn.  */
1183   /* Check that we don't violate matching constraints or earlyclobbers.  */
1184   extract_insn (emit_insn (set1));
1185   if (! constrain_operands (1))
1186     goto failure;
1187   insn2 = emit (set2);
1188   if (GET_CODE (insn2) == BARRIER)
1189     goto failure;
1190   extract_insn (insn2);
1191   if (! constrain_operands (1))
1192     {
1193       rtx tmp;
1194     failure:
1195       tmp = replacements[0];
1196       replacements[0] = replacements[1];
1197       replacements[1] = tmp;
1198       tmp = replacements[2];
1199       replacements[2] = replacements[3];
1200       replacements[3] = tmp;
1201       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1202       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1203       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1204       FAIL;
1205     }
1206   DONE;
1207 }")
1208
1209 ;; The register allocator is rather clumsy in handling multi-way conditional
1210 ;; moves, so allow the combiner to make them, and we split them up after
1211 ;; reload.  */
1212 (define_insn_and_split "*movsicc_umin"
1213   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1214         (umin:SI (if_then_else:SI
1215                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1216                        (const_int 0))
1217                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1218                    (match_operand:SI 3 "register_operand" "0"))
1219                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1220    (clobber (match_scratch:SI 5 "=&r"))]
1221   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1222   "#"
1223   "TARGET_SHMEDIA && reload_completed"
1224   [(pc)]
1225   "
1226 {
1227   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1228                                 operands[3]));
1229   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1230   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1231                                 operands[0]));
1232   DONE;
1233 }")
1234
1235 (define_insn "*movsicc_t_false"
1236   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1237         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1238                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1239                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1240   "TARGET_PRETEND_CMOVE
1241    && (arith_reg_operand (operands[1], SImode)
1242        || (immediate_operand (operands[1], SImode)
1243            && satisfies_constraint_I08 (operands[1])))"
1244   "bt 0f\;mov %1,%0\\n0:"
1245   [(set_attr "type" "mt_group,arith") ;; poor approximation
1246    (set_attr "length" "4")])
1247
1248 (define_insn "*movsicc_t_true"
1249   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1250         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1251                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1252                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1253   "TARGET_PRETEND_CMOVE
1254    && (arith_reg_operand (operands[1], SImode)
1255        || (immediate_operand (operands[1], SImode)
1256            && satisfies_constraint_I08 (operands[1])))"
1257   "bf 0f\;mov %1,%0\\n0:"
1258   [(set_attr "type" "mt_group,arith") ;; poor approximation
1259    (set_attr "length" "4")])
1260
1261 (define_expand "movsicc"
1262   [(set (match_operand:SI 0 "arith_reg_dest" "")
1263         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1264                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1265                          (match_operand:SI 3 "arith_reg_operand" "")))]
1266   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1267   "
1268 {
1269   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1270       && GET_MODE (sh_compare_op0) == SImode
1271       && (TARGET_SHMEDIA
1272           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1273       && sh_compare_op1 == const0_rtx)
1274     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1275                                   sh_compare_op0, sh_compare_op1);
1276   else if (TARGET_PRETEND_CMOVE)
1277     {
1278       enum rtx_code code = GET_CODE (operands[1]);
1279       enum rtx_code new_code = code;
1280       rtx tmp;
1281
1282       if (! currently_expanding_to_rtl)
1283         FAIL;
1284       switch (code)
1285         {
1286         case LT: case LE: case LEU: case LTU:
1287           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1288             break;
1289         case NE:
1290           new_code = reverse_condition (code);
1291           break;
1292         case EQ: case GT: case GE: case GEU: case GTU:
1293           break;
1294         default:
1295           FAIL;
1296         }
1297       tmp = prepare_scc_operands (new_code);
1298       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1299                                     tmp, const0_rtx);
1300     }
1301   else
1302     {
1303       rtx tmp;
1304
1305       if (!can_create_pseudo_p ())
1306         FAIL;
1307
1308       tmp = gen_reg_rtx (SImode);
1309
1310       switch (GET_CODE (operands[1]))
1311         {
1312         case EQ:
1313           emit_insn (gen_seq (tmp));
1314           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1315           break;
1316
1317         case NE:
1318           emit_insn (gen_seq (tmp));
1319           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1320           break;
1321
1322         case GT:
1323           emit_insn (gen_sgt (tmp));
1324           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1325           break;
1326
1327         case LT:
1328           emit_insn (gen_slt (tmp));
1329           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1330           break;
1331
1332         case GE:
1333           emit_insn (gen_slt (tmp));
1334           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1335           break;
1336
1337         case LE:
1338           emit_insn (gen_sgt (tmp));
1339           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1340           break;
1341
1342         case GTU:
1343           emit_insn (gen_sgtu (tmp));
1344           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1345           break;
1346
1347         case LTU:
1348           emit_insn (gen_sltu (tmp));
1349           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1350           break;
1351
1352         case GEU:
1353           emit_insn (gen_sltu (tmp));
1354           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1355           break;
1356
1357         case LEU:
1358           emit_insn (gen_sgtu (tmp));
1359           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1360           break;
1361
1362         case UNORDERED:
1363           emit_insn (gen_sunordered (tmp));
1364           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1365           break;
1366
1367         case ORDERED:
1368           emit_insn (gen_sunordered (tmp));
1369           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1370           break;
1371
1372         case UNEQ:
1373         case UNGE:
1374         case UNGT:
1375         case UNLE:
1376         case UNLT:
1377         case LTGT:
1378           FAIL;
1379
1380         default:
1381           abort ();
1382         }
1383     }
1384 }")
1385
1386 (define_expand "movqicc"
1387   [(set (match_operand:QI 0 "register_operand" "")
1388         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1389                          (match_operand:QI 2 "register_operand" "")
1390                          (match_operand:QI 3 "register_operand" "")))]
1391   "TARGET_SHMEDIA"
1392   "
1393 {
1394   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1395   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1396   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1397   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1398   DONE;
1399 }")
1400 \f
1401 ;; -------------------------------------------------------------------------
1402 ;; Addition instructions
1403 ;; -------------------------------------------------------------------------
1404
1405 (define_expand "adddi3"
1406   [(set (match_operand:DI 0 "arith_reg_operand" "")
1407         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1408                  (match_operand:DI 2 "arith_operand" "")))]
1409   ""
1410   "
1411 {
1412   if (TARGET_SH1)
1413     {
1414       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1415         FAIL;
1416       operands[2] = force_reg (DImode, operands[2]);
1417       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1418       DONE;
1419     }
1420 }")
1421
1422 (define_insn "*adddi3_media"
1423   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1425                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1426   "TARGET_SHMEDIA"
1427   "@
1428         add     %1, %2, %0
1429         addi    %1, %2, %0"
1430   [(set_attr "type" "arith_media")])
1431
1432 (define_insn "*adddisi3_media"
1433   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1434         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1435                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1436   "TARGET_SHMEDIA"
1437   "@
1438         add.l   %1, %2, %0
1439         addi.l  %1, %2, %0"
1440   [(set_attr "type" "arith_media")
1441    (set_attr "highpart" "ignore")])
1442
1443 (define_insn "adddi3z_media"
1444   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1445         (zero_extend:DI
1446          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1447                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1448   "TARGET_SHMEDIA"
1449   "addz.l       %1, %N2, %0"
1450   [(set_attr "type" "arith_media")
1451    (set_attr "highpart" "ignore")])
1452
1453 (define_insn "adddi3_compact"
1454   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1455         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1456                  (match_operand:DI 2 "arith_reg_operand" "r")))
1457    (clobber (reg:SI T_REG))]
1458   "TARGET_SH1"
1459   "#"
1460   [(set_attr "length" "6")])
1461
1462 (define_split
1463   [(set (match_operand:DI 0 "arith_reg_dest" "")
1464         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1465                  (match_operand:DI 2 "arith_reg_operand" "")))
1466    (clobber (reg:SI T_REG))]
1467   "TARGET_SH1 && reload_completed"
1468   [(const_int 0)]
1469   "
1470 {
1471   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1472   high0 = gen_rtx_REG (SImode,
1473                        true_regnum (operands[0])
1474                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1475   high2 = gen_rtx_REG (SImode,
1476                        true_regnum (operands[2])
1477                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1478   emit_insn (gen_clrt ());
1479   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1480   emit_insn (gen_addc1 (high0, high0, high2));
1481   DONE;
1482 }")
1483
1484 (define_insn "addc"
1485   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1486         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1487                           (match_operand:SI 2 "arith_reg_operand" "r"))
1488                  (reg:SI T_REG)))
1489    (set (reg:SI T_REG)
1490         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1491   "TARGET_SH1"
1492   "addc %2,%0"
1493   [(set_attr "type" "arith")])
1494
1495 (define_insn "addc1"
1496   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1497         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1498                           (match_operand:SI 2 "arith_reg_operand" "r"))
1499                  (reg:SI T_REG)))
1500    (clobber (reg:SI T_REG))]
1501   "TARGET_SH1"
1502   "addc %2,%0"
1503   [(set_attr "type" "arith")])
1504
1505 (define_expand "addsi3"
1506   [(set (match_operand:SI 0 "arith_reg_operand" "")
1507         (plus:SI (match_operand:SI 1 "arith_operand" "")
1508                  (match_operand:SI 2 "arith_operand" "")))]
1509   ""
1510   "
1511 {
1512   if (TARGET_SHMEDIA)
1513     operands[1] = force_reg (SImode, operands[1]);
1514 }")
1515
1516 (define_insn "addsi3_media"
1517   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1518         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1519                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1520   "TARGET_SHMEDIA"
1521   "@
1522         add.l   %1, %2, %0
1523         addi.l  %1, %2, %0"
1524   [(set_attr "type" "arith_media")
1525    (set_attr "highpart" "ignore")])
1526
1527 (define_insn "addsidi3_media"
1528   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1529         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1530                                   "%r,r")
1531                                  (match_operand:SI 2 "arith_operand"
1532                                   "r,I10"))))]
1533   "TARGET_SHMEDIA"
1534   "@
1535         add.l   %1, %2, %0
1536         addi.l  %1, %2, %0"
1537   [(set_attr "type" "arith_media")
1538    (set_attr "highpart" "ignore")])
1539
1540 (define_insn "*addsi3_compact"
1541   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1542         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1543                  (match_operand:SI 2 "arith_operand" "rI08")))]
1544   "TARGET_SH1"
1545   "add  %2,%0"
1546   [(set_attr "type" "arith")])
1547
1548 ;; -------------------------------------------------------------------------
1549 ;; Subtraction instructions
1550 ;; -------------------------------------------------------------------------
1551
1552 (define_expand "subdi3"
1553   [(set (match_operand:DI 0 "arith_reg_operand" "")
1554         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1555                   (match_operand:DI 2 "arith_reg_operand" "")))]
1556   ""
1557   "
1558 {
1559   if (TARGET_SH1)
1560     {
1561       operands[1] = force_reg (DImode, operands[1]);
1562       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1563       DONE;
1564     }
1565 }")
1566
1567 (define_insn "*subdi3_media"
1568   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1569         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1570                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1571   "TARGET_SHMEDIA"
1572   "sub  %N1, %2, %0"
1573   [(set_attr "type" "arith_media")])
1574   
1575 (define_insn "subdisi3_media"
1576   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1577         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1578                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1579   "TARGET_SHMEDIA"
1580   "sub.l        %N1, %2, %0"
1581   [(set_attr "type" "arith_media")
1582    (set_attr "highpart" "ignore")])
1583
1584 (define_insn "subdi3_compact"
1585   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1586         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1587                  (match_operand:DI 2 "arith_reg_operand" "r")))
1588    (clobber (reg:SI T_REG))]
1589   "TARGET_SH1"
1590   "#"
1591   [(set_attr "length" "6")])
1592
1593 (define_split
1594   [(set (match_operand:DI 0 "arith_reg_dest" "")
1595         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1596                   (match_operand:DI 2 "arith_reg_operand" "")))
1597    (clobber (reg:SI T_REG))]
1598   "TARGET_SH1 && reload_completed"
1599   [(const_int 0)]
1600   "
1601 {
1602   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1603   high0 = gen_rtx_REG (SImode,
1604                        true_regnum (operands[0])
1605                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1606   high2 = gen_rtx_REG (SImode,
1607                        true_regnum (operands[2])
1608                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1609   emit_insn (gen_clrt ());
1610   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1611   emit_insn (gen_subc1 (high0, high0, high2));
1612   DONE;
1613 }")
1614
1615 (define_insn "subc"
1616   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1617         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1618                             (match_operand:SI 2 "arith_reg_operand" "r"))
1619                   (reg:SI T_REG)))
1620    (set (reg:SI T_REG)
1621         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1622                           (reg:SI T_REG))
1623                 (match_dup 1)))]
1624   "TARGET_SH1"
1625   "subc %2,%0"
1626   [(set_attr "type" "arith")])
1627
1628 (define_insn "subc1"
1629   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1630         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1631                             (match_operand:SI 2 "arith_reg_operand" "r"))
1632                   (reg:SI T_REG)))
1633    (clobber (reg:SI T_REG))]
1634   "TARGET_SH1"
1635   "subc %2,%0"
1636   [(set_attr "type" "arith")])
1637
1638 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1639 ;; pattern for this case.  This helps multimedia applications that compute
1640 ;; the sum of absolute differences.
1641 (define_insn "mov_neg_si_t"
1642   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1643   "TARGET_SH1"
1644   "subc %0,%0"
1645   [(set_attr "type" "arith")])
1646
1647 (define_insn "*subsi3_internal"
1648   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1649         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1650                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1651   "TARGET_SH1"
1652   "sub  %2,%0"
1653   [(set_attr "type" "arith")])
1654
1655 (define_insn_and_split "*subsi3_media"
1656   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1657         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1658                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1659   "TARGET_SHMEDIA
1660    && (operands[1] != constm1_rtx
1661        || (GET_CODE (operands[2]) != TRUNCATE
1662            && GET_CODE (operands[2]) != SUBREG))"
1663   "sub.l        %N1, %2, %0"
1664   "operands[1] == constm1_rtx"
1665   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1666   ""
1667   [(set_attr "type" "arith_media")
1668    (set_attr "highpart" "ignore")])
1669
1670 (define_split
1671   [(set (match_operand:SI 0 "arith_reg_dest" "")
1672         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1673                                                        "general_extend_operand"
1674                                                        "") 0)) 0)))]
1675   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1676   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1677    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1678   "")
1679
1680 (define_split
1681   [(set (match_operand:SI 0 "arith_reg_dest" "")
1682         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1683                                                        "general_extend_operand"
1684                                                        "") 0)) 3)))]
1685   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1686   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1687    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1688   "")
1689 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1690 ;; will sometimes save one instruction.  Otherwise we might get
1691 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1692 ;; are the same.
1693
1694 (define_expand "subsi3"
1695   [(set (match_operand:SI 0 "arith_reg_operand" "")
1696         (minus:SI (match_operand:SI 1 "arith_operand" "")
1697                   (match_operand:SI 2 "arith_reg_operand" "")))]
1698   ""
1699   "
1700 {
1701   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1702     {
1703       emit_insn (gen_negsi2 (operands[0], operands[2]));
1704       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1705       DONE;
1706     }
1707   if (TARGET_SHMEDIA)
1708     {
1709       if (!can_create_pseudo_p ()
1710           && ! arith_reg_or_0_operand (operands[1], SImode))
1711         FAIL;
1712       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1713         operands[1] = force_reg (SImode, operands[1]);
1714     }
1715 }")
1716 \f
1717 ;; -------------------------------------------------------------------------
1718 ;; Division instructions
1719 ;; -------------------------------------------------------------------------
1720
1721 ;; We take advantage of the library routines which don't clobber as many
1722 ;; registers as a normal function call would.
1723
1724 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1725 ;; also has an effect on the register that holds the address of the sfunc.
1726 ;; To make this work, we have an extra dummy insn that shows the use
1727 ;; of this register for reorg.
1728
1729 (define_insn "use_sfunc_addr"
1730   [(set (reg:SI PR_REG)
1731         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1732   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1733   ""
1734   [(set_attr "length" "0")])
1735
1736 (define_insn "udivsi3_sh2a"
1737   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1738         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1739                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1740   "TARGET_SH2A"
1741   "divu %2,%1"
1742   [(set_attr "type" "arith")
1743    (set_attr "in_delay_slot" "no")])
1744
1745 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1746 ;; hard register 0.  If we used hard register 0, then the next instruction
1747 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1748 ;; gets allocated to a stack slot that needs its address reloaded, then
1749 ;; there is nothing to prevent reload from using r0 to reload the address.
1750 ;; This reload would clobber the value in r0 we are trying to store.
1751 ;; If we let reload allocate r0, then this problem can never happen.
1752
1753 (define_insn "udivsi3_i1"
1754   [(set (match_operand:SI 0 "register_operand" "=z")
1755         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1756    (clobber (reg:SI T_REG))
1757    (clobber (reg:SI PR_REG))
1758    (clobber (reg:SI R4_REG))
1759    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1760   "TARGET_SH1 && ! TARGET_SH4"
1761   "jsr  @%1%#"
1762   [(set_attr "type" "sfunc")
1763    (set_attr "needs_delay_slot" "yes")])
1764
1765 ; Since shmedia-nofpu code could be linked against shcompact code, and
1766 ; the udivsi3 libcall has the same name, we must consider all registers
1767 ; clobbered that are in the union of the registers clobbered by the
1768 ; shmedia and the shcompact implementation.  Note, if the shcompact
1769 ; implementation actually used shcompact code, we'd need to clobber
1770 ; also r23 and fr23.
1771 (define_insn "udivsi3_i1_media"
1772   [(set (match_operand:SI 0 "register_operand" "=z")
1773         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1774    (clobber (reg:SI T_MEDIA_REG))
1775    (clobber (reg:SI PR_MEDIA_REG))
1776    (clobber (reg:SI R20_REG))
1777    (clobber (reg:SI R21_REG))
1778    (clobber (reg:SI R22_REG))
1779    (clobber (reg:DI TR0_REG))
1780    (clobber (reg:DI TR1_REG))
1781    (clobber (reg:DI TR2_REG))
1782    (use (match_operand 1 "target_reg_operand" "b"))]
1783   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1784   "blink        %1, r18"
1785   [(set_attr "type" "sfunc")
1786    (set_attr "needs_delay_slot" "yes")])
1787
1788 (define_expand "udivsi3_i4_media"
1789   [(set (match_dup 3)
1790         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1791    (set (match_dup 4)
1792         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1793    (set (match_dup 5) (float:DF (match_dup 3)))
1794    (set (match_dup 6) (float:DF (match_dup 4)))
1795    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1796    (set (match_dup 8) (fix:DI (match_dup 7)))
1797    (set (match_operand:SI 0 "register_operand" "")
1798         (truncate:SI (match_dup 8)))]
1799   "TARGET_SHMEDIA_FPU"
1800   "
1801 {
1802   operands[3] = gen_reg_rtx (DImode);
1803   operands[4] = gen_reg_rtx (DImode);
1804   operands[5] = gen_reg_rtx (DFmode);
1805   operands[6] = gen_reg_rtx (DFmode);
1806   operands[7] = gen_reg_rtx (DFmode);
1807   operands[8] = gen_reg_rtx (DImode);
1808 }")
1809
1810 (define_insn "udivsi3_i4"
1811   [(set (match_operand:SI 0 "register_operand" "=y")
1812         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1813    (clobber (reg:SI T_REG))
1814    (clobber (reg:SI PR_REG))
1815    (clobber (reg:DF DR0_REG))
1816    (clobber (reg:DF DR2_REG))
1817    (clobber (reg:DF DR4_REG))
1818    (clobber (reg:SI R0_REG))
1819    (clobber (reg:SI R1_REG))
1820    (clobber (reg:SI R4_REG))
1821    (clobber (reg:SI R5_REG))
1822    (use (reg:PSI FPSCR_REG))
1823    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1824   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1825   "jsr  @%1%#"
1826   [(set_attr "type" "sfunc")
1827    (set_attr "fp_mode" "double")
1828    (set_attr "needs_delay_slot" "yes")])
1829
1830 (define_insn "udivsi3_i4_single"
1831   [(set (match_operand:SI 0 "register_operand" "=y")
1832         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1833    (clobber (reg:SI T_REG))
1834    (clobber (reg:SI PR_REG))
1835    (clobber (reg:DF DR0_REG))
1836    (clobber (reg:DF DR2_REG))
1837    (clobber (reg:DF DR4_REG))
1838    (clobber (reg:SI R0_REG))
1839    (clobber (reg:SI R1_REG))
1840    (clobber (reg:SI R4_REG))
1841    (clobber (reg:SI R5_REG))
1842    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1844   "jsr  @%1%#"
1845   [(set_attr "type" "sfunc")
1846    (set_attr "needs_delay_slot" "yes")])
1847
1848 (define_insn "udivsi3_i4_int"
1849   [(set (match_operand:SI 0 "register_operand" "=z")
1850         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1851    (clobber (reg:SI T_REG))
1852    (clobber (reg:SI R1_REG))
1853    (clobber (reg:SI PR_REG))
1854    (clobber (reg:SI MACH_REG))
1855    (clobber (reg:SI MACL_REG))
1856    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1857   "TARGET_SH1"
1858   "jsr  @%1%#"
1859   [(set_attr "type" "sfunc")
1860    (set_attr "needs_delay_slot" "yes")])
1861
1862
1863 (define_expand "udivsi3"
1864   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1865    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1866    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1867    (parallel [(set (match_operand:SI 0 "register_operand" "")
1868                    (udiv:SI (reg:SI R4_REG)
1869                             (reg:SI R5_REG)))
1870               (clobber (reg:SI T_REG))
1871               (clobber (reg:SI PR_REG))
1872               (clobber (reg:SI R4_REG))
1873               (use (match_dup 3))])]
1874   ""
1875   "
1876 {
1877   rtx last;
1878
1879   operands[3] = gen_reg_rtx (Pmode);
1880   /* Emit the move of the address to a pseudo outside of the libcall.  */
1881   if (TARGET_DIVIDE_CALL_TABLE)
1882     {
1883       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1884          that causes problems when the divide code is supposed to come from a
1885          separate library.  Division by zero is undefined, so dividing 1 can be
1886          implemented by comparing with the divisor.  */
1887       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1888         {
1889           emit_insn (gen_cmpsi (operands[1], operands[2]));
1890           emit_insn (gen_sgeu (operands[0]));
1891           DONE;
1892         }
1893       else if (operands[2] == const0_rtx)
1894         {
1895           emit_move_insn (operands[0], operands[2]);
1896           DONE;
1897         }
1898       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1899       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1900     }
1901   else if (TARGET_DIVIDE_CALL_FP)
1902     {
1903       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1904       if (TARGET_FPU_SINGLE)
1905         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1906       else
1907         last = gen_udivsi3_i4 (operands[0], operands[3]);
1908     }
1909   else if (TARGET_SHMEDIA_FPU)
1910     {
1911       operands[1] = force_reg (SImode, operands[1]);
1912       operands[2] = force_reg (SImode, operands[2]);
1913       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1914       DONE;
1915     }
1916   else if (TARGET_SH2A)
1917     {
1918       operands[1] = force_reg (SImode, operands[1]);
1919       operands[2] = force_reg (SImode, operands[2]);
1920       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1921       DONE;
1922     }
1923   else if (TARGET_SH5)
1924     {
1925       function_symbol (operands[3],
1926                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1927                        SFUNC_STATIC);
1928
1929       if (TARGET_SHMEDIA)
1930         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1931       else if (TARGET_FPU_ANY)
1932         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1933       else
1934         last = gen_udivsi3_i1 (operands[0], operands[3]);
1935     }
1936   else
1937     {
1938       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1939       last = gen_udivsi3_i1 (operands[0], operands[3]);
1940     }
1941   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1942   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1943   emit_insn (last);
1944   DONE;
1945 }")
1946
1947 (define_insn "divsi3_sh2a"
1948   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1949         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1950                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1951   "TARGET_SH2A"
1952   "divs %2,%1"
1953   [(set_attr "type" "arith")
1954    (set_attr "in_delay_slot" "no")])
1955
1956 (define_insn "divsi3_i1"
1957   [(set (match_operand:SI 0 "register_operand" "=z")
1958         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959    (clobber (reg:SI T_REG))
1960    (clobber (reg:SI PR_REG))
1961    (clobber (reg:SI R1_REG))
1962    (clobber (reg:SI R2_REG))
1963    (clobber (reg:SI R3_REG))
1964    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1965   "TARGET_SH1 && ! TARGET_SH4"
1966   "jsr  @%1%#"
1967   [(set_attr "type" "sfunc")
1968    (set_attr "needs_delay_slot" "yes")])
1969
1970 (define_insn "divsi3_i1_media"
1971   [(set (match_operand:SI 0 "register_operand" "=z")
1972         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973    (clobber (reg:SI T_MEDIA_REG))
1974    (clobber (reg:SI PR_MEDIA_REG))
1975    (clobber (reg:SI R1_REG))
1976    (clobber (reg:SI R20_REG))
1977    (clobber (reg:SI R21_REG))
1978    (clobber (reg:SI TR0_REG))
1979    (use (match_operand 1 "target_reg_operand" "b"))]
1980   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1981   "blink        %1, r18"
1982   [(set_attr "type" "sfunc")])
1983
1984 (define_insn "divsi3_media_2"
1985   [(set (match_operand:SI 0 "register_operand" "=z")
1986         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1987    (clobber (reg:SI T_MEDIA_REG))
1988    (clobber (reg:SI PR_MEDIA_REG))
1989    (clobber (reg:SI R1_REG))
1990    (clobber (reg:SI R21_REG))
1991    (clobber (reg:SI TR0_REG))
1992    (use (reg:SI R20_REG))
1993    (use (match_operand 1 "target_reg_operand" "b"))]
1994   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1995   "blink        %1, r18"
1996   [(set_attr "type" "sfunc")])
1997
1998 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1999 ;; hard reg clobbers and data dependencies that we need when we want
2000 ;; to rematerialize the division into a call.
2001 (define_insn_and_split "divsi_inv_call"
2002   [(set (match_operand:SI 0 "register_operand" "=r")
2003         (div:SI (match_operand:SI 1 "register_operand" "r")
2004                 (match_operand:SI 2 "register_operand" "r")))
2005    (clobber (reg:SI R4_REG))
2006    (clobber (reg:SI R5_REG))
2007    (clobber (reg:SI T_MEDIA_REG))
2008    (clobber (reg:SI PR_MEDIA_REG))
2009    (clobber (reg:SI R1_REG))
2010    (clobber (reg:SI R21_REG))
2011    (clobber (reg:SI TR0_REG))
2012    (clobber (reg:SI R20_REG))
2013    (use (match_operand:SI 3 "register_operand" "r"))]
2014   "TARGET_SHMEDIA"
2015   "#"
2016   "&& (high_life_started || reload_completed)"
2017   [(set (match_dup 0) (match_dup 3))]
2018   ""
2019   [(set_attr "highpart" "must_split")])
2020
2021 ;; This is the combiner pattern for -mdiv=inv:call .
2022 (define_insn_and_split "*divsi_inv_call_combine"
2023   [(set (match_operand:SI 0 "register_operand" "=z")
2024         (div:SI (match_operand:SI 1 "register_operand" "r")
2025                 (match_operand:SI 2 "register_operand" "r")))
2026    (clobber (reg:SI R4_REG))
2027    (clobber (reg:SI R5_REG))
2028    (clobber (reg:SI T_MEDIA_REG))
2029    (clobber (reg:SI PR_MEDIA_REG))
2030    (clobber (reg:SI R1_REG))
2031    (clobber (reg:SI R21_REG))
2032    (clobber (reg:SI TR0_REG))
2033    (clobber (reg:SI R20_REG))
2034    (use (unspec:SI [(match_dup 1)
2035                     (match_operand:SI 3 "" "")
2036                     (unspec:SI [(match_operand:SI 4 "" "")
2037                                 (match_dup 3)
2038                                 (match_operand:DI 5 "" "")]
2039                      UNSPEC_DIV_INV_M2)
2040                     (match_operand:DI 6 "" "")
2041                     (const_int 0)
2042                     (const_int 0)]
2043          UNSPEC_DIV_INV_M3))]
2044   "TARGET_SHMEDIA"
2045   "#"
2046   "&& (high_life_started || reload_completed)"
2047   [(pc)]
2048   "
2049 {
2050   const char *name = sh_divsi3_libfunc;
2051   enum sh_function_kind kind = SFUNC_GOT;
2052   rtx sym;
2053
2054   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2055   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2056   while (TARGET_DIVIDE_INV_CALL2)
2057     {
2058       rtx x = operands[3];
2059
2060       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2061         break;
2062       x = XVECEXP (x, 0, 0);
2063       name = \"__sdivsi3_2\";
2064       kind = SFUNC_STATIC;
2065       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2066       break;
2067     }
2068   sym = function_symbol (NULL, name, kind);
2069   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2070   DONE;
2071 }"
2072   [(set_attr "highpart" "must_split")])
2073
2074 (define_expand "divsi3_i4_media"
2075   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2076    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2077    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2078    (set (match_operand:SI 0 "register_operand" "=r")
2079         (fix:SI (match_dup 5)))]
2080   "TARGET_SHMEDIA_FPU"
2081   "
2082 {
2083   operands[3] = gen_reg_rtx (DFmode);
2084   operands[4] = gen_reg_rtx (DFmode);
2085   operands[5] = gen_reg_rtx (DFmode);
2086 }")
2087
2088 (define_insn "divsi3_i4"
2089   [(set (match_operand:SI 0 "register_operand" "=y")
2090         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091    (clobber (reg:SI PR_REG))
2092    (clobber (reg:DF DR0_REG))
2093    (clobber (reg:DF DR2_REG))
2094    (use (reg:PSI FPSCR_REG))
2095    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2097   "jsr  @%1%#"
2098   [(set_attr "type" "sfunc")
2099    (set_attr "fp_mode" "double")
2100    (set_attr "needs_delay_slot" "yes")])
2101
2102 (define_insn "divsi3_i4_single"
2103   [(set (match_operand:SI 0 "register_operand" "=y")
2104         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2105    (clobber (reg:SI PR_REG))
2106    (clobber (reg:DF DR0_REG))
2107    (clobber (reg:DF DR2_REG))
2108    (clobber (reg:SI R2_REG))
2109    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2111   "jsr  @%1%#"
2112   [(set_attr "type" "sfunc")
2113    (set_attr "needs_delay_slot" "yes")])
2114
2115 (define_insn "divsi3_i4_int"
2116   [(set (match_operand:SI 0 "register_operand" "=z")
2117         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2118    (clobber (reg:SI T_REG))
2119    (clobber (reg:SI PR_REG))
2120    (clobber (reg:SI R1_REG))
2121    (clobber (reg:SI MACH_REG))
2122    (clobber (reg:SI MACL_REG))
2123    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2124   "TARGET_SH1"
2125   "jsr  @%1%#"
2126   [(set_attr "type" "sfunc")
2127    (set_attr "needs_delay_slot" "yes")])
2128
2129 (define_expand "divsi3"
2130   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2131    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2132    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2133    (parallel [(set (match_operand:SI 0 "register_operand" "")
2134                    (div:SI (reg:SI R4_REG)
2135                            (reg:SI R5_REG)))
2136               (clobber (reg:SI T_REG))
2137               (clobber (reg:SI PR_REG))
2138               (clobber (reg:SI R1_REG))
2139               (clobber (reg:SI R2_REG))
2140               (clobber (reg:SI R3_REG))
2141               (use (match_dup 3))])]
2142   ""
2143   "
2144 {
2145   rtx last;
2146
2147   operands[3] = gen_reg_rtx (Pmode);
2148   /* Emit the move of the address to a pseudo outside of the libcall.  */
2149   if (TARGET_DIVIDE_CALL_TABLE)
2150     {
2151       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2152       last = gen_divsi3_i4_int (operands[0], operands[3]);
2153     }
2154   else if (TARGET_DIVIDE_CALL_FP)
2155     {
2156       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2157       if (TARGET_FPU_SINGLE)
2158         last = gen_divsi3_i4_single (operands[0], operands[3]);
2159       else
2160         last = gen_divsi3_i4 (operands[0], operands[3]);
2161     }
2162   else if (TARGET_SH2A)
2163     {
2164       operands[1] = force_reg (SImode, operands[1]);
2165       operands[2] = force_reg (SImode, operands[2]);
2166       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2167       DONE;
2168     }
2169   else if (TARGET_DIVIDE_INV)
2170     {
2171       rtx dividend = operands[1];
2172       rtx divisor = operands[2];
2173       rtx tab_base;
2174       rtx nsb_res = gen_reg_rtx (DImode);
2175       rtx norm64 = gen_reg_rtx (DImode);
2176       rtx tab_ix = gen_reg_rtx (DImode);
2177       rtx norm32 = gen_reg_rtx (SImode);
2178       rtx i92 = force_reg (DImode, GEN_INT (92));
2179       rtx scratch0a = gen_reg_rtx (DImode);
2180       rtx scratch0b = gen_reg_rtx (DImode);
2181       rtx inv0 = gen_reg_rtx (SImode);
2182       rtx scratch1a = gen_reg_rtx (DImode);
2183       rtx scratch1b = gen_reg_rtx (DImode);
2184       rtx shift = gen_reg_rtx (DImode);
2185       rtx i2p27, i43;
2186       rtx inv1 = gen_reg_rtx (SImode);
2187       rtx scratch2a = gen_reg_rtx (DImode);
2188       rtx scratch2b = gen_reg_rtx (SImode);
2189       rtx inv2 = gen_reg_rtx (SImode);
2190       rtx scratch3a = gen_reg_rtx (DImode);
2191       rtx scratch3b = gen_reg_rtx (DImode);
2192       rtx scratch3c = gen_reg_rtx (DImode);
2193       rtx scratch3d = gen_reg_rtx (SImode);
2194       rtx scratch3e = gen_reg_rtx (DImode);
2195       rtx result = gen_reg_rtx (SImode);
2196
2197       if (! arith_reg_or_0_operand (dividend, SImode))
2198         dividend = force_reg (SImode, dividend);
2199       if (! arith_reg_operand (divisor, SImode))
2200         divisor = force_reg (SImode, divisor);
2201       if (flag_pic && Pmode != DImode)
2202         {
2203           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2204           tab_base = gen_datalabel_ref (tab_base);
2205           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2206         }
2207       else
2208         {
2209           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2210           tab_base = gen_datalabel_ref (tab_base);
2211           tab_base = force_reg (DImode, tab_base);
2212         }
2213       if (TARGET_DIVIDE_INV20U)
2214         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2215       else
2216         i2p27 = GEN_INT (0);
2217       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2218         i43 = force_reg (DImode, GEN_INT (43));
2219       else
2220         i43 = GEN_INT (0);
2221       emit_insn (gen_nsbdi (nsb_res,
2222                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2223       emit_insn (gen_ashldi3_media (norm64,
2224                                     gen_rtx_SUBREG (DImode, divisor, 0),
2225                                     nsb_res));
2226       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2227       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2228       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2229                                    inv0, scratch0a, scratch0b,
2230                                    scratch1a, scratch1b));
2231       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2232       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2233                                    scratch2a));
2234       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2235                                    i2p27, i43,
2236                                    scratch3a, scratch3b, scratch3c,
2237                                    scratch2a, scratch2b, scratch3d, scratch3e));
2238       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2239         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2240       else if (TARGET_DIVIDE_INV_FP)
2241         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2242                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2243                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2244                                      gen_reg_rtx (DFmode)));
2245       else
2246         emit_move_insn (operands[0], result);
2247       DONE;
2248     }
2249   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2250     {
2251       operands[1] = force_reg (SImode, operands[1]);
2252       operands[2] = force_reg (SImode, operands[2]);
2253       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2254       DONE;
2255     }
2256   else if (TARGET_SH5)
2257     {
2258       if (TARGET_DIVIDE_CALL2)
2259         {
2260           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2261           tab_base = gen_datalabel_ref (tab_base);
2262           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2263         }
2264       if (TARGET_FPU_ANY && TARGET_SH1)
2265         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2266       else if (TARGET_DIVIDE_CALL2)
2267         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2268       else
2269         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2270
2271       if (TARGET_SHMEDIA)
2272         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2273                 (operands[0], operands[3]));
2274       else if (TARGET_FPU_ANY)
2275         last = gen_divsi3_i4_single (operands[0], operands[3]);
2276       else
2277         last = gen_divsi3_i1 (operands[0], operands[3]);
2278     }
2279   else
2280     {
2281       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2282       last = gen_divsi3_i1 (operands[0], operands[3]);
2283     }
2284   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2285   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2286   emit_insn (last);
2287   DONE;
2288 }")
2289
2290 ;; operands: scratch, tab_base, tab_ix
2291 ;; These are unspecs because we could generate an indexed addressing mode
2292 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2293 ;; confuse reload.  See PR27117.
2294
2295 (define_insn "divsi_inv_qitable"
2296   [(set (match_operand:DI 0 "register_operand" "=r")
2297         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2298                                     (match_operand:DI 2 "register_operand" "r")]
2299                          UNSPEC_DIV_INV_TABLE)))]
2300   "TARGET_SHMEDIA"
2301   "@
2302         ldx.ub  %1, %2, %0"
2303   [(set_attr "type" "load_media")
2304    (set_attr "highpart" "user")])
2305
2306 ;; operands: scratch, tab_base, tab_ix
2307 (define_insn "divsi_inv_hitable"
2308   [(set (match_operand:DI 0 "register_operand" "=r")
2309         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2310                                     (match_operand:DI 2 "register_operand" "r")]
2311                          UNSPEC_DIV_INV_TABLE)))]
2312   "TARGET_SHMEDIA"
2313   "@
2314         ldx.w   %1, %2, %0"
2315   [(set_attr "type" "load_media")
2316    (set_attr "highpart" "user")])
2317
2318 ;; operands: inv0, tab_base, tab_ix, norm32
2319 ;; scratch equiv in sdivsi3_2: r19, r21
2320 (define_expand "divsi_inv_m0"
2321   [(set (match_operand:SI 0 "register_operand" "=r")
2322         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2323                     (match_operand:DI 2 "register_operand" "r")
2324                     (match_operand:SI 3 "register_operand" "r")]
2325          UNSPEC_DIV_INV_M0))
2326    (clobber (match_operand:DI 4 "register_operand" "=r"))
2327    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2328   "TARGET_SHMEDIA"
2329   "
2330 {
2331 /*
2332 tab_base: r20
2333 tab_ix: r21
2334 norm32: r25
2335  ldx.ub r20, r21, r19 // u0.8
2336  shlli r21, 1, r21
2337  muls.l r25, r19, r19 // s2.38
2338  ldx.w r20, r21, r21  // s2.14
2339  shari r19, 24, r19   // truncate to s2.14
2340  sub r21, r19, r19    // some 11 bit inverse in s1.14
2341 */
2342
2343   rtx inv0 = operands[0];
2344   rtx tab_base = operands[1];
2345   rtx tab_ix = operands[2];
2346   rtx norm32 = operands[3];
2347   rtx scratch0 = operands[4];
2348   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2349   rtx scratch1 = operands[5];
2350
2351   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2352   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2353   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2354   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2355   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2356   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2357   DONE;
2358 }")
2359
2360 ;; operands: inv1, tab_base, tab_ix, norm32
2361 (define_insn_and_split "divsi_inv_m1"
2362   [(set (match_operand:SI 0 "register_operand" "=r")
2363         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2364                     (match_operand:DI 2 "register_operand" "r")
2365                     (match_operand:SI 3 "register_operand" "r")]
2366          UNSPEC_DIV_INV_M1))
2367    (clobber (match_operand:SI 4 "register_operand" "=r"))
2368    (clobber (match_operand:DI 5 "register_operand" "=r"))
2369    (clobber (match_operand:DI 6 "register_operand" "=r"))
2370    (clobber (match_operand:DI 7 "register_operand" "=r"))
2371    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2372   "TARGET_SHMEDIA"
2373   "#"
2374   "&& !can_create_pseudo_p ()"
2375   [(pc)]
2376   "
2377 {
2378 /* inv0: r19
2379  muls.l r19, r19, r18 // u0.28
2380  muls.l r25, r18, r18 // s2.58
2381  shlli r19, 45, r0    // multiply by two and convert to s2.58
2382  sub r0, r18, r18
2383  shari r18, 28, r18   // some 18 bit inverse in s1.30
2384 */
2385
2386   rtx inv1 = operands[0];
2387   rtx tab_base = operands[1];
2388   rtx tab_ix = operands[2];
2389   rtx norm32 = operands[3];
2390   rtx inv0 = operands[4];
2391   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2392   rtx scratch0a = operands[5];
2393   rtx scratch0b = operands[6];
2394   rtx scratch0 = operands[7];
2395   rtx scratch1 = operands[8];
2396   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2397
2398   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2399                                scratch0a, scratch0b));
2400   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2401   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2402   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2403   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2404   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2405   DONE;
2406 }")
2407
2408 ;; operands: inv2, norm32, inv1, i92
2409 (define_insn_and_split "divsi_inv_m2"
2410   [(set (match_operand:SI 0 "register_operand" "=r")
2411         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2412                     (match_operand:SI 2 "register_operand" "r")
2413                     (match_operand:DI 3 "register_operand" "r")]
2414          UNSPEC_DIV_INV_M2))
2415    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2416   "TARGET_SHMEDIA"
2417   "#"
2418   "&& !can_create_pseudo_p ()"
2419   [(pc)]
2420   "
2421 {
2422 /*
2423  muls.l r18, r25, r0  // s2.60
2424  shari r0, 16, r0     // s-16.44
2425   sub
2426  muls.l r0, r18, r19  // s-16.74
2427  shari r19, 30, r19   // s-16.44
2428 */
2429   rtx inv2 = operands[0];
2430   rtx norm32 = operands[1];
2431   rtx inv1 = operands[2];
2432   rtx i92 = operands[3];
2433   rtx scratch0 = operands[4];
2434   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2435
2436   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2437   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2438   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2439   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2440   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2441   DONE;
2442 }")
2443
2444 (define_insn_and_split "divsi_inv_m3"
2445   [(set (match_operand:SI 0 "register_operand" "=r")
2446         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2447                     (match_operand:SI 2 "register_operand" "r")
2448                     (match_operand:SI 3 "register_operand" "r")
2449                     (match_operand:DI 4 "register_operand" "r")
2450                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2451                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2452          UNSPEC_DIV_INV_M3))
2453    (clobber (match_operand:DI 7 "register_operand" "=r"))
2454    (clobber (match_operand:DI 8 "register_operand" "=r"))
2455    (clobber (match_operand:DI 9 "register_operand" "=r"))
2456    (clobber (match_operand:DI 10 "register_operand" "=r"))
2457    (clobber (match_operand:SI 11 "register_operand" "=r"))
2458    (clobber (match_operand:SI 12 "register_operand" "=r"))
2459    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2460   "TARGET_SHMEDIA"
2461   "#"
2462   "&& !can_create_pseudo_p ()"
2463   [(pc)]
2464   "
2465 {
2466 /*
2467   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2468   r0: scratch0  r19: scratch1 r21: scratch2
2469
2470   muls.l r18, r4, r25 // s32.30
2471  muls.l r19, r4, r19  // s15.30
2472  shari r25, 63, r21
2473   shari r19, 14, r19  // s18.-14
2474  sub r25, r19, r0
2475  shard r0, r1, r0
2476  sub r0, r21, r0
2477 */
2478
2479   rtx result = operands[0];
2480   rtx dividend = operands[1];
2481   rtx inv1 = operands[2];
2482   rtx inv2 = operands[3];
2483   rtx shift = operands[4];
2484   rtx scratch0 = operands[7];
2485   rtx scratch1 = operands[8];
2486   rtx scratch2 = operands[9];
2487
2488   if (satisfies_constraint_N (dividend))
2489     {
2490       emit_move_insn (result, dividend);
2491       DONE;
2492     }
2493
2494   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2495   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2496   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2497   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2498   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2499   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2500   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2501   DONE;
2502 }")
2503
2504 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2505 ;; inv1: tab_base, tab_ix, norm32
2506 ;; inv2: norm32, inv1, i92
2507 (define_insn_and_split "divsi_inv_m1_3"
2508   [(set (match_operand:SI 0 "register_operand" "=r")
2509         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2510                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2511                                 (match_operand:DI 3 "register_operand" "r")
2512                                 (match_operand:SI 4 "register_operand" "r")]
2513                      UNSPEC_DIV_INV_M1)
2514                     (unspec:SI [(match_dup 4)
2515                                 (unspec:SI [(match_dup 2)
2516                                             (match_dup 3)
2517                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2518                                 (match_operand:SI 5 "" "")]
2519                      UNSPEC_DIV_INV_M2)
2520                     (match_operand:DI 6 "register_operand" "r")
2521                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2522                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2523          UNSPEC_DIV_INV_M3))
2524    (clobber (match_operand:DI 9 "register_operand" "=r"))
2525    (clobber (match_operand:DI 10 "register_operand" "=r"))
2526    (clobber (match_operand:DI 11 "register_operand" "=r"))
2527    (clobber (match_operand:DI 12 "register_operand" "=r"))
2528    (clobber (match_operand:SI 13 "register_operand" "=r"))
2529    (clobber (match_operand:SI 14 "register_operand" "=r"))
2530    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2531   "TARGET_SHMEDIA
2532    && (TARGET_DIVIDE_INV_MINLAT
2533        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2534   "#"
2535   "&& !can_create_pseudo_p ()"
2536   [(pc)]
2537   "
2538 {
2539   rtx result = operands[0];
2540   rtx dividend = operands[1];
2541   rtx tab_base = operands[2];
2542   rtx tab_ix = operands[3];
2543   rtx norm32 = operands[4];
2544   /* rtx i92 = operands[5]; */
2545   rtx shift = operands[6];
2546   rtx i2p27 = operands[7];
2547   rtx i43 = operands[8];
2548   rtx scratch0 = operands[9];
2549   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2550   rtx scratch1 = operands[10];
2551   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2552   rtx scratch2 = operands[11];
2553   rtx scratch3 = operands[12];
2554   rtx scratch4 = operands[13];
2555   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2556   rtx scratch5 = operands[14];
2557   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2558   rtx scratch6 = operands[15];
2559
2560   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2561                                scratch0, scratch1));
2562   /* inv0 == scratch4 */
2563   if (! TARGET_DIVIDE_INV20U)
2564     {
2565       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2566       i2p27 = scratch0;
2567       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2568     }
2569   else
2570     {
2571       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2572       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2573     }
2574   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2575   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2576   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2577   /* inv1 == scratch4 */
2578
2579   if (TARGET_DIVIDE_INV_MINLAT)
2580     {
2581       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2582       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2583       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2584       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2585       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2586       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2587       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2588       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2589       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2590       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2591       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2592     }
2593   else
2594     {
2595       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2596       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2597       emit_insn (gen_nsbdi (scratch6,
2598                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2599       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2600       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2601       emit_insn (gen_divsi_inv20 (scratch2,
2602                                   norm32, scratch4, dividend,
2603                                   scratch6, scratch3, i43,
2604                                   /* scratch0 may be shared with i2p27.  */
2605                                   scratch0, scratch1, scratch5,
2606                                   label, label, i2p27));
2607     }
2608   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2609   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2610   DONE;
2611 }")
2612
2613 (define_insn "divsi_inv20"
2614   [(set (match_operand:DI 0 "register_operand" "=&r")
2615         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2616                     (match_operand:SI 2 "register_operand" "r")
2617                     (match_operand:SI 3 "register_operand" "r")
2618                     (match_operand:DI 4 "register_operand" "r")
2619                     (match_operand:DI 5 "register_operand" "r")
2620                     (match_operand:DI 6 "register_operand" "r")
2621                     (match_operand:DI 12 "register_operand" "r")
2622                     (match_operand 10 "target_operand" "b")
2623                     (match_operand 11 "immediate_operand" "i")]
2624          UNSPEC_DIV_INV20))
2625    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2626    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2627    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2628   "TARGET_SHMEDIA
2629    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2630   "*
2631 {
2632 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2633              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2634              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2635              %10 label (tr), %11 label (imm)
2636
2637  muls.l inv1, norm32, scratch0  // s2.60
2638   muls.l inv1, dividend, result // s32.30
2639   xor i2p27, result_sign, round_scratch
2640  bge/u dividend_nsb, i43, tr.. (label)
2641  shari scratch0, 16, scratch0   // s-16.44
2642  muls.l sratch0_si, inv1, scratch0 // s-16.74
2643   sub result, round_scratch, result
2644   shari dividend, 14, scratch1   // s19.-14
2645  shari scratch0, 30, scratch0   // s-16.44
2646  muls.l scratch0, scratch1, round_scratch // s15.30
2647 label:
2648  sub result, round_scratch, result */
2649
2650   int likely = TARGET_DIVIDE_INV20L;
2651
2652   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2653   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2654   output_asm_insn (likely
2655                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2656                    : \"bge/u\t%4, %6, %10\", operands);
2657   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2658   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2659   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2660   return (likely
2661           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2662           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2663 }")
2664
2665 (define_insn_and_split "divsi_inv_fp"
2666   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2667         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2668                 (match_operand:SI 2 "register_operand" "rf")))
2669    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2670    (clobber (match_operand:SI 4 "register_operand" "=r"))
2671    (clobber (match_operand:SI 5 "register_operand" "=r"))
2672    (clobber (match_operand:DF 6 "register_operand" "=r"))
2673    (clobber (match_operand:DF 7 "register_operand" "=r"))
2674    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2675   "TARGET_SHMEDIA_FPU"
2676   "#"
2677   "&& (high_life_started || reload_completed)"
2678   [(set (match_dup 0) (match_dup 3))]
2679   ""
2680   [(set_attr "highpart" "must_split")])
2681
2682 ;; If a matching group of divide-by-inverse instructions is in the same
2683 ;; basic block after gcse & loop optimizations, we want to transform them
2684 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2685 (define_insn_and_split "*divsi_inv_fp_combine"
2686   [(set (match_operand:SI 0 "register_operand" "=f")
2687         (div:SI (match_operand:SI 1 "register_operand" "f")
2688                 (match_operand:SI 2 "register_operand" "f")))
2689    (use (unspec:SI [(match_dup 1)
2690                     (match_operand:SI 3 "" "")
2691                     (unspec:SI [(match_operand:SI 4 "" "")
2692                                 (match_dup 3)
2693                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2694                     (match_operand:DI 6 "" "")
2695                     (const_int 0)
2696                     (const_int 0)] UNSPEC_DIV_INV_M3))
2697    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2698    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2699    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2700    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2701    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2702   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2703   "#"
2704   "&& 1"
2705   [(set (match_dup 9) (float:DF (match_dup 1)))
2706    (set (match_dup 10) (float:DF (match_dup 2)))
2707    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2708    (set (match_dup 8)
2709         (fix:SI (match_dup 11)))
2710    (set (match_dup 0) (match_dup 8))]
2711   "
2712 {
2713   if (! fp_arith_reg_operand (operands[1], SImode))
2714     {
2715       emit_move_insn (operands[7], operands[1]);
2716       operands[1] = operands[7];
2717     }
2718   if (! fp_arith_reg_operand (operands[2], SImode))
2719     {
2720       emit_move_insn (operands[8], operands[2]);
2721       operands[2] = operands[8];
2722     }
2723 }"
2724   [(set_attr "highpart" "must_split")])
2725 \f
2726 ;; -------------------------------------------------------------------------
2727 ;; Multiplication instructions
2728 ;; -------------------------------------------------------------------------
2729
2730 (define_insn "umulhisi3_i"
2731   [(set (reg:SI MACL_REG)
2732         (mult:SI (zero_extend:SI
2733                   (match_operand:HI 0 "arith_reg_operand" "r"))
2734                  (zero_extend:SI
2735                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2736   "TARGET_SH1"
2737   "mulu.w       %1,%0"
2738   [(set_attr "type" "smpy")])
2739
2740 (define_insn "mulhisi3_i"
2741   [(set (reg:SI MACL_REG)
2742         (mult:SI (sign_extend:SI
2743                   (match_operand:HI 0 "arith_reg_operand" "r"))
2744                  (sign_extend:SI
2745                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2746   "TARGET_SH1"
2747   "muls.w       %1,%0"
2748   [(set_attr "type" "smpy")])
2749
2750 (define_expand "mulhisi3"
2751   [(set (reg:SI MACL_REG)
2752         (mult:SI (sign_extend:SI
2753                   (match_operand:HI 1 "arith_reg_operand" ""))
2754                  (sign_extend:SI
2755                   (match_operand:HI 2 "arith_reg_operand" ""))))
2756    (set (match_operand:SI 0 "arith_reg_operand" "")
2757         (reg:SI MACL_REG))]
2758   "TARGET_SH1"
2759   "
2760 {
2761   rtx insn, macl;
2762
2763   macl = gen_rtx_REG (SImode, MACL_REG);
2764   start_sequence ();
2765   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2766   insn = get_insns ();  
2767   end_sequence ();
2768   /* expand_binop can't find a suitable code in umul_widen_optab to
2769      make a REG_EQUAL note from, so make one here.
2770      See also smulsi3_highpart.
2771      ??? Alternatively, we could put this at the calling site of expand_binop,
2772      i.e. expand_expr.  */
2773   /* Use emit_libcall_block for loop invariant code motion and to make
2774      a REG_EQUAL note.  */
2775   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2776
2777   DONE;
2778 }")
2779
2780 (define_expand "umulhisi3"
2781   [(set (reg:SI MACL_REG)
2782         (mult:SI (zero_extend:SI
2783                   (match_operand:HI 1 "arith_reg_operand" ""))
2784                  (zero_extend:SI
2785                   (match_operand:HI 2 "arith_reg_operand" ""))))
2786    (set (match_operand:SI 0 "arith_reg_operand" "")
2787         (reg:SI MACL_REG))]
2788   "TARGET_SH1"
2789   "
2790 {
2791   rtx insn, macl;
2792
2793   macl = gen_rtx_REG (SImode, MACL_REG);
2794   start_sequence ();
2795   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2796   insn = get_insns ();  
2797   end_sequence ();
2798   /* expand_binop can't find a suitable code in umul_widen_optab to
2799      make a REG_EQUAL note from, so make one here.
2800      See also smulsi3_highpart.
2801      ??? Alternatively, we could put this at the calling site of expand_binop,
2802      i.e. expand_expr.  */
2803   /* Use emit_libcall_block for loop invariant code motion and to make
2804      a REG_EQUAL note.  */
2805   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2806
2807   DONE;
2808 }")
2809
2810 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2811 ;; a call to a routine which clobbers known registers.
2812
2813 (define_insn ""
2814   [(set (match_operand:SI 1 "register_operand" "=z")
2815         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2816    (clobber (reg:SI MACL_REG))
2817    (clobber (reg:SI T_REG))
2818    (clobber (reg:SI PR_REG))
2819    (clobber (reg:SI R3_REG))
2820    (clobber (reg:SI R2_REG))
2821    (clobber (reg:SI R1_REG))
2822    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2823   "TARGET_SH1"
2824   "jsr  @%0%#"
2825   [(set_attr "type" "sfunc")
2826    (set_attr "needs_delay_slot" "yes")])
2827
2828 (define_expand "mulsi3_call"
2829   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2830    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2831    (parallel[(set (match_operand:SI 0 "register_operand" "")
2832                   (mult:SI (reg:SI R4_REG)
2833                            (reg:SI R5_REG)))
2834              (clobber (reg:SI MACL_REG))
2835              (clobber (reg:SI T_REG))
2836              (clobber (reg:SI PR_REG))
2837              (clobber (reg:SI R3_REG))
2838              (clobber (reg:SI R2_REG))
2839              (clobber (reg:SI R1_REG))
2840              (use (match_operand:SI 3 "register_operand" ""))])]
2841   "TARGET_SH1"
2842   "")
2843
2844 (define_insn "mul_r"
2845   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2846         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2847                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2848   "TARGET_SH2A"
2849   "mulr %2,%0"
2850   [(set_attr "type" "dmpy")])
2851
2852 (define_insn "mul_l"
2853   [(set (reg:SI MACL_REG)
2854         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2855                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2856   "TARGET_SH2"
2857   "mul.l        %1,%0"
2858   [(set_attr "type" "dmpy")])
2859
2860 (define_expand "mulsi3"
2861   [(set (reg:SI MACL_REG)
2862         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2863                   (match_operand:SI 2 "arith_reg_operand" "")))
2864    (set (match_operand:SI 0 "arith_reg_operand" "")
2865         (reg:SI MACL_REG))]
2866   "TARGET_SH1"
2867   "
2868 {
2869   if (!TARGET_SH2)
2870     {
2871       /* The address must be set outside the libcall,
2872          since it goes into a pseudo.  */
2873       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2874       rtx addr = force_reg (SImode, sym);
2875       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2876                                    operands[2], addr);
2877       emit_insn (insns);
2878     }
2879   else
2880     {
2881       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2882
2883       emit_insn (gen_mul_l (operands[1], operands[2]));
2884       /* consec_sets_giv can only recognize the first insn that sets a
2885          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2886          note.  */
2887       emit_insn (gen_movsi_i ((operands[0]), macl));
2888     }
2889   DONE;
2890 }")
2891
2892 (define_insn "mulsidi3_i"
2893   [(set (reg:SI MACH_REG)
2894         (truncate:SI
2895          (lshiftrt:DI
2896           (mult:DI
2897            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2898            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2899           (const_int 32))))
2900    (set (reg:SI MACL_REG)
2901         (mult:SI (match_dup 0)
2902                  (match_dup 1)))]
2903   "TARGET_SH2"
2904   "dmuls.l      %1,%0"
2905   [(set_attr "type" "dmpy")])
2906
2907 (define_expand "mulsidi3"
2908   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2909         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2910                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2911   "TARGET_SH2 || TARGET_SHMEDIA"
2912   "
2913 {
2914   if (TARGET_SH2)
2915     {
2916        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2917                                         operands[2]));
2918        DONE;
2919     }
2920 }")
2921
2922 (define_insn "mulsidi3_media"
2923   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2924         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2925                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2926   "TARGET_SHMEDIA"
2927   "muls.l       %1, %2, %0"
2928   [(set_attr "type" "dmpy_media")
2929    (set_attr "highpart" "ignore")])
2930
2931 (define_insn "mulsidi3_compact"
2932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2933         (mult:DI
2934          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2935          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2936    (clobber (reg:SI MACH_REG))
2937    (clobber (reg:SI MACL_REG))]
2938   "TARGET_SH2"
2939   "#")
2940
2941 (define_split
2942   [(set (match_operand:DI 0 "arith_reg_dest" "")
2943         (mult:DI
2944          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2945          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2946    (clobber (reg:SI MACH_REG))
2947    (clobber (reg:SI MACL_REG))]
2948   "TARGET_SH2"
2949   [(const_int 0)]
2950   "
2951 {
2952   rtx low_dst = gen_lowpart (SImode, operands[0]);
2953   rtx high_dst = gen_highpart (SImode, operands[0]);
2954
2955   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2956
2957   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2958   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2959   /* We need something to tag the possible REG_EQUAL notes on to.  */
2960   emit_move_insn (operands[0], operands[0]);
2961   DONE;
2962 }")
2963
2964 (define_insn "umulsidi3_i"
2965   [(set (reg:SI MACH_REG)
2966         (truncate:SI
2967          (lshiftrt:DI
2968           (mult:DI
2969            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2970            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2971           (const_int 32))))
2972    (set (reg:SI MACL_REG)
2973         (mult:SI (match_dup 0)
2974                  (match_dup 1)))]
2975   "TARGET_SH2"
2976   "dmulu.l      %1,%0"
2977   [(set_attr "type" "dmpy")])
2978
2979 (define_expand "umulsidi3"
2980   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2981         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2982                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2983   "TARGET_SH2 || TARGET_SHMEDIA"
2984   "
2985 {
2986   if (TARGET_SH2)
2987     {
2988        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2989                                          operands[2]));
2990        DONE;
2991     }
2992 }")
2993
2994 (define_insn "umulsidi3_media"
2995   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2996         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2997                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2998   "TARGET_SHMEDIA"
2999   "mulu.l       %1, %2, %0"
3000   [(set_attr "type" "dmpy_media")
3001    (set_attr "highpart" "ignore")])
3002
3003 (define_insn "umulsidi3_compact"
3004   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3005         (mult:DI
3006          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3007          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3008    (clobber (reg:SI MACH_REG))
3009    (clobber (reg:SI MACL_REG))]
3010   "TARGET_SH2"
3011   "#")
3012
3013 (define_split
3014   [(set (match_operand:DI 0 "arith_reg_dest" "")
3015         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3016                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3017    (clobber (reg:SI MACH_REG))
3018    (clobber (reg:SI MACL_REG))]
3019   "TARGET_SH2"
3020   [(const_int 0)]
3021   "
3022 {
3023   rtx low_dst = gen_lowpart (SImode, operands[0]);
3024   rtx high_dst = gen_highpart (SImode, operands[0]);
3025
3026   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3027
3028   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3029   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3030   /* We need something to tag the possible REG_EQUAL notes on to.  */
3031   emit_move_insn (operands[0], operands[0]);
3032   DONE;
3033 }")
3034
3035 (define_insn "smulsi3_highpart_i"
3036   [(set (reg:SI MACH_REG)
3037         (truncate:SI
3038          (lshiftrt:DI
3039           (mult:DI
3040            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3041            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3042           (const_int 32))))
3043    (clobber (reg:SI MACL_REG))]
3044   "TARGET_SH2"
3045   "dmuls.l      %1,%0"
3046   [(set_attr "type" "dmpy")])
3047
3048 (define_expand "smulsi3_highpart"
3049   [(parallel
3050     [(set (reg:SI MACH_REG)
3051           (truncate:SI
3052            (lshiftrt:DI
3053             (mult:DI
3054              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3055              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3056             (const_int 32))))
3057     (clobber (reg:SI MACL_REG))])
3058    (set (match_operand:SI 0 "arith_reg_operand" "")
3059         (reg:SI MACH_REG))]
3060   "TARGET_SH2"
3061   "
3062 {
3063   rtx insn, mach;
3064
3065   mach = gen_rtx_REG (SImode, MACH_REG);
3066   start_sequence ();
3067   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3068   insn = get_insns ();  
3069   end_sequence ();
3070   /* expand_binop can't find a suitable code in mul_highpart_optab to
3071      make a REG_EQUAL note from, so make one here.
3072      See also {,u}mulhisi.
3073      ??? Alternatively, we could put this at the calling site of expand_binop,
3074      i.e. expand_mult_highpart.  */
3075   /* Use emit_libcall_block for loop invariant code motion and to make
3076      a REG_EQUAL note.  */
3077   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3078
3079   DONE;
3080 }")
3081
3082 (define_insn "umulsi3_highpart_i"
3083   [(set (reg:SI MACH_REG)
3084         (truncate:SI
3085          (lshiftrt:DI
3086           (mult:DI
3087            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3088            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3089           (const_int 32))))
3090    (clobber (reg:SI MACL_REG))]
3091   "TARGET_SH2"
3092   "dmulu.l      %1,%0"
3093   [(set_attr "type" "dmpy")])
3094
3095 (define_expand "umulsi3_highpart"
3096   [(parallel
3097     [(set (reg:SI MACH_REG)
3098           (truncate:SI
3099            (lshiftrt:DI
3100             (mult:DI
3101              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3102              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3103             (const_int 32))))
3104     (clobber (reg:SI MACL_REG))])
3105    (set (match_operand:SI 0 "arith_reg_operand" "")
3106         (reg:SI MACH_REG))]
3107   "TARGET_SH2"
3108   "
3109 {
3110   rtx insn, mach;
3111
3112   mach = gen_rtx_REG (SImode, MACH_REG);
3113   start_sequence ();
3114   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3115   insn = get_insns ();  
3116   end_sequence ();
3117   /* Use emit_libcall_block for loop invariant code motion and to make
3118      a REG_EQUAL note.  */
3119   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3120
3121   DONE;
3122 }")
3123
3124 (define_insn_and_split "muldi3"
3125   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3126         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3127                  (match_operand:DI 2 "arith_reg_operand" "r")))
3128    (clobber (match_scratch:DI 3 "=&r"))
3129    (clobber (match_scratch:DI 4 "=r"))]
3130   "TARGET_SHMEDIA"
3131   "#"
3132   "reload_completed"
3133   [(const_int 0)]
3134   "
3135 {
3136   rtx op3_v2si, op2_v2si;
3137
3138   op3_v2si = operands[3];
3139   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3140     {
3141       op3_v2si = XEXP (op3_v2si, 0);
3142       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3143     }
3144   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3145   op2_v2si = operands[2];
3146   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3147     {
3148       op2_v2si = XEXP (op2_v2si, 0);
3149       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3150     }
3151   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3152   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3153   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3154   emit_insn (gen_umulsidi3_media (operands[4],
3155                                  sh_gen_truncate (SImode, operands[1], 0),
3156                                  sh_gen_truncate (SImode, operands[2], 0)));
3157   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3158   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3159   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3160   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3161   DONE;
3162 }")
3163
3164 \f
3165 ;; -------------------------------------------------------------------------
3166 ;; Logical operations
3167 ;; -------------------------------------------------------------------------
3168
3169 (define_insn "*andsi3_compact"
3170   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3171         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3172                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3173   "TARGET_SH1"
3174   "and  %2,%0"
3175   [(set_attr "type" "arith")])
3176
3177 (define_insn "*andsi3_media"
3178   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3179         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3180                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3181   "TARGET_SHMEDIA"
3182   "@
3183         and     %1, %2, %0
3184         andi    %1, %2, %0"
3185   [(set_attr "type" "arith_media")])
3186
3187 (define_insn "*andsi3_bclr"
3188   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3189         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3190                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3191   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3192   "bclr\\t%W2,%0"
3193   [(set_attr "type" "arith")])
3194
3195 ;; If the constant is 255, then emit an extu.b instruction instead of an
3196 ;; and, since that will give better code.
3197
3198 (define_expand "andsi3"
3199   [(set (match_operand:SI 0 "arith_reg_operand" "")
3200         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3201                 (match_operand:SI 2 "logical_operand" "")))]
3202   ""
3203   "
3204 {
3205   if (TARGET_SH1
3206       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3207     {
3208       emit_insn (gen_zero_extendqisi2 (operands[0],
3209                                        gen_lowpart (QImode, operands[1])));
3210       DONE;
3211     }
3212 }")
3213
3214 (define_insn_and_split "anddi3"
3215   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3216         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3217                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3218   "TARGET_SHMEDIA"
3219   "@
3220         and     %1, %2, %0
3221         andi    %1, %2, %0
3222         #"
3223   "reload_completed
3224    && ! logical_operand (operands[2], DImode)"
3225   [(const_int 0)]
3226   "
3227 {
3228   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3229     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3230   else
3231     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3232   DONE;
3233 }"
3234   [(set_attr "type" "arith_media")])
3235
3236 (define_insn "andcsi3"
3237   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3238         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3239                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3240   "TARGET_SHMEDIA"
3241   "andc %1,%2,%0"
3242   [(set_attr "type" "arith_media")])
3243
3244 (define_insn "andcdi3"
3245   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3246         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3247                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3248   "TARGET_SHMEDIA"
3249   "andc %1,%2,%0"
3250   [(set_attr "type" "arith_media")])
3251
3252 (define_expand "iorsi3"
3253   [(set (match_operand:SI 0 "arith_reg_operand" "")
3254         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3255                 (match_operand:SI 2 "logical_operand" "")))]
3256   ""
3257   "")
3258
3259 (define_insn "*iorsi3_compact"
3260   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3261         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3262                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3263   "TARGET_SH1
3264    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3265   "or   %2,%0"
3266   [(set_attr "type" "arith")])
3267
3268 (define_insn "*iorsi3_media"
3269   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3270         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3271                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3272   "TARGET_SHMEDIA"
3273   "@
3274         or      %1, %2, %0
3275         ori     %1, %2, %0"
3276   [(set_attr "type" "arith_media")])
3277
3278 (define_insn "*iorsi3_bset"
3279   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3280         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3281         (match_operand:SI 2 "const_int_operand" "Pso")))]
3282   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3283   "bset\\t%V2,%0"
3284   [(set_attr "type" "arith")])
3285
3286 (define_insn "iordi3"
3287   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3288         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3289                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3290   "TARGET_SHMEDIA"
3291   "@
3292         or      %1, %2, %0
3293         ori     %1, %2, %0"
3294   [(set_attr "type" "arith_media")])
3295
3296 (define_insn_and_split "*logical_sidi3"
3297   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3298         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3299                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3300                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3301   "TARGET_SHMEDIA"
3302   "#"
3303   "&& reload_completed"
3304   [(set (match_dup 0) (match_dup 3))]
3305   "
3306 {
3307   operands[3]
3308     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3309                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3310                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3311 }")
3312
3313 (define_insn_and_split "*logical_sidisi3"
3314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315         (truncate:SI (sign_extend:DI
3316                         (match_operator:SI 3 "logical_operator"
3317                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3318                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3319   "TARGET_SHMEDIA"
3320   "#"
3321   "&& 1"
3322   [(set (match_dup 0) (match_dup 3))])
3323
3324 (define_insn_and_split "*logical_sidi3_2"
3325   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3326         (sign_extend:DI (truncate:SI (sign_extend:DI
3327                         (match_operator:SI 3 "logical_operator"
3328                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3329                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3330   "TARGET_SHMEDIA"
3331   "#"
3332   "&& 1"
3333   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3334
3335 (define_expand "xorsi3"
3336   [(set (match_operand:SI 0 "arith_reg_operand" "")
3337         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3338                 (match_operand:SI 2 "xor_operand" "")))]
3339   ""
3340   "")
3341
3342 (define_insn "*xorsi3_compact"
3343   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3344         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3345                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3346   "TARGET_SH1"
3347   "xor  %2,%0"
3348   [(set_attr "type" "arith")])
3349
3350 (define_insn "*xorsi3_media"
3351   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3352         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3353                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3354   "TARGET_SHMEDIA"
3355   "@
3356         xor     %1, %2, %0
3357         xori    %1, %2, %0"
3358   [(set_attr "type" "arith_media")])
3359
3360 ;; Store the complements of the T bit in a register.
3361 (define_insn "xorsi3_movrt"
3362   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3363         (xor:SI (reg:SI T_REG)
3364                 (const_int 1)))]
3365   "TARGET_SH2A"
3366   "movrt\\t%0"
3367   [(set_attr "type" "arith")])
3368
3369 (define_insn "xordi3"
3370   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3371         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3372                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3373   "TARGET_SHMEDIA"
3374   "@
3375         xor     %1, %2, %0
3376         xori    %1, %2, %0"
3377   [(set_attr "type" "arith_media")])
3378
3379 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3380 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3381 (define_split
3382   [(set (match_operand:DI 0 "arith_reg_dest" "")
3383         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3384                           [(match_operand 1 "any_register_operand" "")
3385                            (match_operand 2 "any_register_operand" "")])))]
3386   "TARGET_SHMEDIA"
3387   [(set (match_dup 5) (match_dup 4))
3388    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3389 "
3390 {
3391   enum machine_mode inmode = GET_MODE (operands[1]);
3392   int offset = 0;
3393
3394   if (GET_CODE (operands[0]) == SUBREG)
3395     {
3396       offset = SUBREG_BYTE (operands[0]);
3397       operands[0] = SUBREG_REG (operands[0]);
3398     }
3399   gcc_assert (GET_CODE (operands[0]) == REG);
3400   if (! TARGET_LITTLE_ENDIAN)
3401     offset += 8 - GET_MODE_SIZE (inmode);
3402   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3403 }")
3404 \f
3405 ;; -------------------------------------------------------------------------
3406 ;; Shifts and rotates
3407 ;; -------------------------------------------------------------------------
3408
3409 (define_expand "rotldi3"
3410   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3411         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3412                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3413   "TARGET_SHMEDIA"
3414   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3415
3416 (define_insn "rotldi3_mextr"
3417   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3418         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3419                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3420   "TARGET_SHMEDIA"
3421   "*
3422 {
3423   static char templ[16];
3424
3425   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3426            8 - (int) (INTVAL (operands[2]) >> 3));
3427   return templ;
3428 }"
3429   [(set_attr "type" "arith_media")])
3430
3431 (define_expand "rotrdi3"
3432   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3433         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3434                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3435   "TARGET_SHMEDIA"
3436   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3437
3438 (define_insn "rotrdi3_mextr"
3439   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3440         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3441                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3442   "TARGET_SHMEDIA"
3443   "*
3444 {
3445   static char templ[16];
3446
3447   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3448   return templ;
3449 }"
3450   [(set_attr "type" "arith_media")])
3451
3452 (define_split
3453   [(set (match_operand:DI 0 "arith_reg_dest" "")
3454         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3455                                          "ua_address_operand" "")))
3456                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3457                            (const_int 8))))
3458    (clobber (match_operand:DI 3 "register_operand" ""))]
3459   "TARGET_SHMEDIA"
3460   [(match_dup 4) (match_dup 5)]
3461   "
3462 {
3463   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3464                  (operands[3], operands[1]));
3465   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3466                               GEN_INT (56), GEN_INT (8));
3467 }")
3468
3469 (define_insn "rotlsi3_1"
3470   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3471         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3472                    (const_int 1)))
3473    (set (reg:SI T_REG)
3474         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3475   "TARGET_SH1"
3476   "rotl %0"
3477   [(set_attr "type" "arith")])
3478
3479 (define_insn "rotlsi3_31"
3480   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3481         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3482                    (const_int 31)))
3483    (clobber (reg:SI T_REG))]
3484   "TARGET_SH1"
3485   "rotr %0"
3486   [(set_attr "type" "arith")])
3487
3488 (define_insn "rotlsi3_16"
3489   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3490         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3491                    (const_int 16)))]
3492   "TARGET_SH1"
3493   "swap.w       %1,%0"
3494   [(set_attr "type" "arith")])
3495
3496 (define_expand "rotlsi3"
3497   [(set (match_operand:SI 0 "arith_reg_dest" "")
3498         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3499                    (match_operand:SI 2 "immediate_operand" "")))]
3500   "TARGET_SH1"
3501   "
3502 {
3503   static const char rot_tab[] = {
3504     000, 000, 000, 000, 000, 000, 010, 001,
3505     001, 001, 011, 013, 003, 003, 003, 003,
3506     003, 003, 003, 003, 003, 013, 012, 002,
3507     002, 002, 010, 000, 000, 000, 000, 000,
3508   };
3509
3510   int count, choice;
3511
3512   if (GET_CODE (operands[2]) != CONST_INT)
3513     FAIL;
3514   count = INTVAL (operands[2]);
3515   choice = rot_tab[count];
3516   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3517     FAIL;
3518   choice &= 7;
3519   switch (choice)
3520     {
3521     case 0:
3522       emit_move_insn (operands[0], operands[1]);
3523       count -= (count & 16) * 2;
3524       break;
3525     case 3:
3526      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3527      count -= 16;
3528      break;
3529     case 1:
3530     case 2:
3531       {
3532         rtx parts[2];
3533         parts[0] = gen_reg_rtx (SImode);
3534         parts[1] = gen_reg_rtx (SImode);
3535         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3536         emit_move_insn (parts[choice-1], operands[1]);
3537         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3538         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3539         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3540         count = (count & ~16) - 8;
3541       }
3542     }
3543
3544   for (; count > 0; count--)
3545     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3546   for (; count < 0; count++)
3547     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3548
3549   DONE;
3550 }")
3551
3552 (define_insn "*rotlhi3_8"
3553   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3554         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3555                    (const_int 8)))]
3556   "TARGET_SH1"
3557   "swap.b       %1,%0"
3558   [(set_attr "type" "arith")])
3559
3560 (define_expand "rotlhi3"
3561   [(set (match_operand:HI 0 "arith_reg_operand" "")
3562         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3563                    (match_operand:HI 2 "immediate_operand" "")))]
3564   "TARGET_SH1"
3565   "
3566 {
3567   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3568     FAIL;
3569 }")
3570
3571 ;;
3572 ;; shift left
3573
3574 (define_insn "ashlsi3_sh2a"
3575   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3578   "TARGET_SH2A"
3579   "shad %2,%0"
3580   [(set_attr "type" "arith")
3581    (set_attr "length" "4")])
3582
3583 ;; This pattern is used by init_expmed for computing the costs of shift
3584 ;; insns.
3585
3586 (define_insn_and_split "ashlsi3_std"
3587   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3588         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3589                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3590    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3591   "TARGET_SH3
3592    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3593   "@
3594    shld %2,%0
3595    add  %0,%0
3596    shll%O2      %0
3597    #"
3598   "TARGET_SH3
3599    && reload_completed
3600    && GET_CODE (operands[2]) == CONST_INT
3601    && ! satisfies_constraint_P27 (operands[2])"
3602   [(set (match_dup 3) (match_dup 2))
3603    (parallel
3604     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3605      (clobber (match_dup 4))])]
3606   "operands[4] = gen_rtx_SCRATCH (SImode);"
3607   [(set_attr "length" "*,*,*,4")
3608    (set_attr "type" "dyn_shift,arith,arith,arith")])
3609
3610 (define_insn "ashlhi3_k"
3611   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3612         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3613                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3614   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3615   "@
3616         add     %0,%0
3617         shll%O2 %0"
3618   [(set_attr "type" "arith")])
3619
3620 (define_insn "ashlsi3_n"
3621   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3622         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3623                    (match_operand:SI 2 "const_int_operand" "n")))
3624    (clobber (reg:SI T_REG))]
3625   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3626   "#"
3627   [(set (attr "length")
3628         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3629                (const_string "2")
3630                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3631                (const_string "4")
3632                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3633                (const_string "6")]
3634               (const_string "8")))
3635    (set_attr "type" "arith")])
3636
3637 (define_split
3638   [(set (match_operand:SI 0 "arith_reg_dest" "")
3639         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3640                    (match_operand:SI 2 "const_int_operand" "")))
3641    (clobber (reg:SI T_REG))]
3642   "TARGET_SH1 && reload_completed"
3643   [(use (reg:SI R0_REG))]
3644   "
3645 {
3646   gen_shifty_op (ASHIFT, operands);
3647   DONE;
3648 }")
3649
3650 (define_insn "ashlsi3_media"
3651   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3652         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3653                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3654   "TARGET_SHMEDIA"
3655   "@
3656         shlld.l %1, %2, %0
3657         shlli.l %1, %2, %0"
3658   [(set_attr "type" "arith_media")
3659    (set_attr "highpart" "ignore")])
3660
3661 (define_expand "ashlsi3"
3662   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3663                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3664                               (match_operand:SI 2 "nonmemory_operand" "")))
3665               (clobber (reg:SI T_REG))])]
3666   ""
3667   "
3668 {
3669   if (TARGET_SHMEDIA)
3670     {
3671       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3672       DONE;
3673     }
3674   if (GET_CODE (operands[2]) == CONST_INT
3675       && sh_dynamicalize_shift_p (operands[2]))
3676     operands[2] = force_reg (SImode, operands[2]);
3677   if (TARGET_SH3)
3678     {
3679       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3680       DONE;
3681     }
3682   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3683     FAIL;
3684 }")
3685
3686 (define_insn "*ashlhi3_n"
3687   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3688         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3689                    (match_operand:HI 2 "const_int_operand" "n")))
3690    (clobber (reg:SI T_REG))]
3691   "TARGET_SH1"
3692   "#"
3693   [(set (attr "length")
3694         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3695                (const_string "2")
3696                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3697                (const_string "4")]
3698               (const_string "6")))
3699    (set_attr "type" "arith")])
3700
3701 (define_expand "ashlhi3"
3702   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3703                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3704                               (match_operand:SI 2 "nonmemory_operand" "")))
3705               (clobber (reg:SI T_REG))])]
3706   "TARGET_SH1"
3707   "
3708 {
3709   if (GET_CODE (operands[2]) != CONST_INT)
3710     FAIL;
3711   /* It may be possible to call gen_ashlhi3 directly with more generic
3712      operands.  Make sure operands[1] is a HImode register here.  */
3713   if (!arith_reg_operand (operands[1], HImode))
3714     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3715 }")
3716
3717 (define_split
3718   [(set (match_operand:HI 0 "arith_reg_dest" "")
3719         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3720                    (match_operand:HI 2 "const_int_operand" "")))
3721    (clobber (reg:SI T_REG))]
3722   "TARGET_SH1 && reload_completed"
3723   [(use (reg:SI R0_REG))]
3724   "
3725 {
3726   gen_shifty_hi_op (ASHIFT, operands);
3727   DONE;
3728 }")
3729
3730 ;
3731 ; arithmetic shift right
3732 ;
3733
3734 (define_insn "ashrsi3_sh2a"
3735   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3736         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3737                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3738   "TARGET_SH2A"
3739   "shad %2,%0"
3740   [(set_attr "type" "dyn_shift")
3741    (set_attr "length" "4")])
3742
3743 (define_insn "ashrsi3_k"
3744   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3745         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3746                      (match_operand:SI 2 "const_int_operand" "M")))
3747    (clobber (reg:SI T_REG))]
3748   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3749   "shar %0"
3750   [(set_attr "type" "arith")])
3751
3752 ;; We can't do HImode right shifts correctly unless we start out with an
3753 ;; explicit zero / sign extension; doing that would result in worse overall
3754 ;; code, so just let the machine independent code widen the mode.
3755 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3756
3757
3758 ;; ??? This should be a define expand.
3759
3760 (define_insn "ashrsi2_16"
3761   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3762         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3763                      (const_int 16)))]
3764   "TARGET_SH1"
3765   "#"
3766   [(set_attr "length" "4")])
3767
3768 (define_split
3769   [(set (match_operand:SI 0 "arith_reg_dest" "")
3770         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3771                      (const_int 16)))]
3772   "TARGET_SH1"
3773   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3774    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3775   "operands[2] = gen_lowpart (HImode, operands[0]);")
3776
3777 ;; ??? This should be a define expand.
3778
3779 (define_insn "ashrsi2_31"
3780   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3781         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3782                      (const_int 31)))
3783    (clobber (reg:SI T_REG))]
3784   "TARGET_SH1"
3785   "#"
3786   [(set_attr "length" "4")])
3787
3788 (define_split
3789   [(set (match_operand:SI 0 "arith_reg_dest" "")
3790         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3791                      (const_int 31)))
3792    (clobber (reg:SI T_REG))]
3793   "TARGET_SH1"
3794   [(const_int 0)]
3795   "
3796 {
3797   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3798   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3799   DONE;
3800 }")
3801
3802 (define_peephole2
3803   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3804    (set (reg:SI T_REG)
3805         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3806   "TARGET_SH1
3807    && peep2_reg_dead_p (2, operands[0])
3808    && peep2_reg_dead_p (2, operands[1])"
3809   [(const_int 0)]
3810   "
3811 {
3812   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3813   DONE;
3814 }")
3815
3816 (define_insn "ashlsi_c"
3817   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3818         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3819    (set (reg:SI T_REG)
3820         (lt:SI (match_dup 1) (const_int 0)))]
3821   "TARGET_SH1"
3822   "shll %0"
3823   [(set_attr "type" "arith")])
3824
3825 (define_insn "*ashlsi_c_void"
3826   [(set (reg:SI T_REG)
3827         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3828    (clobber (match_scratch:SI 1 "=0"))]
3829   "TARGET_SH1 && cse_not_expected"
3830   "shll %0"
3831   [(set_attr "type" "arith")])
3832
3833 (define_insn "ashrsi3_d"
3834   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3835         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3836                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3837   "TARGET_SH3"
3838   "shad %2,%0"
3839   [(set_attr "type" "dyn_shift")])
3840
3841 (define_insn "ashrsi3_n"
3842   [(set (reg:SI R4_REG)
3843         (ashiftrt:SI (reg:SI R4_REG)
3844                      (match_operand:SI 0 "const_int_operand" "i")))
3845    (clobber (reg:SI T_REG))
3846    (clobber (reg:SI PR_REG))
3847    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3848   "TARGET_SH1"
3849   "jsr  @%1%#"
3850   [(set_attr "type" "sfunc")
3851    (set_attr "needs_delay_slot" "yes")])
3852
3853 (define_insn "ashrsi3_media"
3854   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3855         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3856                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3857   "TARGET_SHMEDIA"
3858   "@
3859         shard.l %1, %2, %0
3860         shari.l %1, %2, %0"
3861   [(set_attr "type" "arith_media")
3862    (set_attr "highpart" "ignore")])
3863
3864 (define_expand "ashrsi3"
3865   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3866                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3867                                 (match_operand:SI 2 "nonmemory_operand" "")))
3868               (clobber (reg:SI T_REG))])]
3869   ""
3870   "
3871 {
3872   if (TARGET_SHMEDIA)
3873     {
3874       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3875       DONE;
3876     }
3877   if (expand_ashiftrt (operands))
3878     DONE;
3879   else
3880     FAIL;
3881 }")
3882
3883 ;; logical shift right
3884
3885 (define_insn "lshrsi3_sh2a"
3886   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3887         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3888                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3889   "TARGET_SH2A"
3890   "shld %2,%0"
3891   [(set_attr "type" "dyn_shift")
3892    (set_attr "length" "4")])
3893
3894 (define_insn "lshrsi3_d"
3895   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3896         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3897                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3898   "TARGET_SH3"
3899   "shld %2,%0"
3900   [(set_attr "type" "dyn_shift")])
3901
3902 ;;  Only the single bit shift clobbers the T bit.
3903
3904 (define_insn "lshrsi3_m"
3905   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3906         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3907                      (match_operand:SI 2 "const_int_operand" "M")))
3908    (clobber (reg:SI T_REG))]
3909   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3910   "shlr %0"
3911   [(set_attr "type" "arith")])
3912
3913 (define_insn "lshrsi3_k"
3914   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3915         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3916                      (match_operand:SI 2 "const_int_operand" "P27")))]
3917   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3918    && ! satisfies_constraint_M (operands[2])"
3919   "shlr%O2      %0"
3920   [(set_attr "type" "arith")])
3921
3922 (define_insn "lshrsi3_n"
3923   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3924         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3925                      (match_operand:SI 2 "const_int_operand" "n")))
3926    (clobber (reg:SI T_REG))]
3927   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3928   "#"
3929   [(set (attr "length")
3930         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3931                (const_string "2")
3932                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3933                (const_string "4")
3934                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3935                (const_string "6")]
3936               (const_string "8")))
3937    (set_attr "type" "arith")])
3938
3939 (define_split
3940   [(set (match_operand:SI 0 "arith_reg_dest" "")
3941         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3942                      (match_operand:SI 2 "const_int_operand" "")))
3943    (clobber (reg:SI T_REG))]
3944   "TARGET_SH1 && reload_completed"
3945   [(use (reg:SI R0_REG))]
3946   "
3947 {
3948   gen_shifty_op (LSHIFTRT, operands);
3949   DONE;
3950 }")
3951
3952 (define_insn "lshrsi3_media"
3953   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3954         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3955                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3956   "TARGET_SHMEDIA"
3957   "@
3958         shlrd.l %1, %2, %0
3959         shlri.l %1, %2, %0"
3960   [(set_attr "type" "arith_media")
3961    (set_attr "highpart" "ignore")])
3962
3963 (define_expand "lshrsi3"
3964   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3965                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3966                                 (match_operand:SI 2 "nonmemory_operand" "")))
3967               (clobber (reg:SI T_REG))])]
3968   ""
3969   "
3970 {
3971   if (TARGET_SHMEDIA)
3972     {
3973       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3974       DONE;
3975     }
3976   if (GET_CODE (operands[2]) == CONST_INT
3977       && sh_dynamicalize_shift_p (operands[2]))
3978     operands[2] = force_reg (SImode, operands[2]);
3979   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3980     {
3981       rtx count = copy_to_mode_reg (SImode, operands[2]);
3982       emit_insn (gen_negsi2 (count, count));
3983       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3984       DONE;
3985     }
3986   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3987     FAIL;
3988 }")
3989
3990 ;; ??? This should be a define expand.
3991
3992 (define_insn "ashldi3_k"
3993   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3994         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3995                    (const_int 1)))
3996    (clobber (reg:SI T_REG))]
3997   "TARGET_SH1"
3998   "shll %R0\;rotcl      %S0"
3999   [(set_attr "length" "4")
4000    (set_attr "type" "arith")])
4001
4002 (define_insn "ashldi3_media"
4003   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4004         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4005                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
4006   "TARGET_SHMEDIA"
4007   "@
4008         shlld   %1, %2, %0
4009         shlli   %1, %2, %0"
4010   [(set_attr "type" "arith_media")])
4011
4012 (define_insn "*ashldisi3_media"
4013   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4014         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4015                    (match_operand:DI 2 "const_int_operand" "n")))]
4016   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4017   "shlli.l      %1, %2, %0"
4018   [(set_attr "type" "arith_media")
4019    (set_attr "highpart" "ignore")])
4020
4021 (define_expand "ashldi3"
4022   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4023                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4024                               (match_operand:DI 2 "immediate_operand" "")))
4025               (clobber (reg:SI T_REG))])]
4026   ""
4027   "
4028 {
4029   if (TARGET_SHMEDIA)
4030     {
4031       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4032       DONE;
4033     }
4034   if (GET_CODE (operands[2]) != CONST_INT
4035       || INTVAL (operands[2]) != 1)
4036     FAIL;
4037 }")
4038
4039 ;; ??? This should be a define expand.
4040
4041 (define_insn "lshrdi3_k"
4042   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4043         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4044                      (const_int 1)))
4045    (clobber (reg:SI T_REG))]
4046   "TARGET_SH1"
4047   "shlr %S0\;rotcr      %R0"
4048   [(set_attr "length" "4")
4049    (set_attr "type" "arith")])
4050
4051 (define_insn "lshrdi3_media"
4052   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4053         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4054                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4055   "TARGET_SHMEDIA
4056    && (arith_reg_dest (operands[0], DImode)
4057        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4058   "@
4059         shlrd   %1, %2, %0
4060         shlri   %1, %2, %0"
4061   [(set_attr "type" "arith_media")])
4062
4063 (define_insn "*lshrdisi3_media"
4064   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4065         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4066                      (match_operand:DI 2 "const_int_operand" "n")))]
4067   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4068   "shlri.l      %1, %2, %0"
4069   [(set_attr "type" "arith_media")
4070    (set_attr "highpart" "ignore")])
4071
4072 (define_expand "lshrdi3"
4073   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4074                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4075                                (match_operand:DI 2 "immediate_operand" "")))
4076              (clobber (reg:SI T_REG))])]
4077   ""
4078   "
4079 {
4080   if (TARGET_SHMEDIA)
4081     {
4082       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4083       DONE;
4084     }
4085   if (GET_CODE (operands[2]) != CONST_INT
4086       || INTVAL (operands[2]) != 1)
4087     FAIL;
4088 }")
4089
4090 ;; ??? This should be a define expand.
4091
4092 (define_insn "ashrdi3_k"
4093   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4094         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4095                      (const_int 1)))
4096    (clobber (reg:SI T_REG))]
4097   "TARGET_SH1"
4098   "shar %S0\;rotcr      %R0"
4099   [(set_attr "length" "4")
4100    (set_attr "type" "arith")])
4101
4102 (define_insn "ashrdi3_media"
4103   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4104         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4105                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4106   "TARGET_SHMEDIA
4107    && (arith_reg_dest (operands[0], DImode)
4108        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4109   "@
4110         shard   %1, %2, %0
4111         shari   %1, %2, %0"
4112   [(set_attr "type" "arith_media")])
4113
4114 (define_insn "*ashrdisi3_media"
4115   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4116         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4117                      (match_operand:DI 2 "const_int_operand" "n")))]
4118   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4119   "shari.l      %1, %2, %0"
4120   [(set_attr "type" "arith_media")
4121    (set_attr "highpart" "ignore")])
4122
4123 (define_insn "ashrdisi3_media_high"
4124   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4125         (truncate:SI
4126            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4127                         (match_operand:DI 2 "const_int_operand" "n"))))]
4128   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4129   "shari        %1, %2, %0"
4130   [(set_attr "type" "arith_media")])
4131
4132 (define_insn "ashrdisi3_media_opaque"
4133   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4134         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4135                     (match_operand:DI 2 "const_int_operand" "n")]
4136          UNSPEC_ASHIFTRT))]
4137   "TARGET_SHMEDIA"
4138   "shari        %1, %2, %0"
4139   [(set_attr "type" "arith_media")])
4140
4141 (define_expand "ashrdi3"
4142   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4143                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4144                                 (match_operand:DI 2 "immediate_operand" "")))
4145               (clobber (reg:SI T_REG))])]
4146   ""
4147   "
4148 {
4149   if (TARGET_SHMEDIA)
4150     {
4151       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4152       DONE;
4153     }
4154   if (GET_CODE (operands[2]) != CONST_INT
4155       || INTVAL (operands[2]) != 1)
4156     FAIL;
4157 }")
4158
4159 ;; combined left/right shift
4160
4161 (define_split
4162   [(set (match_operand:SI 0 "register_operand" "")
4163         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4164                            (match_operand:SI 2 "const_int_operand" ""))
4165                 (match_operand:SI 3 "const_int_operand" "")))]
4166   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4167   [(use (reg:SI R0_REG))]
4168   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4169    DONE;")
4170
4171 (define_split
4172   [(set (match_operand:SI 0 "register_operand" "")
4173         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4174                            (match_operand:SI 2 "const_int_operand" ""))
4175                 (match_operand:SI 3 "const_int_operand" "")))
4176    (clobber (reg:SI T_REG))]
4177   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4178   [(use (reg:SI R0_REG))]
4179   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4180    DONE;")
4181
4182 (define_insn ""
4183   [(set (match_operand:SI 0 "register_operand" "=r")
4184         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4185                            (match_operand:SI 2 "const_int_operand" "n"))
4186                 (match_operand:SI 3 "const_int_operand" "n")))
4187    (clobber (reg:SI T_REG))]
4188   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4189  "#"
4190   [(set (attr "length")
4191         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4192                (const_string "4")
4193                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4194                (const_string "6")
4195                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4196                (const_string "8")
4197                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4198                (const_string "10")
4199                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4200                (const_string "12")
4201                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4202                (const_string "14")
4203                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4204                (const_string "16")]
4205               (const_string "18")))
4206    (set_attr "type" "arith")])
4207
4208 (define_insn ""
4209   [(set (match_operand:SI 0 "register_operand" "=z")
4210         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4211                            (match_operand:SI 2 "const_int_operand" "n"))
4212                 (match_operand:SI 3 "const_int_operand" "n")))
4213    (clobber (reg:SI T_REG))]
4214   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4215  "#"
4216   [(set (attr "length")
4217         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4218                (const_string "4")
4219                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4220                (const_string "6")
4221                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4222                (const_string "8")]
4223               (const_string "10")))
4224    (set_attr "type" "arith")])
4225
4226 ;; shift left / and combination with a scratch register: The combine pass
4227 ;; does not accept the individual instructions, even though they are
4228 ;; cheap.  But it needs a precise description so that it is usable after
4229 ;; reload.
4230 (define_insn "and_shl_scratch"
4231   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4232         (lshiftrt:SI
4233          (ashift:SI
4234           (and:SI
4235            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4236                         (match_operand:SI 2 "const_int_operand" "N,n"))
4237            (match_operand:SI 3 "" "0,r"))
4238           (match_operand:SI 4 "const_int_operand" "n,n"))
4239          (match_operand:SI 5 "const_int_operand" "n,n")))
4240    (clobber (reg:SI T_REG))]
4241   "TARGET_SH1"
4242   "#"
4243   [(set (attr "length")
4244         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4245                (const_string "4")
4246                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4247                (const_string "6")
4248                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4249                (const_string "8")
4250                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4251                (const_string "10")]
4252               (const_string "12")))
4253    (set_attr "type" "arith")])
4254
4255 (define_split
4256   [(set (match_operand:SI 0 "register_operand" "")
4257         (lshiftrt:SI
4258          (ashift:SI
4259           (and:SI
4260            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4261                         (match_operand:SI 2 "const_int_operand" ""))
4262            (match_operand:SI 3 "register_operand" ""))
4263           (match_operand:SI 4 "const_int_operand" ""))
4264          (match_operand:SI 5 "const_int_operand" "")))
4265    (clobber (reg:SI T_REG))]
4266   "TARGET_SH1"
4267   [(use (reg:SI R0_REG))]
4268   "
4269 {
4270   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4271
4272   if (INTVAL (operands[2]))
4273     {
4274       gen_shifty_op (LSHIFTRT, operands);
4275     }
4276   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4277   operands[2] = operands[4];
4278   gen_shifty_op (ASHIFT, operands);
4279   if (INTVAL (operands[5]))
4280     {
4281       operands[2] = operands[5];
4282       gen_shifty_op (LSHIFTRT, operands);
4283     }
4284   DONE;
4285 }")
4286
4287 ;; signed left/right shift combination.
4288 (define_split
4289   [(set (match_operand:SI 0 "register_operand" "")
4290         (sign_extract:SI
4291          (ashift:SI (match_operand:SI 1 "register_operand" "")
4292                     (match_operand:SI 2 "const_int_operand" ""))
4293          (match_operand:SI 3 "const_int_operand" "")
4294          (const_int 0)))
4295    (clobber (reg:SI T_REG))]
4296   "TARGET_SH1"
4297   [(use (reg:SI R0_REG))]
4298   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4299    DONE;")
4300
4301 (define_insn "shl_sext_ext"
4302   [(set (match_operand:SI 0 "register_operand" "=r")
4303         (sign_extract:SI
4304          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4305                     (match_operand:SI 2 "const_int_operand" "n"))
4306          (match_operand:SI 3 "const_int_operand" "n")
4307          (const_int 0)))
4308    (clobber (reg:SI T_REG))]
4309   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4310   "#"
4311   [(set (attr "length")
4312         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4313                (const_string "2")
4314                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4315                (const_string "4")
4316                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4317                (const_string "6")
4318                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4319                (const_string "8")
4320                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4321                (const_string "10")
4322                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4323                (const_string "12")
4324                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4325                (const_string "14")
4326                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4327                (const_string "16")]
4328               (const_string "18")))
4329     (set_attr "type" "arith")])
4330
4331 (define_insn "shl_sext_sub"
4332   [(set (match_operand:SI 0 "register_operand" "=z")
4333         (sign_extract:SI
4334          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4335                     (match_operand:SI 2 "const_int_operand" "n"))
4336          (match_operand:SI 3 "const_int_operand" "n")
4337          (const_int 0)))
4338    (clobber (reg:SI T_REG))]
4339   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4340   "#"
4341   [(set (attr "length")
4342         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4343                (const_string "6")
4344                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4345                (const_string "8")
4346                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4347                (const_string "10")
4348                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4349                (const_string "12")]
4350               (const_string "14")))
4351     (set_attr "type" "arith")])
4352
4353 ;; These patterns are found in expansions of DImode shifts by 16, and
4354 ;; allow the xtrct instruction to be generated from C source.
4355
4356 (define_insn "xtrct_left"
4357   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4358         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4359                            (const_int 16))
4360                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4361                              (const_int 16))))]
4362   "TARGET_SH1"
4363   "xtrct        %1,%0"
4364   [(set_attr "type" "arith")])
4365
4366 (define_insn "xtrct_right"
4367   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4368         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4369                              (const_int 16))
4370                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4371                            (const_int 16))))]
4372   "TARGET_SH1"
4373   "xtrct        %2,%0"
4374   [(set_attr "type" "arith")])
4375
4376 ;; -------------------------------------------------------------------------
4377 ;; Unary arithmetic
4378 ;; -------------------------------------------------------------------------
4379
4380 (define_insn "negc"
4381   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4382         (neg:SI (plus:SI (reg:SI T_REG)
4383                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4384    (set (reg:SI T_REG)
4385         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4386                (const_int 0)))]
4387   "TARGET_SH1"
4388   "negc %1,%0"
4389   [(set_attr "type" "arith")])
4390
4391 (define_insn "*negdi_media"
4392   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4393         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4394   "TARGET_SHMEDIA"
4395   "sub  r63, %1, %0"
4396   [(set_attr "type" "arith_media")])
4397
4398 (define_expand "negdi2"
4399   [(set (match_operand:DI 0 "arith_reg_operand" "")
4400         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4401   ""
4402   "
4403 {
4404   if (TARGET_SH1)
4405     {
4406       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4407       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4408
4409       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4410       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4411
4412       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4413       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4414
4415       emit_insn (gen_clrt ());
4416       emit_insn (gen_negc (low_dst, low_src));
4417       emit_insn (gen_negc (high_dst, high_src));
4418       DONE;
4419     }
4420 }")
4421
4422 (define_insn "negsi2"
4423   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4424         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4425   "TARGET_SH1"
4426   "neg  %1,%0"
4427   [(set_attr "type" "arith")])
4428
4429 (define_insn "one_cmplsi2"
4430   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4431         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4432   "TARGET_SH1"
4433   "not  %1,%0"
4434   [(set_attr "type" "arith")])
4435
4436 (define_expand "one_cmpldi2"
4437   [(set (match_operand:DI 0 "arith_reg_dest" "")
4438         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4439                 (const_int -1)))]
4440   "TARGET_SHMEDIA" "")
4441
4442 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4443    This can be used as some kind of conditional execution, which is useful
4444    for abs.  */
4445 (define_split
4446   [(set (match_operand:SI 0 "arith_reg_dest" "")
4447         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4448                          (match_operand:SI 1 "arith_reg_operand" ""))
4449                  (reg:SI T_REG)))]
4450   "TARGET_HARD_SH4"
4451   [(const_int 0)]
4452   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4453    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4454    DONE;")
4455
4456 (define_insn "cneg"
4457   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4458         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4459                       (match_operand:SI 1 "arith_reg_operand" "0")
4460                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4461   "TARGET_HARD_SH4"
4462   "bf 0f\;neg %2,%0\\n0:"
4463   [(set_attr "type" "arith") ;; poor approximation
4464    (set_attr "length" "4")])
4465
4466 \f
4467 ;; -------------------------------------------------------------------------
4468 ;; Zero extension instructions
4469 ;; -------------------------------------------------------------------------
4470
4471 (define_insn "zero_extendsidi2"
4472   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4473         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4474   "TARGET_SHMEDIA"
4475   "addz.l       %1, r63, %0"
4476   [(set_attr "type" "arith_media")
4477    (set_attr "highpart" "extend")])
4478
4479 (define_insn "zero_extendhidi2"
4480   [(set (match_operand:DI 0 "register_operand" "=r,r")
4481         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4482   "TARGET_SHMEDIA"
4483   "@
4484         #
4485         ld%M1.uw        %m1, %0"
4486   [(set_attr "type" "*,load_media")
4487    (set (attr "highpart")
4488         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4489                (const_string "user")]
4490               (const_string "ignore")))])
4491
4492 (define_split
4493   [(set (match_operand:DI 0 "register_operand" "")
4494         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4495   "TARGET_SHMEDIA && reload_completed"
4496   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4497    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4498   "
4499 {
4500   if (GET_CODE (operands[1]) == TRUNCATE)
4501     operands[1] = XEXP (operands[1], 0);
4502 }")
4503
4504 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4505 ;; reload the entire truncate expression.
4506 (define_insn_and_split "*loaddi_trunc"
4507   [(set (match_operand 0 "any_register_operand" "=r")
4508         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4509   "TARGET_SHMEDIA && reload_completed"
4510   "#"
4511   "TARGET_SHMEDIA && reload_completed"
4512   [(set (match_dup 0) (match_dup 1))]
4513   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4514
4515 (define_insn "zero_extendqidi2"
4516   [(set (match_operand:DI 0 "register_operand" "=r,r")
4517         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4518   "TARGET_SHMEDIA"
4519   "@
4520         andi    %1, 255, %0
4521         ld%M1.ub        %m1, %0"
4522   [(set_attr "type" "arith_media,load_media")
4523    (set (attr "highpart")
4524         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4525                (const_string "user")]
4526               (const_string "ignore")))])
4527
4528 (define_expand "zero_extendhisi2"
4529   [(set (match_operand:SI 0 "arith_reg_operand" "")
4530         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4531   ""
4532   "
4533 {
4534   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4535     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4536 }")
4537
4538 (define_insn "*zero_extendhisi2_compact"
4539   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4540         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4541   "TARGET_SH1"
4542   "extu.w       %1,%0"
4543   [(set_attr "type" "arith")])
4544
4545 (define_insn "*zero_extendhisi2_media"
4546   [(set (match_operand:SI 0 "register_operand" "=r,r")
4547         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4548   "TARGET_SHMEDIA"
4549   "@
4550         #
4551         ld%M1.uw        %m1, %0"
4552   [(set_attr "type" "arith_media,load_media")
4553    (set (attr "highpart")
4554         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4555                (const_string "user")]
4556               (const_string "ignore")))])
4557
4558 (define_split
4559   [(set (match_operand:SI 0 "register_operand" "")
4560         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4561   "TARGET_SHMEDIA && reload_completed"
4562   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4563    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4564   "
4565 {
4566   rtx op1 = operands[1];
4567
4568   if (GET_CODE (op1) == TRUNCATE)
4569     op1 = XEXP (op1, 0);
4570   operands[2]
4571     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4572                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4573 }")
4574
4575 (define_expand "zero_extendqisi2"
4576   [(set (match_operand:SI 0 "arith_reg_operand" "")
4577         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4578   ""
4579   "
4580 {
4581   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4582     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4583 }")
4584
4585 (define_insn "*zero_extendqisi2_compact"
4586   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4587         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4588   "TARGET_SH1"
4589   "extu.b       %1,%0"
4590   [(set_attr "type" "arith")])
4591
4592 (define_insn "*zero_extendqisi2_media"
4593   [(set (match_operand:SI 0 "register_operand" "=r,r")
4594         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4595   "TARGET_SHMEDIA"
4596   "@
4597         andi    %1, 255, %0
4598         ld%M1.ub        %m1, %0"
4599   [(set_attr "type" "arith_media,load_media")
4600    (set (attr "highpart")
4601         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4602                (const_string "user")]
4603               (const_string "ignore")))])
4604
4605 (define_insn "zero_extendqihi2"
4606   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4607         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4608   "TARGET_SH1"
4609   "extu.b       %1,%0"
4610   [(set_attr "type" "arith")])
4611
4612 ;; -------------------------------------------------------------------------
4613 ;; Sign extension instructions
4614 ;; -------------------------------------------------------------------------
4615
4616 ;; ??? This should be a define expand.
4617 ;; ??? Or perhaps it should be dropped?
4618
4619 ;; convert_move generates good code for SH[1-4].
4620 (define_insn "extendsidi2"
4621   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4622         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4623   "TARGET_SHMEDIA"
4624   "@
4625         add.l   %1, r63, %0
4626         ld%M1.l %m1, %0
4627         fmov.sl %1, %0"
4628   [(set_attr "type" "arith_media,load_media,fpconv_media")
4629    (set (attr "highpart")
4630         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4631                (const_string "user")]
4632               (const_string "extend")))])
4633
4634 (define_insn "extendhidi2"
4635   [(set (match_operand:DI 0 "register_operand" "=r,r")
4636         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4637   "TARGET_SHMEDIA"
4638   "@
4639         #
4640         ld%M1.w %m1, %0"
4641   [(set_attr "type" "*,load_media")
4642    (set (attr "highpart")
4643         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4644                (const_string "user")]
4645               (const_string "ignore")))])
4646
4647 (define_split
4648   [(set (match_operand:DI 0 "register_operand" "")
4649         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4650   "TARGET_SHMEDIA && reload_completed"
4651   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4652    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4653   "
4654 {
4655   if (GET_CODE (operands[1]) == TRUNCATE)
4656     operands[1] = XEXP (operands[1], 0);
4657 }")
4658
4659 (define_insn "extendqidi2"
4660   [(set (match_operand:DI 0 "register_operand" "=r,r")
4661         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4662   "TARGET_SHMEDIA"
4663   "@
4664         #
4665         ld%M1.b %m1, %0"
4666   [(set_attr "type" "*,load_media")
4667    (set (attr "highpart")
4668         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4669                (const_string "user")]
4670               (const_string "ignore")))])
4671
4672 (define_split
4673   [(set (match_operand:DI 0 "register_operand" "")
4674         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4675   "TARGET_SHMEDIA && reload_completed"
4676   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4677    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4678   "
4679 {
4680   if (GET_CODE (operands[1]) == TRUNCATE)
4681     operands[1] = XEXP (operands[1], 0);
4682 }")
4683
4684 (define_expand "extendhisi2"
4685   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4686         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4687   ""
4688   "")
4689
4690 (define_insn "*extendhisi2_compact"
4691   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4692         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4693   "TARGET_SH1"
4694   "@
4695         exts.w  %1,%0
4696         mov.w   %1,%0"
4697   [(set_attr "type" "arith,load")])
4698
4699 (define_insn "*extendhisi2_media"
4700   [(set (match_operand:SI 0 "register_operand" "=r,r")
4701         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4702   "TARGET_SHMEDIA"
4703   "@
4704         #
4705         ld%M1.w %m1, %0"
4706   [(set_attr "type" "arith_media,load_media")
4707    (set (attr "highpart")
4708         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4709                (const_string "user")]
4710               (const_string "ignore")))])
4711
4712 (define_split
4713   [(set (match_operand:SI 0 "register_operand" "")
4714         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4715   "TARGET_SHMEDIA && reload_completed"
4716   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4717    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4718   "
4719 {
4720   rtx op1 = operands[1];
4721   if (GET_CODE (op1) == TRUNCATE)
4722     op1 = XEXP (op1, 0);
4723   operands[2]
4724     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4725                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4726 }")
4727
4728 (define_expand "extendqisi2"
4729   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4730         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4731   ""
4732   "")
4733
4734 (define_insn "*extendqisi2_compact"
4735   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4736         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4737   "TARGET_SH1"
4738   "@
4739         exts.b  %1,%0
4740         mov.b   %1,%0"
4741   [(set_attr "type" "arith,load")
4742    (set_attr_alternative "length"
4743      [(const_int 2)
4744        (if_then_else
4745         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4746         (const_int 4) (const_int 2))])])
4747
4748 (define_insn "*extendqisi2_media"
4749   [(set (match_operand:SI 0 "register_operand" "=r,r")
4750         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4751   "TARGET_SHMEDIA"
4752   "@
4753         #
4754         ld%M1.b %m1, %0"
4755   [(set_attr "type" "arith_media,load_media")
4756    (set (attr "highpart")
4757         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4758                (const_string "user")]
4759               (const_string "ignore")))])
4760
4761 (define_split
4762   [(set (match_operand:SI 0 "register_operand" "")
4763         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4764   "TARGET_SHMEDIA && reload_completed"
4765   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4766    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4767    "
4768 {
4769   rtx op1 = operands[1];
4770   if (GET_CODE (op1) == TRUNCATE)
4771     op1 = XEXP (op1, 0);
4772   operands[2]
4773     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4774                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4775 }")
4776
4777 (define_insn "extendqihi2"
4778   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4779         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4780   "TARGET_SH1"
4781   "@
4782         exts.b  %1,%0
4783         mov.b   %1,%0"
4784   [(set_attr "type" "arith,load")
4785    (set_attr_alternative "length"
4786      [(const_int 2)
4787        (if_then_else
4788         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4789         (const_int 4) (const_int 2))])])
4790
4791 /* It would seem useful to combine the truncXi patterns into the movXi
4792    patterns, but unary operators are ignored when matching constraints,
4793    so we need separate patterns.  */
4794 (define_insn "truncdisi2"
4795   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4796         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4797   "TARGET_SHMEDIA"
4798   "@
4799         add.l   %1, r63, %0
4800         st%M0.l %m0, %1
4801         fst%M0.s        %m0, %T1
4802         fmov.ls %1, %0
4803         fmov.sl %T1, %0
4804         fmov.s  %T1, %0"
4805   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4806    (set (attr "highpart")
4807         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4808                (const_string "user")]
4809               (const_string "extend")))])
4810
4811 (define_insn "truncdihi2"
4812   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4813         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4814   "TARGET_SHMEDIA"
4815   "@
4816         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4817         st%M0.w %m0, %1"
4818   [(set_attr "type"   "arith_media,store_media")
4819    (set_attr "length" "8,4")
4820    (set (attr "highpart")
4821         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4822                (const_string "user")]
4823               (const_string "extend")))])
4824
4825 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4826 ; Because we use zero extension, we can't provide signed QImode compares
4827 ; using a simple compare or conditional branch insn.
4828 (define_insn "truncdiqi2"
4829   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4830         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4831   "TARGET_SHMEDIA"
4832   "@
4833         andi    %1, 255, %0
4834         st%M0.b %m0, %1"
4835   [(set_attr "type"   "arith_media,store")
4836    (set (attr "highpart")
4837         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4838                (const_string "user")]
4839               (const_string "extend")))])
4840 ;; -------------------------------------------------------------------------
4841 ;; Move instructions
4842 ;; -------------------------------------------------------------------------
4843
4844 ;; define push and pop so it is easy for sh.c
4845 ;; We can't use push and pop on SHcompact because the stack must always
4846 ;; be 8-byte aligned.
4847
4848 (define_expand "push"
4849   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4850         (match_operand:SI 0 "register_operand" "r,l,x"))]
4851   "TARGET_SH1 && ! TARGET_SH5"
4852   "")
4853
4854 (define_expand "pop"
4855   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4856         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4857   "TARGET_SH1 && ! TARGET_SH5"
4858   "")
4859
4860 (define_expand "push_e"
4861   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4862                    (match_operand:SF 0 "" ""))
4863               (use (reg:PSI FPSCR_REG))
4864               (clobber (scratch:SI))])]
4865   "TARGET_SH1 && ! TARGET_SH5"
4866   "")
4867
4868 (define_insn "push_fpul"
4869   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4870   "TARGET_SH2E && ! TARGET_SH5"
4871   "sts.l        fpul,@-r15"
4872   [(set_attr "type" "fstore")
4873    (set_attr "late_fp_use" "yes")
4874    (set_attr "hit_stack" "yes")])
4875
4876 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4877 ;; so use that.
4878 (define_expand "push_4"
4879   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4880                    (match_operand:DF 0 "" ""))
4881               (use (reg:PSI FPSCR_REG))
4882               (clobber (scratch:SI))])]
4883   "TARGET_SH1 && ! TARGET_SH5"
4884   "")
4885
4886 (define_expand "pop_e"
4887   [(parallel [(set (match_operand:SF 0 "" "")
4888               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4889               (use (reg:PSI FPSCR_REG))
4890               (clobber (scratch:SI))])]
4891   "TARGET_SH1 && ! TARGET_SH5"
4892   "")
4893
4894 (define_insn "pop_fpul"
4895   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4896   "TARGET_SH2E && ! TARGET_SH5"
4897   "lds.l        @r15+,fpul"
4898   [(set_attr "type" "load")
4899    (set_attr "hit_stack" "yes")])
4900
4901 (define_expand "pop_4"
4902   [(parallel [(set (match_operand:DF 0 "" "")
4903                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4904               (use (reg:PSI FPSCR_REG))
4905               (clobber (scratch:SI))])]
4906   "TARGET_SH1 && ! TARGET_SH5"
4907   "")
4908
4909 (define_expand "push_fpscr"
4910   [(const_int 0)]
4911   "TARGET_SH2E"
4912   "
4913 {
4914   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4915                                                  gen_rtx_PRE_DEC (Pmode,
4916                                                           stack_pointer_rtx)),
4917                                         get_fpscr_rtx ()));
4918   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4919   DONE;
4920 }")
4921
4922 (define_expand "pop_fpscr"
4923   [(const_int 0)]
4924   "TARGET_SH2E"
4925   "
4926 {
4927   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4928                                         gen_frame_mem (PSImode,
4929                                                  gen_rtx_POST_INC (Pmode,
4930                                                           stack_pointer_rtx))));
4931   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4932   DONE;
4933 }")
4934
4935 ;; These two patterns can happen as the result of optimization, when
4936 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4937 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4938
4939 (define_insn "clrt"
4940   [(set (reg:SI T_REG) (const_int 0))]
4941   "TARGET_SH1"
4942   "clrt")
4943
4944 (define_insn "sett"
4945   [(set (reg:SI T_REG) (const_int 1))]
4946   "TARGET_SH1"
4947   "sett")
4948
4949 ;; t/r must come after r/r, lest reload will try to reload stuff like
4950 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4951 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4952 (define_insn "movsi_i"
4953   [(set (match_operand:SI 0 "general_movdst_operand"
4954             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4955         (match_operand:SI 1 "general_movsrc_operand"
4956          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4957   "TARGET_SH1
4958    && ! TARGET_SH2E
4959    && ! TARGET_SH2A
4960    && (register_operand (operands[0], SImode)
4961        || register_operand (operands[1], SImode))"
4962   "@
4963         mov.l   %1,%0
4964         mov     %1,%0
4965         mov     %1,%0
4966         cmp/pl  %1
4967         mov.l   %1,%0
4968         sts     %1,%0
4969         sts     %1,%0
4970         movt    %0
4971         mov.l   %1,%0
4972         sts.l   %1,%0
4973         sts.l   %1,%0
4974         lds     %1,%0
4975         lds     %1,%0
4976         lds.l   %1,%0
4977         lds.l   %1,%0
4978         fake    %1,%0"
4979   [(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")
4980    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4981
4982 ;; t/r must come after r/r, lest reload will try to reload stuff like
4983 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4984 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4985 ;; will require a reload.
4986 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4987 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4988 (define_insn "movsi_ie"
4989   [(set (match_operand:SI 0 "general_movdst_operand"
4990             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4991         (match_operand:SI 1 "general_movsrc_operand"
4992          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4993   "(TARGET_SH2E || TARGET_SH2A)
4994    && (register_operand (operands[0], SImode)
4995        || register_operand (operands[1], SImode))"
4996   "@
4997         mov.l   %1,%0
4998         mov     %1,%0
4999         mov     %1,%0
5000         movi20  %1,%0
5001         movi20s %1,%0
5002         cmp/pl  %1
5003         mov.l   %1,%0
5004         sts     %1,%0
5005         sts     %1,%0
5006         movt    %0
5007         mov.l   %1,%0
5008         sts.l   %1,%0
5009         sts.l   %1,%0
5010         lds     %1,%0
5011         lds     %1,%0
5012         lds.l   %1,%0
5013         lds.l   %1,%0
5014         lds.l   %1,%0
5015         sts.l   %1,%0
5016         fake    %1,%0
5017         lds     %1,%0
5018         sts     %1,%0
5019         fsts    fpul,%0
5020         flds    %1,fpul
5021         fmov    %1,%0
5022         ! move optimized away"
5023   [(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")
5024    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5025    (set_attr_alternative "length"
5026      [(const_int 2)
5027       (const_int 2)
5028       (const_int 2)
5029       (const_int 4)
5030       (const_int 4)
5031       (const_int 2)
5032       (if_then_else
5033         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5034         (const_int 4) (const_int 2))
5035       (const_int 2)
5036       (const_int 2)
5037       (const_int 2)
5038       (if_then_else
5039         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5040         (const_int 4) (const_int 2))
5041       (const_int 2)
5042       (const_int 2)
5043       (const_int 2)
5044       (const_int 2)
5045       (const_int 2)
5046       (const_int 2)
5047       (const_int 2)
5048       (const_int 2)
5049       (const_int 2)
5050       (const_int 2)
5051       (const_int 2)
5052       (const_int 2)
5053       (const_int 2)
5054       (const_int 2)
5055       (const_int 0)])])
5056
5057 (define_insn "movsi_i_lowpart"
5058   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5059         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5060    "TARGET_SH1
5061     && (register_operand (operands[0], SImode)
5062         || register_operand (operands[1], SImode))"
5063   "@
5064         mov.l   %1,%0
5065         mov     %1,%0
5066         mov     %1,%0
5067         mov.l   %1,%0
5068         sts     %1,%0
5069         sts     %1,%0
5070         movt    %0
5071         mov.l   %1,%0
5072         fake    %1,%0"
5073   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5074
5075 (define_insn_and_split "load_ra"
5076   [(set (match_operand:SI 0 "general_movdst_operand" "")
5077         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5078   "TARGET_SH1"
5079   "#"
5080   "&& ! currently_expanding_to_rtl"
5081   [(set (match_dup 0) (match_dup 1))]
5082   "
5083 {
5084   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5085     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5086 }")
5087
5088 ;; The '?'s in the following constraints may not reflect the time taken
5089 ;; to perform the move. They are there to discourage the use of floating-
5090 ;; point registers for storing integer values.
5091 (define_insn "*movsi_media"
5092   [(set (match_operand:SI 0 "general_movdst_operand"
5093                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5094         (match_operand:SI 1 "general_movsrc_operand"
5095          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5096   "TARGET_SHMEDIA_FPU
5097    && (register_operand (operands[0], SImode)
5098        || sh_register_operand (operands[1], SImode)
5099        || GET_CODE (operands[1]) == TRUNCATE)"
5100   "@
5101         add.l   %1, r63, %0
5102         movi    %1, %0
5103         #
5104         ld%M1.l %m1, %0
5105         st%M0.l %m0, %N1
5106         fld%M1.s        %m1, %0
5107         fst%M0.s        %m0, %1
5108         fmov.ls %N1, %0
5109         fmov.sl %1, %0
5110         fmov.s  %1, %0
5111         ptabs   %1, %0
5112         gettr   %1, %0
5113         pt      %1, %0"
5114   [(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")
5115    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5116    (set (attr "highpart")
5117         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5118                (const_string "user")]
5119               (const_string "ignore")))])
5120
5121 (define_insn "*movsi_media_nofpu"
5122   [(set (match_operand:SI 0 "general_movdst_operand"
5123                 "=r,r,r,r,m,*b,r,*b")
5124         (match_operand:SI 1 "general_movsrc_operand"
5125          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5126   "TARGET_SHMEDIA
5127    && (register_operand (operands[0], SImode)
5128        || sh_register_operand (operands[1], SImode)
5129        || GET_CODE (operands[1]) == TRUNCATE)"
5130   "@
5131         add.l   %1, r63, %0
5132         movi    %1, %0
5133         #
5134         ld%M1.l %m1, %0
5135         st%M0.l %m0, %N1
5136         ptabs   %1, %0
5137         gettr   %1, %0
5138         pt      %1, %0"
5139   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5140    (set_attr "length" "4,4,8,4,4,4,4,12")
5141    (set (attr "highpart")
5142         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5143                (const_string "user")]
5144               (const_string "ignore")))])
5145
5146 (define_expand "movsi_const"
5147   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5148         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5149                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5150    (set (match_dup 0)
5151         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5152                 (const:SI (unspec:SI [(match_dup 1)
5153                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5154   "TARGET_SHMEDIA && reload_completed
5155    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5156   "
5157 {
5158   if (GET_CODE (operands[1]) == LABEL_REF
5159       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5160     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5161   else if (GOTOFF_P (operands[1]))
5162     {
5163       rtx unspec = XEXP (operands[1], 0);
5164
5165       if (! UNSPEC_GOTOFF_P (unspec))
5166         {
5167           unspec = XEXP (unspec, 0);
5168           if (! UNSPEC_GOTOFF_P (unspec))
5169             abort ();
5170         }
5171       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5172           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5173         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5174     }
5175 }")
5176
5177 (define_expand "movsi_const_16bit"
5178   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5179         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5180                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5181   "TARGET_SHMEDIA && flag_pic && reload_completed
5182    && GET_CODE (operands[1]) == SYMBOL_REF"
5183   "")
5184
5185 (define_split
5186   [(set (match_operand:SI 0 "arith_reg_dest" "")
5187         (match_operand:SI 1 "immediate_operand" ""))]
5188   "TARGET_SHMEDIA && reload_completed
5189    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5190   [(const_int 0)]
5191   "
5192 {
5193   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5194
5195   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5196
5197   DONE;
5198 }")
5199
5200 (define_split
5201   [(set (match_operand:SI 0 "register_operand" "")
5202         (match_operand:SI 1 "immediate_operand" ""))]
5203   "TARGET_SHMEDIA && reload_completed
5204    && ((GET_CODE (operands[1]) == CONST_INT
5205         && ! satisfies_constraint_I16 (operands[1]))
5206        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5207   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5208
5209 (define_expand "movsi"
5210   [(set (match_operand:SI 0 "general_movdst_operand" "")
5211         (match_operand:SI 1 "general_movsrc_operand" ""))]
5212   ""
5213   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5214
5215 (define_expand "ic_invalidate_line"
5216   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5217                                 (match_dup 1)] UNSPEC_ICACHE)
5218               (clobber (scratch:SI))])]
5219   "TARGET_HARD_SH4 || TARGET_SH5"
5220   "
5221 {
5222   if (TARGET_SHMEDIA)
5223     {
5224       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5225       DONE;
5226     }
5227   else if (TARGET_SHCOMPACT)
5228     {
5229       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5230       operands[1] = force_reg (Pmode, operands[1]);
5231       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5232       DONE;
5233     }
5234   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5235     {
5236       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5237       DONE;
5238     }
5239   operands[0] = force_reg (Pmode, operands[0]);
5240   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5241                                                                Pmode)));
5242 }")
5243
5244 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5245 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5246 ;; the requirement *1*00 for associative address writes.  The alignment of
5247 ;; %0 implies that its least significant bit is cleared,
5248 ;; thus we clear the V bit of a matching entry if there is one.
5249 (define_insn "ic_invalidate_line_i"
5250   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5251                      (match_operand:SI 1 "register_operand" "r")]
5252                      UNSPEC_ICACHE)
5253    (clobber (match_scratch:SI 2 "=&r"))]
5254   "TARGET_HARD_SH4"
5255   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5256   [(set_attr "length" "8")
5257    (set_attr "type" "cwb")])
5258
5259 (define_insn "ic_invalidate_line_sh4a"
5260   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5261                     UNSPEC_ICACHE)]
5262   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5263   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5264   [(set_attr "length" "16")
5265    (set_attr "type" "cwb")])
5266
5267 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5268 ;; an add in the code that calculates the address.
5269 (define_insn "ic_invalidate_line_media"
5270   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5271                     UNSPEC_ICACHE)]
5272   "TARGET_SHMEDIA"
5273   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5274   [(set_attr "length" "16")
5275    (set_attr "type" "invalidate_line_media")])
5276
5277 (define_insn "ic_invalidate_line_compact"
5278   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5279                      (match_operand:SI 1 "register_operand" "r")]
5280                     UNSPEC_ICACHE)
5281    (clobber (reg:SI PR_REG))]
5282   "TARGET_SHCOMPACT"
5283   "jsr @%1%#"
5284   [(set_attr "type" "sfunc")
5285    (set_attr "needs_delay_slot" "yes")])
5286
5287 (define_expand "initialize_trampoline"
5288   [(match_operand:SI 0 "" "")
5289    (match_operand:SI 1 "" "")
5290    (match_operand:SI 2 "" "")]
5291   "TARGET_SHCOMPACT"
5292   "
5293 {
5294   rtx sfun, tramp;
5295
5296   tramp = force_reg (Pmode, operands[0]);
5297   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5298                                             SFUNC_STATIC));
5299   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5300   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5301
5302   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5303   DONE;
5304 }")
5305
5306 (define_insn "initialize_trampoline_compact"
5307   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5308                      (match_operand:SI 1 "register_operand" "r")
5309                      (reg:SI R2_REG) (reg:SI R3_REG)]
5310                     UNSPEC_INIT_TRAMP)
5311
5312    (clobber (reg:SI PR_REG))]
5313   "TARGET_SHCOMPACT"
5314   "jsr @%1%#"
5315   [(set_attr "type" "sfunc")
5316    (set_attr "needs_delay_slot" "yes")])
5317
5318 (define_insn "movqi_i"
5319   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5320         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5321   "TARGET_SH1
5322    && (arith_reg_operand (operands[0], QImode)
5323        || arith_reg_operand (operands[1], QImode))"
5324   "@
5325         mov     %1,%0
5326         mov     %1,%0
5327         mov.b   %1,%0
5328         mov.b   %1,%0
5329         movt    %0
5330         sts     %1,%0
5331         lds     %1,%0"
5332  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5333   (set_attr_alternative "length"
5334      [(const_int 2)
5335       (const_int 2)
5336       (if_then_else
5337         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5338         (const_int 4) (const_int 2))
5339       (if_then_else
5340         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5341         (const_int 4) (const_int 2))
5342       (const_int 2)
5343       (const_int 2)
5344       (const_int 2)])])
5345
5346 (define_insn "*movqi_media"
5347   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5348         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5349   "TARGET_SHMEDIA
5350    && (arith_reg_operand (operands[0], QImode)
5351        || extend_reg_or_0_operand (operands[1], QImode))"
5352   "@
5353         add.l   %1, r63, %0
5354         movi    %1, %0
5355         ld%M1.ub        %m1, %0
5356         st%M0.b %m0, %N1"
5357   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5358    (set (attr "highpart")
5359         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5360                (const_string "user")]
5361               (const_string "ignore")))])
5362
5363 (define_expand "movqi"
5364   [(set (match_operand:QI 0 "general_operand" "")
5365         (match_operand:QI 1 "general_operand"  ""))]
5366   ""
5367   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5368
5369 (define_expand "reload_inqi"
5370   [(set (match_operand:SI 2 "" "=&r")
5371         (match_operand:QI 1 "inqhi_operand" ""))
5372    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5373         (truncate:QI (match_dup 3)))]
5374   "TARGET_SHMEDIA"
5375   "
5376 {
5377   rtx inner = XEXP (operands[1], 0);
5378   int regno = REGNO (inner);
5379
5380   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5381   operands[1] = gen_rtx_REG (SImode, regno);
5382   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5383 }")
5384
5385 /* When storing r0, we have to avoid reg+reg addressing.  */
5386 (define_insn "movhi_i"
5387   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5388         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5389   "TARGET_SH1
5390    && (arith_reg_operand (operands[0], HImode)
5391        || arith_reg_operand (operands[1], HImode))
5392    && (GET_CODE (operands[0]) != MEM
5393        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5394        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5395        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5396   "@
5397         mov.w   %1,%0
5398         mov     %1,%0
5399         mov.w   %1,%0
5400         movt    %0
5401         mov.w   %1,%0
5402         sts     %1,%0
5403         lds     %1,%0
5404         fake    %1,%0"
5405   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5406
5407 (define_insn "*movhi_media"
5408   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5409         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5410   "TARGET_SHMEDIA
5411    && (arith_reg_operand (operands[0], HImode)
5412        || arith_reg_or_0_operand (operands[1], HImode))"
5413   "@
5414         add.l   %1, r63, %0
5415         movi    %1, %0
5416         #
5417         ld%M1.w %m1, %0
5418         st%M0.w %m0, %N1"
5419   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5420    (set (attr "highpart")
5421         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5422                (const_string "user")]
5423               (const_string "ignore")))])
5424
5425 (define_split
5426   [(set (match_operand:HI 0 "register_operand" "")
5427         (match_operand:HI 1 "immediate_operand" ""))]
5428   "TARGET_SHMEDIA && reload_completed
5429    && ! satisfies_constraint_I16 (operands[1])"
5430   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5431
5432 (define_expand "movhi"
5433   [(set (match_operand:HI 0 "general_movdst_operand" "")
5434         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5435   ""
5436   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5437
5438 (define_expand "reload_inhi"
5439   [(set (match_operand:SI 2 "" "=&r")
5440         (match_operand:HI 1 "inqhi_operand" ""))
5441    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5442         (truncate:HI (match_dup 3)))]
5443   "TARGET_SHMEDIA"
5444   "
5445 {
5446   rtx inner = XEXP (operands[1], 0);
5447   int regno = REGNO (inner);
5448
5449   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5450   operands[1] = gen_rtx_REG (SImode, regno);
5451   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5452 }")
5453
5454 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5455 ;; compiled with -m2 -ml -O3 -funroll-loops
5456 (define_insn "*movdi_i"
5457   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5458         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5459   "TARGET_SH1
5460    && (arith_reg_operand (operands[0], DImode)
5461        || arith_reg_operand (operands[1], DImode))"
5462   "* return output_movedouble (insn, operands, DImode);"
5463   [(set_attr "length" "4")
5464    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5465
5466 ;; If the output is a register and the input is memory or a register, we have
5467 ;; to be careful and see which word needs to be loaded first.
5468
5469 (define_split
5470   [(set (match_operand:DI 0 "general_movdst_operand" "")
5471         (match_operand:DI 1 "general_movsrc_operand" ""))]
5472   "TARGET_SH1 && reload_completed"
5473   [(set (match_dup 2) (match_dup 3))
5474    (set (match_dup 4) (match_dup 5))]
5475   "
5476 {
5477   int regno;
5478
5479   if ((GET_CODE (operands[0]) == MEM
5480        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5481       || (GET_CODE (operands[1]) == MEM
5482           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5483     FAIL;
5484
5485   switch (GET_CODE (operands[0]))
5486     {
5487     case REG:
5488       regno = REGNO (operands[0]);
5489       break;
5490     case SUBREG:
5491       regno = subreg_regno (operands[0]);
5492       break;
5493     case MEM:
5494       regno = -1;
5495       break;
5496     default:
5497       gcc_unreachable ();
5498     }
5499
5500   if (regno == -1
5501       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5502     {
5503       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5504       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5505       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5506       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5507     }
5508   else
5509     {
5510       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5511       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5512       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5513       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5514     }
5515
5516   if (operands[2] == 0 || operands[3] == 0
5517       || operands[4] == 0 || operands[5] == 0)
5518     FAIL;
5519 }")
5520
5521 ;; The '?'s in the following constraints may not reflect the time taken
5522 ;; to perform the move. They are there to discourage the use of floating-
5523 ;; point registers for storing integer values.
5524 (define_insn "*movdi_media"
5525   [(set (match_operand:DI 0 "general_movdst_operand"
5526                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5527         (match_operand:DI 1 "general_movsrc_operand"
5528          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5529   "TARGET_SHMEDIA_FPU
5530    && (register_operand (operands[0], DImode)
5531        || sh_register_operand (operands[1], DImode))"
5532   "@
5533         add     %1, r63, %0
5534         movi    %1, %0
5535         #
5536         ld%M1.q %m1, %0
5537         st%M0.q %m0, %N1
5538         fld%M1.d        %m1, %0
5539         fst%M0.d        %m0, %1
5540         fmov.qd %N1, %0
5541         fmov.dq %1, %0
5542         fmov.d  %1, %0
5543         ptabs   %1, %0
5544         gettr   %1, %0
5545         pt      %1, %0"
5546   [(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")
5547    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5548
5549 (define_insn "*movdi_media_nofpu"
5550   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5551         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5552   "TARGET_SHMEDIA
5553    && (register_operand (operands[0], DImode)
5554        || sh_register_operand (operands[1], DImode))"
5555   "@
5556         add     %1, r63, %0
5557         movi    %1, %0
5558         #
5559         ld%M1.q %m1, %0
5560         st%M0.q %m0, %N1
5561         ptabs   %1, %0
5562         gettr   %1, %0
5563         pt      %1, %0"
5564   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5565    (set_attr "length" "4,4,16,4,4,4,4,*")])
5566
5567 (define_insn "*movdi_media_I16"
5568   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5569         (match_operand:DI 1 "const_int_operand" "I16"))]
5570   "TARGET_SHMEDIA && reload_completed"
5571   "movi %1, %0"
5572   [(set_attr "type" "arith_media")
5573    (set_attr "length" "4")])
5574
5575 (define_split
5576   [(set (match_operand:DI 0 "arith_reg_dest" "")
5577         (match_operand:DI 1 "immediate_operand" ""))]
5578   "TARGET_SHMEDIA && reload_completed
5579    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5580   [(set (match_dup 0) (match_dup 1))]
5581   "
5582 {
5583   rtx insn;
5584
5585   if (TARGET_SHMEDIA64)
5586     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5587   else
5588     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5589
5590   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5591
5592   DONE;
5593 }")
5594
5595 (define_expand "movdi_const"
5596   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5597         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5598                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5599    (set (match_dup 0)
5600         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5601                 (const:DI (unspec:DI [(match_dup 1)
5602                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5603    (set (match_dup 0)
5604         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5605                 (const:DI (unspec:DI [(match_dup 1)
5606                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5607    (set (match_dup 0)
5608         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5609                 (const:DI (unspec:DI [(match_dup 1)
5610                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5611   "TARGET_SHMEDIA64 && reload_completed
5612    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5613   "
5614 {
5615   sh_mark_label (operands[1], 4);
5616 }")
5617
5618 (define_expand "movdi_const_32bit"
5619   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5620         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5621                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5622    (set (match_dup 0)
5623         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5624                 (const:DI (unspec:DI [(match_dup 1)
5625                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5626   "TARGET_SHMEDIA32 && reload_completed
5627    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5628   "
5629 {
5630   sh_mark_label (operands[1], 2);
5631 }")
5632
5633 (define_expand "movdi_const_16bit"
5634   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5635         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5636                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5637   "TARGET_SHMEDIA && flag_pic && reload_completed
5638    && GET_CODE (operands[1]) == SYMBOL_REF"
5639   "")
5640
5641 (define_split
5642   [(set (match_operand:DI 0 "ext_dest_operand" "")
5643         (match_operand:DI 1 "immediate_operand" ""))]
5644   "TARGET_SHMEDIA && reload_completed
5645    && GET_CODE (operands[1]) == CONST_INT
5646    && ! satisfies_constraint_I16 (operands[1])"
5647   [(set (match_dup 0) (match_dup 2))
5648    (match_dup 1)]
5649   "
5650 {
5651   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5652   unsigned HOST_WIDE_INT low = val;
5653   unsigned HOST_WIDE_INT high = val;
5654   unsigned HOST_WIDE_INT sign;
5655   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5656
5657   /* Zero-extend the 16 least-significant bits.  */
5658   low &= 0xffff;
5659
5660   /* Arithmetic shift right the word by 16 bits.  */
5661   high >>= 16;
5662   if (GET_CODE (operands[0]) == SUBREG
5663       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5664     {
5665       high &= 0xffff;
5666       high ^= 0x8000;
5667       high -= 0x8000;
5668     }
5669   else
5670     {
5671       sign = 1;
5672       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5673       high ^= sign;
5674       high -= sign;
5675     }
5676   do
5677     {
5678       /* If we can't generate the constant with a two-insn movi / shori
5679          sequence, try some other strategies.  */
5680       if (! CONST_OK_FOR_I16 (high))
5681         {
5682           /* Try constant load / left shift.  We know VAL != 0.  */
5683           val2 = val ^ (val-1);
5684           if (val2 > 0x1ffff)
5685             {
5686               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5687
5688               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5689                   || (! CONST_OK_FOR_I16 (high >> 16)
5690                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5691                 {
5692                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5693                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5694                                                    GEN_INT (trailing_zeroes));
5695                   break;
5696                 }
5697             }
5698           /* Try constant load / right shift.  */
5699           val2 = (val >> 15) + 1;
5700           if (val2 == (val2 & -val2))
5701             {
5702               int shift = 49 - exact_log2 (val2);
5703
5704               val2 = trunc_int_for_mode (val << shift, DImode);
5705               if (CONST_OK_FOR_I16 (val2))
5706                 {
5707                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5708                                                    GEN_INT (shift));
5709                   break;
5710                 }
5711             }
5712           /* Try mperm.w .  */
5713           val2 = val & 0xffff;
5714           if ((val >> 16 & 0xffff) == val2
5715               && (val >> 32 & 0xffff) == val2
5716               && (val >> 48 & 0xffff) == val2)
5717             {
5718               val2 = (HOST_WIDE_INT) val >> 48;
5719               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5720               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5721               break;
5722             }
5723           /* Try movi / mshflo.l  */
5724           val2 = (HOST_WIDE_INT) val >> 32;
5725           if (val2 == ((unsigned HOST_WIDE_INT)
5726                         trunc_int_for_mode (val, SImode)))
5727             {
5728               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5729                                              operands[0]);
5730               break;
5731             }
5732           /* Try movi / mshflo.l w/ r63.  */
5733           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5734           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5735             {
5736               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5737                                              const0_rtx);
5738               break;
5739             }
5740         }
5741       val2 = high;
5742       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5743     }
5744   while (0);
5745   operands[2] = GEN_INT (val2);
5746 }")
5747
5748 (define_split
5749   [(set (match_operand:DI 0 "ext_dest_operand" "")
5750         (match_operand:DI 1 "immediate_operand" ""))]
5751   "TARGET_SHMEDIA && reload_completed
5752    && GET_CODE (operands[1]) == CONST_DOUBLE"
5753   [(set (match_dup 0) (match_dup 2))
5754   (set (match_dup 0)
5755        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5756   "
5757 {
5758   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5759   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5760   unsigned HOST_WIDE_INT val = low;
5761   unsigned HOST_WIDE_INT sign;
5762
5763   /* Zero-extend the 16 least-significant bits.  */
5764   val &= 0xffff;
5765   operands[1] = GEN_INT (val);
5766
5767   /* Arithmetic shift right the double-word by 16 bits.  */
5768   low >>= 16;
5769   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5770   high >>= 16;
5771   sign = 1;
5772   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5773   high ^= sign;
5774   high -= sign;
5775
5776   /* This will only be true if high is a sign-extension of low, i.e.,
5777      it must be either 0 or (unsigned)-1, and be zero iff the
5778      most-significant bit of low is set.  */
5779   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5780     operands[2] = GEN_INT (low);
5781   else
5782     operands[2] = immed_double_const (low, high, DImode);
5783 }")
5784
5785 (define_insn "shori_media"
5786   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5787         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5788                            (const_int 16))
5789                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5790   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5791   "@
5792         shori   %u2, %0
5793         #"
5794   [(set_attr "type" "arith_media,*")])
5795
5796 (define_insn "*shori_media_si"
5797   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5798         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5799                            (const_int 16))
5800                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5801   "TARGET_SHMEDIA"
5802   "shori        %u2, %0")
5803
5804 (define_expand "movdi"
5805   [(set (match_operand:DI 0 "general_movdst_operand" "")
5806         (match_operand:DI 1 "general_movsrc_operand" ""))]
5807   ""
5808   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5809
5810 (define_insn "movdf_media"
5811   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5812         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5813   "TARGET_SHMEDIA_FPU
5814    && (register_operand (operands[0], DFmode)
5815        || sh_register_operand (operands[1], DFmode))"
5816   "@
5817         fmov.d  %1, %0
5818         fmov.qd %N1, %0
5819         fmov.dq %1, %0
5820         add     %1, r63, %0
5821         #
5822         fld%M1.d        %m1, %0
5823         fst%M0.d        %m0, %1
5824         ld%M1.q %m1, %0
5825         st%M0.q %m0, %N1"
5826   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5827
5828 (define_insn "movdf_media_nofpu"
5829   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5830         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5831   "TARGET_SHMEDIA
5832    && (register_operand (operands[0], DFmode)
5833        || sh_register_operand (operands[1], DFmode))"
5834   "@
5835         add     %1, r63, %0
5836         #
5837         ld%M1.q %m1, %0
5838         st%M0.q %m0, %N1"
5839   [(set_attr "type" "arith_media,*,load_media,store_media")])
5840
5841 (define_split
5842   [(set (match_operand:DF 0 "arith_reg_dest" "")
5843         (match_operand:DF 1 "immediate_operand" ""))]
5844   "TARGET_SHMEDIA && reload_completed"
5845   [(set (match_dup 3) (match_dup 2))]
5846   "
5847 {
5848   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5849   long values[2];
5850   REAL_VALUE_TYPE value;
5851
5852   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5853   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5854
5855   if (HOST_BITS_PER_WIDE_INT >= 64)
5856     operands[2] = immed_double_const ((unsigned long) values[endian]
5857                                       | ((HOST_WIDE_INT) values[1 - endian]
5858                                          << 32), 0, DImode);
5859   else
5860     {
5861       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5862       operands[2] = immed_double_const (values[endian], values[1 - endian],
5863                                         DImode);
5864     }
5865
5866   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5867 }")
5868
5869 ;; ??? This should be a define expand.
5870
5871 (define_insn "movdf_k"
5872   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5873         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5874   "TARGET_SH1
5875    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5876        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5877        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5878        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5879    && (arith_reg_operand (operands[0], DFmode)
5880        || arith_reg_operand (operands[1], DFmode))"
5881   "* return output_movedouble (insn, operands, DFmode);"
5882   [(set_attr "length" "4")
5883    (set_attr "type" "move,pcload,load,store")])
5884
5885 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5886 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5887 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5888 ;; the d/m/c/X alternative, which is split later into single-precision
5889 ;; instructions.  And when not optimizing, no splits are done before fixing
5890 ;; up pcloads, so we need usable length information for that.
5891 (define_insn "movdf_i4"
5892   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5893         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5894    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5895    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5896   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5897    && (arith_reg_operand (operands[0], DFmode)
5898        || arith_reg_operand (operands[1], DFmode))"
5899   "@
5900         fmov    %1,%0
5901         #
5902         #
5903         fmov.d  %1,%0
5904         fmov.d  %1,%0
5905         #
5906         #
5907         #
5908         #
5909         #"
5910   [(set_attr_alternative "length"
5911      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5912       (const_int 4)
5913       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5914       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5915       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5916       (const_int 4)
5917       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5918       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5919       ;; increment or decrement r15 explicitly.
5920       (if_then_else
5921        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5922        (const_int 10) (const_int 8))
5923       (if_then_else
5924        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5925        (const_int 10) (const_int 8))])
5926    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5927    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5928    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5929                                            (const_string "double")
5930                                            (const_string "none")))])
5931
5932 ;; Moving DFmode between fp/general registers through memory
5933 ;; (the top of the stack) is faster than moving through fpul even for
5934 ;; little endian.  Because the type of an instruction is important for its
5935 ;; scheduling,  it is beneficial to split these operations, rather than
5936 ;; emitting them in one single chunk, even if this will expose a stack
5937 ;; use that will prevent scheduling of other stack accesses beyond this
5938 ;; instruction.
5939 (define_split
5940   [(set (match_operand:DF 0 "register_operand" "")
5941         (match_operand:DF 1 "register_operand" ""))
5942    (use (match_operand:PSI 2 "fpscr_operand" ""))
5943    (clobber (match_scratch:SI 3 "=X"))]
5944   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5945    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5946   [(const_int 0)]
5947   "
5948 {
5949   rtx insn, tos;
5950
5951   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5952     {
5953       emit_move_insn (stack_pointer_rtx,
5954                       plus_constant (stack_pointer_rtx, -8));
5955       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5956     }
5957   else
5958     tos = gen_tmp_stack_mem (DFmode,
5959                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5960   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5961   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5962     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5963   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5964     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5965   else
5966     tos = gen_tmp_stack_mem (DFmode,
5967                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5968   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5969   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5970     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5971   else
5972     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5973   DONE;
5974 }")
5975
5976 ;; local-alloc sometimes allocates scratch registers even when not required,
5977 ;; so we must be prepared to handle these.
5978
5979 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5980 (define_split
5981   [(set (match_operand:DF 0 "general_movdst_operand" "")
5982         (match_operand:DF 1 "general_movsrc_operand"  ""))
5983    (use (match_operand:PSI 2 "fpscr_operand" ""))
5984    (clobber (match_scratch:SI 3 ""))]
5985   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5986    && reload_completed
5987    && true_regnum (operands[0]) < 16
5988    && true_regnum (operands[1]) < 16"
5989   [(set (match_dup 0) (match_dup 1))]
5990   "
5991 {
5992   /* If this was a reg <-> mem operation with base + index reg addressing,
5993      we have to handle this in a special way.  */
5994   rtx mem = operands[0];
5995   int store_p = 1;
5996   if (! memory_operand (mem, DFmode))
5997     {
5998       mem = operands[1];
5999       store_p = 0;
6000     }
6001   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6002     mem = SUBREG_REG (mem);
6003   if (GET_CODE (mem) == MEM)
6004     {
6005       rtx addr = XEXP (mem, 0);
6006       if (GET_CODE (addr) == PLUS
6007           && GET_CODE (XEXP (addr, 0)) == REG
6008           && GET_CODE (XEXP (addr, 1)) == REG)
6009         {
6010           int offset;
6011           rtx reg0 = gen_rtx_REG (Pmode, 0);
6012           rtx regop = operands[store_p], word0 ,word1;
6013
6014           if (GET_CODE (regop) == SUBREG)
6015             alter_subreg (&regop);
6016           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6017             offset = 2;
6018           else
6019             offset = 4;
6020           mem = copy_rtx (mem);
6021           PUT_MODE (mem, SImode);
6022           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6023           alter_subreg (&word0);
6024           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6025           alter_subreg (&word1);
6026           if (store_p || ! refers_to_regno_p (REGNO (word0),
6027                                               REGNO (word0) + 1, addr, 0))
6028             {
6029               emit_insn (store_p
6030                          ? gen_movsi_ie (mem, word0)
6031                          : gen_movsi_ie (word0, mem));
6032               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6033               mem = copy_rtx (mem);
6034               emit_insn (store_p
6035                          ? gen_movsi_ie (mem, word1)
6036                          : gen_movsi_ie (word1, mem));
6037               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6038             }
6039           else
6040             {
6041               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6042               emit_insn (gen_movsi_ie (word1, mem));
6043               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6044               mem = copy_rtx (mem);
6045               emit_insn (gen_movsi_ie (word0, mem));
6046             }
6047           DONE;
6048         }
6049     }
6050 }")
6051
6052 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6053 (define_split
6054   [(set (match_operand:DF 0 "register_operand" "")
6055         (match_operand:DF 1 "memory_operand"  ""))
6056    (use (match_operand:PSI 2 "fpscr_operand" ""))
6057    (clobber (reg:SI R0_REG))]
6058   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6059   [(parallel [(set (match_dup 0) (match_dup 1))
6060               (use (match_dup 2))
6061               (clobber (scratch:SI))])]
6062   "")
6063
6064 (define_expand "reload_indf__frn"
6065   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6066                    (match_operand:DF 1 "immediate_operand" "FQ"))
6067               (use (reg:PSI FPSCR_REG))
6068               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6069   "TARGET_SH1"
6070   "")
6071
6072 (define_expand "reload_outdf__RnFRm"
6073   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6074                    (match_operand:DF 1 "register_operand" "af,r"))
6075               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6076   "TARGET_SH1"
6077   "")
6078
6079 ;; Simplify no-op moves.
6080 (define_split
6081   [(set (match_operand:SF 0 "register_operand" "")
6082         (match_operand:SF 1 "register_operand" ""))
6083    (use (match_operand:PSI 2 "fpscr_operand" ""))
6084    (clobber (match_scratch:SI 3 ""))]
6085   "TARGET_SH2E && reload_completed
6086    && true_regnum (operands[0]) == true_regnum (operands[1])"
6087   [(set (match_dup 0) (match_dup 0))]
6088   "")
6089
6090 ;; fmovd substitute post-reload splits
6091 (define_split
6092   [(set (match_operand:DF 0 "register_operand" "")
6093         (match_operand:DF 1 "register_operand" ""))
6094    (use (match_operand:PSI 2 "fpscr_operand" ""))
6095    (clobber (match_scratch:SI 3 ""))]
6096   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6097    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6098    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6099   [(const_int 0)]
6100   "
6101 {
6102   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6103   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6104                            gen_rtx_REG (SFmode, src), operands[2]));
6105   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6106                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6107   DONE;
6108 }")
6109
6110 (define_split
6111   [(set (match_operand:DF 0 "register_operand" "")
6112         (mem:DF (match_operand:SI 1 "register_operand" "")))
6113    (use (match_operand:PSI 2 "fpscr_operand" ""))
6114    (clobber (match_scratch:SI 3 ""))]
6115   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6116    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6117    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6118   [(const_int 0)]
6119   "
6120 {
6121   int regno = true_regnum (operands[0]);
6122   rtx insn;
6123   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6124   rtx mem2
6125     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6126   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6127                                            regno + !! TARGET_LITTLE_ENDIAN),
6128                                   mem2, operands[2]));
6129   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6130   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6131                                                regno + ! TARGET_LITTLE_ENDIAN),
6132                                   change_address (mem, SFmode, NULL_RTX),
6133                                   operands[2]));
6134   DONE;
6135 }")
6136
6137 (define_split
6138   [(set (match_operand:DF 0 "register_operand" "")
6139         (match_operand:DF 1 "memory_operand" ""))
6140    (use (match_operand:PSI 2 "fpscr_operand" ""))
6141    (clobber (match_scratch:SI 3 ""))]
6142   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6143    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6144   [(const_int 0)]
6145   "
6146 {
6147   int regno = true_regnum (operands[0]);
6148   rtx addr, insn, adjust = NULL_RTX;
6149   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6150   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6151   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6152
6153   operands[1] = copy_rtx (mem2);
6154   addr = XEXP (mem2, 0);
6155   if (GET_CODE (addr) != POST_INC)
6156     {
6157       /* If we have to modify the stack pointer, the value that we have
6158          read with post-increment might be modified by an interrupt,
6159          so write it back.  */
6160       if (REGNO (addr) == STACK_POINTER_REGNUM)
6161         adjust = gen_push_e (reg0);
6162       else
6163         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6164       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6165     }
6166   addr = XEXP (addr, 0);
6167   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6168   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6169   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6170   if (adjust)
6171     emit_insn (adjust);
6172   else
6173     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6174   DONE;
6175 }")
6176
6177 (define_split
6178   [(set (match_operand:DF 0 "memory_operand" "")
6179         (match_operand:DF 1 "register_operand" ""))
6180    (use (match_operand:PSI 2 "fpscr_operand" ""))
6181    (clobber (match_scratch:SI 3 ""))]
6182   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6183    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6184   [(const_int 0)]
6185   "
6186 {
6187   int regno = true_regnum (operands[1]);
6188   rtx insn, addr, adjust = NULL_RTX;
6189
6190   operands[0] = copy_rtx (operands[0]);
6191   PUT_MODE (operands[0], SFmode);
6192   insn = emit_insn (gen_movsf_ie (operands[0],
6193                                   gen_rtx_REG (SFmode,
6194                                            regno + ! TARGET_LITTLE_ENDIAN),
6195                                   operands[2]));
6196   operands[0] = copy_rtx (operands[0]);
6197   addr = XEXP (operands[0], 0);
6198   if (GET_CODE (addr) != PRE_DEC)
6199     {
6200       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6201       emit_insn_before (adjust, insn);
6202       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6203     }
6204   addr = XEXP (addr, 0);
6205   if (! adjust)
6206     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6207   insn = emit_insn (gen_movsf_ie (operands[0],
6208                                   gen_rtx_REG (SFmode,
6209                                            regno + !! TARGET_LITTLE_ENDIAN),
6210                                   operands[2]));
6211   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6212   DONE;
6213 }")
6214
6215 ;; If the output is a register and the input is memory or a register, we have
6216 ;; to be careful and see which word needs to be loaded first.
6217
6218 (define_split
6219   [(set (match_operand:DF 0 "general_movdst_operand" "")
6220         (match_operand:DF 1 "general_movsrc_operand" ""))]
6221   "TARGET_SH1 && reload_completed"
6222   [(set (match_dup 2) (match_dup 3))
6223    (set (match_dup 4) (match_dup 5))]
6224   "
6225 {
6226   int regno;
6227
6228   if ((GET_CODE (operands[0]) == MEM
6229        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6230       || (GET_CODE (operands[1]) == MEM
6231           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6232     FAIL;
6233
6234   switch (GET_CODE (operands[0]))
6235     {
6236     case REG:
6237       regno = REGNO (operands[0]);
6238       break;
6239     case SUBREG:
6240       regno = subreg_regno (operands[0]);
6241       break;
6242     case MEM:
6243       regno = -1;
6244       break;
6245     default:
6246       gcc_unreachable ();
6247     }
6248
6249   if (regno == -1
6250       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6251     {
6252       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6253       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6254       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6255       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6256     }
6257   else
6258     {
6259       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6260       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6261       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6262       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6263     }
6264
6265   if (operands[2] == 0 || operands[3] == 0
6266       || operands[4] == 0 || operands[5] == 0)
6267     FAIL;
6268 }")
6269
6270 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6271 ;; used only once, let combine add in the index again.
6272
6273 (define_split
6274   [(set (match_operand:SI 0 "register_operand" "")
6275         (match_operand:SI 1 "" ""))
6276    (clobber (match_operand 2 "register_operand" ""))]
6277   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6278    && ALLOW_INDEXED_ADDRESS"
6279   [(use (reg:SI R0_REG))]
6280   "
6281 {
6282   rtx addr, reg, const_int;
6283
6284   if (GET_CODE (operands[1]) != MEM)
6285     FAIL;
6286   addr = XEXP (operands[1], 0);
6287   if (GET_CODE (addr) != PLUS)
6288     FAIL;
6289   reg = XEXP (addr, 0);
6290   const_int = XEXP (addr, 1);
6291   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6292          && GET_CODE (const_int) == CONST_INT))
6293     FAIL;
6294   emit_move_insn (operands[2], const_int);
6295   emit_move_insn (operands[0],
6296                   change_address (operands[1], VOIDmode,
6297                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6298   DONE;
6299 }")
6300
6301 (define_split
6302   [(set (match_operand:SI 1 "" "")
6303         (match_operand:SI 0 "register_operand" ""))
6304    (clobber (match_operand 2 "register_operand" ""))]
6305   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6306    && ALLOW_INDEXED_ADDRESS"
6307   [(use (reg:SI R0_REG))]
6308   "
6309 {
6310   rtx addr, reg, const_int;
6311
6312   if (GET_CODE (operands[1]) != MEM)
6313     FAIL;
6314   addr = XEXP (operands[1], 0);
6315   if (GET_CODE (addr) != PLUS)
6316     FAIL;
6317   reg = XEXP (addr, 0);
6318   const_int = XEXP (addr, 1);
6319   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6320          && GET_CODE (const_int) == CONST_INT))
6321     FAIL;
6322   emit_move_insn (operands[2], const_int);
6323   emit_move_insn (change_address (operands[1], VOIDmode,
6324                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6325                   operands[0]);
6326   DONE;
6327 }")
6328
6329 (define_expand "movdf"
6330   [(set (match_operand:DF 0 "general_movdst_operand" "")
6331         (match_operand:DF 1 "general_movsrc_operand" ""))]
6332   ""
6333   "
6334 {
6335   if (prepare_move_operands (operands, DFmode)) DONE;
6336   if (TARGET_SHMEDIA)
6337     {
6338       if (TARGET_SHMEDIA_FPU)
6339         emit_insn (gen_movdf_media (operands[0], operands[1]));
6340       else
6341         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6342       DONE;
6343     }
6344   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6345     {
6346       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6347       DONE;
6348     }
6349 }")
6350
6351 ;;This is incompatible with the way gcc uses subregs.
6352 ;;(define_insn "movv2sf_i"
6353 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6354 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6355 ;;  "TARGET_SHMEDIA_FPU
6356 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6357 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6358 ;;  "@
6359 ;;      #
6360 ;;      fld%M1.p        %m1, %0
6361 ;;      fst%M0.p        %m0, %1"
6362 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6363
6364 (define_insn_and_split "movv2sf_i"
6365   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6366         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6367   "TARGET_SHMEDIA_FPU"
6368   "#"
6369   "TARGET_SHMEDIA_FPU && reload_completed"
6370   [(set (match_dup 0) (match_dup 1))]
6371   "
6372 {
6373   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6374   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6375 }")
6376
6377 (define_expand "movv2sf"
6378   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6379         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6380   "TARGET_SHMEDIA_FPU"
6381   "
6382 {
6383   if (prepare_move_operands (operands, V2SFmode))
6384     DONE;
6385 }")
6386
6387 (define_expand "addv2sf3"
6388   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6389    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6390    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6391   "TARGET_SHMEDIA_FPU"
6392   "
6393 {
6394   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6395   DONE;
6396 }")
6397
6398 (define_expand "subv2sf3"
6399   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6400    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6401    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6402   "TARGET_SHMEDIA_FPU"
6403   "
6404 {
6405   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6406   DONE;
6407 }")
6408
6409 (define_expand "mulv2sf3"
6410   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6411    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6412    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6413   "TARGET_SHMEDIA_FPU"
6414   "
6415 {
6416   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6417   DONE;
6418 }")
6419
6420 (define_expand "divv2sf3"
6421   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6422    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6423    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6424   "TARGET_SHMEDIA_FPU"
6425   "
6426 {
6427   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6428   DONE;
6429 }")
6430
6431 (define_insn_and_split "*movv4sf_i"
6432   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6433         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6434   "TARGET_SHMEDIA_FPU"
6435   "#"
6436   "&& reload_completed"
6437   [(const_int 0)]
6438   "
6439 {
6440   int i;
6441
6442   for (i = 0; i < 4/2; i++)
6443     {
6444       rtx x, y;
6445
6446       if (GET_CODE (operands[0]) == MEM)
6447         x = adjust_address (operands[0], V2SFmode,
6448                             i * GET_MODE_SIZE (V2SFmode));
6449       else
6450         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6451
6452       if (GET_CODE (operands[1]) == MEM)
6453         y = adjust_address (operands[1], V2SFmode,
6454                             i * GET_MODE_SIZE (V2SFmode));
6455       else
6456         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6457
6458       emit_insn (gen_movv2sf_i (x, y));
6459     }
6460
6461   DONE;
6462 }"
6463   [(set_attr "length" "8")])
6464
6465 (define_expand "movv4sf"
6466   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6467         (match_operand:V4SF 1 "general_operand" ""))]
6468   "TARGET_SHMEDIA_FPU"
6469   "
6470 {
6471   if (prepare_move_operands (operands, V4SFmode))
6472     DONE;
6473 }")
6474
6475 (define_insn_and_split "*movv16sf_i"
6476   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6477         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6478   "TARGET_SHMEDIA_FPU"
6479   "#"
6480   "&& reload_completed"
6481   [(const_int 0)]
6482   "
6483 {
6484   int i;
6485
6486   for (i = 0; i < 16/2; i++)
6487     {
6488       rtx x,y;
6489
6490       if (GET_CODE (operands[0]) == MEM)
6491         x = adjust_address (operands[0], V2SFmode,
6492                             i * GET_MODE_SIZE (V2SFmode));
6493       else
6494         {
6495           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6496           alter_subreg (&x);
6497         }
6498
6499       if (GET_CODE (operands[1]) == MEM)
6500         y = adjust_address (operands[1], V2SFmode,
6501                             i * GET_MODE_SIZE (V2SFmode));
6502       else
6503         {
6504           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6505           alter_subreg (&y);
6506         }
6507
6508       emit_insn (gen_movv2sf_i (x, y));
6509     }
6510
6511   DONE;
6512 }"
6513   [(set_attr "length" "32")])
6514
6515 (define_expand "movv16sf"
6516   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6517         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6518   "TARGET_SHMEDIA_FPU"
6519   "
6520 {
6521   if (prepare_move_operands (operands, V16SFmode))
6522     DONE;
6523 }")
6524
6525 (define_insn "movsf_media"
6526   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6527         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6528   "TARGET_SHMEDIA_FPU
6529    && (register_operand (operands[0], SFmode)
6530        || sh_register_operand (operands[1], SFmode))"
6531   "@
6532         fmov.s  %1, %0
6533         fmov.ls %N1, %0
6534         fmov.sl %1, %0
6535         add.l   %1, r63, %0
6536         #
6537         fld%M1.s        %m1, %0
6538         fst%M0.s        %m0, %1
6539         ld%M1.l %m1, %0
6540         st%M0.l %m0, %N1"
6541   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6542    (set (attr "highpart")
6543         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6544                (const_string "user")]
6545               (const_string "ignore")))])
6546
6547 (define_insn "movsf_media_nofpu"
6548   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6549         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6550   "TARGET_SHMEDIA
6551    && (register_operand (operands[0], SFmode)
6552        || sh_register_operand (operands[1], SFmode))"
6553   "@
6554         add.l   %1, r63, %0
6555         #
6556         ld%M1.l %m1, %0
6557         st%M0.l %m0, %N1"
6558   [(set_attr "type" "arith_media,*,load_media,store_media")
6559    (set (attr "highpart")
6560         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6561                (const_string "user")]
6562               (const_string "ignore")))])
6563
6564 (define_split
6565   [(set (match_operand:SF 0 "arith_reg_dest" "")
6566         (match_operand:SF 1 "immediate_operand" ""))]
6567   "TARGET_SHMEDIA && reload_completed
6568    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6569   [(set (match_dup 3) (match_dup 2))]
6570   "
6571 {
6572   long values;
6573   REAL_VALUE_TYPE value;
6574
6575   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6576   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6577   operands[2] = GEN_INT (values);
6578
6579   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6580 }")
6581
6582 (define_insn "movsf_i"
6583   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6584         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6585   "TARGET_SH1
6586    && (! TARGET_SH2E
6587        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6588        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6589        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6590    && (arith_reg_operand (operands[0], SFmode)
6591        || arith_reg_operand (operands[1], SFmode))"
6592   "@
6593         mov     %1,%0
6594         mov     #0,%0
6595         mov.l   %1,%0
6596         mov.l   %1,%0
6597         mov.l   %1,%0
6598         lds     %1,%0
6599         sts     %1,%0"
6600   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6601
6602 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6603 ;; update_flow_info would not know where to put REG_EQUAL notes
6604 ;; when the destination changes mode.
6605 (define_insn "movsf_ie"
6606   [(set (match_operand:SF 0 "general_movdst_operand"
6607          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6608         (match_operand:SF 1 "general_movsrc_operand"
6609           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6610    (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"))
6611    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6612
6613   "TARGET_SH2E
6614    && (arith_reg_operand (operands[0], SFmode)
6615        || arith_reg_operand (operands[1], SFmode)
6616        || arith_reg_operand (operands[3], SImode)
6617        || (fpul_operand (operands[0], SFmode)
6618            && memory_operand (operands[1], SFmode)
6619            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6620        || (fpul_operand (operands[1], SFmode)
6621            && memory_operand (operands[0], SFmode)
6622            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6623   "@
6624         fmov    %1,%0
6625         mov     %1,%0
6626         fldi0   %0
6627         fldi1   %0
6628         #
6629         fmov.s  %1,%0
6630         fmov.s  %1,%0
6631         mov.l   %1,%0
6632         mov.l   %1,%0
6633         mov.l   %1,%0
6634         fsts    fpul,%0
6635         flds    %1,fpul
6636         lds.l   %1,%0
6637         #
6638         sts     %1,%0
6639         lds     %1,%0
6640         sts.l   %1,%0
6641         lds.l   %1,%0
6642         ! move optimized away"
6643   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6644    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6645    (set_attr_alternative "length"
6646      [(const_int 2)
6647       (const_int 2)
6648       (const_int 2)
6649       (const_int 2)
6650       (const_int 4)
6651       (if_then_else
6652         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6653         (const_int 4) (const_int 2))
6654       (if_then_else
6655         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6656         (const_int 4) (const_int 2))
6657       (const_int 2)
6658       (if_then_else
6659         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6660         (const_int 4) (const_int 2))
6661       (if_then_else
6662         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6663         (const_int 4) (const_int 2))
6664       (const_int 2)
6665       (const_int 2)
6666       (const_int 2)
6667       (const_int 4)
6668       (const_int 2)
6669       (const_int 2)
6670       (const_int 2)
6671       (const_int 2)
6672       (const_int 0)])
6673    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6674                                            (const_string "single")
6675                                            (const_string "none")))])
6676
6677 (define_split
6678   [(set (match_operand:SF 0 "register_operand" "")
6679         (match_operand:SF 1 "register_operand" ""))
6680    (use (match_operand:PSI 2 "fpscr_operand" ""))
6681    (clobber (reg:SI FPUL_REG))]
6682   "TARGET_SH1"
6683   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6684               (use (match_dup 2))
6685               (clobber (scratch:SI))])
6686    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6687               (use (match_dup 2))
6688               (clobber (scratch:SI))])]
6689   "")
6690
6691 (define_expand "movsf"
6692   [(set (match_operand:SF 0 "general_movdst_operand" "")
6693         (match_operand:SF 1 "general_movsrc_operand" ""))]
6694   ""
6695   "
6696 {
6697   if (prepare_move_operands (operands, SFmode))
6698     DONE;
6699   if (TARGET_SHMEDIA)
6700     {
6701       if (TARGET_SHMEDIA_FPU)
6702         emit_insn (gen_movsf_media (operands[0], operands[1]));
6703       else
6704         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6705       DONE;
6706     }
6707   if (TARGET_SH2E)
6708     {
6709       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6710       DONE;
6711     }
6712 }")
6713
6714 (define_insn "mov_nop"
6715   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6716   "TARGET_SH2E"
6717   ""
6718   [(set_attr "length" "0")
6719    (set_attr "type" "nil")])
6720
6721 (define_expand "reload_insf__frn"
6722   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6723                    (match_operand:SF 1 "immediate_operand" "FQ"))
6724               (use (reg:PSI FPSCR_REG))
6725               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6726   "TARGET_SH1"
6727   "")
6728
6729 (define_expand "reload_insi__i_fpul"
6730   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6731                    (match_operand:SI 1 "immediate_operand" "i"))
6732               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6733   "TARGET_SH1"
6734   "")
6735
6736 (define_expand "ptabs"
6737   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6738   "TARGET_SHMEDIA"
6739   "
6740 {
6741   if (!TARGET_PT_FIXED)
6742     {
6743       rtx eq = operands[1];
6744
6745       /* ??? For canonical RTL we really should remove any CONST from EQ
6746          before wrapping it in the AND, and finally wrap the EQ into a
6747          const if is constant.  However, for reload we must expose the
6748          input register or symbolic constant, and we can't have
6749          different insn structures outside of the operands for different
6750          alternatives of the same pattern.  */
6751       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6752                        GEN_INT (3));
6753       operands[1]
6754         = (gen_rtx_IF_THEN_ELSE
6755             (PDImode,
6756              eq,
6757              gen_rtx_MEM (PDImode, operands[1]),
6758              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6759                             PDImode, operands[1])));
6760     }
6761 }")
6762
6763 ;; expanded by ptabs expander.
6764 (define_insn "*extendsipdi_media"
6765   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6766         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6767                                                           "r,Csy")
6768                                       (const_int 3))
6769                               (const_int 3))
6770                           (mem:PDI (match_dup 1))
6771                           (sign_extend:PDI (match_dup 1))))]
6772   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6773   "@
6774         ptabs   %1, %0
6775         pt      %1, %0"
6776   [(set_attr "type"   "ptabs_media,pt_media")
6777    (set_attr "length" "4,*")])
6778
6779 (define_insn "*truncdipdi_media"
6780   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6781         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6782                                                           "r,Csy")
6783                                       (const_int 3))
6784                               (const_int 3))
6785                           (mem:PDI (match_dup 1))
6786                           (truncate:PDI (match_dup 1))))]
6787   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6788   "@
6789         ptabs   %1, %0
6790         pt      %1, %0"
6791   [(set_attr "type"   "ptabs_media,pt_media")
6792    (set_attr "length" "4,*")])
6793
6794 (define_insn "*movsi_y"
6795   [(set (match_operand:SI 0 "register_operand" "=y,y")
6796         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6797    (clobber (match_scratch:SI 2 "=&z,r"))]
6798   "TARGET_SH2E
6799    && (reload_in_progress || reload_completed)"
6800   "#"
6801   [(set_attr "length" "4")
6802    (set_attr "type" "pcload,move")])
6803
6804 (define_split
6805   [(set (match_operand:SI 0 "register_operand" "")
6806         (match_operand:SI 1 "immediate_operand" ""))
6807    (clobber (match_operand:SI 2 "register_operand" ""))]
6808   "TARGET_SH1"
6809   [(set (match_dup 2) (match_dup 1))
6810    (set (match_dup 0) (match_dup 2))]
6811   "")
6812
6813 (define_split
6814   [(set (match_operand:SI 0 "register_operand" "")
6815         (match_operand:SI 1 "memory_operand" ""))
6816    (clobber (reg:SI R0_REG))]
6817   "TARGET_SH1"
6818   [(set (match_dup 0) (match_dup 1))]
6819   "")
6820 \f
6821 ;; ------------------------------------------------------------------------
6822 ;; Define the real conditional branch instructions.
6823 ;; ------------------------------------------------------------------------
6824
6825 (define_insn "branch_true"
6826   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6827                            (label_ref (match_operand 0 "" ""))
6828                            (pc)))]
6829   "TARGET_SH1"
6830   "* return output_branch (1, insn, operands);"
6831   [(set_attr "type" "cbranch")])
6832
6833 (define_insn "branch_false"
6834   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6835                            (label_ref (match_operand 0 "" ""))
6836                            (pc)))]
6837   "TARGET_SH1"
6838   "* return output_branch (0, insn, operands);"
6839   [(set_attr "type" "cbranch")])
6840
6841 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6842 ;; which destination is too far away.
6843 ;; The const_int_operand is distinct for each branch target; it avoids
6844 ;; unwanted matches with redundant_insn.
6845 (define_insn "block_branch_redirect"
6846   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6847   "TARGET_SH1"
6848   ""
6849   [(set_attr "length" "0")])
6850
6851 ;; This one has the additional purpose to record a possible scratch register
6852 ;; for the following branch.
6853 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6854 ;; because the insn then might be deemed dead and deleted.  And we can't
6855 ;; make the use in the jump insn explicit because that would disable
6856 ;; delay slot scheduling from the target.
6857 (define_insn "indirect_jump_scratch"
6858   [(set (match_operand:SI 0 "register_operand" "=r")
6859         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6860    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6861   "TARGET_SH1"
6862   ""
6863   [(set_attr "length" "0")])
6864
6865 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6866 ;; being pulled into the delay slot of a condbranch that has been made to
6867 ;; jump around the unconditional jump because it was out of range.
6868 (define_insn "stuff_delay_slot"
6869   [(set (pc)
6870         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6871    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6872   "TARGET_SH1"
6873   ""
6874   [(set_attr "length" "0")
6875    (set_attr "cond_delay_slot" "yes")])
6876 \f
6877 ;; Conditional branch insns
6878
6879 (define_expand "beq_media"
6880   [(set (pc)
6881         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6882                           (match_operand:DI 2 "arith_operand" "r,I06"))
6883                       (match_operand 0 "" "")
6884                       (pc)))]
6885   "TARGET_SHMEDIA"
6886   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6887
6888 (define_insn "*beq_media_i"
6889   [(set (pc)
6890         (if_then_else (match_operator 3 "equality_comparison_operator"
6891                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6892                          (match_operand:DI 2 "arith_operand" "r,I06")])
6893                       (match_operand 0 "target_operand" "b,b")
6894                       (pc)))]
6895   "TARGET_SHMEDIA"
6896   "@
6897         b%o3%'  %1, %2, %0%>
6898         b%o3i%' %1, %2, %0%>"
6899   [(set_attr "type" "cbranch_media")])
6900
6901 (define_insn "*beq_media_i32"
6902   [(set (pc)
6903         (if_then_else (match_operator 3 "equality_comparison_operator"
6904                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6905                          (match_operand:SI 2 "arith_operand" "r,I06")])
6906                       (match_operand 0 "target_operand" "b,b")
6907                       (pc)))]
6908   "TARGET_SHMEDIA"
6909   "@
6910         b%o3%'  %1, %2, %0%>
6911         b%o3i%' %1, %2, %0%>"
6912   [(set_attr "type" "cbranch_media")])
6913
6914 (define_expand "bne_media"
6915   [(set (pc)
6916         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6917                           (match_operand:DI 2 "arith_operand" "r,I06"))
6918                       (match_operand 0 "" "")
6919                       (pc)))]
6920   "TARGET_SHMEDIA"
6921   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6922
6923 (define_expand "bgt_media"
6924   [(set (pc)
6925         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6926                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6927                       (match_operand 0 "" "")
6928                       (pc)))]
6929   "TARGET_SHMEDIA"
6930   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6931
6932 (define_expand "bge_media"
6933   [(set (pc)
6934         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6935                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6936                       (match_operand 0 "" "")
6937                       (pc)))]
6938   "TARGET_SHMEDIA"
6939   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6940
6941 (define_expand "bgtu_media"
6942   [(set (pc)
6943         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6944                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6945                       (match_operand 0 "" "")
6946                       (pc)))]
6947   "TARGET_SHMEDIA"
6948   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6949
6950 (define_expand "bgeu_media"
6951   [(set (pc)
6952         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6953                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6954                       (match_operand 0 "" "")
6955                       (pc)))]
6956   "TARGET_SHMEDIA"
6957   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6958
6959 (define_insn "*bgt_media_i"
6960   [(set (pc)
6961         (if_then_else (match_operator 3 "greater_comparison_operator"
6962                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6963                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6964                       (match_operand 0 "target_operand" "b")
6965                       (pc)))]
6966   "TARGET_SHMEDIA"
6967   "b%o3%'       %N1, %N2, %0%>"
6968   [(set_attr "type" "cbranch_media")])
6969
6970 (define_insn "*bgt_media_i32"
6971   [(set (pc)
6972         (if_then_else (match_operator 3 "greater_comparison_operator"
6973                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6974                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6975                       (match_operand 0 "target_operand" "b")
6976                       (pc)))]
6977   "TARGET_SHMEDIA"
6978   "b%o3%'       %N1, %N2, %0%>"
6979   [(set_attr "type" "cbranch_media")])
6980
6981 ;; These are only needed to make invert_jump() happy - otherwise, jump
6982 ;; optimization will be silently disabled.
6983 (define_insn "*blt_media_i"
6984   [(set (pc)
6985         (if_then_else (match_operator 3 "less_comparison_operator"
6986                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6987                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6988                       (match_operand 0 "target_operand" "b")
6989                       (pc)))]
6990   "TARGET_SHMEDIA"
6991   "b%o3%'       %N2, %N1, %0%>"
6992   [(set_attr "type" "cbranch_media")])
6993
6994 (define_insn "*blt_media_i32"
6995   [(set (pc)
6996         (if_then_else (match_operator 3 "less_comparison_operator"
6997                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6998                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6999                       (match_operand 0 "target_operand" "b")
7000                       (pc)))]
7001   "TARGET_SHMEDIA"
7002   "b%o3%'       %N2, %N1, %0%>"
7003   [(set_attr "type" "cbranch_media")])
7004
7005 (define_expand "beq"
7006   [(set (pc)
7007         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7008                       (label_ref (match_operand 0 "" ""))
7009                       (pc)))]
7010   ""
7011   "
7012 {
7013   if (TARGET_SHMEDIA)
7014     {
7015       enum machine_mode mode = GET_MODE (sh_compare_op0);
7016
7017       if (mode != DImode && mode != SImode)
7018         {
7019           rtx tmp = gen_reg_rtx (DImode);
7020
7021           emit_insn (gen_seq (tmp));
7022           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7023           DONE;
7024         }
7025
7026       sh_compare_op0 = force_reg (mode, sh_compare_op0);
7027       if (CONSTANT_P (sh_compare_op1)
7028           && (! satisfies_constraint_I06 (sh_compare_op1)))
7029         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030       emit_jump_insn (gen_beq_media (operands[0],
7031                                      sh_compare_op0, sh_compare_op1));
7032       DONE;
7033     }
7034
7035   from_compare (operands, EQ);
7036 }")
7037
7038 (define_expand "bne"
7039   [(set (pc)
7040         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7041                       (label_ref (match_operand 0 "" ""))
7042                       (pc)))]
7043   ""
7044   "
7045 {
7046   if (TARGET_SHMEDIA)
7047     {
7048       enum machine_mode mode = GET_MODE (sh_compare_op0);
7049
7050       if (mode != DImode && mode != SImode)
7051         {
7052           rtx tmp = gen_reg_rtx (DImode);
7053
7054           emit_insn (gen_seq (tmp));
7055           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7056           DONE;
7057         }
7058
7059       sh_compare_op0 = force_reg (mode, sh_compare_op0);
7060       if (CONSTANT_P (sh_compare_op1)
7061           && (! satisfies_constraint_I06 (sh_compare_op1)))
7062         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7063       emit_jump_insn (gen_bne_media (operands[0],
7064                                      sh_compare_op0, sh_compare_op1));
7065       DONE;
7066     }
7067
7068   from_compare (operands, EQ);
7069 }")
7070
7071 (define_expand "bgt"
7072   [(set (pc)
7073         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7074                       (label_ref (match_operand 0 "" ""))
7075                       (pc)))]
7076   ""
7077   "
7078 {
7079   if (TARGET_SHMEDIA)
7080     {
7081       enum machine_mode mode = GET_MODE (sh_compare_op0);
7082
7083       if (mode != DImode && mode != SImode)
7084         {
7085           rtx tmp = gen_reg_rtx (DImode);
7086
7087           emit_insn (gen_sgt (tmp));
7088           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7089           DONE;
7090         }
7091
7092       if (sh_compare_op0 != const0_rtx)
7093         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7094       if (sh_compare_op1 != const0_rtx)
7095         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7096       emit_jump_insn (gen_bgt_media (operands[0],
7097                                      sh_compare_op0, sh_compare_op1));
7098       DONE;
7099     }
7100
7101   from_compare (operands, GT);
7102 }")
7103
7104 (define_expand "blt"
7105   [(set (pc)
7106         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7107                       (label_ref (match_operand 0 "" ""))
7108                       (pc)))]
7109   ""
7110   "
7111 {
7112   if (TARGET_SHMEDIA)
7113     {
7114       enum machine_mode mode = GET_MODE (sh_compare_op0);
7115
7116       if (mode != DImode && mode != SImode)
7117         {
7118           rtx tmp = gen_reg_rtx (DImode);
7119
7120           emit_insn (gen_slt (tmp));
7121           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7122           DONE;
7123         }
7124
7125       if (sh_compare_op0 != const0_rtx)
7126         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7127       if (sh_compare_op1 != const0_rtx)
7128         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7129       emit_jump_insn (gen_bgt_media (operands[0],
7130                                      sh_compare_op1, sh_compare_op0));
7131       DONE;
7132     }
7133
7134   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7135     {
7136       rtx tmp = sh_compare_op0;
7137       sh_compare_op0 = sh_compare_op1;
7138       sh_compare_op1 = tmp;
7139       emit_insn (gen_bgt (operands[0]));
7140       DONE;
7141     }
7142   from_compare (operands, GE);
7143 }")
7144
7145 (define_expand "ble"
7146   [(set (pc)
7147         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7148                       (label_ref (match_operand 0 "" ""))
7149                       (pc)))]
7150   ""
7151   "
7152 {
7153   if (TARGET_SHMEDIA)
7154     {
7155       enum machine_mode mode = GET_MODE (sh_compare_op0);
7156
7157       if (mode != DImode && mode != SImode)
7158         {
7159           rtx tmp = gen_reg_rtx (DImode);
7160
7161           emit_insn (gen_sle (tmp));
7162           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7163           DONE;
7164         }
7165
7166       if (sh_compare_op0 != const0_rtx)
7167         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7168       if (sh_compare_op1 != const0_rtx)
7169         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7170       emit_jump_insn (gen_bge_media (operands[0],
7171                                      sh_compare_op1, sh_compare_op0));
7172       DONE;
7173     }
7174
7175   if (TARGET_SH2E
7176       && TARGET_IEEE
7177       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7178     {
7179       rtx tmp = sh_compare_op0;
7180       sh_compare_op0 = sh_compare_op1;
7181       sh_compare_op1 = tmp;
7182       emit_insn (gen_bge (operands[0]));
7183       DONE;
7184     }
7185   from_compare (operands, GT);
7186 }")
7187
7188 (define_expand "bge"
7189   [(set (pc)
7190         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7191                       (label_ref (match_operand 0 "" ""))
7192                       (pc)))]
7193   ""
7194   "
7195 {
7196   if (TARGET_SHMEDIA)
7197     {
7198       enum machine_mode mode = GET_MODE (sh_compare_op0);
7199
7200       if (mode != DImode && mode != SImode)
7201         {
7202           rtx tmp = gen_reg_rtx (DImode);
7203
7204           emit_insn (gen_sge (tmp));
7205           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7206           DONE;
7207         }
7208
7209       if (sh_compare_op0 != const0_rtx)
7210         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7211       if (sh_compare_op1 != const0_rtx)
7212         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7213       emit_jump_insn (gen_bge_media (operands[0],
7214                                      sh_compare_op0, sh_compare_op1));
7215       DONE;
7216     }
7217
7218   if (TARGET_SH2E
7219       && ! TARGET_IEEE
7220       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7221     {
7222       rtx tmp = sh_compare_op0;
7223       sh_compare_op0 = sh_compare_op1;
7224       sh_compare_op1 = tmp;
7225       emit_insn (gen_ble (operands[0]));
7226       DONE;
7227     }
7228   from_compare (operands, GE);
7229 }")
7230
7231 (define_expand "bgtu"
7232   [(set (pc)
7233         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7234                       (label_ref (match_operand 0 "" ""))
7235                       (pc)))]
7236   ""
7237   "
7238 {
7239   if (TARGET_SHMEDIA)
7240     {
7241       enum machine_mode mode = GET_MODE (sh_compare_op0);
7242
7243       if (sh_compare_op0 != const0_rtx)
7244         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7245       if (sh_compare_op1 != const0_rtx)
7246         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7247       emit_jump_insn (gen_bgtu_media (operands[0],
7248                                       sh_compare_op0, sh_compare_op1));
7249       DONE;
7250     }
7251
7252   from_compare (operands, GTU);
7253 }")
7254
7255 (define_expand "bltu"
7256   [(set (pc)
7257         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7258                       (label_ref (match_operand 0 "" ""))
7259                       (pc)))]
7260   ""
7261   "
7262 {
7263   if (TARGET_SHMEDIA)
7264     {
7265       enum machine_mode mode = GET_MODE (sh_compare_op0);
7266
7267       if (sh_compare_op0 != const0_rtx)
7268         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7269       if (sh_compare_op1 != const0_rtx)
7270         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7271       emit_jump_insn (gen_bgtu_media (operands[0],
7272                                       sh_compare_op1, sh_compare_op0));
7273       DONE;
7274     }
7275
7276   from_compare (operands, GEU);
7277 }")
7278
7279 (define_expand "bgeu"
7280   [(set (pc)
7281         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7282                       (label_ref (match_operand 0 "" ""))
7283                       (pc)))]
7284   ""
7285   "
7286 {
7287   if (TARGET_SHMEDIA)
7288     {
7289       enum machine_mode mode = GET_MODE (sh_compare_op0);
7290
7291       if (sh_compare_op0 != const0_rtx)
7292         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7293       if (sh_compare_op1 != const0_rtx)
7294         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7295       emit_jump_insn (gen_bgeu_media (operands[0],
7296                                       sh_compare_op0, sh_compare_op1));
7297       DONE;
7298     }
7299
7300   from_compare (operands, GEU);
7301 }")
7302
7303 (define_expand "bleu"
7304   [(set (pc)
7305         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7306                       (label_ref (match_operand 0 "" ""))
7307                       (pc)))]
7308   ""
7309   "
7310 {
7311   if (TARGET_SHMEDIA)
7312     {
7313       enum machine_mode mode = GET_MODE (sh_compare_op0);
7314
7315       if (sh_compare_op0 != const0_rtx)
7316         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7317       if (sh_compare_op1 != const0_rtx)
7318         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7319       emit_jump_insn (gen_bgeu_media (operands[0],
7320                                       sh_compare_op1, sh_compare_op0));
7321       DONE;
7322     }
7323
7324   from_compare (operands, GTU);
7325 }")
7326
7327 (define_expand "bunordered"
7328   [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7329    (set (pc)
7330         (if_then_else (ne (match_dup 1) (const_int 0))
7331                       (match_operand 0 "" "")
7332                       (pc)))]
7333   "TARGET_SHMEDIA"
7334   "
7335 {
7336   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7337   operands[1] = gen_reg_rtx (SImode);
7338   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7339   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7340 }")
7341
7342 ;; combiner splitter for test-and-branch on single bit in register.  This
7343 ;; is endian dependent because the non-paradoxical subreg looks different
7344 ;; on big endian.
7345 (define_split
7346   [(set (pc)
7347         (if_then_else
7348           (match_operator 3 "equality_comparison_operator"
7349             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7350                                                       "extend_reg_operand" "")
7351                                                     0)
7352                                          (const_int 1)
7353                                          (match_operand 2
7354                                           "const_int_operand" "")) 0)
7355              (const_int 0)])
7356           (match_operand 0 "target_operand" "")
7357           (pc)))
7358    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7359   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7360   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7361    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7362
7363   "
7364 {
7365   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7366   operands[6] = (GET_CODE (operands[3]) == EQ
7367                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7368                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7369 }")
7370
7371 ; operand 0 is the loop count pseudo register
7372 ; operand 1 is the number of loop iterations or 0 if it is unknown
7373 ; operand 2 is the maximum number of loop iterations
7374 ; operand 3 is the number of levels of enclosed loops
7375 ; operand 4 is the label to jump to at the top of the loop
7376
7377 (define_expand "doloop_end"
7378   [(parallel [(set (pc) (if_then_else
7379                           (ne:SI (match_operand:SI 0 "" "")
7380                               (const_int 1))
7381                           (label_ref (match_operand 4 "" ""))
7382                           (pc)))
7383               (set (match_dup 0)
7384                    (plus:SI (match_dup 0) (const_int -1)))
7385               (clobber (reg:SI T_REG))])]
7386   "TARGET_SH2"
7387   "
7388 {
7389   if (GET_MODE (operands[0]) != SImode)
7390     FAIL;
7391 }
7392 ")
7393
7394 (define_insn_and_split "doloop_end_split"
7395   [(set (pc)
7396         (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7397                           (const_int 1))
7398                       (label_ref (match_operand 1 "" ""))
7399                       (pc)))
7400    (set (match_dup 0)
7401         (plus (match_dup 0) (const_int -1)))
7402    (clobber (reg:SI T_REG))]
7403   "TARGET_SH2"
7404   "#"
7405   ""
7406   [(parallel [(set (reg:SI T_REG)
7407                    (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7408                           (const_int 1)))
7409               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7410    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7411                            (label_ref (match_operand 1 "" ""))
7412                            (pc)))]
7413 ""
7414    [(set_attr "type" "cbranch")])
7415
7416 \f
7417 ;; ------------------------------------------------------------------------
7418 ;; Jump and linkage insns
7419 ;; ------------------------------------------------------------------------
7420
7421 (define_insn "jump_compact"
7422   [(set (pc)
7423         (label_ref (match_operand 0 "" "")))]
7424   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7425   "*
7426 {
7427   /* The length is 16 if the delay slot is unfilled.  */
7428   if (get_attr_length(insn) > 4)
7429     return output_far_jump(insn, operands[0]);
7430   else
7431     return   \"bra      %l0%#\";
7432 }"
7433   [(set_attr "type" "jump")
7434    (set_attr "needs_delay_slot" "yes")])
7435
7436 ;; ??? It would be much saner to explicitly use the scratch register
7437 ;; in the jump insn, and have indirect_jump_scratch only set it,
7438 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7439 ;; from the target then, as it uses simplejump_p.
7440 ;;(define_insn "jump_compact_far"
7441 ;;  [(set (pc)
7442 ;;      (label_ref (match_operand 0 "" "")))
7443 ;;   (use (match_operand 1 "register_operand" "r")]
7444 ;;  "TARGET_SH1"
7445 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7446 ;;  [(set_attr "type" "jump")
7447 ;;   (set_attr "needs_delay_slot" "yes")])
7448
7449 (define_insn "jump_media"
7450   [(set (pc)
7451         (match_operand 0 "target_operand" "b"))]
7452   "TARGET_SHMEDIA"
7453   "blink        %0, r63%>"
7454   [(set_attr "type" "jump_media")])
7455
7456 (define_expand "jump"
7457   [(set (pc)
7458         (label_ref (match_operand 0 "" "")))]
7459   ""
7460   "
7461 {
7462   if (TARGET_SH1)
7463     emit_jump_insn (gen_jump_compact (operands[0]));
7464   else if (TARGET_SHMEDIA)
7465     {
7466       if (reload_in_progress || reload_completed)
7467         FAIL;
7468       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7469                                                          operands[0])));
7470     }
7471   DONE;
7472 }")
7473
7474 (define_insn "force_mode_for_call"
7475   [(use (reg:PSI FPSCR_REG))]
7476   "TARGET_SHCOMPACT"
7477   ""
7478   [(set_attr "length" "0")
7479    (set (attr "fp_mode")
7480         (if_then_else (eq_attr "fpu_single" "yes")
7481                       (const_string "single") (const_string "double")))])
7482
7483 (define_insn "calli"
7484   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7485          (match_operand 1 "" ""))
7486    (use (reg:PSI FPSCR_REG))
7487    (clobber (reg:SI PR_REG))]
7488   "TARGET_SH1"
7489   "*
7490    {
7491      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7492         return \"jsr/n\\t@%0\";
7493      else
7494         return \"jsr\\t@%0%#\";
7495    }"
7496
7497   [(set_attr "type" "call")
7498    (set (attr "fp_mode")
7499         (if_then_else (eq_attr "fpu_single" "yes")
7500                       (const_string "single") (const_string "double")))
7501    (set_attr "needs_delay_slot" "yes")
7502    (set_attr "fp_set" "unknown")])
7503
7504 ;; This is TBR relative jump instruction for SH2A architecture.
7505 ;; Its use is enabled assigning an attribute "function_vector"
7506 ;; and the vector number to a function during its declaration.
7507
7508 (define_insn "calli_tbr_rel"
7509   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7510          (match_operand 1 "" ""))
7511    (use (reg:PSI FPSCR_REG))
7512    (clobber (reg:SI PR_REG))]
7513   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7514   "*
7515 {
7516   unsigned HOST_WIDE_INT vect_num;
7517   vect_num = sh2a_get_function_vector_number (operands[0]);
7518   operands[2] = GEN_INT (vect_num * 4);
7519
7520   return \"jsr/n\\t@@(%O2,tbr)\";
7521 }"
7522   [(set_attr "type" "call")
7523    (set (attr "fp_mode")
7524         (if_then_else (eq_attr "fpu_single" "yes")
7525                       (const_string "single") (const_string "double")))
7526    (set_attr "needs_delay_slot" "no")
7527    (set_attr "fp_set" "unknown")])
7528
7529 ;; This is a pc-rel call, using bsrf, for use with PIC.
7530
7531 (define_insn "calli_pcrel"
7532   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7533          (match_operand 1 "" ""))
7534    (use (reg:PSI FPSCR_REG))
7535    (use (reg:SI PIC_REG))
7536    (use (match_operand 2 "" ""))
7537    (clobber (reg:SI PR_REG))]
7538   "TARGET_SH2"
7539   "bsrf %0\\n%O2:%#"
7540   [(set_attr "type" "call")
7541    (set (attr "fp_mode")
7542         (if_then_else (eq_attr "fpu_single" "yes")
7543                       (const_string "single") (const_string "double")))
7544    (set_attr "needs_delay_slot" "yes")
7545    (set_attr "fp_set" "unknown")])
7546
7547 (define_insn_and_split "call_pcrel"
7548   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7549          (match_operand 1 "" ""))
7550    (use (reg:PSI FPSCR_REG))
7551    (use (reg:SI PIC_REG))
7552    (clobber (reg:SI PR_REG))
7553    (clobber (match_scratch:SI 2 "=r"))]
7554   "TARGET_SH2"
7555   "#"
7556   "reload_completed"
7557   [(const_int 0)]
7558   "
7559 {
7560   rtx lab = PATTERN (gen_call_site ());
7561
7562   if (SYMBOL_REF_LOCAL_P (operands[0]))
7563     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7564   else
7565     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7566   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7567   DONE;
7568 }"
7569   [(set_attr "type" "call")
7570    (set (attr "fp_mode")
7571         (if_then_else (eq_attr "fpu_single" "yes")
7572                       (const_string "single") (const_string "double")))
7573    (set_attr "needs_delay_slot" "yes")
7574    (set_attr "fp_set" "unknown")])
7575
7576 (define_insn "call_compact"
7577   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7578          (match_operand 1 "" ""))
7579    (match_operand 2 "immediate_operand" "n")
7580    (use (reg:SI R0_REG))
7581    (use (reg:SI R1_REG))
7582    (use (reg:PSI FPSCR_REG))
7583    (clobber (reg:SI PR_REG))]
7584   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7585   "jsr  @%0%#"
7586   [(set_attr "type" "call")
7587    (set (attr "fp_mode")
7588         (if_then_else (eq_attr "fpu_single" "yes")
7589                       (const_string "single") (const_string "double")))
7590    (set_attr "needs_delay_slot" "yes")])
7591
7592 (define_insn "call_compact_rettramp"
7593   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7594          (match_operand 1 "" ""))
7595    (match_operand 2 "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[2]) & CALL_COOKIE_RET_TRAMP (1))"
7602   "jsr  @%0%#"
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_media"
7610   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7611          (match_operand 1 "" ""))
7612    (clobber (reg:DI PR_MEDIA_REG))]
7613   "TARGET_SHMEDIA"
7614   "blink        %0, r18"
7615   [(set_attr "type" "jump_media")])
7616
7617 (define_insn "call_valuei"
7618   [(set (match_operand 0 "" "=rf")
7619         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7620               (match_operand 2 "" "")))
7621    (use (reg:PSI FPSCR_REG))
7622    (clobber (reg:SI PR_REG))]
7623   "TARGET_SH1"
7624   "*
7625    {
7626      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7627         return \"jsr/n\\t@%1\";
7628      else
7629         return \"jsr\\t@%1%#\";
7630    }"
7631   [(set_attr "type" "call")
7632    (set (attr "fp_mode")
7633         (if_then_else (eq_attr "fpu_single" "yes")
7634                       (const_string "single") (const_string "double")))
7635    (set_attr "needs_delay_slot" "yes")
7636    (set_attr "fp_set" "unknown")])
7637
7638 ;; This is TBR relative jump instruction for SH2A architecture.
7639 ;; Its use is enabled assigning an attribute "function_vector"
7640 ;; and the vector number to a function during its declaration.
7641
7642 (define_insn "call_valuei_tbr_rel"
7643   [(set (match_operand 0 "" "=rf")
7644         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7645               (match_operand 2 "" "")))
7646    (use (reg:PSI FPSCR_REG))
7647    (clobber (reg:SI PR_REG))]
7648   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7649   "*
7650 {
7651   unsigned HOST_WIDE_INT vect_num;
7652   vect_num = sh2a_get_function_vector_number (operands[1]);
7653   operands[3] = GEN_INT (vect_num * 4);
7654
7655   return \"jsr/n\\t@@(%O3,tbr)\";
7656 }"
7657   [(set_attr "type" "call")
7658    (set (attr "fp_mode")
7659         (if_then_else (eq_attr "fpu_single" "yes")
7660                       (const_string "single") (const_string "double")))
7661    (set_attr "needs_delay_slot" "no")
7662    (set_attr "fp_set" "unknown")])
7663
7664 (define_insn "call_valuei_pcrel"
7665   [(set (match_operand 0 "" "=rf")
7666         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7667               (match_operand 2 "" "")))
7668    (use (reg:PSI FPSCR_REG))
7669    (use (reg:SI PIC_REG))
7670    (use (match_operand 3 "" ""))
7671    (clobber (reg:SI PR_REG))]
7672   "TARGET_SH2"
7673   "bsrf %1\\n%O3:%#"
7674   [(set_attr "type" "call")
7675    (set (attr "fp_mode")
7676         (if_then_else (eq_attr "fpu_single" "yes")
7677                       (const_string "single") (const_string "double")))
7678    (set_attr "needs_delay_slot" "yes")
7679    (set_attr "fp_set" "unknown")])
7680
7681 (define_insn_and_split "call_value_pcrel"
7682   [(set (match_operand 0 "" "=rf")
7683         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7684               (match_operand 2 "" "")))
7685    (use (reg:PSI FPSCR_REG))
7686    (use (reg:SI PIC_REG))
7687    (clobber (reg:SI PR_REG))
7688    (clobber (match_scratch:SI 3 "=r"))]
7689   "TARGET_SH2"
7690   "#"
7691   "reload_completed"
7692   [(const_int 0)]
7693   "
7694 {
7695   rtx lab = PATTERN (gen_call_site ());
7696
7697   if (SYMBOL_REF_LOCAL_P (operands[1]))
7698     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7699   else
7700     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7701   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7702                                          operands[2], copy_rtx (lab)));
7703   DONE;
7704 }"
7705   [(set_attr "type" "call")
7706    (set (attr "fp_mode")
7707         (if_then_else (eq_attr "fpu_single" "yes")
7708                       (const_string "single") (const_string "double")))
7709    (set_attr "needs_delay_slot" "yes")
7710    (set_attr "fp_set" "unknown")])
7711
7712 (define_insn "call_value_compact"
7713   [(set (match_operand 0 "" "=rf")
7714         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7715               (match_operand 2 "" "")))
7716    (match_operand 3 "immediate_operand" "n")
7717    (use (reg:SI R0_REG))
7718    (use (reg:SI R1_REG))
7719    (use (reg:PSI FPSCR_REG))
7720    (clobber (reg:SI PR_REG))]
7721   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7722   "jsr  @%1%#"
7723   [(set_attr "type" "call")
7724    (set (attr "fp_mode")
7725         (if_then_else (eq_attr "fpu_single" "yes")
7726                       (const_string "single") (const_string "double")))
7727    (set_attr "needs_delay_slot" "yes")])
7728
7729 (define_insn "call_value_compact_rettramp"
7730   [(set (match_operand 0 "" "=rf")
7731         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7732               (match_operand 2 "" "")))
7733    (match_operand 3 "immediate_operand" "n")
7734    (use (reg:SI R0_REG))
7735    (use (reg:SI R1_REG))
7736    (use (reg:PSI FPSCR_REG))
7737    (clobber (reg:SI R10_REG))
7738    (clobber (reg:SI PR_REG))]
7739   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7740   "jsr  @%1%#"
7741   [(set_attr "type" "call")
7742    (set (attr "fp_mode")
7743         (if_then_else (eq_attr "fpu_single" "yes")
7744                       (const_string "single") (const_string "double")))
7745    (set_attr "needs_delay_slot" "yes")])
7746
7747 (define_insn "call_value_media"
7748   [(set (match_operand 0 "" "=rf")
7749         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7750               (match_operand 2 "" "")))
7751    (clobber (reg:DI PR_MEDIA_REG))]
7752   "TARGET_SHMEDIA"
7753   "blink        %1, r18"
7754   [(set_attr "type" "jump_media")])
7755
7756 (define_expand "call"
7757   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7758                             (match_operand 1 "" ""))
7759               (match_operand 2 "" "")
7760               (use (reg:PSI FPSCR_REG))
7761               (clobber (reg:SI PR_REG))])]
7762   ""
7763   "
7764 {
7765   if (TARGET_SHMEDIA)
7766     {
7767       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7768       emit_call_insn (gen_call_media (operands[0], operands[1]));
7769       DONE;
7770     }
7771   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7772     {
7773       rtx cookie_rtx = operands[2];
7774       long cookie = INTVAL (cookie_rtx);
7775       rtx func = XEXP (operands[0], 0);
7776       rtx r0, r1;
7777
7778       if (flag_pic)
7779         {
7780           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7781             {
7782               rtx reg = gen_reg_rtx (Pmode);
7783
7784               emit_insn (gen_symGOTPLT2reg (reg, func));
7785               func = reg;
7786             }
7787           else
7788             func = legitimize_pic_address (func, Pmode, 0);
7789         }
7790
7791       r0 = gen_rtx_REG (SImode, R0_REG);
7792       r1 = gen_rtx_REG (SImode, R1_REG);
7793
7794       /* Since such a call function may use all call-clobbered
7795          registers, we force a mode switch earlier, so that we don't
7796          run out of registers when adjusting fpscr for the call.  */
7797       emit_insn (gen_force_mode_for_call ());
7798
7799       operands[0]
7800         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7801                            SFUNC_GOT);
7802       operands[0] = force_reg (SImode, operands[0]);
7803
7804       emit_move_insn (r0, func);
7805       emit_move_insn (r1, cookie_rtx);
7806
7807       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7808         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7809                                                    operands[2]));
7810       else
7811         emit_call_insn (gen_call_compact (operands[0], operands[1],
7812                                           operands[2]));
7813
7814       DONE;
7815     }
7816   else if (TARGET_SHCOMPACT && flag_pic
7817            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7818            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7819     {
7820       rtx reg = gen_reg_rtx (Pmode);
7821
7822       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7823       XEXP (operands[0], 0) = reg;
7824     }
7825   if (!flag_pic && TARGET_SH2A
7826       && GET_CODE (operands[0]) == MEM
7827       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7828     {
7829       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7830         {
7831           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7832                                              operands[1]));
7833           DONE;
7834         }
7835     }
7836   if (flag_pic && TARGET_SH2
7837       && GET_CODE (operands[0]) == MEM
7838       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7839     {
7840       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7841       DONE;
7842     }
7843   else
7844   {
7845     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7846     operands[1] = operands[2];
7847   }
7848
7849   emit_call_insn (gen_calli (operands[0], operands[1]));
7850   DONE;
7851 }")
7852
7853 (define_insn "call_pop_compact"
7854   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7855          (match_operand 1 "" ""))
7856    (match_operand 2 "immediate_operand" "n")
7857    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7858                                  (match_operand 3 "immediate_operand" "n")))
7859    (use (reg:SI R0_REG))
7860    (use (reg:SI R1_REG))
7861    (use (reg:PSI FPSCR_REG))
7862    (clobber (reg:SI PR_REG))]
7863   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7864   "jsr  @%0%#"
7865   [(set_attr "type" "call")
7866    (set (attr "fp_mode")
7867         (if_then_else (eq_attr "fpu_single" "yes")
7868                       (const_string "single") (const_string "double")))
7869    (set_attr "needs_delay_slot" "yes")])
7870
7871 (define_insn "call_pop_compact_rettramp"
7872   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7873          (match_operand 1 "" ""))
7874    (match_operand 2 "immediate_operand" "n")
7875    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7876                                  (match_operand 3 "immediate_operand" "n")))
7877    (use (reg:SI R0_REG))
7878    (use (reg:SI R1_REG))
7879    (use (reg:PSI FPSCR_REG))
7880    (clobber (reg:SI R10_REG))
7881    (clobber (reg:SI PR_REG))]
7882   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7883   "jsr  @%0%#"
7884   [(set_attr "type" "call")
7885    (set (attr "fp_mode")
7886         (if_then_else (eq_attr "fpu_single" "yes")
7887                       (const_string "single") (const_string "double")))
7888    (set_attr "needs_delay_slot" "yes")])
7889
7890 (define_expand "call_pop"
7891   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7892                     (match_operand 1 "" ""))
7893              (match_operand 2 "" "")
7894              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7895                                            (match_operand 3 "" "")))])]
7896   "TARGET_SHCOMPACT"
7897   "
7898 {
7899   rtx cookie_rtx;
7900   long cookie;
7901   rtx func;
7902   rtx r0, r1;
7903
7904   gcc_assert (operands[2] && INTVAL (operands[2]));
7905   cookie_rtx = operands[2];
7906   cookie = INTVAL (cookie_rtx);
7907   func = XEXP (operands[0], 0);
7908
7909   if (flag_pic)
7910     {
7911       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7912         {
7913           rtx reg = gen_reg_rtx (Pmode);
7914           emit_insn (gen_symGOTPLT2reg (reg, func));
7915           func = reg;
7916         }
7917       else
7918         func = legitimize_pic_address (func, Pmode, 0);
7919     }
7920
7921   r0 = gen_rtx_REG (SImode, R0_REG);
7922   r1 = gen_rtx_REG (SImode, R1_REG);
7923
7924   /* Since such a call function may use all call-clobbered
7925      registers, we force a mode switch earlier, so that we don't
7926      run out of registers when adjusting fpscr for the call.  */
7927   emit_insn (gen_force_mode_for_call ());
7928
7929   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7930                                  SFUNC_GOT);
7931   operands[0] = force_reg (SImode, operands[0]);
7932
7933   emit_move_insn (r0, func);
7934   emit_move_insn (r1, cookie_rtx);
7935
7936   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7937     emit_call_insn (gen_call_pop_compact_rettramp
7938                      (operands[0], operands[1], operands[2], operands[3]));
7939   else
7940     emit_call_insn (gen_call_pop_compact
7941                      (operands[0], operands[1], operands[2], operands[3]));
7942
7943   DONE;
7944 }")
7945
7946 (define_expand "call_value"
7947   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7948                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7949                                  (match_operand 2 "" "")))
7950               (match_operand 3 "" "")
7951               (use (reg:PSI FPSCR_REG))
7952               (clobber (reg:SI PR_REG))])]
7953   ""
7954   "
7955 {
7956   if (TARGET_SHMEDIA)
7957     {
7958       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7959       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7960                                             operands[2]));
7961       DONE;
7962     }
7963   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7964     {
7965       rtx cookie_rtx = operands[3];
7966       long cookie = INTVAL (cookie_rtx);
7967       rtx func = XEXP (operands[1], 0);
7968       rtx r0, r1;
7969
7970       if (flag_pic)
7971         {
7972           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7973             {
7974               rtx reg = gen_reg_rtx (Pmode);
7975
7976               emit_insn (gen_symGOTPLT2reg (reg, func));
7977               func = reg;
7978             }
7979           else
7980             func = legitimize_pic_address (func, Pmode, 0);
7981         }
7982
7983       r0 = gen_rtx_REG (SImode, R0_REG);
7984       r1 = gen_rtx_REG (SImode, R1_REG);
7985
7986       /* Since such a call function may use all call-clobbered
7987          registers, we force a mode switch earlier, so that we don't
7988          run out of registers when adjusting fpscr for the call.  */
7989       emit_insn (gen_force_mode_for_call ());
7990
7991       operands[1]
7992         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7993                            SFUNC_GOT);
7994       operands[1] = force_reg (SImode, operands[1]);
7995
7996       emit_move_insn (r0, func);
7997       emit_move_insn (r1, cookie_rtx);
7998
7999       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8000         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
8001                                                          operands[1],
8002                                                          operands[2],
8003                                                          operands[3]));
8004       else
8005         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
8006                                                 operands[2], operands[3]));
8007
8008       DONE;
8009     }
8010   else if (TARGET_SHCOMPACT && flag_pic
8011            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8012            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8013     {
8014       rtx reg = gen_reg_rtx (Pmode);
8015
8016       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
8017       XEXP (operands[1], 0) = reg;
8018     }
8019   if (!flag_pic && TARGET_SH2A
8020       && GET_CODE (operands[1]) == MEM
8021       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8022     {
8023       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
8024         {
8025           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
8026                                  XEXP (operands[1], 0), operands[2]));
8027           DONE;
8028         }
8029     }
8030   if (flag_pic && TARGET_SH2
8031       && GET_CODE (operands[1]) == MEM
8032       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8033     {
8034       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
8035                                             operands[2]));
8036       DONE;
8037     }
8038   else
8039     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8040
8041   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
8042   DONE;
8043 }")
8044
8045 (define_insn "sibcalli"
8046   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
8047          (match_operand 1 "" ""))
8048    (use (reg:PSI FPSCR_REG))
8049    (return)]
8050   "TARGET_SH1"
8051   "jmp  @%0%#"
8052   [(set_attr "needs_delay_slot" "yes")
8053    (set (attr "fp_mode")
8054         (if_then_else (eq_attr "fpu_single" "yes")
8055                       (const_string "single") (const_string "double")))
8056    (set_attr "type" "jump_ind")])
8057
8058 (define_insn "sibcalli_pcrel"
8059   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
8060          (match_operand 1 "" ""))
8061    (use (match_operand 2 "" ""))
8062    (use (reg:PSI FPSCR_REG))
8063    (return)]
8064   "TARGET_SH2"
8065   "braf %0\\n%O2:%#"
8066   [(set_attr "needs_delay_slot" "yes")
8067    (set (attr "fp_mode")
8068         (if_then_else (eq_attr "fpu_single" "yes")
8069                       (const_string "single") (const_string "double")))
8070    (set_attr "type" "jump_ind")])
8071
8072 ;; This uses an unspec to describe that the symbol_ref is very close.
8073 (define_insn "sibcalli_thunk"
8074   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
8075                              UNSPEC_THUNK))
8076          (match_operand 1 "" ""))
8077    (use (reg:PSI FPSCR_REG))
8078    (return)]
8079   "TARGET_SH1"
8080   "bra  %O0"
8081   [(set_attr "needs_delay_slot" "yes")
8082    (set (attr "fp_mode")
8083         (if_then_else (eq_attr "fpu_single" "yes")
8084                       (const_string "single") (const_string "double")))
8085    (set_attr "type" "jump")
8086    (set_attr "length" "2")])
8087
8088 (define_insn_and_split "sibcall_pcrel"
8089   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8090          (match_operand 1 "" ""))
8091    (use (reg:PSI FPSCR_REG))
8092    (clobber (match_scratch:SI 2 "=k"))
8093    (return)]
8094   "TARGET_SH2"
8095   "#"
8096   "reload_completed"
8097   [(const_int 0)]
8098   "
8099 {
8100   rtx lab = PATTERN (gen_call_site ());
8101   rtx call_insn;
8102
8103   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8104   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
8105                                                   copy_rtx (lab)));
8106   SIBLING_CALL_P (call_insn) = 1;
8107   DONE;
8108 }"
8109   [(set_attr "needs_delay_slot" "yes")
8110    (set (attr "fp_mode")
8111         (if_then_else (eq_attr "fpu_single" "yes")
8112                       (const_string "single") (const_string "double")))
8113    (set_attr "type" "jump_ind")])
8114
8115 (define_insn "sibcall_compact"
8116   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8117          (match_operand 1 "" ""))
8118    (return)
8119    (use (match_operand:SI 2 "register_operand" "z,x"))
8120    (use (reg:SI R1_REG))
8121    (use (reg:PSI FPSCR_REG))
8122    ;; We want to make sure the `x' above will only match MACH_REG
8123    ;; because sibcall_epilogue may clobber MACL_REG.
8124    (clobber (reg:SI MACL_REG))]
8125   "TARGET_SHCOMPACT"
8126   "@
8127         jmp     @%0%#
8128         jmp     @%0\\n  sts     %2, r0"
8129   [(set_attr "needs_delay_slot" "yes,no")
8130    (set_attr "length" "2,4")
8131    (set (attr "fp_mode") (const_string "single"))
8132    (set_attr "type" "jump_ind")])
8133
8134 (define_insn "sibcall_media"
8135   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8136          (match_operand 1 "" ""))
8137    (use (reg:SI PR_MEDIA_REG))
8138    (return)]
8139   "TARGET_SHMEDIA"
8140   "blink        %0, r63"
8141   [(set_attr "type" "jump_media")])
8142
8143 (define_expand "sibcall"
8144   [(parallel
8145     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8146            (match_operand 1 "" ""))
8147      (match_operand 2 "" "")
8148      (use (reg:PSI FPSCR_REG))
8149      (return)])]
8150   ""
8151   "
8152 {
8153   if (TARGET_SHMEDIA)
8154     {
8155       operands[0] = shmedia_prepare_call_address (operands[0], 1);
8156       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8157       DONE;
8158     }
8159   else if (TARGET_SHCOMPACT && operands[2]
8160            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8161     {
8162       rtx cookie_rtx = operands[2];
8163       long cookie = INTVAL (cookie_rtx);
8164       rtx func = XEXP (operands[0], 0);
8165       rtx mach, r1;
8166
8167       if (flag_pic)
8168         {
8169           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8170             {
8171               rtx reg = gen_reg_rtx (Pmode);
8172
8173               emit_insn (gen_symGOT2reg (reg, func));
8174               func = reg;
8175             }
8176           else
8177             func = legitimize_pic_address (func, Pmode, 0);
8178         }
8179
8180       /* FIXME: if we could tell whether all argument registers are
8181          already taken, we could decide whether to force the use of
8182          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8183          simple way to tell.  We could use the CALL_COOKIE, but we
8184          can't currently tell a register used for regular argument
8185          passing from one that is unused.  If we leave it up to reload
8186          to decide which register to use, it seems to always choose
8187          R0_REG, which leaves no available registers in SIBCALL_REGS
8188          to hold the address of the trampoline.  */
8189       mach = gen_rtx_REG (SImode, MACH_REG);
8190       r1 = gen_rtx_REG (SImode, R1_REG);
8191
8192       /* Since such a call function may use all call-clobbered
8193          registers, we force a mode switch earlier, so that we don't
8194          run out of registers when adjusting fpscr for the call.  */
8195       emit_insn (gen_force_mode_for_call ());
8196
8197       operands[0]
8198         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8199                            SFUNC_GOT);
8200       operands[0] = force_reg (SImode, operands[0]);
8201
8202       /* We don't need a return trampoline, since the callee will
8203          return directly to the upper caller.  */
8204       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8205         {
8206           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8207           cookie_rtx = GEN_INT (cookie);
8208         }
8209
8210       emit_move_insn (mach, func);
8211       emit_move_insn (r1, cookie_rtx);
8212
8213       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8214       DONE;
8215     }
8216   else if (TARGET_SHCOMPACT && flag_pic
8217            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8218            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8219     {
8220       rtx reg = gen_reg_rtx (Pmode);
8221
8222       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8223       XEXP (operands[0], 0) = reg;
8224     }
8225   if (flag_pic && TARGET_SH2
8226       && GET_CODE (operands[0]) == MEM
8227       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8228       /* The PLT needs the PIC register, but the epilogue would have
8229          to restore it, so we can only use PC-relative PIC calls for
8230          static functions.  */
8231       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8232     {
8233       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8234       DONE;
8235     }
8236   else
8237     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8238
8239   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8240   DONE;
8241 }")
8242
8243 (define_insn "sibcall_valuei"
8244   [(set (match_operand 0 "" "=rf")
8245         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8246               (match_operand 2 "" "")))
8247    (use (reg:PSI FPSCR_REG))
8248    (return)]
8249   "TARGET_SH1"
8250   "jmp  @%1%#"
8251   [(set_attr "needs_delay_slot" "yes")
8252    (set (attr "fp_mode")
8253         (if_then_else (eq_attr "fpu_single" "yes")
8254                       (const_string "single") (const_string "double")))
8255    (set_attr "type" "jump_ind")])
8256
8257 (define_insn "sibcall_valuei_pcrel"
8258   [(set (match_operand 0 "" "=rf")
8259         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8260               (match_operand 2 "" "")))
8261    (use (match_operand 3 "" ""))
8262    (use (reg:PSI FPSCR_REG))
8263    (return)]
8264   "TARGET_SH2"
8265   "braf %1\\n%O3:%#"
8266   [(set_attr "needs_delay_slot" "yes")
8267    (set (attr "fp_mode")
8268         (if_then_else (eq_attr "fpu_single" "yes")
8269                       (const_string "single") (const_string "double")))
8270    (set_attr "type" "jump_ind")])
8271
8272 (define_insn_and_split "sibcall_value_pcrel"
8273   [(set (match_operand 0 "" "=rf")
8274         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8275               (match_operand 2 "" "")))
8276    (use (reg:PSI FPSCR_REG))
8277    (clobber (match_scratch:SI 3 "=k"))
8278    (return)]
8279   "TARGET_SH2"
8280   "#"
8281   "reload_completed"
8282   [(const_int 0)]
8283   "
8284 {
8285   rtx lab = PATTERN (gen_call_site ());
8286   rtx call_insn;
8287
8288   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8289   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8290                                                         operands[3],
8291                                                         operands[2],
8292                                                         copy_rtx (lab)));
8293   SIBLING_CALL_P (call_insn) = 1;
8294   DONE;
8295 }"
8296   [(set_attr "needs_delay_slot" "yes")
8297    (set (attr "fp_mode")
8298         (if_then_else (eq_attr "fpu_single" "yes")
8299                       (const_string "single") (const_string "double")))
8300    (set_attr "type" "jump_ind")])
8301
8302 (define_insn "sibcall_value_compact"
8303   [(set (match_operand 0 "" "=rf,rf")
8304         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8305               (match_operand 2 "" "")))
8306    (return)
8307    (use (match_operand:SI 3 "register_operand" "z,x"))
8308    (use (reg:SI R1_REG))
8309    (use (reg:PSI FPSCR_REG))
8310    ;; We want to make sure the `x' above will only match MACH_REG
8311    ;; because sibcall_epilogue may clobber MACL_REG.
8312    (clobber (reg:SI MACL_REG))]
8313   "TARGET_SHCOMPACT"
8314   "@
8315         jmp     @%1%#
8316         jmp     @%1\\n  sts     %3, r0"
8317   [(set_attr "needs_delay_slot" "yes,no")
8318    (set_attr "length" "2,4")
8319    (set (attr "fp_mode") (const_string "single"))
8320    (set_attr "type" "jump_ind")])
8321
8322 (define_insn "sibcall_value_media"
8323   [(set (match_operand 0 "" "=rf")
8324         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8325               (match_operand 2 "" "")))
8326    (use (reg:SI PR_MEDIA_REG))
8327    (return)]
8328   "TARGET_SHMEDIA"
8329   "blink        %1, r63"
8330   [(set_attr "type" "jump_media")])
8331
8332 (define_expand "sibcall_value"
8333   [(parallel
8334     [(set (match_operand 0 "arith_reg_operand" "")
8335           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8336                 (match_operand 2 "" "")))
8337      (match_operand 3 "" "")
8338      (use (reg:PSI FPSCR_REG))
8339      (return)])]
8340   ""
8341   "
8342 {
8343   if (TARGET_SHMEDIA)
8344     {
8345       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8346       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8347                                                operands[2]));
8348       DONE;
8349     }
8350   else if (TARGET_SHCOMPACT && operands[3]
8351            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8352     {
8353       rtx cookie_rtx = operands[3];
8354       long cookie = INTVAL (cookie_rtx);
8355       rtx func = XEXP (operands[1], 0);
8356       rtx mach, r1;
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_symGOT2reg (reg, func));
8365               func = reg;
8366             }
8367           else
8368             func = legitimize_pic_address (func, Pmode, 0);
8369         }
8370
8371       /* FIXME: if we could tell whether all argument registers are
8372          already taken, we could decide whether to force the use of
8373          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8374          simple way to tell.  We could use the CALL_COOKIE, but we
8375          can't currently tell a register used for regular argument
8376          passing from one that is unused.  If we leave it up to reload
8377          to decide which register to use, it seems to always choose
8378          R0_REG, which leaves no available registers in SIBCALL_REGS
8379          to hold the address of the trampoline.  */
8380       mach = gen_rtx_REG (SImode, MACH_REG);
8381       r1 = gen_rtx_REG (SImode, R1_REG);
8382
8383       /* Since such a call function may use all call-clobbered
8384          registers, we force a mode switch earlier, so that we don't
8385          run out of registers when adjusting fpscr for the call.  */
8386       emit_insn (gen_force_mode_for_call ());
8387
8388       operands[1]
8389         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8390                            SFUNC_GOT);
8391       operands[1] = force_reg (SImode, operands[1]);
8392
8393       /* We don't need a return trampoline, since the callee will
8394          return directly to the upper caller.  */
8395       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8396         {
8397           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8398           cookie_rtx = GEN_INT (cookie);
8399         }
8400
8401       emit_move_insn (mach, func);
8402       emit_move_insn (r1, cookie_rtx);
8403
8404       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8405                                                  operands[2], mach));
8406       DONE;
8407     }
8408   else if (TARGET_SHCOMPACT && flag_pic
8409            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8410            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8411     {
8412       rtx reg = gen_reg_rtx (Pmode);
8413
8414       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8415       XEXP (operands[1], 0) = reg;
8416     }
8417   if (flag_pic && TARGET_SH2
8418       && GET_CODE (operands[1]) == MEM
8419       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8420       /* The PLT needs the PIC register, but the epilogue would have
8421          to restore it, so we can only use PC-relative PIC calls for
8422          static functions.  */
8423       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8424     {
8425       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8426                                                XEXP (operands[1], 0),
8427                                                operands[2]));
8428       DONE;
8429     }
8430   else
8431     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8432
8433   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8434   DONE;
8435 }")
8436
8437 (define_insn "call_value_pop_compact"
8438   [(set (match_operand 0 "" "=rf")
8439         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8440               (match_operand 2 "" "")))
8441    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8442                                  (match_operand 4 "immediate_operand" "n")))
8443    (match_operand 3 "immediate_operand" "n")
8444    (use (reg:SI R0_REG))
8445    (use (reg:SI R1_REG))
8446    (use (reg:PSI FPSCR_REG))
8447    (clobber (reg:SI PR_REG))]
8448   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8449   "jsr  @%1%#"
8450   [(set_attr "type" "call")
8451    (set (attr "fp_mode")
8452         (if_then_else (eq_attr "fpu_single" "yes")
8453                       (const_string "single") (const_string "double")))
8454    (set_attr "needs_delay_slot" "yes")])
8455
8456 (define_insn "call_value_pop_compact_rettramp"
8457   [(set (match_operand 0 "" "=rf")
8458         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8459               (match_operand 2 "" "")))
8460    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8461                                  (match_operand 4 "immediate_operand" "n")))
8462    (match_operand 3 "immediate_operand" "n")
8463    (use (reg:SI R0_REG))
8464    (use (reg:SI R1_REG))
8465    (use (reg:PSI FPSCR_REG))
8466    (clobber (reg:SI R10_REG))
8467    (clobber (reg:SI PR_REG))]
8468   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8469   "jsr  @%1%#"
8470   [(set_attr "type" "call")
8471    (set (attr "fp_mode")
8472         (if_then_else (eq_attr "fpu_single" "yes")
8473                       (const_string "single") (const_string "double")))
8474    (set_attr "needs_delay_slot" "yes")])
8475
8476 (define_expand "call_value_pop"
8477   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8478                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8479                                  (match_operand 2 "" "")))
8480               (match_operand 3 "" "")
8481               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8482                                             (match_operand 4 "" "")))])]
8483   "TARGET_SHCOMPACT"
8484   "
8485 {
8486   rtx cookie_rtx;
8487   long cookie;
8488   rtx func;
8489   rtx r0, r1;
8490
8491   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8492   cookie_rtx = operands[3];
8493   cookie = INTVAL (cookie_rtx);
8494   func = XEXP (operands[1], 0);
8495
8496   if (flag_pic)
8497     {
8498       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8499         {
8500           rtx reg = gen_reg_rtx (Pmode);
8501
8502           emit_insn (gen_symGOTPLT2reg (reg, func));
8503           func = reg;
8504         }
8505       else
8506         func = legitimize_pic_address (func, Pmode, 0);
8507     }
8508
8509   r0 = gen_rtx_REG (SImode, R0_REG);
8510   r1 = gen_rtx_REG (SImode, R1_REG);
8511
8512   /* Since such a call function may use all call-clobbered
8513      registers, we force a mode switch earlier, so that we don't
8514      run out of registers when adjusting fpscr for the call.  */
8515   emit_insn (gen_force_mode_for_call ());
8516
8517   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8518                                  SFUNC_GOT);
8519   operands[1] = force_reg (SImode, operands[1]);
8520
8521   emit_move_insn (r0, func);
8522   emit_move_insn (r1, cookie_rtx);
8523
8524   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8525     emit_call_insn (gen_call_value_pop_compact_rettramp
8526                         (operands[0], operands[1], operands[2],
8527                          operands[3], operands[4]));
8528   else
8529     emit_call_insn (gen_call_value_pop_compact
8530                         (operands[0], operands[1], operands[2],
8531                          operands[3], operands[4]));
8532
8533   DONE;
8534 }")
8535
8536 (define_expand "sibcall_epilogue"
8537   [(return)]
8538   ""
8539   "
8540 {
8541   sh_expand_epilogue (1);
8542   if (TARGET_SHCOMPACT)
8543     {
8544       rtx insn, set;
8545
8546       /* If epilogue clobbers r0, preserve it in macl.  */
8547       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8548         if ((set = single_set (insn))
8549             && GET_CODE (SET_DEST (set)) == REG
8550             && REGNO (SET_DEST (set)) == R0_REG)
8551           {
8552             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8553             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8554
8555             /* We can't tell at this point whether the sibcall is a
8556                sibcall_compact and, if it is, whether it uses r0 or
8557                mach as operand 2, so let the instructions that
8558                preserve r0 be optimized away if r0 turns out to be
8559                dead.  */
8560             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8561             emit_move_insn (r0, tmp);
8562             break;
8563           }
8564     }
8565   DONE;
8566 }")
8567
8568 (define_insn "indirect_jump_compact"
8569   [(set (pc)
8570         (match_operand:SI 0 "arith_reg_operand" "r"))]
8571   "TARGET_SH1"
8572   "jmp  @%0%#"
8573   [(set_attr "needs_delay_slot" "yes")
8574    (set_attr "type" "jump_ind")])
8575
8576 (define_expand "indirect_jump"
8577   [(set (pc)
8578         (match_operand 0 "register_operand" ""))]
8579   ""
8580   "
8581 {
8582   if (GET_MODE (operands[0]) != Pmode)
8583     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8584 }")
8585
8586 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8587 ;; which can be present in structured code from indirect jumps which can not
8588 ;; be present in structured code.  This allows -fprofile-arcs to work.
8589
8590 ;; For SH1 processors.
8591 (define_insn "casesi_jump_1"
8592   [(set (pc)
8593         (match_operand:SI 0 "register_operand" "r"))
8594    (use (label_ref (match_operand 1 "" "")))]
8595   "TARGET_SH1"
8596   "jmp  @%0%#"
8597   [(set_attr "needs_delay_slot" "yes")
8598    (set_attr "type" "jump_ind")])
8599
8600 ;; For all later processors.
8601 (define_insn "casesi_jump_2"
8602   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8603                       (label_ref (match_operand 1 "" ""))))
8604    (use (label_ref (match_operand 2 "" "")))]
8605   "TARGET_SH2
8606    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8607   "braf %0%#"
8608   [(set_attr "needs_delay_slot" "yes")
8609    (set_attr "type" "jump_ind")])
8610
8611 (define_insn "casesi_jump_media"
8612   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8613    (use (label_ref (match_operand 1 "" "")))]
8614   "TARGET_SHMEDIA"
8615   "blink        %0, r63"
8616   [(set_attr "type" "jump_media")])
8617
8618 ;; Call subroutine returning any type.
8619 ;; ??? This probably doesn't work.
8620
8621 (define_expand "untyped_call"
8622   [(parallel [(call (match_operand 0 "" "")
8623                     (const_int 0))
8624               (match_operand 1 "" "")
8625               (match_operand 2 "" "")])]
8626   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8627   "
8628 {
8629   int i;
8630
8631   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8632
8633   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8634     {
8635       rtx set = XVECEXP (operands[2], 0, i);
8636       emit_move_insn (SET_DEST (set), SET_SRC (set));
8637     }
8638
8639   /* The optimizer does not know that the call sets the function value
8640      registers we stored in the result block.  We avoid problems by
8641      claiming that all hard registers are used and clobbered at this
8642      point.  */
8643   emit_insn (gen_blockage ());
8644
8645   DONE;
8646 }")
8647 \f
8648 ;; ------------------------------------------------------------------------
8649 ;; Misc insns
8650 ;; ------------------------------------------------------------------------
8651
8652 (define_insn "dect"
8653   [(set (reg:SI T_REG)
8654         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8655    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8656   "TARGET_SH2"
8657   "dt   %0"
8658   [(set_attr "type" "arith")])
8659
8660 (define_insn "nop"
8661   [(const_int 0)]
8662   ""
8663   "nop")
8664
8665 ;; Load address of a label. This is only generated by the casesi expand,
8666 ;; and by machine_dependent_reorg (fixing up fp moves).
8667 ;; This must use unspec, because this only works for labels that are
8668 ;; within range,
8669
8670 (define_insn "mova"
8671   [(set (reg:SI R0_REG)
8672         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8673   "TARGET_SH1"
8674   "mova %O0,r0"
8675   [(set_attr "in_delay_slot" "no")
8676    (set_attr "type" "arith")])
8677
8678 ;; machine_dependent_reorg will make this a `mova'.
8679 (define_insn "mova_const"
8680   [(set (reg:SI R0_REG)
8681         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8682   "TARGET_SH1"
8683   "#"
8684   [(set_attr "in_delay_slot" "no")
8685    (set_attr "type" "arith")])
8686
8687 (define_expand "GOTaddr2picreg"
8688   [(set (reg:SI R0_REG)
8689         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8690                    UNSPEC_MOVA))
8691    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8692    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8693   "" "
8694 {
8695   if (TARGET_VXWORKS_RTP)
8696     {
8697       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8698       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8699       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8700       DONE;
8701     }
8702
8703   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8704   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8705
8706   if (TARGET_SHMEDIA)
8707     {
8708       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8709       rtx pic = operands[0];
8710       rtx lab = PATTERN (gen_call_site ());
8711       rtx insn, equiv;
8712
8713       equiv = operands[1];
8714       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8715                                     UNSPEC_PCREL_SYMOFF);
8716       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8717
8718       if (Pmode == SImode)
8719         {
8720           emit_insn (gen_movsi_const (pic, operands[1]));
8721           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8722         }
8723       else
8724         {
8725           emit_insn (gen_movdi_const (pic, operands[1]));
8726           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8727         }
8728
8729       insn = emit_move_insn (operands[0], tr);
8730
8731       set_unique_reg_note (insn, REG_EQUAL, equiv);
8732
8733       DONE;
8734     }
8735 }
8736 ")
8737
8738 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8739 ;; PIC register.
8740
8741 (define_expand "vxworks_picreg"
8742   [(set (reg:SI PIC_REG)
8743         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8744    (set (reg:SI R0_REG)
8745         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8746    (set (reg:SI PIC_REG)
8747         (mem:SI (reg:SI PIC_REG)))
8748    (set (reg:SI PIC_REG)
8749         (mem:SI (plus:SI (reg:SI PIC_REG)
8750                          (reg:SI R0_REG))))]
8751   "TARGET_VXWORKS_RTP")
8752
8753 (define_insn "*ptb"
8754   [(set (match_operand 0 "target_reg_operand" "=b")
8755         (const (unspec [(match_operand 1 "" "Csy")]
8756                              UNSPEC_DATALABEL)))]
8757   "TARGET_SHMEDIA && flag_pic
8758    && satisfies_constraint_Csy (operands[1])"
8759   "ptb/u        datalabel %1, %0"
8760   [(set_attr "type" "ptabs_media")
8761    (set_attr "length" "*")])
8762
8763 (define_insn "ptrel_si"
8764   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8765         (plus:SI (match_operand:SI 1 "register_operand" "r")
8766               (pc)))
8767    (match_operand:SI 2 "" "")]
8768   "TARGET_SHMEDIA"
8769   "%O2: ptrel/u %1, %0"
8770   [(set_attr "type" "ptabs_media")])
8771
8772 (define_insn "ptrel_di"
8773   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8774         (plus:DI (match_operand:DI 1 "register_operand" "r")
8775               (pc)))
8776    (match_operand:DI 2 "" "")]
8777   "TARGET_SHMEDIA"
8778   "%O2: ptrel/u %1, %0"
8779   [(set_attr "type" "ptabs_media")])
8780
8781 (define_expand "builtin_setjmp_receiver"
8782   [(match_operand 0 "" "")]
8783   "flag_pic"
8784   "
8785 {
8786   emit_insn (gen_GOTaddr2picreg ());
8787   DONE;
8788 }")
8789
8790 (define_expand "call_site"
8791   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8792   "TARGET_SH1"
8793   "
8794 {
8795   static HOST_WIDE_INT i = 0;
8796   operands[0] = GEN_INT (i);
8797   i++;
8798 }")
8799
8800 (define_expand "sym_label2reg"
8801   [(set (match_operand:SI 0 "" "")
8802         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8803                               (const (plus:SI (match_operand:SI 2 "" "")
8804                                               (const_int 2)))]
8805                              UNSPEC_SYMOFF)))]
8806   "TARGET_SH1" "")
8807
8808 (define_expand "symGOT_load"
8809   [(set (match_dup 2) (match_operand 1 "" ""))
8810    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8811    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8812   ""
8813   "
8814 {
8815   rtx insn, mem;
8816
8817   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8818   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8819
8820   if (TARGET_SHMEDIA)
8821     {
8822       rtx reg = operands[2];
8823
8824       if (Pmode == DImode)
8825         {      
8826           if (flag_pic > 1)
8827             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8828           else
8829             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8830         }
8831       else
8832         {
8833           if (flag_pic > 1)
8834             emit_insn (gen_movsi_const (reg, operands[1]));
8835           else
8836             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8837         }
8838     }
8839   else
8840     emit_move_insn (operands[2], operands[1]);
8841
8842   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8843                                              operands[2],
8844                                              gen_rtx_REG (Pmode, PIC_REG)));
8845
8846   /* When stack protector inserts codes after the result is set to
8847      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8848      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8849      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8850      matter because this is a rare situation.  */
8851   if (!TARGET_SHMEDIA
8852       && flag_stack_protect
8853       && GET_CODE (operands[1]) == CONST
8854       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8855       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8856       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8857                  \"__stack_chk_guard\") == 0)
8858     emit_insn (gen_blockage ());
8859
8860   /* N.B. This is not constant for a GOTPLT relocation.  */
8861   mem = gen_rtx_MEM (Pmode, operands[3]);
8862   MEM_NOTRAP_P (mem) = 1;
8863   /* ??? Should we have a special alias set for the GOT?  */
8864   insn = emit_move_insn (operands[0], mem);
8865
8866   DONE;
8867 }")
8868
8869 (define_expand "sym2GOT"
8870   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8871   ""
8872   "")
8873
8874 (define_expand "symGOT2reg"
8875   [(match_operand 0 "" "") (match_operand 1 "" "")]
8876   ""
8877   "
8878 {
8879   rtx gotsym, insn;
8880
8881   gotsym = gen_sym2GOT (operands[1]);
8882   PUT_MODE (gotsym, Pmode);
8883   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8884
8885   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8886
8887   DONE;
8888 }")
8889
8890 (define_expand "symGOTPLT2reg"
8891   [(match_operand 0 "" "") (match_operand 1 "" "")]
8892   ""
8893   "
8894 {
8895   rtx pltsym = gen_rtx_CONST (Pmode,
8896                               gen_rtx_UNSPEC (Pmode,
8897                                               gen_rtvec (1, operands[1]),
8898                                               UNSPEC_GOTPLT));
8899   emit_insn (gen_symGOT_load (operands[0], pltsym));
8900   DONE;
8901 }")
8902
8903 (define_expand "sym2GOTOFF"
8904   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8905   ""
8906   "")
8907
8908 (define_expand "symGOTOFF2reg"
8909   [(match_operand 0 "" "") (match_operand 1 "" "")]
8910   ""
8911   "
8912 {
8913   rtx gotoffsym, insn;
8914   rtx t = (!can_create_pseudo_p ()
8915            ? operands[0]
8916            : gen_reg_rtx (GET_MODE (operands[0])));
8917
8918   gotoffsym = gen_sym2GOTOFF (operands[1]);
8919   PUT_MODE (gotoffsym, Pmode);
8920   emit_move_insn (t, gotoffsym);
8921   insn = emit_move_insn (operands[0],
8922                          gen_rtx_PLUS (Pmode, t,
8923                                        gen_rtx_REG (Pmode, PIC_REG)));
8924
8925   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8926
8927   DONE;
8928 }")
8929
8930 (define_expand "symPLT_label2reg"
8931   [(set (match_operand:SI 0 "" "")
8932         (const:SI
8933          (unspec:SI
8934           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8935            (const:SI (plus:SI (match_operand:SI 2 "" "")
8936                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8937    ;; Even though the PIC register is not really used by the call
8938    ;; sequence in which this is expanded, the PLT code assumes the PIC
8939    ;; register is set, so we must not skip its initialization.  Since
8940    ;; we only use this expand as part of calling sequences, and never
8941    ;; to take the address of a function, this is the best point to
8942    ;; insert the (use).  Using the PLT to take the address of a
8943    ;; function would be wrong, not only because the PLT entry could
8944    ;; then be called from a function that doesn't initialize the PIC
8945    ;; register to the proper GOT, but also because pointers to the
8946    ;; same function might not compare equal, should they be set by
8947    ;; different shared libraries.
8948    (use (reg:SI PIC_REG))]
8949   "TARGET_SH1"
8950   "")
8951
8952 (define_expand "sym2PIC"
8953   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8954   ""
8955   "")
8956
8957 ;; TLS code generation.
8958 ;; ??? this should be a define_insn_and_split
8959 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8960 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8961 ;; for details.
8962
8963 (define_insn "tls_global_dynamic"
8964   [(set (match_operand:SI 0 "register_operand" "=&z")
8965         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8966                                   UNSPEC_TLSGD))
8967               (const_int 0)))
8968    (use (reg:PSI FPSCR_REG))
8969    (use (reg:SI PIC_REG))
8970    (clobber (reg:SI PR_REG))
8971    (clobber (scratch:SI))]
8972   "TARGET_SH1"
8973   "*
8974 {
8975   return \"\\
8976 mov.l\\t1f,r4\\n\\
8977 \\tmova\\t2f,r0\\n\\
8978 \\tmov.l\\t2f,r1\\n\\
8979 \\tadd\\tr0,r1\\n\\
8980 \\tjsr\\t@r1\\n\\
8981 \\tadd\\tr12,r4\\n\\
8982 \\tbra\\t3f\\n\\
8983 \\tnop\\n\\
8984 \\t.align\\t2\\n\\
8985 1:\\t.long\\t%a1@TLSGD\\n\\
8986 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8987 3:\";
8988 }"
8989   [(set_attr "type" "tls_load")
8990    (set_attr "length" "26")])
8991
8992 (define_insn "tls_local_dynamic"
8993   [(set (match_operand:SI 0 "register_operand" "=&z")
8994         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8995                                   UNSPEC_TLSLDM))
8996               (const_int 0)))
8997    (use (reg:PSI FPSCR_REG))
8998    (use (reg:SI PIC_REG))
8999    (clobber (reg:SI PR_REG))
9000    (clobber (scratch:SI))]
9001   "TARGET_SH1"
9002   "*
9003 {
9004   return \"\\
9005 mov.l\\t1f,r4\\n\\
9006 \\tmova\\t2f,r0\\n\\
9007 \\tmov.l\\t2f,r1\\n\\
9008 \\tadd\\tr0,r1\\n\\
9009 \\tjsr\\t@r1\\n\\
9010 \\tadd\\tr12,r4\\n\\
9011 \\tbra\\t3f\\n\\
9012 \\tnop\\n\\
9013 \\t.align\\t2\\n\\
9014 1:\\t.long\\t%a1@TLSLDM\\n\\
9015 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9016 3:\";
9017 }"
9018   [(set_attr "type" "tls_load")
9019    (set_attr "length" "26")])
9020
9021 (define_expand "sym2DTPOFF"
9022   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
9023   ""
9024   "")
9025
9026 (define_expand "symDTPOFF2reg"
9027   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
9028   ""
9029   "
9030 {
9031   rtx dtpoffsym, insn;
9032   rtx t = (!can_create_pseudo_p ()
9033            ? operands[0]
9034            : gen_reg_rtx (GET_MODE (operands[0])));
9035
9036   dtpoffsym = gen_sym2DTPOFF (operands[1]);
9037   PUT_MODE (dtpoffsym, Pmode);
9038   emit_move_insn (t, dtpoffsym);
9039   insn = emit_move_insn (operands[0],
9040                          gen_rtx_PLUS (Pmode, t, operands[2]));
9041   DONE;
9042 }")
9043
9044 (define_expand "sym2GOTTPOFF"
9045   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
9046   ""
9047   "")
9048
9049 (define_insn "tls_initial_exec"
9050   [(set (match_operand:SI 0 "register_operand" "=&r")
9051         (unspec:SI [(match_operand:SI 1 "" "")]
9052                     UNSPEC_TLSIE))
9053    (use (reg:SI GBR_REG))
9054    (use (reg:SI PIC_REG))
9055    (clobber (reg:SI R0_REG))]
9056   ""
9057   "*
9058 {
9059   return \"\\
9060 mov.l\\t1f,r0\\n\\
9061 \\tstc\\tgbr,%0\\n\\
9062 \\tmov.l\\t@(r0,r12),r0\\n\\
9063 \\tbra\\t2f\\n\\
9064 \\tadd\\tr0,%0\\n\\
9065 \\t.align\\t2\\n\\
9066 1:\\t.long\\t%a1\\n\\
9067 2:\";
9068 }"
9069   [(set_attr "type" "tls_load")
9070    (set_attr "length" "16")])
9071
9072 (define_expand "sym2TPOFF"
9073   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
9074   ""
9075   "")
9076
9077 (define_expand "symTPOFF2reg"
9078   [(match_operand 0 "" "") (match_operand 1 "" "")]
9079   ""
9080   "
9081 {
9082   rtx tpoffsym, insn;
9083
9084   tpoffsym = gen_sym2TPOFF (operands[1]);
9085   PUT_MODE (tpoffsym, Pmode);
9086   insn = emit_move_insn (operands[0], tpoffsym);
9087   DONE;
9088 }")
9089
9090 (define_insn "load_gbr"
9091   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
9092    (use (reg:SI GBR_REG))]
9093   ""
9094   "stc  gbr,%0"
9095   [(set_attr "type" "tls_load")])
9096
9097 ;; case instruction for switch statements.
9098
9099 ;; Operand 0 is index
9100 ;; operand 1 is the minimum bound
9101 ;; operand 2 is the maximum bound - minimum bound + 1
9102 ;; operand 3 is CODE_LABEL for the table;
9103 ;; operand 4 is the CODE_LABEL to go to if index out of range.
9104
9105 (define_expand "casesi"
9106   [(match_operand:SI 0 "arith_reg_operand" "")
9107    (match_operand:SI 1 "arith_reg_operand" "")
9108    (match_operand:SI 2 "arith_reg_operand" "")
9109    (match_operand 3 "" "") (match_operand 4 "" "")]
9110   ""
9111   "
9112 {
9113   rtx reg = gen_reg_rtx (SImode);
9114   rtx reg2 = gen_reg_rtx (SImode);
9115   if (TARGET_SHMEDIA)
9116     {
9117       rtx reg = gen_reg_rtx (DImode);
9118       rtx reg2 = gen_reg_rtx (DImode);
9119       rtx reg3 = gen_reg_rtx (Pmode);
9120       rtx reg4 = gen_reg_rtx (Pmode);
9121       rtx reg5 = gen_reg_rtx (Pmode);
9122       rtx load;
9123
9124       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9125       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9126       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9127
9128       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9129       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9130       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9131       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9132       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9133                                                (Pmode, operands[3])));
9134       /* Messy: can we subreg to clean this up? */
9135       if (Pmode == DImode)
9136         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9137       else
9138         load = gen_casesi_load_media (reg4,
9139                                       gen_rtx_SUBREG (DImode, reg3, 0),
9140                                       reg2, operands[3]);
9141       PUT_MODE (SET_SRC (load), Pmode);
9142       emit_insn (load);
9143       /* ??? The following add could be eliminated if we used ptrel.  */
9144       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9145       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9146       emit_barrier ();
9147       DONE;
9148     }
9149   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9150   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9151   /* If optimizing, casesi_worker depends on the mode of the instruction
9152      before label it 'uses' - operands[3].  */
9153   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9154                            reg));
9155   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9156   if (TARGET_SH2)
9157     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9158   else
9159     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9160   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9161      operands[3], but to lab.  We will fix this up in
9162      machine_dependent_reorg.  */
9163   emit_barrier ();
9164   DONE;
9165 }")
9166
9167 (define_expand "casesi_0"
9168   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9169    (set (match_dup 4) (minus:SI (match_dup 4)
9170                                 (match_operand:SI 1 "arith_operand" "")))
9171    (set (reg:SI T_REG)
9172         (gtu:SI (match_dup 4)
9173                 (match_operand:SI 2 "arith_reg_operand" "")))
9174    (set (pc)
9175         (if_then_else (ne (reg:SI T_REG)
9176                           (const_int 0))
9177                       (label_ref (match_operand 3 "" ""))
9178                       (pc)))]
9179   "TARGET_SH1"
9180   "")
9181
9182 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9183 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9184 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9185
9186 (define_insn "casesi_worker_0"
9187   [(set (match_operand:SI 0 "register_operand" "=r,r")
9188         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9189                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9190    (clobber (match_scratch:SI 3 "=X,1"))
9191    (clobber (match_scratch:SI 4 "=&z,z"))]
9192   "TARGET_SH1"
9193   "#")
9194
9195 (define_split
9196   [(set (match_operand:SI 0 "register_operand" "")
9197         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9198                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9199    (clobber (match_scratch:SI 3 ""))
9200    (clobber (match_scratch:SI 4 ""))]
9201   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9202   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9203    (parallel [(set (match_dup 0)
9204               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9205                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9206               (clobber (match_dup 3))])
9207    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9208   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9209
9210 (define_split
9211   [(set (match_operand:SI 0 "register_operand" "")
9212         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9213                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9214    (clobber (match_scratch:SI 3 ""))
9215    (clobber (match_scratch:SI 4 ""))]
9216   "TARGET_SH2 && reload_completed"
9217   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9218    (parallel [(set (match_dup 0)
9219               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9220                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9221               (clobber (match_dup 3))])]
9222   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9223
9224 (define_insn "casesi_worker_1"
9225   [(set (match_operand:SI 0 "register_operand" "=r,r")
9226         (unspec:SI [(reg:SI R0_REG)
9227                     (match_operand:SI 1 "register_operand" "0,r")
9228                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9229    (clobber (match_scratch:SI 3 "=X,1"))]
9230   "TARGET_SH1"
9231   "*
9232 {
9233   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9234
9235   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9236
9237   switch (GET_MODE (diff_vec))
9238     {
9239     case SImode:
9240       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9241     case HImode:
9242       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9243     case QImode:
9244       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9245         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9246       return \"mov.b    @(r0,%1),%0\";
9247     default:
9248       gcc_unreachable ();
9249     }
9250 }"
9251   [(set_attr "length" "4")])
9252
9253 (define_insn "casesi_worker_2"
9254   [(set (match_operand:SI 0 "register_operand" "=r,r")
9255         (unspec:SI [(reg:SI R0_REG)
9256                     (match_operand:SI 1 "register_operand" "0,r")
9257                     (label_ref (match_operand 2 "" ""))
9258                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9259    (clobber (match_operand:SI 4 "" "=X,1"))]
9260   "TARGET_SH2 && reload_completed && flag_pic"
9261   "*
9262 {
9263   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9264   const char *load;
9265
9266   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9267
9268   switch (GET_MODE (diff_vec))
9269     {
9270     case SImode:
9271       output_asm_insn (\"shll2    %1\", operands);
9272       load = \"mov.l    @(r0,%1),%0\"; break;
9273     case HImode:
9274       output_asm_insn (\"add    %1,%1\", operands);
9275       load = \"mov.w    @(r0,%1),%0\"; break;
9276     case QImode:
9277       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9278         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9279       else
9280         load = \"mov.b  @(r0,%1),%0\";
9281       break;
9282     default:
9283       gcc_unreachable ();
9284     }
9285   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9286   return load;
9287 }"
9288   [(set_attr "length" "8")])
9289
9290 (define_insn "casesi_shift_media"
9291   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9292         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9293                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9294                     UNSPEC_CASESI)))]
9295   "TARGET_SHMEDIA"
9296   "*
9297 {
9298   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9299
9300   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9301
9302   switch (GET_MODE (diff_vec))
9303     {
9304     case SImode:
9305       return \"shlli    %1, 2, %0\";
9306     case HImode:
9307       return \"shlli    %1, 1, %0\";
9308     case QImode:
9309       if (rtx_equal_p (operands[0], operands[1]))
9310         return \"\";
9311       return \"add      %1, r63, %0\";
9312     default:
9313       gcc_unreachable ();
9314     }
9315 }"
9316   [(set_attr "type" "arith_media")])
9317
9318 (define_insn "casesi_load_media"
9319   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9320         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9321                          (match_operand:DI 2 "arith_reg_operand" "r")
9322                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9323   "TARGET_SHMEDIA"
9324   "*
9325 {
9326   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9327
9328   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9329
9330   switch (GET_MODE (diff_vec))
9331     {
9332     case SImode:
9333       return \"ldx.l    %1, %2, %0\";
9334     case HImode:
9335 #if 0
9336       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9337         return \"ldx.uw %1, %2, %0\";
9338 #endif
9339       return \"ldx.w    %1, %2, %0\";
9340     case QImode:
9341       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9342         return \"ldx.ub %1, %2, %0\";
9343       return \"ldx.b    %1, %2, %0\";
9344     default:
9345       gcc_unreachable ();
9346     }
9347 }"
9348   [(set_attr "type" "load_media")])
9349
9350 (define_expand "return"
9351   [(return)]
9352   "reload_completed && ! sh_need_epilogue ()"
9353   "
9354 {
9355   if (TARGET_SHMEDIA)
9356     {
9357       emit_jump_insn (gen_return_media ());
9358       DONE;
9359     }
9360
9361   if (TARGET_SHCOMPACT
9362       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9363     {
9364       emit_jump_insn (gen_shcompact_return_tramp ());
9365       DONE;
9366     }
9367 }")
9368
9369 (define_insn "*return_i"
9370   [(return)]
9371   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9372                     && (crtl->args.info.call_cookie
9373                         & CALL_COOKIE_RET_TRAMP (1)))
9374    && reload_completed
9375    && lookup_attribute (\"trap_exit\",
9376                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9377   "*
9378   {
9379     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9380                         && !current_function_interrupt)
9381        return \"rts/n\";
9382     else
9383        return \"%@      %#\";
9384   }"
9385   [(set_attr "type" "return")
9386    (set_attr "needs_delay_slot" "yes")])
9387
9388 ;; trapa has no delay slot.
9389 (define_insn "*return_trapa"
9390   [(return)]
9391   "TARGET_SH1 && !TARGET_SHCOMPACT
9392    && reload_completed"
9393   "%@"
9394   [(set_attr "type" "return")])
9395
9396 (define_expand "shcompact_return_tramp"
9397   [(return)]
9398   "TARGET_SHCOMPACT
9399    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9400   "
9401 {
9402   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9403
9404   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9405   emit_jump_insn (gen_shcompact_return_tramp_i ());
9406   DONE;
9407 }")
9408
9409 (define_insn "shcompact_return_tramp_i"
9410   [(parallel [(return) (use (reg:SI R0_REG))])]
9411   "TARGET_SHCOMPACT
9412    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9413   "jmp  @r0%#"
9414   [(set_attr "type" "jump_ind")
9415    (set_attr "needs_delay_slot" "yes")])
9416
9417 (define_insn "return_media_i"
9418   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9419   "TARGET_SHMEDIA && reload_completed"
9420   "blink        %0, r63"
9421   [(set_attr "type" "jump_media")])
9422
9423 (define_insn "return_media_rte"
9424   [(return)]
9425   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9426   "rte"
9427   [(set_attr "type" "jump_media")])
9428
9429 (define_expand "return_media"
9430   [(return)]
9431   "TARGET_SHMEDIA && reload_completed"
9432   "
9433 {
9434   int tr_regno = sh_media_register_for_return ();
9435   rtx tr;
9436
9437   if (current_function_interrupt)
9438     {
9439       emit_jump_insn (gen_return_media_rte ());
9440       DONE;
9441     }
9442   if (tr_regno < 0)
9443     {
9444       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9445
9446       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9447       tr_regno = TR0_REG;
9448       tr = gen_rtx_REG (Pmode, tr_regno);
9449       emit_move_insn (tr, r18);
9450     }
9451   else
9452     tr = gen_rtx_REG (Pmode, tr_regno);
9453
9454   emit_jump_insn (gen_return_media_i (tr));
9455   DONE;
9456 }")
9457
9458 (define_insn "shcompact_preserve_incoming_args"
9459   [(set (match_operand:SI 0 "register_operand" "+r")
9460         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9461   "TARGET_SHCOMPACT"
9462   ""
9463   [(set_attr "length" "0")])
9464
9465 (define_insn "shcompact_incoming_args"
9466   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9467    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9468    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9469    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9470    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9471    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9472    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9473    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9474    (set (mem:BLK (reg:SI MACL_REG))
9475         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9476    (use (reg:SI R0_REG))
9477    (clobber (reg:SI R0_REG))
9478    (clobber (reg:SI MACL_REG))
9479    (clobber (reg:SI MACH_REG))
9480    (clobber (reg:SI PR_REG))]
9481   "TARGET_SHCOMPACT"
9482   "jsr  @r0%#"
9483   [(set_attr "needs_delay_slot" "yes")])
9484
9485 (define_insn "shmedia_save_restore_regs_compact"
9486   [(set (reg:SI SP_REG)
9487         (plus:SI (reg:SI SP_REG)
9488                  (match_operand:SI 0 "immediate_operand" "i")))
9489    (use (reg:SI R0_REG))
9490    (clobber (reg:SI PR_REG))]
9491   "TARGET_SHCOMPACT
9492    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9493        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9494   "jsr @r0%#"
9495   [(set_attr "needs_delay_slot" "yes")])
9496
9497 (define_expand "prologue"
9498   [(const_int 0)]
9499   ""
9500   "sh_expand_prologue (); DONE;")
9501
9502 (define_expand "epilogue"
9503   [(return)]
9504   ""
9505   "
9506 {
9507   sh_expand_epilogue (0);
9508   emit_jump_insn (gen_return ());
9509   DONE;
9510 }")
9511
9512 (define_expand "eh_return"
9513   [(use (match_operand 0 "register_operand" ""))]
9514   ""
9515 {
9516   rtx ra = operands[0];
9517
9518   if (TARGET_SHMEDIA64)
9519     emit_insn (gen_eh_set_ra_di (ra));
9520   else
9521     emit_insn (gen_eh_set_ra_si (ra));
9522
9523   DONE;
9524 })
9525
9526 ;; Clobber the return address on the stack.  We can't expand this
9527 ;; until we know where it will be put in the stack frame.
9528
9529 (define_insn "eh_set_ra_si"
9530   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9531       UNSPECV_EH_RETURN)
9532    (clobber (match_scratch:SI 1 "=&r"))]
9533   "! TARGET_SHMEDIA64"
9534   "#")
9535
9536 (define_insn "eh_set_ra_di"
9537   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9538       UNSPECV_EH_RETURN)
9539    (clobber (match_scratch:DI 1 "=&r"))]
9540   "TARGET_SHMEDIA64"
9541   "#")
9542
9543 (define_split
9544   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9545       UNSPECV_EH_RETURN)
9546    (clobber (match_scratch 1 ""))]
9547   "reload_completed"
9548   [(const_int 0)]
9549   "
9550 {
9551   sh_set_return_address (operands[0], operands[1]);
9552   DONE;
9553 }")
9554
9555 (define_insn "blockage"
9556   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9557   ""
9558   ""
9559   [(set_attr "length" "0")])
9560 \f
9561 ;; ------------------------------------------------------------------------
9562 ;; Scc instructions
9563 ;; ------------------------------------------------------------------------
9564
9565 (define_insn "movt"
9566   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9567         (eq:SI (reg:SI T_REG) (const_int 1)))]
9568   "TARGET_SH1"
9569   "movt %0"
9570   [(set_attr "type" "arith")])
9571
9572 ;; complements the T bit and stores the result in a register
9573 (define_insn "movrt"
9574   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9575         (if_then_else (eq:SI (reg:SI T_REG) (const_int 0))
9576         (const_int 1)
9577         (const_int 0)))]
9578   "TARGET_SH2A"
9579   "movrt\\t%0"
9580    [(set_attr "type" "arith")])
9581
9582 (define_expand "seq"
9583   [(set (match_operand:SI 0 "arith_reg_dest" "")
9584         (match_dup 1))]
9585   ""
9586   "
9587 {
9588   if (TARGET_SHMEDIA)
9589     {
9590       rtx reg;
9591
9592       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9593       if (sh_compare_op1 != const0_rtx)
9594         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9595                                     ? GET_MODE (sh_compare_op0)
9596                                     : GET_MODE (sh_compare_op1),
9597                                     sh_compare_op1);
9598       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9599         {
9600           if (GET_MODE (operands[0]) != SImode)
9601             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9602
9603           switch (GET_MODE (sh_compare_op0))
9604             {
9605             case SImode:
9606               emit_insn (gen_cmpeqsi_media (operands[0],
9607                                               sh_compare_op0, sh_compare_op1));
9608               break;
9609
9610             case DImode:
9611               emit_insn (gen_cmpeqdi_media (operands[0],
9612                                               sh_compare_op0, sh_compare_op1));
9613               break;
9614
9615             case SFmode:
9616               if (! TARGET_SHMEDIA_FPU)
9617                 FAIL;
9618               emit_insn (gen_cmpeqsf_media (operands[0],
9619                                               sh_compare_op0, sh_compare_op1));
9620               break;
9621
9622             case DFmode:
9623               if (! TARGET_SHMEDIA_FPU)
9624                 FAIL;
9625               emit_insn (gen_cmpeqdf_media (operands[0],
9626                                               sh_compare_op0, sh_compare_op1));
9627               break;
9628
9629             default:
9630               FAIL;
9631             }
9632           DONE;
9633         }
9634
9635       reg = operands[0];
9636       if (GET_MODE (operands[0]) != SImode)
9637         reg = (!can_create_pseudo_p ()
9638                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9639                : gen_reg_rtx (SImode));
9640
9641       switch (GET_MODE (sh_compare_op0))
9642         {
9643         case SImode:
9644           emit_insn (gen_cmpeqsi_media (reg,
9645                                         sh_compare_op0, sh_compare_op1));
9646           break;
9647
9648         case DImode:
9649           emit_insn (gen_cmpeqdi_media (reg,
9650                                         sh_compare_op0, sh_compare_op1));
9651           break;
9652
9653         case SFmode:
9654           if (! TARGET_SHMEDIA_FPU)
9655             FAIL;
9656           emit_insn (gen_cmpeqsf_media (reg,
9657                                         sh_compare_op0, sh_compare_op1));
9658           break;
9659
9660         case DFmode:
9661           if (! TARGET_SHMEDIA_FPU)
9662             FAIL;
9663           emit_insn (gen_cmpeqdf_media (reg,
9664                                         sh_compare_op0, sh_compare_op1));
9665           break;
9666
9667         default:
9668           FAIL;
9669         }
9670
9671       if (GET_MODE (operands[0]) == DImode)
9672         emit_insn (gen_extendsidi2 (operands[0], reg));
9673
9674       DONE;
9675     }
9676   if (sh_expand_t_scc (EQ, operands[0]))
9677     DONE;
9678   if (! currently_expanding_to_rtl)
9679     FAIL;
9680   operands[1] = prepare_scc_operands (EQ);
9681 }")
9682
9683 (define_expand "slt"
9684   [(set (match_operand:SI 0 "arith_reg_operand" "")
9685         (match_dup 1))]
9686   ""
9687   "
9688 {
9689   if (TARGET_SHMEDIA)
9690     {
9691       rtx reg;
9692
9693       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9694       if (sh_compare_op1 != const0_rtx)
9695         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9696                                     ? GET_MODE (sh_compare_op0)
9697                                     : GET_MODE (sh_compare_op1),
9698                                     sh_compare_op1);
9699
9700       reg = operands[0];
9701       if (GET_MODE (operands[0]) != SImode)
9702         reg = (!can_create_pseudo_p ()
9703                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9704                : gen_reg_rtx (SImode));
9705
9706       switch (GET_MODE (sh_compare_op0))
9707         {
9708         case SImode:
9709           emit_insn (gen_cmpgtsi_media (reg,
9710                                         sh_compare_op1, sh_compare_op0));
9711           break;
9712
9713         case DImode:
9714           emit_insn (gen_cmpgtdi_media (reg,
9715                                         sh_compare_op1, sh_compare_op0));
9716           break;
9717
9718         case SFmode:
9719           if (! TARGET_SHMEDIA_FPU)
9720             FAIL;
9721           emit_insn (gen_cmpgtsf_media (reg,
9722                                         sh_compare_op1, sh_compare_op0));
9723           break;
9724
9725         case DFmode:
9726           if (! TARGET_SHMEDIA_FPU)
9727             FAIL;
9728           emit_insn (gen_cmpgtdf_media (reg,
9729                                         sh_compare_op1, sh_compare_op0));
9730           break;
9731
9732         default:
9733           FAIL;
9734         }
9735
9736       if (GET_MODE (operands[0]) == DImode)
9737         emit_insn (gen_extendsidi2 (operands[0], reg));
9738
9739       DONE;
9740     }
9741   if (! currently_expanding_to_rtl)
9742     FAIL;
9743   operands[1] = prepare_scc_operands (LT);
9744 }")
9745
9746 (define_expand "sle"
9747   [(match_operand:SI 0 "arith_reg_operand" "")]
9748   ""
9749   "
9750 {
9751   rtx tmp = sh_compare_op0;
9752
9753   if (TARGET_SHMEDIA)
9754     {
9755       rtx reg;
9756
9757       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9758       if (sh_compare_op1 != const0_rtx)
9759         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9760                                     ? GET_MODE (sh_compare_op0)
9761                                     : GET_MODE (sh_compare_op1),
9762                                     sh_compare_op1);
9763
9764       reg = operands[0];
9765       if (GET_MODE (operands[0]) != SImode)
9766         reg = (!can_create_pseudo_p ()
9767                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9768                : gen_reg_rtx (SImode));
9769
9770       switch (GET_MODE (sh_compare_op0))
9771         {
9772         case SImode:
9773           {
9774             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9775
9776             emit_insn (gen_cmpgtsi_media (tmp,
9777                                           sh_compare_op0, sh_compare_op1));
9778             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9779             break;
9780           }
9781
9782         case DImode:
9783           {
9784             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9785
9786             emit_insn (gen_cmpgtdi_media (tmp,
9787                                           sh_compare_op0, sh_compare_op1));
9788             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9789             break;
9790           }
9791
9792         case SFmode:
9793           if (! TARGET_SHMEDIA_FPU)
9794             FAIL;
9795           emit_insn (gen_cmpgesf_media (reg,
9796                                         sh_compare_op1, sh_compare_op0));
9797           break;
9798
9799         case DFmode:
9800           if (! TARGET_SHMEDIA_FPU)
9801             FAIL;
9802           emit_insn (gen_cmpgedf_media (reg,
9803                                         sh_compare_op1, sh_compare_op0));
9804           break;
9805
9806         default:
9807           FAIL;
9808         }
9809
9810       if (GET_MODE (operands[0]) == DImode)
9811         emit_insn (gen_extendsidi2 (operands[0], reg));
9812
9813       DONE;
9814     }
9815
9816   sh_compare_op0 = sh_compare_op1;
9817   sh_compare_op1 = tmp;
9818   emit_insn (gen_sge (operands[0]));
9819   DONE;
9820 }")
9821
9822 (define_expand "sgt"
9823   [(set (match_operand:SI 0 "arith_reg_operand" "")
9824         (match_dup 1))]
9825   ""
9826   "
9827 {
9828   if (TARGET_SHMEDIA)
9829     {
9830       rtx reg;
9831
9832       reg = operands[0];
9833       if (GET_MODE (operands[0]) != SImode)
9834         reg = (!can_create_pseudo_p () ?
9835                gen_rtx_SUBREG (SImode, operands[0], 0)
9836                : gen_reg_rtx (SImode));
9837       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9838       if (sh_compare_op1 != const0_rtx)
9839         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9840                                     ? GET_MODE (sh_compare_op0)
9841                                     : GET_MODE (sh_compare_op1),
9842                                     sh_compare_op1);
9843
9844       switch (GET_MODE (sh_compare_op0))
9845         {
9846         case SImode:
9847           emit_insn (gen_cmpgtsi_media (reg,
9848                                         sh_compare_op0, sh_compare_op1));
9849           break;
9850
9851         case DImode:
9852           emit_insn (gen_cmpgtdi_media (reg,
9853                                         sh_compare_op0, sh_compare_op1));
9854           break;
9855
9856         case SFmode:
9857           if (! TARGET_SHMEDIA_FPU)
9858             FAIL;
9859           emit_insn (gen_cmpgtsf_media (reg,
9860                                         sh_compare_op0, sh_compare_op1));
9861           break;
9862
9863         case DFmode:
9864           if (! TARGET_SHMEDIA_FPU)
9865             FAIL;
9866           emit_insn (gen_cmpgtdf_media (reg,
9867                                         sh_compare_op0, sh_compare_op1));
9868           break;
9869
9870         default:
9871           FAIL;
9872         }
9873
9874       if (GET_MODE (operands[0]) == DImode)
9875         emit_insn (gen_extendsidi2 (operands[0], reg));
9876
9877       DONE;
9878     }
9879   if (! currently_expanding_to_rtl)
9880     FAIL;
9881   operands[1] = prepare_scc_operands (GT);
9882 }")
9883
9884 (define_expand "sge"
9885   [(set (match_operand:SI 0 "arith_reg_operand" "")
9886         (match_dup 1))]
9887   ""
9888   "
9889 {
9890   if (TARGET_SHMEDIA)
9891     {
9892       rtx reg;
9893       enum machine_mode mode = GET_MODE (sh_compare_op0);
9894
9895       if ((mode) == VOIDmode)
9896         mode = GET_MODE (sh_compare_op1);
9897       reg = operands[0];
9898       if (GET_MODE (operands[0]) != SImode)
9899         reg = (!can_create_pseudo_p ()
9900                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9901                : gen_reg_rtx (SImode));
9902       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9903       if (sh_compare_op1 != const0_rtx)
9904         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9905
9906       switch (mode)
9907         {
9908         case SImode:
9909           {
9910             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9911
9912             emit_insn (gen_cmpgtsi_media (tmp,
9913                                           sh_compare_op1, sh_compare_op0));
9914             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9915             break;
9916           }
9917
9918         case DImode:
9919           {
9920             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9921
9922             emit_insn (gen_cmpgtdi_media (tmp,
9923                                           sh_compare_op1, sh_compare_op0));
9924             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9925             break;
9926           }
9927
9928         case SFmode:
9929           if (! TARGET_SHMEDIA_FPU)
9930             FAIL;
9931           emit_insn (gen_cmpgesf_media (reg,
9932                                         sh_compare_op0, sh_compare_op1));
9933           break;
9934
9935         case DFmode:
9936           if (! TARGET_SHMEDIA_FPU)
9937             FAIL;
9938           emit_insn (gen_cmpgedf_media (reg,
9939                                         sh_compare_op0, sh_compare_op1));
9940           break;
9941
9942         default:
9943           FAIL;
9944         }
9945
9946       if (GET_MODE (operands[0]) == DImode)
9947         emit_insn (gen_extendsidi2 (operands[0], reg));
9948
9949       DONE;
9950     }
9951
9952   if (! currently_expanding_to_rtl)
9953     FAIL;
9954   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9955     {
9956       if (TARGET_IEEE)
9957         {
9958           rtx lab = gen_label_rtx ();
9959           prepare_scc_operands (EQ);
9960           emit_jump_insn (gen_branch_true (lab));
9961           prepare_scc_operands (GT);
9962           emit_label (lab);
9963           emit_insn (gen_movt (operands[0]));
9964         }
9965       else
9966         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9967       DONE;
9968     }
9969   operands[1] = prepare_scc_operands (GE);
9970 }")
9971
9972 (define_expand "sgtu"
9973   [(set (match_operand:SI 0 "arith_reg_operand" "")
9974         (match_dup 1))]
9975   ""
9976   "
9977 {
9978   if (TARGET_SHMEDIA)
9979     {
9980       rtx reg;
9981
9982       reg = operands[0];
9983       if (GET_MODE (operands[0]) == DImode)
9984         reg = (!can_create_pseudo_p ()
9985                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9986                : gen_reg_rtx (SImode));
9987       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9988       if (sh_compare_op1 != const0_rtx)
9989         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9990                                     ? GET_MODE (sh_compare_op0)
9991                                     : GET_MODE (sh_compare_op1),
9992                                     sh_compare_op1);
9993
9994       emit_insn (gen_cmpgtudi_media (reg,
9995                                      sh_compare_op0, sh_compare_op1));
9996       if (GET_MODE (operands[0]) == DImode)
9997         emit_insn (gen_extendsidi2 (operands[0], reg));
9998
9999       DONE;
10000     }
10001   if (! currently_expanding_to_rtl)
10002     FAIL;
10003   operands[1] = prepare_scc_operands (GTU);
10004 }")
10005
10006 (define_expand "sltu"
10007   [(set (match_operand:SI 0 "arith_reg_operand" "")
10008         (match_dup 1))]
10009   ""
10010   "
10011 {
10012   if (TARGET_SHMEDIA)
10013     {
10014       rtx reg;
10015
10016       reg = operands[0];
10017       if (GET_MODE (operands[0]) == DImode)
10018         reg = (!can_create_pseudo_p ()
10019                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10020                : gen_reg_rtx (SImode));
10021       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10022       if (sh_compare_op1 != const0_rtx)
10023         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10024                                     ? GET_MODE (sh_compare_op0)
10025                                     : GET_MODE (sh_compare_op1),
10026                                     sh_compare_op1);
10027
10028       emit_insn (gen_cmpgtudi_media (reg,
10029                                      sh_compare_op1, sh_compare_op0));
10030       if (GET_MODE (operands[0]) == DImode)
10031         emit_insn (gen_extendsidi2 (operands[0], reg));
10032
10033       DONE;
10034     }
10035   if (! currently_expanding_to_rtl)
10036     FAIL;
10037   operands[1] = prepare_scc_operands (LTU);
10038 }")
10039
10040 (define_expand "sleu"
10041   [(set (match_operand:SI 0 "arith_reg_operand" "")
10042         (match_dup 1))]
10043   ""
10044   "
10045 {
10046   if (TARGET_SHMEDIA)
10047     {
10048       rtx tmp, reg;
10049
10050       reg = operands[0];
10051       if (GET_MODE (operands[0]) != SImode)
10052         reg = (!can_create_pseudo_p ()
10053                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10054                : gen_reg_rtx (SImode));
10055       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10056       if (sh_compare_op1 != const0_rtx)
10057         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10058                                     ? GET_MODE (sh_compare_op0)
10059                                     : GET_MODE (sh_compare_op1),
10060                                     sh_compare_op1);
10061
10062       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10063
10064       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
10065       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10066       if (GET_MODE (operands[0]) == DImode)
10067         emit_insn (gen_extendsidi2 (operands[0], reg));
10068
10069       DONE;
10070     }
10071   if (! currently_expanding_to_rtl)
10072     FAIL;
10073   operands[1] = prepare_scc_operands (LEU);
10074 }")
10075
10076 (define_expand "sgeu"
10077   [(set (match_operand:SI 0 "arith_reg_operand" "")
10078         (match_dup 1))]
10079   ""
10080   "
10081 {
10082   if (TARGET_SHMEDIA)
10083     {
10084       rtx tmp, reg;
10085
10086       reg = operands[0];
10087       if (GET_MODE (operands[0]) != SImode)
10088         reg = (!can_create_pseudo_p ()
10089                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10090                : gen_reg_rtx (SImode));
10091       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10092       if (sh_compare_op1 != const0_rtx)
10093         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10094                                     ? GET_MODE (sh_compare_op0)
10095                                     : GET_MODE (sh_compare_op1),
10096                                     sh_compare_op1);
10097
10098       tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
10099
10100       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
10101       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10102       if (GET_MODE (operands[0]) == DImode)
10103         emit_insn (gen_extendsidi2 (operands[0], reg));
10104
10105       DONE;
10106     }
10107
10108   if (! currently_expanding_to_rtl)
10109     FAIL;
10110   operands[1] = prepare_scc_operands (GEU);
10111 }")
10112
10113 ;; sne moves the complement of the T reg to DEST like this:
10114 ;;      cmp/eq ...
10115 ;;      mov    #-1,temp
10116 ;;      negc   temp,dest
10117 ;;   This is better than xoring compare result with 1 because it does
10118 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
10119 ;;   loop.
10120
10121 (define_expand "sne"
10122   [(set (match_dup 2) (const_int -1))
10123    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
10124                    (neg:SI (plus:SI (match_dup 1)
10125                                     (match_dup 2))))
10126               (set (reg:SI T_REG)
10127                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10128                           (const_int 0)))])]
10129   ""
10130   "
10131 {
10132   if (TARGET_SHMEDIA)
10133     {
10134       rtx tmp, reg;
10135
10136       reg = operands[0];
10137       if (GET_MODE (operands[0]) != SImode)
10138         reg = (!can_create_pseudo_p ()
10139                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10140                : gen_reg_rtx (SImode));
10141       if (! TARGET_SHMEDIA_FPU
10142           && GET_MODE (sh_compare_op0) != DImode
10143           && GET_MODE (sh_compare_op0) != SImode)
10144         FAIL;
10145
10146       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10147       if (sh_compare_op1 != const0_rtx)
10148         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10149                                     ? GET_MODE (sh_compare_op0)
10150                                     : GET_MODE (sh_compare_op1),
10151                                     sh_compare_op1);
10152
10153       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10154
10155       emit_insn (gen_seq (tmp));
10156       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10157       if (GET_MODE (operands[0]) == DImode)
10158         emit_insn (gen_extendsidi2 (operands[0], reg));
10159
10160       DONE;
10161     }
10162
10163   if (sh_expand_t_scc (NE, operands[0]))
10164     DONE;
10165   if (! currently_expanding_to_rtl)
10166     FAIL;
10167   operands[1] = prepare_scc_operands (EQ);
10168   operands[2] = gen_reg_rtx (SImode);
10169 }")
10170
10171 (define_expand "sunordered"
10172   [(set (match_operand:SI 0 "arith_reg_operand" "")
10173         (unordered:SI (match_dup 1) (match_dup 2)))]
10174   "TARGET_SHMEDIA_FPU"
10175   "
10176 {
10177   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10178   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10179 }")
10180
10181 ;; Use the same trick for FP sle / sge
10182
10183 ;; Apart from the constant use and the T setting, this is like movt,
10184 ;; except that it uses the logically negated value of T, i.e.
10185 ;; operand[0] := T ? 0 : 1.
10186 (define_expand "movnegt"
10187   [(set (match_dup 2) (const_int -1))
10188    (parallel [(set (match_operand 0 "" "")
10189                    (neg:SI (plus:SI (match_dup 1)
10190                                     (match_dup 2))))
10191               (set (reg:SI T_REG)
10192                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10193                           (const_int 0)))])]
10194   "TARGET_SH1"
10195   "operands[2] = gen_reg_rtx (SImode);")
10196
10197 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10198 ;; This prevents a regression that occurred when we switched from xor to
10199 ;; mov/neg for sne.
10200
10201 (define_split
10202   [(set (match_operand:SI 0 "arith_reg_dest" "")
10203         (plus:SI (reg:SI T_REG)
10204                  (const_int -1)))]
10205   "TARGET_SH1"
10206   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10207    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10208   "")
10209
10210 ;; -------------------------------------------------------------------------
10211 ;; Instructions to cope with inline literal tables
10212 ;; -------------------------------------------------------------------------
10213
10214 ; 2 byte integer in line
10215
10216 (define_insn "consttable_2"
10217  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10218                     (match_operand 1 "" "")]
10219                    UNSPECV_CONST2)]
10220  ""
10221  "*
10222 {
10223   if (operands[1] != const0_rtx)
10224     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10225   return \"\";
10226 }"
10227  [(set_attr "length" "2")
10228  (set_attr "in_delay_slot" "no")])
10229
10230 ; 4 byte integer in line
10231
10232 (define_insn "consttable_4"
10233  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10234                     (match_operand 1 "" "")]
10235                    UNSPECV_CONST4)]
10236  ""
10237  "*
10238 {
10239   if (operands[1] != const0_rtx)
10240     {
10241       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10242       mark_symbol_refs_as_used (operands[0]);
10243     }
10244   return \"\";
10245 }"
10246  [(set_attr "length" "4")
10247   (set_attr "in_delay_slot" "no")])
10248
10249 ; 8 byte integer in line
10250
10251 (define_insn "consttable_8"
10252  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10253                     (match_operand 1 "" "")]
10254                    UNSPECV_CONST8)]
10255  ""
10256  "*
10257 {
10258   if (operands[1] != const0_rtx)
10259     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10260   return \"\";
10261 }"
10262  [(set_attr "length" "8")
10263   (set_attr "in_delay_slot" "no")])
10264
10265 ; 4 byte floating point
10266
10267 (define_insn "consttable_sf"
10268  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10269                     (match_operand 1 "" "")]
10270                    UNSPECV_CONST4)]
10271  ""
10272  "*
10273 {
10274   if (operands[1] != const0_rtx)
10275     {
10276       REAL_VALUE_TYPE d;
10277       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10278       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10279     }
10280   return \"\";
10281 }"
10282  [(set_attr "length" "4")
10283   (set_attr "in_delay_slot" "no")])
10284
10285 ; 8 byte floating point
10286
10287 (define_insn "consttable_df"
10288  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10289                     (match_operand 1 "" "")]
10290                    UNSPECV_CONST8)]
10291  ""
10292  "*
10293 {
10294   if (operands[1] != const0_rtx)
10295     {
10296       REAL_VALUE_TYPE d;
10297       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10298       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10299     }
10300   return \"\";
10301 }"
10302  [(set_attr "length" "8")
10303   (set_attr "in_delay_slot" "no")])
10304
10305 ;; Alignment is needed for some constant tables; it may also be added for
10306 ;; Instructions at the start of loops, or after unconditional branches.
10307 ;; ??? We would get more accurate lengths if we did instruction
10308 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10309 ;; here is too conservative.
10310
10311 ; align to a two byte boundary
10312
10313 (define_expand "align_2"
10314  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10315  ""
10316  "")
10317
10318 ; align to a four byte boundary
10319 ;; align_4 and align_log are instructions for the starts of loops, or
10320 ;; after unconditional branches, which may take up extra room.
10321
10322 (define_expand "align_4"
10323  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10324  ""
10325  "")
10326
10327 ; align to a cache line boundary
10328
10329 (define_insn "align_log"
10330  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10331  ""
10332  ""
10333  [(set_attr "length" "0")
10334   (set_attr "in_delay_slot" "no")])
10335
10336 ; emitted at the end of the literal table, used to emit the
10337 ; 32bit branch labels if needed.
10338
10339 (define_insn "consttable_end"
10340   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10341   ""
10342   "* return output_jump_label_table ();"
10343   [(set_attr "in_delay_slot" "no")])
10344
10345 ; emitted at the end of the window in the literal table.
10346
10347 (define_insn "consttable_window_end"
10348   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10349   ""
10350   ""
10351   [(set_attr "length" "0")
10352    (set_attr "in_delay_slot" "no")])
10353
10354 ;; -------------------------------------------------------------------------
10355 ;; Misc
10356 ;; -------------------------------------------------------------------------
10357
10358 ;; String/block move insn.
10359
10360 (define_expand "movmemsi"
10361   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10362                    (mem:BLK (match_operand:BLK 1 "" "")))
10363               (use (match_operand:SI 2 "nonmemory_operand" ""))
10364               (use (match_operand:SI 3 "immediate_operand" ""))
10365               (clobber (reg:SI PR_REG))
10366               (clobber (reg:SI R4_REG))
10367               (clobber (reg:SI R5_REG))
10368               (clobber (reg:SI R0_REG))])]
10369   "TARGET_SH1 && ! TARGET_SH5"
10370   "
10371 {
10372   if(expand_block_move (operands))
10373      DONE;
10374   else FAIL;
10375 }")
10376
10377 (define_insn "block_move_real"
10378   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10379                    (mem:BLK (reg:SI R5_REG)))
10380               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10381               (clobber (reg:SI PR_REG))
10382               (clobber (reg:SI R0_REG))])]
10383   "TARGET_SH1 && ! TARGET_HARD_SH4"
10384   "jsr  @%0%#"
10385   [(set_attr "type" "sfunc")
10386    (set_attr "needs_delay_slot" "yes")])
10387
10388 (define_insn "block_lump_real"
10389   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10390                    (mem:BLK (reg:SI R5_REG)))
10391               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10392               (use (reg:SI R6_REG))
10393               (clobber (reg:SI PR_REG))
10394               (clobber (reg:SI T_REG))
10395               (clobber (reg:SI R4_REG))
10396               (clobber (reg:SI R5_REG))
10397               (clobber (reg:SI R6_REG))
10398               (clobber (reg:SI R0_REG))])]
10399   "TARGET_SH1 && ! TARGET_HARD_SH4"
10400   "jsr  @%0%#"
10401   [(set_attr "type" "sfunc")
10402    (set_attr "needs_delay_slot" "yes")])
10403
10404 (define_insn "block_move_real_i4"
10405   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10406                    (mem:BLK (reg:SI R5_REG)))
10407               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10408               (clobber (reg:SI PR_REG))
10409               (clobber (reg:SI R0_REG))
10410               (clobber (reg:SI R1_REG))
10411               (clobber (reg:SI R2_REG))])]
10412   "TARGET_HARD_SH4"
10413   "jsr  @%0%#"
10414   [(set_attr "type" "sfunc")
10415    (set_attr "needs_delay_slot" "yes")])
10416
10417 (define_insn "block_lump_real_i4"
10418   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10419                    (mem:BLK (reg:SI R5_REG)))
10420               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10421               (use (reg:SI R6_REG))
10422               (clobber (reg:SI PR_REG))
10423               (clobber (reg:SI T_REG))
10424               (clobber (reg:SI R4_REG))
10425               (clobber (reg:SI R5_REG))
10426               (clobber (reg:SI R6_REG))
10427               (clobber (reg:SI R0_REG))
10428               (clobber (reg:SI R1_REG))
10429               (clobber (reg:SI R2_REG))
10430               (clobber (reg:SI R3_REG))])]
10431   "TARGET_HARD_SH4"
10432   "jsr  @%0%#"
10433   [(set_attr "type" "sfunc")
10434    (set_attr "needs_delay_slot" "yes")])
10435 \f
10436 ;; -------------------------------------------------------------------------
10437 ;; Floating point instructions.
10438 ;; -------------------------------------------------------------------------
10439
10440 ;; ??? All patterns should have a type attribute.
10441
10442 (define_expand "movpsi"
10443   [(set (match_operand:PSI 0 "register_operand" "")
10444         (match_operand:PSI 1 "general_movsrc_operand" ""))]
10445   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10446   "")
10447
10448 ;; The c / m alternative is a fake to guide reload to load directly into
10449 ;; fpscr, since reload doesn't know how to use post-increment.
10450 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10451 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10452 ;; predicate after reload.
10453 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10454 ;; like a mac -> gpr move.
10455 (define_insn "fpu_switch"
10456   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10457         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10458   "TARGET_SH2E
10459    && (! reload_completed
10460        || true_regnum (operands[0]) != FPSCR_REG
10461        || GET_CODE (operands[1]) != MEM
10462        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10463   "@
10464         ! precision stays the same
10465         lds.l   %1,fpscr
10466         mov.l   %1,%0
10467         #
10468         lds     %1,fpscr
10469         mov     %1,%0
10470         mov.l   %1,%0
10471         sts     fpscr,%0
10472         sts.l   fpscr,%0"
10473   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10474    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10475
10476 (define_peephole2
10477   [(set (reg:PSI FPSCR_REG)
10478         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10479   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10480   [(const_int 0)]
10481 {
10482   rtx fpscr, mem, new_insn;
10483
10484   fpscr = SET_DEST (PATTERN (curr_insn));
10485   mem = SET_SRC (PATTERN (curr_insn));
10486   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10487
10488   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10489   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10490   DONE;
10491 })
10492
10493 (define_split
10494   [(set (reg:PSI FPSCR_REG)
10495         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10496   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10497    && (flag_peephole2 ? epilogue_completed : reload_completed)"
10498   [(const_int 0)]
10499 {
10500   rtx fpscr, mem, new_insn;
10501
10502   fpscr = SET_DEST (PATTERN (curr_insn));
10503   mem = SET_SRC (PATTERN (curr_insn));
10504   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10505
10506   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10507   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10508
10509   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10510     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10511   DONE;
10512 })
10513
10514 ;; ??? This uses the fp unit, but has no type indicating that.
10515 ;; If we did that, this would either give a bogus latency or introduce
10516 ;; a bogus FIFO constraint.
10517 ;; Since this insn is currently only used for prologues/epilogues,
10518 ;; it is probably best to claim no function unit, which matches the
10519 ;; current setting.
10520 (define_insn "toggle_sz"
10521   [(set (reg:PSI FPSCR_REG)
10522         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10523   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10524   "fschg"
10525   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10526
10527 ;; There's no way we can use it today, since optimize mode switching
10528 ;; doesn't enable us to know from which mode we're switching to the
10529 ;; mode it requests, to tell whether we can use a relative mode switch
10530 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10531 ;; memory).
10532 (define_insn "toggle_pr"
10533   [(set (reg:PSI FPSCR_REG)
10534         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10535   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10536   "fpchg"
10537   [(set_attr "type" "fpscr_toggle")])
10538
10539 (define_expand "addsf3"
10540   [(set (match_operand:SF 0 "arith_reg_operand" "")
10541         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10542                  (match_operand:SF 2 "arith_reg_operand" "")))]
10543   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10544   "
10545 {
10546   if (TARGET_SH2E)
10547     {
10548       expand_sf_binop (&gen_addsf3_i, operands);
10549       DONE;
10550     }
10551 }")
10552
10553 (define_insn "*addsf3_media"
10554   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10555         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10556                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10557   "TARGET_SHMEDIA_FPU"
10558   "fadd.s       %1, %2, %0"
10559   [(set_attr "type" "fparith_media")])
10560
10561 (define_insn_and_split "unary_sf_op"
10562   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10563         (vec_select:V2SF
10564          (vec_concat:V2SF
10565           (vec_select:SF
10566            (match_dup 0)
10567            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10568           (match_operator:SF 2 "unary_float_operator"
10569             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10570                             (parallel [(match_operand 4
10571                                         "const_int_operand" "n")]))]))
10572          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10573   "TARGET_SHMEDIA_FPU"
10574   "#"
10575   "TARGET_SHMEDIA_FPU && reload_completed"
10576   [(set (match_dup 5) (match_dup 6))]
10577   "
10578 {
10579   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10580   rtx op1 = gen_rtx_REG (SFmode,
10581                          (true_regnum (operands[1])
10582                           + (INTVAL (operands[4]) ^ endian)));
10583
10584   operands[7] = gen_rtx_REG (SFmode,
10585                              (true_regnum (operands[0])
10586                               + (INTVAL (operands[3]) ^ endian)));
10587   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10588 }"
10589   [(set_attr "type" "fparith_media")])
10590
10591 (define_insn_and_split "binary_sf_op0"
10592   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10593         (vec_concat:V2SF
10594           (match_operator:SF 3 "binary_float_operator"
10595             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10596                             (parallel [(const_int 0)]))
10597              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10598                             (parallel [(const_int 0)]))])
10599           (vec_select:SF
10600            (match_dup 0)
10601            (parallel [(const_int 1)]))))]
10602   "TARGET_SHMEDIA_FPU"
10603   "#"
10604   "&& reload_completed"
10605   [(set (match_dup 4) (match_dup 5))]
10606   "
10607 {
10608   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10609   rtx op1 = gen_rtx_REG (SFmode,
10610                          true_regnum (operands[1]) + endian);
10611   rtx op2 = gen_rtx_REG (SFmode,
10612                          true_regnum (operands[2]) + endian);
10613
10614   operands[4] = gen_rtx_REG (SFmode,
10615                              true_regnum (operands[0]) + endian);
10616   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10617 }"
10618   [(set_attr "type" "fparith_media")])
10619
10620 (define_insn_and_split "binary_sf_op1"
10621   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10622         (vec_concat:V2SF
10623           (vec_select:SF
10624            (match_dup 0)
10625            (parallel [(const_int 0)]))
10626           (match_operator:SF 3 "binary_float_operator"
10627             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10628                             (parallel [(const_int 1)]))
10629              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10630                             (parallel [(const_int 1)]))])))]
10631   "TARGET_SHMEDIA_FPU"
10632   "#"
10633   "&& reload_completed"
10634   [(set (match_dup 4) (match_dup 5))]
10635   "
10636 {
10637   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10638   rtx op1 = gen_rtx_REG (SFmode,
10639                          true_regnum (operands[1]) + (1 ^ endian));
10640   rtx op2 = gen_rtx_REG (SFmode,
10641                          true_regnum (operands[2]) + (1 ^ endian));
10642
10643   operands[4] = gen_rtx_REG (SFmode,
10644                              true_regnum (operands[0]) + (1 ^ endian));
10645   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10646 }"
10647   [(set_attr "type" "fparith_media")])
10648
10649 (define_insn "addsf3_i"
10650   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10651         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10652                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10653    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10654   "TARGET_SH2E"
10655   "fadd %2,%0"
10656   [(set_attr "type" "fp")
10657    (set_attr "fp_mode" "single")])
10658
10659 (define_expand "subsf3"
10660   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10661         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10662                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10663   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10664   "
10665 {
10666   if (TARGET_SH2E)
10667     {
10668       expand_sf_binop (&gen_subsf3_i, operands);
10669       DONE;
10670     }
10671 }")
10672
10673 (define_insn "*subsf3_media"
10674   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10676                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10677   "TARGET_SHMEDIA_FPU"
10678   "fsub.s       %1, %2, %0"
10679   [(set_attr "type" "fparith_media")])
10680
10681 (define_insn "subsf3_i"
10682   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10683         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10684                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10685    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10686   "TARGET_SH2E"
10687   "fsub %2,%0"
10688   [(set_attr "type" "fp")
10689    (set_attr "fp_mode" "single")])
10690
10691 (define_expand "mulsf3"
10692   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10693         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10694                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10695   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10696   "")
10697
10698 (define_insn "*mulsf3_media"
10699   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10700         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10701                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10702   "TARGET_SHMEDIA_FPU"
10703   "fmul.s       %1, %2, %0"
10704   [(set_attr "type" "fparith_media")])
10705
10706 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10707 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10708 ;; we start out with a mulsf pattern that does not depend on fpscr.
10709 ;; This is split after combine to introduce the dependency, in order to
10710 ;; get mode switching and scheduling right.
10711 (define_insn_and_split "mulsf3_ie"
10712   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10713         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10714                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10715   "TARGET_SH2E"
10716   "fmul %2,%0"
10717   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10718   [(const_int 0)]
10719   "
10720 {
10721   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10722              get_fpscr_rtx ()));
10723   DONE;
10724 }"
10725   [(set_attr "type" "fp")])
10726
10727 (define_insn "mulsf3_i4"
10728   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10729         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10730                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10731    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10732   "TARGET_SH2E"
10733   "fmul %2,%0"
10734   [(set_attr "type" "fp")
10735    (set_attr "fp_mode" "single")])
10736
10737 (define_insn "mac_media"
10738   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10739         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10740                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10741                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10742   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10743   "fmac.s %1, %2, %0"
10744   [(set_attr "type" "fparith_media")])
10745
10746 (define_insn "*macsf3"
10747   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10748         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10749                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10750                  (match_operand:SF 3 "arith_reg_operand" "0")))
10751    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10752   "TARGET_SH2E && TARGET_FMAC"
10753   "fmac fr0,%2,%0"
10754   [(set_attr "type" "fp")
10755    (set_attr "fp_mode" "single")])
10756
10757 (define_expand "divsf3"
10758   [(set (match_operand:SF 0 "arith_reg_operand" "")
10759         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10760                 (match_operand:SF 2 "arith_reg_operand" "")))]
10761   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10762   "
10763 {
10764   if (TARGET_SH2E)
10765     {
10766       expand_sf_binop (&gen_divsf3_i, operands);
10767       DONE;
10768     }
10769 }")
10770
10771 (define_insn "*divsf3_media"
10772   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10773         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10774                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10775   "TARGET_SHMEDIA_FPU"
10776   "fdiv.s       %1, %2, %0"
10777   [(set_attr "type" "fdiv_media")])
10778
10779 (define_insn "divsf3_i"
10780   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10781         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10782                  (match_operand:SF 2 "arith_reg_operand" "f")))
10783    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10784   "TARGET_SH2E"
10785   "fdiv %2,%0"
10786   [(set_attr "type" "fdiv")
10787    (set_attr "fp_mode" "single")])
10788
10789 (define_insn "floatdisf2"
10790   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10791         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10792   "TARGET_SHMEDIA_FPU"
10793   "float.qs %1, %0"
10794   [(set_attr "type" "fpconv_media")])
10795
10796 (define_expand "floatsisf2"
10797   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10798         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10799   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10800   "
10801 {
10802   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10803     {
10804       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10805       DONE;
10806     }
10807 }")
10808
10809 (define_insn "*floatsisf2_media"
10810   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10811         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10812   "TARGET_SHMEDIA_FPU"
10813   "float.ls     %1, %0"
10814   [(set_attr "type" "fpconv_media")])
10815
10816 (define_insn "floatsisf2_i4"
10817   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10818         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10819    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10820   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10821   "float        %1,%0"
10822   [(set_attr "type" "fp")
10823    (set_attr "fp_mode" "single")])
10824
10825 (define_insn "*floatsisf2_ie"
10826   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10827         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10828   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10829   "float        %1,%0"
10830   [(set_attr "type" "fp")])
10831
10832 (define_insn "fix_truncsfdi2"
10833   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10834         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10835   "TARGET_SHMEDIA_FPU"
10836   "ftrc.sq %1, %0"
10837   [(set_attr "type" "fpconv_media")])
10838
10839 (define_expand "fix_truncsfsi2"
10840   [(set (match_operand:SI 0 "fpul_operand" "=y")
10841         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10842   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10843   "
10844 {
10845   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10846     {
10847       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10848       DONE;
10849     }
10850 }")
10851
10852 (define_insn "*fix_truncsfsi2_media"
10853   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10854         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10855   "TARGET_SHMEDIA_FPU"
10856   "ftrc.sl      %1, %0"
10857   [(set_attr "type" "fpconv_media")])
10858
10859 (define_insn "fix_truncsfsi2_i4"
10860   [(set (match_operand:SI 0 "fpul_operand" "=y")
10861         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10862    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10863   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10864   "ftrc %1,%0"
10865   [(set_attr "type" "ftrc_s")
10866    (set_attr "fp_mode" "single")])
10867
10868 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10869 ;; fix_truncsfsi2_i4.
10870 ;; (define_insn "fix_truncsfsi2_i4_2"
10871 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10872 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10873 ;;   (use (reg:PSI FPSCR_REG))
10874 ;;   (clobber (reg:SI FPUL_REG))]
10875 ;;  "TARGET_SH4"
10876 ;;  "#"
10877 ;;  [(set_attr "length" "4")
10878 ;;   (set_attr "fp_mode" "single")])
10879
10880 ;;(define_split
10881 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10882 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10883 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10884 ;;   (clobber (reg:SI FPUL_REG))]
10885 ;;  "TARGET_SH4"
10886 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10887 ;;            (use (match_dup 2))])
10888 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10889
10890 (define_insn "*fixsfsi"
10891   [(set (match_operand:SI 0 "fpul_operand" "=y")
10892         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10893   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10894   "ftrc %1,%0"
10895   [(set_attr "type" "fp")])
10896
10897 (define_insn "cmpgtsf_t"
10898   [(set (reg:SI T_REG)
10899         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10900                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10901   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10902   "fcmp/gt      %1,%0"
10903   [(set_attr "type" "fp_cmp")
10904    (set_attr "fp_mode" "single")])
10905
10906 (define_insn "cmpeqsf_t"
10907   [(set (reg:SI T_REG)
10908         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10909                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10910   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10911   "fcmp/eq      %1,%0"
10912   [(set_attr "type" "fp_cmp")
10913    (set_attr "fp_mode" "single")])
10914
10915 (define_insn "ieee_ccmpeqsf_t"
10916   [(set (reg:SI T_REG)
10917         (ior:SI (reg:SI T_REG)
10918                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10919                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10920   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10921   "* return output_ieee_ccmpeq (insn, operands);"
10922   [(set_attr "length" "4")])
10923
10924
10925 (define_insn "cmpgtsf_t_i4"
10926   [(set (reg:SI T_REG)
10927         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10928                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10929    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10930   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10931   "fcmp/gt      %1,%0"
10932   [(set_attr "type" "fp_cmp")
10933    (set_attr "fp_mode" "single")])
10934
10935 (define_insn "cmpeqsf_t_i4"
10936   [(set (reg:SI T_REG)
10937         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10938                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10939    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10940   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10941   "fcmp/eq      %1,%0"
10942   [(set_attr "type" "fp_cmp")
10943    (set_attr "fp_mode" "single")])
10944
10945 (define_insn "*ieee_ccmpeqsf_t_4"
10946   [(set (reg:SI T_REG)
10947         (ior:SI (reg:SI T_REG)
10948                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10949                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10950    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10951   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10952   "* return output_ieee_ccmpeq (insn, operands);"
10953   [(set_attr "length" "4")
10954    (set_attr "fp_mode" "single")])
10955
10956 (define_insn "cmpeqsf_media"
10957   [(set (match_operand:SI 0 "register_operand" "=r")
10958         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10959                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10960   "TARGET_SHMEDIA_FPU"
10961   "fcmpeq.s     %1, %2, %0"
10962   [(set_attr "type" "fcmp_media")])
10963
10964 (define_insn "cmpgtsf_media"
10965   [(set (match_operand:SI 0 "register_operand" "=r")
10966         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10967                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10968   "TARGET_SHMEDIA_FPU"
10969   "fcmpgt.s     %1, %2, %0"
10970   [(set_attr "type" "fcmp_media")])
10971
10972 (define_insn "cmpgesf_media"
10973   [(set (match_operand:SI 0 "register_operand" "=r")
10974         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10975                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10976   "TARGET_SHMEDIA_FPU"
10977   "fcmpge.s     %1, %2, %0"
10978   [(set_attr "type" "fcmp_media")])
10979
10980 (define_insn "cmpunsf_media"
10981   [(set (match_operand:SI 0 "register_operand" "=r")
10982         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10983                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10984   "TARGET_SHMEDIA_FPU"
10985   "fcmpun.s     %1, %2, %0"
10986   [(set_attr "type" "fcmp_media")])
10987
10988 (define_expand "cmpsf"
10989   [(set (reg:SI T_REG)
10990         (compare (match_operand:SF 0 "arith_operand" "")
10991                  (match_operand:SF 1 "arith_operand" "")))]
10992   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10993   "
10994 {
10995   sh_compare_op0 = operands[0];
10996   sh_compare_op1 = operands[1];
10997   DONE;
10998 }")
10999
11000 (define_expand "negsf2"
11001   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11002         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11003   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11004   "
11005 {
11006   if (TARGET_SH2E)
11007     {
11008       expand_sf_unop (&gen_negsf2_i, operands);
11009       DONE;
11010     }
11011 }")
11012
11013 (define_insn "*negsf2_media"
11014   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11015         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11016   "TARGET_SHMEDIA_FPU"
11017   "fneg.s       %1, %0"
11018   [(set_attr "type" "fmove_media")])
11019
11020 (define_insn "negsf2_i"
11021   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11022         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11023    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11024   "TARGET_SH2E"
11025   "fneg %0"
11026   [(set_attr "type" "fmove")
11027    (set_attr "fp_mode" "single")])
11028
11029 (define_expand "sqrtsf2"
11030   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11031         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11032   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
11033   "
11034 {
11035   if (TARGET_SH3E)
11036     {
11037       expand_sf_unop (&gen_sqrtsf2_i, operands);
11038       DONE;
11039     }
11040 }")
11041
11042 (define_insn "*sqrtsf2_media"
11043   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11044         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11045   "TARGET_SHMEDIA_FPU"
11046   "fsqrt.s      %1, %0"
11047   [(set_attr "type" "fdiv_media")])
11048
11049 (define_insn "sqrtsf2_i"
11050   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11051         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11052    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11053   "TARGET_SH3E"
11054   "fsqrt        %0"
11055   [(set_attr "type" "fdiv")
11056    (set_attr "fp_mode" "single")])
11057
11058 (define_insn "rsqrtsf2"
11059   [(set (match_operand:SF 0 "register_operand" "=f")
11060         (div:SF (match_operand:SF 1 "immediate_operand" "i")
11061                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
11062    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11063   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11064    && operands[1] == CONST1_RTX (SFmode)"
11065   "fsrra        %0"
11066   [(set_attr "type" "fsrra")
11067    (set_attr "fp_mode" "single")])
11068
11069 (define_insn "fsca"
11070   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11071         (vec_concat:V2SF
11072          (unspec:SF [(mult:SF
11073                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
11074                       (match_operand:SF 2 "immediate_operand" "i"))
11075                     ] UNSPEC_FSINA)
11076          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
11077                     ] UNSPEC_FCOSA)))
11078    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11079   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11080    && operands[2] == sh_fsca_int2sf ()"
11081   "fsca fpul,%d0"
11082   [(set_attr "type" "fsca")
11083    (set_attr "fp_mode" "single")])
11084
11085 (define_expand "sinsf2"
11086   [(set (match_operand:SF 0 "nonimmediate_operand" "")
11087         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11088                    UNSPEC_FSINA))]
11089   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11090   "
11091 {
11092   rtx scaled = gen_reg_rtx (SFmode);
11093   rtx truncated = gen_reg_rtx (SImode);
11094   rtx fsca = gen_reg_rtx (V2SFmode);
11095   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11096
11097   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11098   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11099   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11100                           get_fpscr_rtx ()));
11101   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
11102   DONE;
11103 }")
11104
11105 (define_expand "cossf2"
11106   [(set (match_operand:SF 0 "nonimmediate_operand" "")
11107         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11108                    UNSPEC_FCOSA))]
11109   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11110   "
11111 {
11112   rtx scaled = gen_reg_rtx (SFmode);
11113   rtx truncated = gen_reg_rtx (SImode);
11114   rtx fsca = gen_reg_rtx (V2SFmode);
11115   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11116
11117   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11118   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11119   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11120                           get_fpscr_rtx ()));
11121   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
11122   DONE;
11123 }")
11124
11125 (define_expand "sindf2"
11126   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11127         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11128                    UNSPEC_FSINA))]
11129   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11130   "
11131 {
11132   rtx scaled = gen_reg_rtx (DFmode);
11133   rtx truncated = gen_reg_rtx (SImode);
11134   rtx fsca = gen_reg_rtx (V2SFmode);
11135   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11136   rtx sfresult = gen_reg_rtx (SFmode);
11137
11138   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11139   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11140   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11141                           get_fpscr_rtx ()));
11142   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11143   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11144   DONE;
11145 }")
11146
11147 (define_expand "cosdf2"
11148   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11149         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11150                    UNSPEC_FCOSA))]
11151   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11152   "
11153 {
11154   rtx scaled = gen_reg_rtx (DFmode);
11155   rtx truncated = gen_reg_rtx (SImode);
11156   rtx fsca = gen_reg_rtx (V2SFmode);
11157   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11158   rtx sfresult = gen_reg_rtx (SFmode);
11159
11160   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11161   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11162   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11163                           get_fpscr_rtx ()));
11164   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11165   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11166   DONE;
11167 }")
11168
11169 (define_expand "abssf2"
11170   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11171         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11172   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11173   "
11174 {
11175   if (TARGET_SH2E)
11176     {
11177       expand_sf_unop (&gen_abssf2_i, operands);
11178       DONE;
11179     }
11180 }")
11181
11182 (define_insn "*abssf2_media"
11183   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11184         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11185   "TARGET_SHMEDIA_FPU"
11186   "fabs.s       %1, %0"
11187   [(set_attr "type" "fmove_media")])
11188
11189 (define_insn "abssf2_i"
11190   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11191         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11192    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11193   "TARGET_SH2E"
11194   "fabs %0"
11195   [(set_attr "type" "fmove")
11196    (set_attr "fp_mode" "single")])
11197
11198 (define_expand "adddf3"
11199   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11200         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11201                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11202   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11203   "
11204 {
11205   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11206     {
11207       expand_df_binop (&gen_adddf3_i, operands);
11208       DONE;
11209     }
11210 }")
11211
11212 (define_insn "*adddf3_media"
11213   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11214         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11215                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11216   "TARGET_SHMEDIA_FPU"
11217   "fadd.d       %1, %2, %0"
11218   [(set_attr "type" "dfparith_media")])
11219
11220 (define_insn "adddf3_i"
11221   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11222         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11223                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11224    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11225   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11226   "fadd %2,%0"
11227   [(set_attr "type" "dfp_arith")
11228    (set_attr "fp_mode" "double")])
11229
11230 (define_expand "subdf3"
11231   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11232         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11233                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11234   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11235   "
11236 {
11237   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11238     {
11239       expand_df_binop (&gen_subdf3_i, operands);
11240       DONE;
11241     }
11242 }")
11243
11244 (define_insn "*subdf3_media"
11245   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11246         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11247                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11248   "TARGET_SHMEDIA_FPU"
11249   "fsub.d       %1, %2, %0"
11250   [(set_attr "type" "dfparith_media")])
11251
11252 (define_insn "subdf3_i"
11253   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11254         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11255                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11256    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11257   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11258   "fsub %2,%0"
11259   [(set_attr "type" "dfp_arith")
11260    (set_attr "fp_mode" "double")])
11261
11262 (define_expand "muldf3"
11263   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11264         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11265                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11266   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11267   "
11268 {
11269   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11270     {
11271       expand_df_binop (&gen_muldf3_i, operands);
11272       DONE;
11273     }
11274 }")
11275
11276 (define_insn "*muldf3_media"
11277   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11278         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11279                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11280   "TARGET_SHMEDIA_FPU"
11281   "fmul.d       %1, %2, %0"
11282   [(set_attr "type" "dfmul_media")])
11283
11284 (define_insn "muldf3_i"
11285   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11286         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11287                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11288    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11289   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11290   "fmul %2,%0"
11291   [(set_attr "type" "dfp_mul")
11292    (set_attr "fp_mode" "double")])
11293
11294 (define_expand "divdf3"
11295   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11296         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11297                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11298   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11299   "
11300 {
11301   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11302     {
11303       expand_df_binop (&gen_divdf3_i, operands);
11304       DONE;
11305     }
11306 }")
11307
11308 (define_insn "*divdf3_media"
11309   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11310         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11311                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11312   "TARGET_SHMEDIA_FPU"
11313   "fdiv.d       %1, %2, %0"
11314   [(set_attr "type" "dfdiv_media")])
11315
11316 (define_insn "divdf3_i"
11317   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11318         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11319                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11320    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11321   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11322   "fdiv %2,%0"
11323   [(set_attr "type" "dfdiv")
11324    (set_attr "fp_mode" "double")])
11325
11326 (define_insn "floatdidf2"
11327   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11328         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11329   "TARGET_SHMEDIA_FPU"
11330   "float.qd     %1, %0"
11331   [(set_attr "type" "dfpconv_media")])
11332
11333 (define_expand "floatsidf2"
11334   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11335         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11336   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11337   "
11338 {
11339   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11340     {
11341       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11342                                       get_fpscr_rtx ()));
11343       DONE;
11344     }
11345 }")
11346
11347 (define_insn "*floatsidf2_media"
11348   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11349         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11350   "TARGET_SHMEDIA_FPU"
11351   "float.ld     %1, %0"
11352   [(set_attr "type" "dfpconv_media")])
11353
11354 (define_insn "floatsidf2_i"
11355   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11356         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11357    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11358   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11359   "float        %1,%0"
11360   [(set_attr "type" "dfp_conv")
11361    (set_attr "fp_mode" "double")])
11362
11363 (define_insn "fix_truncdfdi2"
11364   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11365         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11366   "TARGET_SHMEDIA_FPU"
11367   "ftrc.dq      %1, %0"
11368   [(set_attr "type" "dfpconv_media")])
11369
11370 (define_expand "fix_truncdfsi2"
11371   [(set (match_operand:SI 0 "fpul_operand" "")
11372         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11373   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11374   "
11375 {
11376   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11377     {
11378       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11379                                           get_fpscr_rtx ()));
11380       DONE;
11381     }
11382 }")
11383
11384 (define_insn "*fix_truncdfsi2_media"
11385   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11386         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11387   "TARGET_SHMEDIA_FPU"
11388   "ftrc.dl      %1, %0"
11389   [(set_attr "type" "dfpconv_media")])
11390
11391 (define_insn "fix_truncdfsi2_i"
11392   [(set (match_operand:SI 0 "fpul_operand" "=y")
11393         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11394    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11395   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11396   "ftrc %1,%0"
11397   [(set_attr "type" "dfp_conv")
11398    (set_attr "dfp_comp" "no")
11399    (set_attr "fp_mode" "double")])
11400
11401 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
11402 ;; fix_truncdfsi2_i.
11403 ;; (define_insn "fix_truncdfsi2_i4"
11404 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11405 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11406 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11407 ;;    (clobber (reg:SI FPUL_REG))]
11408 ;;   "TARGET_SH4"
11409 ;;   "#"
11410 ;;   [(set_attr "length" "4")
11411 ;;    (set_attr "fp_mode" "double")])
11412 ;;
11413 ;; (define_split
11414 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11415 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11416 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11417 ;;    (clobber (reg:SI FPUL_REG))]
11418 ;;   "TARGET_SH4"
11419 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11420 ;;            (use (match_dup 2))])
11421 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
11422
11423 (define_insn "cmpgtdf_t"
11424   [(set (reg:SI T_REG)
11425         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11426                (match_operand:DF 1 "arith_reg_operand" "f")))
11427    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11428   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11429   "fcmp/gt      %1,%0"
11430   [(set_attr "type" "dfp_cmp")
11431    (set_attr "fp_mode" "double")])
11432
11433 (define_insn "cmpeqdf_t"
11434   [(set (reg:SI T_REG)
11435         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11436                (match_operand:DF 1 "arith_reg_operand" "f")))
11437    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11438   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11439   "fcmp/eq      %1,%0"
11440   [(set_attr "type" "dfp_cmp")
11441    (set_attr "fp_mode" "double")])
11442
11443 (define_insn "*ieee_ccmpeqdf_t"
11444   [(set (reg:SI T_REG)
11445         (ior:SI (reg:SI T_REG)
11446                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11447                        (match_operand:DF 1 "arith_reg_operand" "f"))))
11448    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11449   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11450   "* return output_ieee_ccmpeq (insn, operands);"
11451   [(set_attr "length" "4")
11452    (set_attr "fp_mode" "double")])
11453
11454 (define_insn "cmpeqdf_media"
11455   [(set (match_operand:SI 0 "register_operand" "=r")
11456         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11457                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11458   "TARGET_SHMEDIA_FPU"
11459   "fcmpeq.d     %1,%2,%0"
11460   [(set_attr "type" "fcmp_media")])
11461
11462 (define_insn "cmpgtdf_media"
11463   [(set (match_operand:SI 0 "register_operand" "=r")
11464         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11465                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11466   "TARGET_SHMEDIA_FPU"
11467   "fcmpgt.d     %1,%2,%0"
11468   [(set_attr "type" "fcmp_media")])
11469
11470 (define_insn "cmpgedf_media"
11471   [(set (match_operand:SI 0 "register_operand" "=r")
11472         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11473                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11474   "TARGET_SHMEDIA_FPU"
11475   "fcmpge.d     %1,%2,%0"
11476   [(set_attr "type" "fcmp_media")])
11477
11478 (define_insn "cmpundf_media"
11479   [(set (match_operand:SI 0 "register_operand" "=r")
11480         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11481                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11482   "TARGET_SHMEDIA_FPU"
11483   "fcmpun.d     %1,%2,%0"
11484   [(set_attr "type" "fcmp_media")])
11485
11486 (define_expand "cmpdf"
11487   [(set (reg:SI T_REG)
11488         (compare (match_operand:DF 0 "arith_operand" "")
11489                  (match_operand:DF 1 "arith_operand" "")))]
11490   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11491   "
11492 {
11493   sh_compare_op0 = operands[0];
11494   sh_compare_op1 = operands[1];
11495   DONE;
11496 }")
11497
11498 (define_expand "negdf2"
11499   [(set (match_operand:DF 0 "arith_reg_operand" "")
11500         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11501   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11502   "
11503 {
11504   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11505     {
11506       expand_df_unop (&gen_negdf2_i, operands);
11507       DONE;
11508     }
11509 }")
11510
11511 (define_insn "*negdf2_media"
11512   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11513         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11514   "TARGET_SHMEDIA_FPU"
11515   "fneg.d       %1, %0"
11516   [(set_attr "type" "fmove_media")])
11517
11518 (define_insn "negdf2_i"
11519   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11520         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11521    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11522   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11523   "fneg %0"
11524   [(set_attr "type" "fmove")
11525    (set_attr "fp_mode" "double")])
11526
11527 (define_expand "sqrtdf2"
11528   [(set (match_operand:DF 0 "arith_reg_operand" "")
11529         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11530   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11531   "
11532 {
11533   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11534     {
11535       expand_df_unop (&gen_sqrtdf2_i, operands);
11536       DONE;
11537     }
11538 }")
11539
11540 (define_insn "*sqrtdf2_media"
11541   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11542         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11543   "TARGET_SHMEDIA_FPU"
11544   "fsqrt.d      %1, %0"
11545   [(set_attr "type" "dfdiv_media")])
11546
11547 (define_insn "sqrtdf2_i"
11548   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11549         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11550    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11551   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11552   "fsqrt        %0"
11553   [(set_attr "type" "dfdiv")
11554    (set_attr "fp_mode" "double")])
11555
11556 (define_expand "absdf2"
11557   [(set (match_operand:DF 0 "arith_reg_operand" "")
11558         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11559   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11560   "
11561 {
11562   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11563     {
11564       expand_df_unop (&gen_absdf2_i, operands);
11565       DONE;
11566     }
11567 }")
11568
11569 (define_insn "*absdf2_media"
11570   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11571         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11572   "TARGET_SHMEDIA_FPU"
11573   "fabs.d       %1, %0"
11574   [(set_attr "type" "fmove_media")])
11575
11576 (define_insn "absdf2_i"
11577   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11578         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11579    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11580   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11581   "fabs %0"
11582   [(set_attr "type" "fmove")
11583    (set_attr "fp_mode" "double")])
11584
11585 (define_expand "extendsfdf2"
11586   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11587         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11588   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11589   "
11590 {
11591   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11592     {
11593       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11594                                         get_fpscr_rtx ()));
11595       DONE;
11596     }
11597 }")
11598
11599 (define_insn "*extendsfdf2_media"
11600   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11601         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11602   "TARGET_SHMEDIA_FPU"
11603   "fcnv.sd      %1, %0"
11604   [(set_attr "type" "dfpconv_media")])
11605
11606 (define_insn "extendsfdf2_i4"
11607   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11608         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11609    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11610   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11611   "fcnvsd  %1,%0"
11612   [(set_attr "type" "fp")
11613    (set_attr "fp_mode" "double")])
11614
11615 (define_expand "truncdfsf2"
11616   [(set (match_operand:SF 0 "fpul_operand" "")
11617         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11618   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11619   "
11620 {
11621   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11622     {
11623       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11624                                        get_fpscr_rtx ()));
11625       DONE;
11626     }
11627 }")
11628
11629 (define_insn "*truncdfsf2_media"
11630   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11631         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11632   "TARGET_SHMEDIA_FPU"
11633   "fcnv.ds      %1, %0"
11634   [(set_attr "type" "dfpconv_media")])
11635
11636 (define_insn "truncdfsf2_i4"
11637   [(set (match_operand:SF 0 "fpul_operand" "=y")
11638         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11639    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11640   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11641   "fcnvds  %1,%0"
11642   [(set_attr "type" "fp")
11643    (set_attr "fp_mode" "double")])
11644 \f
11645 ;; Bit field extract patterns.  These give better code for packed bitfields,
11646 ;; because they allow auto-increment addresses to be generated.
11647
11648 (define_expand "insv"
11649   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11650                          (match_operand:SI 1 "immediate_operand" "")
11651                          (match_operand:SI 2 "immediate_operand" ""))
11652         (match_operand:SI 3 "general_operand" ""))]
11653   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11654   "
11655 {
11656   rtx addr_target, orig_address, shift_reg, qi_val;
11657   HOST_WIDE_INT bitsize, size, v = 0;
11658   rtx x = operands[3];
11659
11660   if (TARGET_SH2A && TARGET_BITOPS
11661       && (satisfies_constraint_Sbw (operands[0])
11662           || satisfies_constraint_Sbv (operands[0]))
11663       && satisfies_constraint_M (operands[1])
11664       && satisfies_constraint_K03 (operands[2]))
11665     {
11666       if (satisfies_constraint_N (operands[3]))
11667         {
11668           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11669           DONE;
11670         }
11671       else if (satisfies_constraint_M (operands[3]))
11672         {
11673           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11674           DONE;
11675         }
11676       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11677                 && satisfies_constraint_M (operands[1]))
11678         {
11679           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11680           DONE;
11681         }
11682       else if (REG_P (operands[3])
11683                && satisfies_constraint_M (operands[1]))
11684         {
11685           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11686           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11687           DONE;
11688         }
11689     }
11690   /* ??? expmed doesn't care for non-register predicates.  */
11691   if (! memory_operand (operands[0], VOIDmode)
11692       || ! immediate_operand (operands[1], VOIDmode)
11693       || ! immediate_operand (operands[2], VOIDmode)
11694       || ! general_operand (x, VOIDmode))
11695     FAIL;
11696   /* If this isn't a 16 / 24 / 32 bit field, or if
11697      it doesn't start on a byte boundary, then fail.  */
11698   bitsize = INTVAL (operands[1]);
11699   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11700       || (INTVAL (operands[2]) % 8) != 0)
11701     FAIL;
11702
11703   size = bitsize / 8;
11704   orig_address = XEXP (operands[0], 0);
11705   shift_reg = gen_reg_rtx (SImode);
11706   if (GET_CODE (x) == CONST_INT)
11707     {
11708       v = INTVAL (x);
11709       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11710     }
11711   else
11712     {
11713       emit_insn (gen_movsi (shift_reg, operands[3]));
11714       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11715     }
11716   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11717
11718   operands[0] = replace_equiv_address (operands[0], addr_target);
11719   emit_insn (gen_movqi (operands[0], qi_val));
11720
11721   while (size -= 1)
11722     {
11723       if (GET_CODE (x) == CONST_INT)
11724         qi_val
11725           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11726       else
11727         {
11728           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11729           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11730         }
11731       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11732       emit_insn (gen_movqi (operands[0], qi_val));
11733     }
11734
11735   DONE;
11736 }")
11737
11738 (define_insn "movua"
11739   [(set (match_operand:SI 0 "register_operand" "=z")
11740         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11741                    UNSPEC_MOVUA))]
11742   "TARGET_SH4A_ARCH"
11743   "movua.l      %1,%0"
11744   [(set_attr "type" "movua")])
11745
11746 ;; We shouldn't need this, but cse replaces increments with references
11747 ;; to other regs before flow has a chance to create post_inc
11748 ;; addressing modes, and only postreload's cse_move2add brings the
11749 ;; increments back to a usable form.
11750 (define_peephole2
11751   [(set (match_operand:SI 0 "register_operand" "")
11752         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11753                          (const_int 32) (const_int 0)))
11754    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11755   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11756   [(set (match_operand:SI 0 "register_operand" "")
11757         (sign_extract:SI (mem:SI (post_inc:SI
11758                                   (match_operand:SI 1 "register_operand" "")))
11759                          (const_int 32) (const_int 0)))]
11760   "")
11761
11762 (define_expand "extv"
11763   [(set (match_operand:SI 0 "register_operand" "")
11764         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11765                          (match_operand 2 "const_int_operand" "")
11766                          (match_operand 3 "const_int_operand" "")))]
11767   "TARGET_SH4A_ARCH || TARGET_SH2A"
11768 {
11769   if (TARGET_SH2A && TARGET_BITOPS
11770       && (satisfies_constraint_Sbw (operands[1])
11771           || satisfies_constraint_Sbv (operands[1]))
11772       && satisfies_constraint_M (operands[2])
11773       && satisfies_constraint_K03 (operands[3]))
11774    {
11775       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11776       if (REGNO (operands[0]) != T_REG)
11777         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11778       DONE;
11779    }
11780   if (TARGET_SH4A_ARCH
11781       && INTVAL (operands[2]) == 32
11782       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11783       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11784     {
11785       rtx src = adjust_address (operands[1], BLKmode, 0);
11786       set_mem_size (src, GEN_INT (4));
11787       emit_insn (gen_movua (operands[0], src));
11788       DONE;
11789     }
11790
11791   FAIL;
11792 })
11793
11794 (define_expand "extzv"
11795   [(set (match_operand:SI 0 "register_operand" "")
11796         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11797                          (match_operand 2 "const_int_operand" "")
11798                          (match_operand 3 "const_int_operand" "")))]
11799   "TARGET_SH4A_ARCH || TARGET_SH2A"
11800 {
11801   if (TARGET_SH2A && TARGET_BITOPS
11802       && (satisfies_constraint_Sbw (operands[1])
11803           || satisfies_constraint_Sbv (operands[1]))
11804       && satisfies_constraint_M (operands[2])
11805       && satisfies_constraint_K03 (operands[3]))
11806     {
11807       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11808       if (REGNO (operands[0]) != T_REG)
11809         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11810       DONE;
11811     }
11812   if (TARGET_SH4A_ARCH
11813       && INTVAL (operands[2]) == 32
11814       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11815       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11816     {
11817       rtx src = adjust_address (operands[1], BLKmode, 0);
11818       set_mem_size (src, GEN_INT (4));
11819       emit_insn (gen_movua (operands[0], src));
11820       DONE;
11821     }
11822
11823   FAIL;
11824 })
11825
11826 ;; SH2A instructions for bitwise operations.
11827
11828 ;; Clear a bit in a memory location.
11829 (define_insn "bclr_m2a"
11830   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11831         (and:QI
11832             (not:QI (ashift:QI (const_int 1)
11833                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11834             (match_dup 0)))]
11835   "TARGET_SH2A && TARGET_BITOPS"
11836   "@
11837         bclr.b\\t%1,%0
11838         bclr.b\\t%1,@(0,%t0)"
11839 [(set_attr "length" "4,4")])
11840
11841 (define_insn "bclrmem_m2a"
11842   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11843         (and:QI (match_dup 0)
11844                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11845   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11846   "@
11847         bclr.b\\t%W1,%0
11848         bclr.b\\t%W1,@(0,%t0)"
11849   [(set_attr "length" "4,4")])
11850
11851 ;; Set a bit in a memory location.
11852 (define_insn "bset_m2a"
11853   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11854         (ior:QI
11855             (ashift:QI (const_int 1)
11856                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11857             (match_dup 0)))]
11858   "TARGET_SH2A && TARGET_BITOPS"
11859   "@
11860         bset.b\\t%1,%0
11861         bset.b\\t%1,@(0,%t0)"
11862   [(set_attr "length" "4,4")])
11863
11864 (define_insn "bsetmem_m2a"
11865   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11866         (ior:QI (match_dup 0)
11867                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11868   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11869   "@
11870         bset.b\\t%V1,%0
11871         bset.b\\t%V1,@(0,%t0)"
11872   [(set_attr "length" "4,4")])
11873
11874 ;;; Transfer the contents of the T bit to a specified bit of memory.
11875 (define_insn "bst_m2a"
11876   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11877         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11878             (and:QI
11879                 (not:QI (ashift:QI (const_int 1)
11880                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11881                 (match_dup 0))
11882             (ior:QI
11883                 (ashift:QI (const_int 1) (match_dup 1))
11884                 (match_dup 0))))]
11885   "TARGET_SH2A && TARGET_BITOPS"
11886   "@
11887         bst.b\\t%1,%0
11888         bst.b\\t%1,@(0,%t0)"
11889   [(set_attr "length" "4")])
11890
11891 ;; Store a specified bit of memory in the T bit.
11892 (define_insn "bld_m2a"
11893   [(set (reg:SI T_REG)
11894         (zero_extract:SI
11895             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11896             (const_int 1)
11897             (match_operand 1 "const_int_operand" "K03,K03")))]
11898   "TARGET_SH2A && TARGET_BITOPS"
11899   "@
11900         bld.b\\t%1,%0
11901         bld.b\\t%1,@(0,%t0)"
11902   [(set_attr "length" "4,4")])
11903
11904 ;; Store a specified bit of memory in the T bit.
11905 (define_insn "bldsign_m2a"
11906   [(set (reg:SI T_REG)
11907         (sign_extract:SI
11908             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11909             (const_int 1)
11910             (match_operand 1 "const_int_operand" "K03,K03")))]
11911   "TARGET_SH2A && TARGET_BITOPS"
11912   "@
11913         bld.b\\t%1,%0
11914         bld.b\\t%1,@(0,%t0)"
11915   [(set_attr "length" "4,4")])
11916
11917 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11918 (define_insn "bld_reg"
11919   [(set (reg:SI T_REG)
11920         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11921                          (const_int 1)
11922                          (match_operand 1 "const_int_operand" "K03")))]
11923   "TARGET_SH2A"
11924   "bld\\t%1,%0")
11925
11926 (define_insn "*bld_regqi"
11927   [(set (reg:SI T_REG)
11928         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11929                          (const_int 1)
11930                          (match_operand 1 "const_int_operand" "K03")))]
11931   "TARGET_SH2A"
11932   "bld\\t%1,%0")
11933
11934 ;; Take logical and of a specified bit of memory with the T bit and
11935 ;; store its result in the T bit.
11936 (define_insn "band_m2a"
11937   [(set (reg:SI T_REG)
11938         (and:SI (reg:SI T_REG)
11939                 (zero_extract:SI
11940                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11941                     (const_int 1)
11942                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11943   "TARGET_SH2A && TARGET_BITOPS"
11944   "@
11945         band.b\\t%1,%0
11946         band.b\\t%1,@(0,%t0)"
11947   [(set_attr "length" "4,4")])
11948
11949 (define_insn "bandreg_m2a"
11950   [(set (match_operand:SI 0 "register_operand" "=r,r")
11951         (and:SI (zero_extract:SI
11952                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11953                     (const_int 1)
11954                     (match_operand 2 "const_int_operand" "K03,K03"))
11955                 (match_operand:SI 3 "register_operand" "r,r")))]
11956   "TARGET_SH2A && TARGET_BITOPS"
11957   "@
11958         band.b\\t%2,%1\;movt\\t%0
11959         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11960   [(set_attr "length" "6,6")])
11961
11962 ;; Take logical or of a specified bit of memory with the T bit and
11963 ;; store its result in the T bit.
11964 (define_insn "bor_m2a"
11965   [(set (reg:SI T_REG)
11966         (ior:SI (reg:SI T_REG)
11967                 (zero_extract:SI
11968                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11969                     (const_int 1)
11970                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11971   "TARGET_SH2A && TARGET_BITOPS"
11972   "@
11973         bor.b\\t%1,%0
11974         bor.b\\t%1,@(0,%t0)"
11975   [(set_attr "length" "4,4")])
11976
11977 (define_insn "borreg_m2a"
11978   [(set (match_operand:SI 0 "register_operand" "=r,r")
11979         (ior:SI (zero_extract:SI
11980                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11981                     (const_int 1)
11982                     (match_operand 2 "const_int_operand" "K03,K03"))
11983                 (match_operand:SI 3 "register_operand" "=r,r")))]
11984   "TARGET_SH2A && TARGET_BITOPS"
11985   "@
11986         bor.b\\t%2,%1\;movt\\t%0
11987         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11988   [(set_attr "length" "6,6")])
11989
11990 ;; Take exclusive or of a specified bit of memory with the T bit and
11991 ;; store its result in the T bit.
11992 (define_insn "bxor_m2a"
11993   [(set (reg:SI T_REG)
11994         (xor:SI (reg:SI T_REG)
11995                 (zero_extract:SI
11996                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11997                     (const_int 1)
11998                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11999   "TARGET_SH2A && TARGET_BITOPS"
12000   "@
12001         bxor.b\\t%1,%0
12002         bxor.b\\t%1,@(0,%t0)"
12003   [(set_attr "length" "4,4")])
12004
12005 (define_insn "bxorreg_m2a"
12006   [(set (match_operand:SI 0 "register_operand" "=r,r")
12007         (xor:SI (zero_extract:SI
12008                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12009                     (const_int 1)
12010                     (match_operand 2 "const_int_operand" "K03,K03"))
12011                 (match_operand:SI 3 "register_operand" "=r,r")))]
12012   "TARGET_SH2A && TARGET_BITOPS"
12013   "@
12014         bxor.b\\t%2,%1\;movt\\t%0
12015         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
12016   [(set_attr "length" "6,6")])
12017
12018 \f
12019 ;; -------------------------------------------------------------------------
12020 ;; Peepholes
12021 ;; -------------------------------------------------------------------------
12022 ;; This matches cases where the bit in a memory location is set.
12023 (define_peephole2
12024   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12025         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12026    (set (match_dup 0)
12027         (ior:SI (match_dup 0)
12028         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
12029    (set (match_dup 1)
12030         (match_operand 3 "arith_reg_operand" "r,r"))]
12031   "TARGET_SH2A && TARGET_BITOPS
12032    && satisfies_constraint_Pso (operands[2])
12033    && REGNO (operands[0]) == REGNO (operands[3])"
12034   [(set (match_dup 1)
12035         (ior:QI (match_dup 1)
12036                 (match_dup 2)))]
12037   "")
12038
12039 ;; This matches cases where the bit in a memory location is cleared.
12040 (define_peephole2
12041   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12042         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12043    (set (match_dup 0)
12044         (and:SI (match_dup 0)
12045         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
12046    (set (match_dup 1)
12047         (match_operand 3 "arith_reg_operand" "r,r"))]
12048   "TARGET_SH2A && TARGET_BITOPS
12049    && satisfies_constraint_Psz (operands[2])
12050    && REGNO (operands[0]) == REGNO (operands[3])"
12051   [(set (match_dup 1)
12052         (and:QI (match_dup 1)
12053                 (match_dup 2)))]
12054   "")
12055
12056 ;; This matches cases where a stack pointer increment at the start of the
12057 ;; epilogue combines with a stack slot read loading the return value.
12058
12059 (define_peephole
12060   [(set (match_operand:SI 0 "arith_reg_operand" "")
12061         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
12062    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
12063   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
12064   "mov.l        @%1+,%0")
12065
12066 ;; See the comment on the dt combiner pattern above.
12067
12068 (define_peephole
12069   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12070         (plus:SI (match_dup 0)
12071                  (const_int -1)))
12072    (set (reg:SI T_REG)
12073         (eq:SI (match_dup 0)
12074                (const_int 0)))]
12075   "TARGET_SH2"
12076   "dt   %0")
12077
12078 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
12079 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
12080 ;; reload when the constant is too large for a reg+offset address.
12081
12082 ;; ??? We would get much better code if this was done in reload.  This would
12083 ;; require modifying find_reloads_address to recognize that if the constant
12084 ;; is out-of-range for an immediate add, then we get better code by reloading
12085 ;; the constant into a register than by reloading the sum into a register,
12086 ;; since the former is one instruction shorter if the address does not need
12087 ;; to be offsettable.  Unfortunately this does not work, because there is
12088 ;; only one register, r0, that can be used as an index register.  This register
12089 ;; is also the function return value register.  So, if we try to force reload
12090 ;; to use double-reg addresses, then we end up with some instructions that
12091 ;; need to use r0 twice.  The only way to fix this is to change the calling
12092 ;; convention so that r0 is not used to return values.
12093
12094 (define_peephole
12095   [(set (match_operand:SI 0 "register_operand" "=r")
12096         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12097    (set (mem:SI (match_dup 0))
12098         (match_operand:SI 2 "general_movsrc_operand" ""))]
12099   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12100   "mov.l        %2,@(%0,%1)")
12101
12102 (define_peephole
12103   [(set (match_operand:SI 0 "register_operand" "=r")
12104         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12105    (set (match_operand:SI 2 "general_movdst_operand" "")
12106         (mem:SI (match_dup 0)))]
12107   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12108   "mov.l        @(%0,%1),%2")
12109
12110 (define_peephole
12111   [(set (match_operand:SI 0 "register_operand" "=r")
12112         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12113    (set (mem:HI (match_dup 0))
12114         (match_operand:HI 2 "general_movsrc_operand" ""))]
12115   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12116   "mov.w        %2,@(%0,%1)")
12117
12118 (define_peephole
12119   [(set (match_operand:SI 0 "register_operand" "=r")
12120         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12121    (set (match_operand:HI 2 "general_movdst_operand" "")
12122         (mem:HI (match_dup 0)))]
12123   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12124   "mov.w        @(%0,%1),%2")
12125
12126 (define_peephole
12127   [(set (match_operand:SI 0 "register_operand" "=r")
12128         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12129    (set (mem:QI (match_dup 0))
12130         (match_operand:QI 2 "general_movsrc_operand" ""))]
12131   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12132   "mov.b        %2,@(%0,%1)")
12133
12134 (define_peephole
12135   [(set (match_operand:SI 0 "register_operand" "=r")
12136         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12137    (set (match_operand:QI 2 "general_movdst_operand" "")
12138         (mem:QI (match_dup 0)))]
12139   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12140   "mov.b        @(%0,%1),%2")
12141
12142 (define_peephole
12143   [(set (match_operand:SI 0 "register_operand" "=r")
12144         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12145    (set (mem:SF (match_dup 0))
12146         (match_operand:SF 2 "general_movsrc_operand" ""))]
12147   "TARGET_SH1 && REGNO (operands[0]) == 0
12148    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12149        || (GET_CODE (operands[2]) == SUBREG
12150            && REGNO (SUBREG_REG (operands[2])) < 16))
12151    && reg_unused_after (operands[0], insn)"
12152   "mov.l        %2,@(%0,%1)")
12153
12154 (define_peephole
12155   [(set (match_operand:SI 0 "register_operand" "=r")
12156         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12157    (set (match_operand:SF 2 "general_movdst_operand" "")
12158
12159         (mem:SF (match_dup 0)))]
12160   "TARGET_SH1 && REGNO (operands[0]) == 0
12161    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12162        || (GET_CODE (operands[2]) == SUBREG
12163            && REGNO (SUBREG_REG (operands[2])) < 16))
12164    && reg_unused_after (operands[0], insn)"
12165   "mov.l        @(%0,%1),%2")
12166
12167 (define_peephole
12168   [(set (match_operand:SI 0 "register_operand" "=r")
12169         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12170    (set (mem:SF (match_dup 0))
12171         (match_operand:SF 2 "general_movsrc_operand" ""))]
12172   "TARGET_SH2E && REGNO (operands[0]) == 0
12173    && ((GET_CODE (operands[2]) == REG
12174         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12175        || (GET_CODE (operands[2]) == SUBREG
12176            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12177    && reg_unused_after (operands[0], insn)"
12178   "fmov{.s|}    %2,@(%0,%1)")
12179
12180 (define_peephole
12181   [(set (match_operand:SI 0 "register_operand" "=r")
12182         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12183    (set (match_operand:SF 2 "general_movdst_operand" "")
12184
12185         (mem:SF (match_dup 0)))]
12186   "TARGET_SH2E && REGNO (operands[0]) == 0
12187    && ((GET_CODE (operands[2]) == REG
12188         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12189        || (GET_CODE (operands[2]) == SUBREG
12190            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12191    && reg_unused_after (operands[0], insn)"
12192   "fmov{.s|}    @(%0,%1),%2")
12193
12194 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
12195 (define_insn "sp_switch_1"
12196   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
12197   "TARGET_SH1"
12198   "*
12199 {
12200   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
12201   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
12202   return \"mov r0,r15\";
12203 }"
12204   [(set_attr "length" "10")])
12205
12206 ;; Switch back to the original stack for interrupt functions with the
12207 ;; sp_switch attribute.  */
12208 (define_insn "sp_switch_2"
12209   [(const_int 2)]
12210   "TARGET_SH1"
12211   "mov.l @r15+,r15\;mov.l @r15+,r0"
12212   [(set_attr "length" "4")])
12213
12214 ;; Integer vector moves
12215
12216 (define_expand "movv8qi"
12217   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
12218         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
12219   "TARGET_SHMEDIA"
12220   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
12221
12222 (define_insn "movv8qi_i"
12223   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
12224         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12225   "TARGET_SHMEDIA
12226    && (register_operand (operands[0], V8QImode)
12227        || sh_register_operand (operands[1], V8QImode))"
12228   "@
12229         add     %1, r63, %0
12230         movi    %1, %0
12231         #
12232         ld%M1.q %m1, %0
12233         st%M0.q %m0, %N1"
12234   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12235    (set_attr "length" "4,4,16,4,4")])
12236
12237 (define_split
12238   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
12239         (subreg:V8QI (const_int 0) 0))]
12240   "TARGET_SHMEDIA"
12241   [(set (match_dup 0)
12242         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
12243                             (const_int 0) (const_int 0) (const_int 0)
12244                             (const_int 0) (const_int 0)]))])
12245
12246 (define_split
12247   [(set (match_operand 0 "arith_reg_dest" "")
12248         (match_operand 1 "sh_rep_vec" ""))]
12249   "TARGET_SHMEDIA && reload_completed
12250    && GET_MODE (operands[0]) == GET_MODE (operands[1])
12251    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
12252    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
12253    && (XVECEXP (operands[1], 0, 0) != const0_rtx
12254        || XVECEXP (operands[1], 0, 1) != const0_rtx)
12255    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
12256        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
12257   [(set (match_dup 0) (match_dup 1))
12258    (match_dup 2)]
12259   "
12260 {
12261   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
12262   rtx elt1 = XVECEXP (operands[1], 0, 1);
12263
12264   if (unit_size > 2)
12265     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
12266   else
12267     {
12268       if (unit_size < 2)
12269         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
12270       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
12271     }
12272   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
12273   operands[1] = XVECEXP (operands[1], 0, 0);
12274   if (unit_size < 2)
12275     {
12276       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
12277         operands[1]
12278           = GEN_INT (TARGET_LITTLE_ENDIAN
12279                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
12280                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
12281       else
12282         {
12283           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
12284           operands[1]
12285             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
12286         }
12287     }
12288 }")
12289
12290 (define_split
12291   [(set (match_operand 0 "arith_reg_dest" "")
12292         (match_operand 1 "sh_const_vec" ""))]
12293   "TARGET_SHMEDIA && reload_completed
12294    && GET_MODE (operands[0]) == GET_MODE (operands[1])
12295    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
12296   [(set (match_dup 0) (match_dup 1))]
12297   "
12298 {
12299   rtx v = operands[1];
12300   enum machine_mode new_mode
12301     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
12302
12303   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
12304   operands[1]
12305     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
12306 }")
12307
12308 (define_expand "movv2hi"
12309   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
12310         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
12311   "TARGET_SHMEDIA"
12312   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
12313
12314 (define_insn "movv2hi_i"
12315   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12316         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12317   "TARGET_SHMEDIA
12318    && (register_operand (operands[0], V2HImode)
12319        || sh_register_operand (operands[1], V2HImode))"
12320   "@
12321         add.l   %1, r63, %0
12322         movi    %1, %0
12323         #
12324         ld%M1.l %m1, %0
12325         st%M0.l %m0, %N1"
12326   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12327    (set_attr "length" "4,4,16,4,4")
12328    (set (attr "highpart")
12329         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
12330                (const_string "user")]
12331               (const_string "ignore")))])
12332
12333 (define_expand "movv4hi"
12334   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
12335         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
12336   "TARGET_SHMEDIA"
12337   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
12338
12339 (define_insn "movv4hi_i"
12340   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12341         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12342   "TARGET_SHMEDIA
12343    && (register_operand (operands[0], V4HImode)
12344        || sh_register_operand (operands[1], V4HImode))"
12345   "@
12346         add     %1, r63, %0
12347         movi    %1, %0
12348         #
12349         ld%M1.q %m1, %0
12350         st%M0.q %m0, %N1"
12351   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12352    (set_attr "length" "4,4,16,4,4")
12353    (set_attr "highpart" "depend")])
12354
12355 (define_expand "movv2si"
12356   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
12357         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
12358   "TARGET_SHMEDIA"
12359   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
12360
12361 (define_insn "movv2si_i"
12362   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
12363         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12364   "TARGET_SHMEDIA
12365    && (register_operand (operands[0], V2SImode)
12366        || sh_register_operand (operands[1], V2SImode))"
12367   "@
12368         add     %1, r63, %0
12369         #
12370         #
12371         ld%M1.q %m1, %0
12372         st%M0.q %m0, %N1"
12373   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12374    (set_attr "length" "4,4,16,4,4")
12375    (set_attr "highpart" "depend")])
12376
12377 ;; Multimedia Intrinsics
12378
12379 (define_insn "absv2si2"
12380   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12381         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
12382   "TARGET_SHMEDIA"
12383   "mabs.l       %1, %0"
12384   [(set_attr "type" "mcmp_media")
12385    (set_attr "highpart" "depend")])
12386
12387 (define_insn "absv4hi2"
12388   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12389         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
12390   "TARGET_SHMEDIA"
12391   "mabs.w       %1, %0"
12392   [(set_attr "type" "mcmp_media")
12393    (set_attr "highpart" "depend")])
12394
12395 (define_insn "addv2si3"
12396   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12397         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12398                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12399   "TARGET_SHMEDIA"
12400   "madd.l       %1, %2, %0"
12401   [(set_attr "type" "arith_media")
12402    (set_attr "highpart" "depend")])
12403
12404 (define_insn "addv4hi3"
12405   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12406         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12407                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12408   "TARGET_SHMEDIA"
12409   "madd.w       %1, %2, %0"
12410   [(set_attr "type" "arith_media")
12411    (set_attr "highpart" "depend")])
12412
12413 (define_insn_and_split "addv2hi3"
12414   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12415         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12416                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12417   "TARGET_SHMEDIA"
12418   "#"
12419   "TARGET_SHMEDIA"
12420   [(const_int 0)]
12421   "
12422 {
12423   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12424   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12425   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12426   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12427   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12428
12429   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12430   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12431   DONE;
12432 }"
12433   [(set_attr "highpart" "must_split")])
12434
12435 (define_insn "ssaddv2si3"
12436   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12437         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12438                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12439   "TARGET_SHMEDIA"
12440   "madds.l      %1, %2, %0"
12441   [(set_attr "type" "mcmp_media")
12442    (set_attr "highpart" "depend")])
12443
12444 (define_insn "usaddv8qi3"
12445   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12446         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12447                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12448   "TARGET_SHMEDIA"
12449   "madds.ub     %1, %2, %0"
12450   [(set_attr "type" "mcmp_media")
12451    (set_attr "highpart" "depend")])
12452
12453 (define_insn "ssaddv4hi3"
12454   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12455         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12456                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12457   "TARGET_SHMEDIA"
12458   "madds.w      %1, %2, %0"
12459   [(set_attr "type" "mcmp_media")
12460    (set_attr "highpart" "depend")])
12461
12462 (define_insn "negcmpeqv8qi"
12463   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12464         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12465                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12466   "TARGET_SHMEDIA"
12467   "mcmpeq.b     %N1, %N2, %0"
12468   [(set_attr "type" "mcmp_media")
12469    (set_attr "highpart" "depend")])
12470
12471 (define_insn "negcmpeqv2si"
12472   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12473         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12474                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12475   "TARGET_SHMEDIA"
12476   "mcmpeq.l     %N1, %N2, %0"
12477   [(set_attr "type" "mcmp_media")
12478    (set_attr "highpart" "depend")])
12479
12480 (define_insn "negcmpeqv4hi"
12481   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12482         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12483                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12484   "TARGET_SHMEDIA"
12485   "mcmpeq.w     %N1, %N2, %0"
12486   [(set_attr "type" "mcmp_media")
12487    (set_attr "highpart" "depend")])
12488
12489 (define_insn "negcmpgtuv8qi"
12490   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12491         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12492                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12493   "TARGET_SHMEDIA"
12494   "mcmpgt.ub    %N1, %N2, %0"
12495   [(set_attr "type" "mcmp_media")
12496    (set_attr "highpart" "depend")])
12497
12498 (define_insn "negcmpgtv2si"
12499   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12500         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12501                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12502   "TARGET_SHMEDIA"
12503   "mcmpgt.l     %N1, %N2, %0"
12504   [(set_attr "type" "mcmp_media")
12505    (set_attr "highpart" "depend")])
12506
12507 (define_insn "negcmpgtv4hi"
12508   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12509         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12510                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12511   "TARGET_SHMEDIA"
12512   "mcmpgt.w     %N1, %N2, %0"
12513   [(set_attr "type" "mcmp_media")
12514    (set_attr "highpart" "depend")])
12515
12516 (define_insn "mcmv"
12517   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12518         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12519                         (match_operand:DI 2 "arith_reg_operand" "r"))
12520                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12521                         (not:DI (match_dup 2)))))]
12522   "TARGET_SHMEDIA"
12523   "mcmv %N1, %2, %0"
12524   [(set_attr "type" "arith_media")
12525    (set_attr "highpart" "depend")])
12526
12527 (define_insn "mcnvs_lw"
12528   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12529         (vec_concat:V4HI
12530          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12531          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12532   "TARGET_SHMEDIA"
12533   "mcnvs.lw     %N1, %N2, %0"
12534   [(set_attr "type" "mcmp_media")])
12535
12536 (define_insn "mcnvs_wb"
12537   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12538         (vec_concat:V8QI
12539          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12540          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12541   "TARGET_SHMEDIA"
12542   "mcnvs.wb     %N1, %N2, %0"
12543   [(set_attr "type" "mcmp_media")])
12544
12545 (define_insn "mcnvs_wub"
12546   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12547         (vec_concat:V8QI
12548          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12549          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12550   "TARGET_SHMEDIA"
12551   "mcnvs.wub    %N1, %N2, %0"
12552   [(set_attr "type" "mcmp_media")])
12553
12554 (define_insn "mextr_rl"
12555   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12556         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12557                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12558                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12559                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12560   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12561   "*
12562 {
12563   static char templ[21];
12564
12565   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12566            (int) INTVAL (operands[3]) >> 3);
12567   return templ;
12568 }"
12569   [(set_attr "type" "arith_media")])
12570
12571 (define_insn "*mextr_lr"
12572   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12573         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12574                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12575                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12576                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12577   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12578   "*
12579 {
12580   static char templ[21];
12581
12582   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12583            (int) INTVAL (operands[4]) >> 3);
12584   return templ;
12585 }"
12586   [(set_attr "type" "arith_media")])
12587
12588 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12589 ; vector then varies depending on endianness.
12590 (define_expand "mextr1"
12591   [(match_operand:DI 0 "arith_reg_dest" "")
12592    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12593    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12594   "TARGET_SHMEDIA"
12595   "
12596 {
12597   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12598                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12599   DONE;
12600 }")
12601
12602 (define_expand "mextr2"
12603   [(match_operand:DI 0 "arith_reg_dest" "")
12604    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12605    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12606   "TARGET_SHMEDIA"
12607   "
12608 {
12609   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12610                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12611   DONE;
12612 }")
12613
12614 (define_expand "mextr3"
12615   [(match_operand:DI 0 "arith_reg_dest" "")
12616    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12617    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12618   "TARGET_SHMEDIA"
12619   "
12620 {
12621   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12622                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12623   DONE;
12624 }")
12625
12626 (define_expand "mextr4"
12627   [(match_operand:DI 0 "arith_reg_dest" "")
12628    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12629    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12630   "TARGET_SHMEDIA"
12631   "
12632 {
12633   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12634                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12635   DONE;
12636 }")
12637
12638 (define_expand "mextr5"
12639   [(match_operand:DI 0 "arith_reg_dest" "")
12640    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12641    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12642   "TARGET_SHMEDIA"
12643   "
12644 {
12645   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12646                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12647   DONE;
12648 }")
12649
12650 (define_expand "mextr6"
12651   [(match_operand:DI 0 "arith_reg_dest" "")
12652    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12653    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12654   "TARGET_SHMEDIA"
12655   "
12656 {
12657   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12658                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12659   DONE;
12660 }")
12661
12662 (define_expand "mextr7"
12663   [(match_operand:DI 0 "arith_reg_dest" "")
12664    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12665    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12666   "TARGET_SHMEDIA"
12667   "
12668 {
12669   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12670                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12671   DONE;
12672 }")
12673
12674 (define_expand "mmacfx_wl"
12675   [(match_operand:V2SI 0 "arith_reg_dest" "")
12676    (match_operand:V2HI 1 "extend_reg_operand" "")
12677    (match_operand:V2HI 2 "extend_reg_operand" "")
12678    (match_operand:V2SI 3 "arith_reg_operand" "")]
12679   "TARGET_SHMEDIA"
12680   "
12681 {
12682   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12683                               operands[1], operands[2]));
12684   DONE;
12685 }")
12686
12687 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12688 ;; is depend
12689 (define_insn "mmacfx_wl_i"
12690   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12691         (ss_plus:V2SI
12692          (match_operand:V2SI 1 "arith_reg_operand" "0")
12693          (ss_truncate:V2SI
12694           (ashift:V2DI
12695            (sign_extend:V2DI
12696             (mult:V2SI
12697              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12698              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12699            (const_int 1)))))]
12700   "TARGET_SHMEDIA"
12701   "mmacfx.wl    %2, %3, %0"
12702   [(set_attr "type" "mac_media")
12703    (set_attr "highpart" "depend")])
12704
12705 (define_expand "mmacnfx_wl"
12706   [(match_operand:V2SI 0 "arith_reg_dest" "")
12707    (match_operand:V2HI 1 "extend_reg_operand" "")
12708    (match_operand:V2HI 2 "extend_reg_operand" "")
12709    (match_operand:V2SI 3 "arith_reg_operand" "")]
12710   "TARGET_SHMEDIA"
12711   "
12712 {
12713   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12714                                operands[1], operands[2]));
12715   DONE;
12716 }")
12717
12718 (define_insn "mmacnfx_wl_i"
12719   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12720         (ss_minus:V2SI
12721          (match_operand:V2SI 1 "arith_reg_operand" "0")
12722          (ss_truncate:V2SI
12723           (ashift:V2DI
12724            (sign_extend:V2DI
12725             (mult:V2SI
12726              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12727              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12728            (const_int 1)))))]
12729   "TARGET_SHMEDIA"
12730   "mmacnfx.wl   %2, %3, %0"
12731   [(set_attr "type" "mac_media")
12732    (set_attr "highpart" "depend")])
12733
12734 (define_insn "mulv2si3"
12735   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12736         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12737                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12738   "TARGET_SHMEDIA"
12739   "mmul.l       %1, %2, %0"
12740   [(set_attr "type" "d2mpy_media")
12741    (set_attr "highpart" "depend")])
12742
12743 (define_insn "mulv4hi3"
12744   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12745         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12746                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12747   "TARGET_SHMEDIA"
12748   "mmul.w       %1, %2, %0"
12749   [(set_attr "type" "dmpy_media")
12750    (set_attr "highpart" "depend")])
12751
12752 (define_insn "mmulfx_l"
12753   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12754         (ss_truncate:V2SI
12755          (ashiftrt:V2DI
12756           (mult:V2DI
12757            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12758            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12759           (const_int 31))))]
12760   "TARGET_SHMEDIA"
12761   "mmulfx.l     %1, %2, %0"
12762   [(set_attr "type" "d2mpy_media")
12763    (set_attr "highpart" "depend")])
12764
12765 (define_insn "mmulfx_w"
12766   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12767         (ss_truncate:V4HI
12768          (ashiftrt:V4SI
12769           (mult:V4SI
12770            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12771            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12772           (const_int 15))))]
12773   "TARGET_SHMEDIA"
12774   "mmulfx.w     %1, %2, %0"
12775   [(set_attr "type" "dmpy_media")
12776    (set_attr "highpart" "depend")])
12777
12778 (define_insn "mmulfxrp_w"
12779   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12780         (ss_truncate:V4HI
12781          (ashiftrt:V4SI
12782           (plus:V4SI
12783            (mult:V4SI
12784             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12785             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12786            (const_int 16384))
12787           (const_int 15))))]
12788   "TARGET_SHMEDIA"
12789   "mmulfxrp.w   %1, %2, %0"
12790   [(set_attr "type" "dmpy_media")
12791    (set_attr "highpart" "depend")])
12792
12793
12794 (define_expand "mmulhi_wl"
12795   [(match_operand:V2SI 0 "arith_reg_dest" "")
12796    (match_operand:V4HI 1 "arith_reg_operand" "")
12797    (match_operand:V4HI 2 "arith_reg_operand" "")]
12798   "TARGET_SHMEDIA"
12799   "
12800 {
12801   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12802              (operands[0], operands[1], operands[2]));
12803   DONE;
12804 }")
12805
12806 (define_expand "mmullo_wl"
12807   [(match_operand:V2SI 0 "arith_reg_dest" "")
12808    (match_operand:V4HI 1 "arith_reg_operand" "")
12809    (match_operand:V4HI 2 "arith_reg_operand" "")]
12810   "TARGET_SHMEDIA"
12811   "
12812 {
12813   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12814              (operands[0], operands[1], operands[2]));
12815   DONE;
12816 }")
12817
12818 (define_insn "mmul23_wl"
12819   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12820         (vec_select:V2SI
12821          (mult:V4SI
12822           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12823           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12824          (parallel [(const_int 2) (const_int 3)])))]
12825   "TARGET_SHMEDIA"
12826   "* return (TARGET_LITTLE_ENDIAN
12827              ? \"mmulhi.wl      %1, %2, %0\"
12828              : \"mmullo.wl      %1, %2, %0\");"
12829   [(set_attr "type" "dmpy_media")
12830    (set (attr "highpart")
12831         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12832          (const_string "user")))])
12833
12834 (define_insn "mmul01_wl"
12835   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12836         (vec_select:V2SI
12837          (mult:V4SI
12838           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12839           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12840          (parallel [(const_int 0) (const_int 1)])))]
12841   "TARGET_SHMEDIA"
12842   "* return (TARGET_LITTLE_ENDIAN
12843              ? \"mmullo.wl      %1, %2, %0\"
12844              : \"mmulhi.wl      %1, %2, %0\");"
12845   [(set_attr "type" "dmpy_media")
12846    (set (attr "highpart")
12847         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12848          (const_string "user")))])
12849
12850
12851 (define_expand "mmulsum_wq"
12852   [(match_operand:DI 0 "arith_reg_dest" "")
12853    (match_operand:V4HI 1 "arith_reg_operand" "")
12854    (match_operand:V4HI 2 "arith_reg_operand" "")
12855    (match_operand:DI 3 "arith_reg_operand" "")]
12856   "TARGET_SHMEDIA"
12857   "
12858 {
12859   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12860                                operands[1], operands[2]));
12861   DONE;
12862 }")
12863
12864 (define_insn "mmulsum_wq_i"
12865   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12866         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12867          (plus:DI
12868           (plus:DI
12869            (vec_select:DI
12870             (mult:V4DI
12871              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12872              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12873             (parallel [(const_int 0)]))
12874            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12875                                      (sign_extend:V4DI (match_dup 3)))
12876                           (parallel [(const_int 1)])))
12877           (plus:DI
12878            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12879                                      (sign_extend:V4DI (match_dup 3)))
12880                           (parallel [(const_int 2)]))
12881            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12882                                      (sign_extend:V4DI (match_dup 3)))
12883                           (parallel [(const_int 3)]))))))]
12884   "TARGET_SHMEDIA"
12885   "mmulsum.wq   %2, %3, %0"
12886   [(set_attr "type" "mac_media")])
12887
12888 (define_expand "mperm_w"
12889   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12890    (match_operand:V4HI 1 "arith_reg_operand" "r")
12891    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12892   "TARGET_SHMEDIA"
12893   "
12894 {
12895   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12896              (operands[0], operands[1], operands[2]));
12897   DONE;
12898 }")
12899
12900 ; This use of vec_select isn't exactly correct according to rtl.texi
12901 ; (because not constant), but it seems a straightforward extension.
12902 (define_insn "mperm_w_little"
12903   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12904         (vec_select:V4HI
12905          (match_operand:V4HI 1 "arith_reg_operand" "r")
12906          (parallel
12907           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12908                             (const_int 2) (const_int 0))
12909            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12910            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12911            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12912   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12913   "mperm.w      %1, %N2, %0"
12914   [(set_attr "type" "arith_media")])
12915
12916 (define_insn "mperm_w_big"
12917   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12918         (vec_select:V4HI
12919          (match_operand:V4HI 1 "arith_reg_operand" "r")
12920          (parallel
12921           [(zero_extract:QI (not:QI (match_operand:QI 2
12922                                      "extend_reg_or_0_operand" "rZ"))
12923                             (const_int 2) (const_int 0))
12924            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12925            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12926            (zero_extract:QI (not:QI (match_dup 2))
12927                             (const_int 2) (const_int 6))])))]
12928   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12929   "mperm.w      %1, %N2, %0"
12930   [(set_attr "type" "arith_media")])
12931
12932 (define_insn "mperm_w0"
12933   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12934         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12935                                           "trunc_hi_operand" "r"))))]
12936   "TARGET_SHMEDIA"
12937   "mperm.w      %1, r63, %0"
12938   [(set_attr "type" "arith_media")
12939    (set_attr "highpart" "ignore")])
12940
12941 (define_expand "msad_ubq"
12942   [(match_operand:DI 0 "arith_reg_dest" "")
12943    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12944    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12945    (match_operand:DI 3 "arith_reg_operand" "")]
12946   "TARGET_SHMEDIA"
12947   "
12948 {
12949   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12950                              operands[1], operands[2]));
12951   DONE;
12952 }")
12953
12954 (define_insn "msad_ubq_i"
12955   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12956         (plus:DI
12957          (plus:DI
12958           (plus:DI
12959            (plus:DI
12960             (match_operand:DI 1 "arith_reg_operand" "0")
12961             (abs:DI (vec_select:DI
12962                      (minus:V8DI
12963                       (zero_extend:V8DI
12964                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12965                       (zero_extend:V8DI
12966                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12967                      (parallel [(const_int 0)]))))
12968            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12969                                               (zero_extend:V8DI (match_dup 3)))
12970                                   (parallel [(const_int 1)]))))
12971           (plus:DI
12972            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12973                                               (zero_extend:V8DI (match_dup 3)))
12974                                   (parallel [(const_int 2)])))
12975            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12976                                               (zero_extend:V8DI (match_dup 3)))
12977                                   (parallel [(const_int 3)])))))
12978          (plus:DI
12979           (plus:DI
12980            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12981                                               (zero_extend:V8DI (match_dup 3)))
12982                                   (parallel [(const_int 4)])))
12983            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12984                                               (zero_extend:V8DI (match_dup 3)))
12985                                   (parallel [(const_int 5)]))))
12986           (plus:DI
12987            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12988                                               (zero_extend:V8DI (match_dup 3)))
12989                                   (parallel [(const_int 6)])))
12990            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12991                                               (zero_extend:V8DI (match_dup 3)))
12992                                   (parallel [(const_int 7)])))))))]
12993   "TARGET_SHMEDIA"
12994   "msad.ubq     %N2, %N3, %0"
12995   [(set_attr "type" "mac_media")])
12996
12997 (define_insn "mshalds_l"
12998   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12999         (ss_truncate:V2SI
13000          (ashift:V2DI
13001           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
13002           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13003                   (const_int 31)))))]
13004   "TARGET_SHMEDIA"
13005   "mshalds.l    %1, %2, %0"
13006   [(set_attr "type" "mcmp_media")
13007    (set_attr "highpart" "depend")])
13008
13009 (define_insn "mshalds_w"
13010   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13011         (ss_truncate:V4HI
13012          (ashift:V4SI
13013           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13014           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13015                   (const_int 15)))))]
13016   "TARGET_SHMEDIA"
13017   "mshalds.w    %1, %2, %0"
13018   [(set_attr "type" "mcmp_media")
13019    (set_attr "highpart" "depend")])
13020
13021 (define_insn "ashrv2si3"
13022   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13023         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13024                        (match_operand:DI 2 "arith_reg_operand" "r")))]
13025   "TARGET_SHMEDIA"
13026   "mshard.l     %1, %2, %0"
13027   [(set_attr "type" "arith_media")
13028    (set_attr "highpart" "depend")])
13029
13030 (define_insn "ashrv4hi3"
13031   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13032         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13033                        (match_operand:DI 2 "arith_reg_operand" "r")))]
13034   "TARGET_SHMEDIA"
13035   "mshard.w     %1, %2, %0"
13036   [(set_attr "type" "arith_media")
13037    (set_attr "highpart" "depend")])
13038
13039 (define_insn "mshards_q"
13040   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
13041         (ss_truncate:HI
13042          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
13043                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
13044   "TARGET_SHMEDIA"
13045   "mshards.q    %1, %N2, %0"
13046   [(set_attr "type" "mcmp_media")])
13047
13048 (define_expand "mshfhi_b"
13049   [(match_operand:V8QI 0 "arith_reg_dest" "")
13050    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13051    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13052   "TARGET_SHMEDIA"
13053   "
13054 {
13055   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
13056              (operands[0], operands[1], operands[2]));
13057   DONE;
13058 }")
13059
13060 (define_expand "mshflo_b"
13061   [(match_operand:V8QI 0 "arith_reg_dest" "")
13062    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13063    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13064   "TARGET_SHMEDIA"
13065   "
13066 {
13067   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
13068              (operands[0], operands[1], operands[2]));
13069   DONE;
13070 }")
13071
13072 (define_insn "mshf4_b"
13073   [(set
13074     (match_operand:V8QI 0 "arith_reg_dest" "=r")
13075     (vec_select:V8QI
13076      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13077                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13078      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
13079                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
13080   "TARGET_SHMEDIA"
13081   "* return (TARGET_LITTLE_ENDIAN
13082              ? \"mshfhi.b       %N1, %N2, %0\"
13083              : \"mshflo.b       %N1, %N2, %0\");"
13084   [(set_attr "type" "arith_media")
13085    (set (attr "highpart")
13086         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13087          (const_string "user")))])
13088
13089 (define_insn "mshf0_b"
13090   [(set
13091     (match_operand:V8QI 0 "arith_reg_dest" "=r")
13092     (vec_select:V8QI
13093      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13094                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13095      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
13096                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
13097   "TARGET_SHMEDIA"
13098   "* return (TARGET_LITTLE_ENDIAN
13099              ? \"mshflo.b       %N1, %N2, %0\"
13100              : \"mshfhi.b       %N1, %N2, %0\");"
13101   [(set_attr "type" "arith_media")
13102    (set (attr "highpart")
13103         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13104          (const_string "user")))])
13105
13106 (define_expand "mshfhi_l"
13107   [(match_operand:V2SI 0 "arith_reg_dest" "")
13108    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13109    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13110   "TARGET_SHMEDIA"
13111   "
13112 {
13113   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
13114              (operands[0], operands[1], operands[2]));
13115   DONE;
13116 }")
13117
13118 (define_expand "mshflo_l"
13119   [(match_operand:V2SI 0 "arith_reg_dest" "")
13120    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13121    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13122   "TARGET_SHMEDIA"
13123   "
13124 {
13125   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
13126              (operands[0], operands[1], operands[2]));
13127   DONE;
13128 }")
13129
13130 (define_insn "mshf4_l"
13131   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13132         (vec_select:V2SI
13133          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13134                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13135          (parallel [(const_int 1) (const_int 3)])))]
13136   "TARGET_SHMEDIA"
13137   "* return (TARGET_LITTLE_ENDIAN
13138              ? \"mshfhi.l       %N1, %N2, %0\"
13139              : \"mshflo.l       %N1, %N2, %0\");"
13140   [(set_attr "type" "arith_media")
13141    (set (attr "highpart")
13142         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13143          (const_string "user")))])
13144
13145 (define_insn "mshf0_l"
13146   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13147         (vec_select:V2SI
13148          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13149                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13150          (parallel [(const_int 0) (const_int 2)])))]
13151   "TARGET_SHMEDIA"
13152   "* return (TARGET_LITTLE_ENDIAN
13153              ? \"mshflo.l       %N1, %N2, %0\"
13154              : \"mshfhi.l       %N1, %N2, %0\");"
13155   [(set_attr "type" "arith_media")
13156    (set (attr "highpart")
13157         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13158          (const_string "user")))])
13159
13160 (define_expand "mshfhi_w"
13161   [(match_operand:V4HI 0 "arith_reg_dest" "")
13162    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13163    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13164   "TARGET_SHMEDIA"
13165   "
13166 {
13167   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
13168              (operands[0], operands[1], operands[2]));
13169   DONE;
13170 }")
13171
13172 (define_expand "mshflo_w"
13173   [(match_operand:V4HI 0 "arith_reg_dest" "")
13174    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13175    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13176   "TARGET_SHMEDIA"
13177   "
13178 {
13179   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
13180              (operands[0], operands[1], operands[2]));
13181   DONE;
13182 }")
13183
13184 (define_insn "mshf4_w"
13185   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13186         (vec_select:V4HI
13187          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13188                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13189          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
13190   "TARGET_SHMEDIA"
13191   "* return (TARGET_LITTLE_ENDIAN
13192              ? \"mshfhi.w       %N1, %N2, %0\"
13193              : \"mshflo.w       %N1, %N2, %0\");"
13194   [(set_attr "type" "arith_media")
13195    (set (attr "highpart")
13196         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13197          (const_string "user")))])
13198
13199 (define_insn "mshf0_w"
13200   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13201         (vec_select:V4HI
13202          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13203                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13204          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
13205   "TARGET_SHMEDIA"
13206   "* return (TARGET_LITTLE_ENDIAN
13207              ? \"mshflo.w       %N1, %N2, %0\"
13208              : \"mshfhi.w       %N1, %N2, %0\");"
13209   [(set_attr "type" "arith_media")
13210    (set (attr "highpart")
13211         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13212          (const_string "user")))])
13213
13214 (define_insn "mshflo_w_x"
13215   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13216         (vec_select:V4HI
13217          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
13218                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
13219          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
13220   "TARGET_SHMEDIA"
13221   "mshflo.w     %N1, %N2, %0"
13222   [(set_attr "type" "arith_media")
13223    (set_attr "highpart" "ignore")])
13224
13225 /* These are useful to expand ANDs and as combiner patterns.  */
13226 (define_insn_and_split "mshfhi_l_di"
13227   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
13228         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
13229                              (const_int 32))
13230                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
13231                         (const_int -4294967296))))]
13232   "TARGET_SHMEDIA"
13233   "@
13234         mshfhi.l        %N1, %N2, %0
13235         #"
13236   "TARGET_SHMEDIA && reload_completed
13237    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13238   [(set (match_dup 3) (match_dup 4))
13239    (set (match_dup 5) (match_dup 6))]
13240   "
13241 {
13242   operands[3] = gen_lowpart (SImode, operands[0]);
13243   operands[4] = gen_highpart (SImode, operands[1]);
13244   operands[5] = gen_highpart (SImode, operands[0]);
13245   operands[6] = gen_highpart (SImode, operands[2]);
13246 }"
13247   [(set_attr "type" "arith_media")])
13248
13249 (define_insn "*mshfhi_l_di_rev"
13250   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13251         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13252                         (const_int -4294967296))
13253                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13254                              (const_int 32))))]
13255   "TARGET_SHMEDIA"
13256   "mshfhi.l     %N2, %N1, %0"
13257   [(set_attr "type" "arith_media")])
13258
13259 (define_split
13260   [(set (match_operand:DI 0 "arith_reg_dest" "")
13261         (ior:DI (zero_extend:DI (match_operand:SI 1
13262                                               "extend_reg_or_0_operand" ""))
13263                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
13264                         (const_int -4294967296))))
13265    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
13266   "TARGET_SHMEDIA"
13267   [(const_int 0)]
13268   "
13269 {
13270   emit_insn (gen_ashldi3_media (operands[3],
13271                                 simplify_gen_subreg (DImode, operands[1],
13272                                                      SImode, 0),
13273                                 GEN_INT (32)));
13274   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
13275   DONE;
13276 }")
13277
13278 (define_insn "mshflo_l_di"
13279   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13280         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13281                         (const_int 4294967295))
13282                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13283                            (const_int 32))))]
13284
13285   "TARGET_SHMEDIA"
13286   "mshflo.l     %N1, %N2, %0"
13287   [(set_attr "type" "arith_media")
13288    (set_attr "highpart" "ignore")])
13289
13290 (define_insn "*mshflo_l_di_rev"
13291   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13292         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13293                            (const_int 32))
13294                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13295                         (const_int 4294967295))))]
13296
13297   "TARGET_SHMEDIA"
13298   "mshflo.l     %N2, %N1, %0"
13299   [(set_attr "type" "arith_media")
13300    (set_attr "highpart" "ignore")])
13301
13302 ;; Combiner pattern for trampoline initialization.
13303 (define_insn_and_split "*double_shori"
13304   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13305         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
13306                            (const_int 32))
13307                 (match_operand:DI 2 "const_int_operand" "n")))]
13308   "TARGET_SHMEDIA
13309    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
13310   "#"
13311   "rtx_equal_p (operands[0], operands[1])"
13312   [(const_int 0)]
13313   "
13314 {
13315   HOST_WIDE_INT v = INTVAL (operands[2]);
13316
13317   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
13318   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
13319   DONE;
13320 }"
13321   [(set_attr "highpart" "ignore")])
13322
13323
13324 (define_insn "*mshflo_l_di_x"
13325   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13326         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
13327                                  "rZ"))
13328                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13329                            (const_int 32))))]
13330
13331   "TARGET_SHMEDIA"
13332   "mshflo.l     %N1, %N2, %0"
13333   [(set_attr "type" "arith_media")
13334    (set_attr "highpart" "ignore")])
13335
13336 (define_insn_and_split "concat_v2sf"
13337   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
13338 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
13339         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
13340                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
13341
13342   "TARGET_SHMEDIA"
13343   "@
13344         mshflo.l        %N1, %N2, %0
13345         #
13346         #"
13347   "TARGET_SHMEDIA && reload_completed
13348    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13349   [(set (match_dup 3) (match_dup 1))
13350    (set (match_dup 4) (match_dup 2))]
13351   "
13352 {
13353   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
13354   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
13355 }"
13356   [(set_attr "type" "arith_media")
13357    (set_attr "highpart" "ignore")])
13358
13359 (define_insn "*mshflo_l_di_x_rev"
13360   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13361         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13362                            (const_int 32))
13363                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
13364
13365   "TARGET_SHMEDIA"
13366   "mshflo.l     %N2, %N1, %0"
13367   [(set_attr "type" "arith_media")
13368    (set_attr "highpart" "ignore")])
13369
13370 (define_insn "ashlv2si3"
13371   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13372         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13373                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13374   "TARGET_SHMEDIA"
13375   "mshlld.l     %1, %2, %0"
13376   [(set_attr "type" "arith_media")
13377    (set_attr "highpart" "depend")])
13378
13379 (define_split
13380   [(set (match_operand 0 "any_register_operand" "")
13381         (match_operator 3 "shift_operator"
13382           [(match_operand 1 "any_register_operand" "")
13383            (match_operand 2 "shift_count_reg_operand" "")]))]
13384   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
13385   [(set (match_dup 0) (match_dup 3))]
13386   "
13387 {
13388   rtx count = operands[2];
13389   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
13390
13391   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
13392          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
13393          || GET_CODE (count) == TRUNCATE)
13394     count = XEXP (count, 0);
13395   inner_mode = GET_MODE (count);
13396   count = simplify_gen_subreg (outer_mode, count, inner_mode,
13397                                subreg_lowpart_offset (outer_mode, inner_mode));
13398   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
13399                                 operands[1], count);
13400 }")
13401
13402 (define_insn "ashlv4hi3"
13403   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13404         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13405                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13406   "TARGET_SHMEDIA"
13407   "mshlld.w     %1, %2, %0"
13408   [(set_attr "type" "arith_media")
13409    (set_attr "highpart" "depend")])
13410
13411 (define_insn "lshrv2si3"
13412   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13413         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13414                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13415   "TARGET_SHMEDIA"
13416   "mshlrd.l     %1, %2, %0"
13417   [(set_attr "type" "arith_media")
13418    (set_attr "highpart" "depend")])
13419
13420 (define_insn "lshrv4hi3"
13421   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13422         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13423                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13424   "TARGET_SHMEDIA"
13425   "mshlrd.w     %1, %2, %0"
13426   [(set_attr "type" "arith_media")
13427    (set_attr "highpart" "depend")])
13428
13429 (define_insn "subv2si3"
13430   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13431         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13432                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13433   "TARGET_SHMEDIA"
13434   "msub.l       %N1, %2, %0"
13435   [(set_attr "type" "arith_media")
13436    (set_attr "highpart" "depend")])
13437
13438 (define_insn "subv4hi3"
13439   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13440         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13441                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13442   "TARGET_SHMEDIA"
13443   "msub.w       %N1, %2, %0"
13444   [(set_attr "type" "arith_media")
13445    (set_attr "highpart" "depend")])
13446
13447 (define_insn_and_split "subv2hi3"
13448   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13449         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13450                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13451   "TARGET_SHMEDIA"
13452   "#"
13453   "TARGET_SHMEDIA"
13454   [(const_int 0)]
13455   "
13456 {
13457   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13458   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13459   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13460   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13461   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13462
13463   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13464   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13465   DONE;
13466 }"
13467   [(set_attr "highpart" "must_split")])
13468
13469 (define_insn "sssubv2si3"
13470   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13471         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13472                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13473   "TARGET_SHMEDIA"
13474   "msubs.l      %N1, %2, %0"
13475   [(set_attr "type" "mcmp_media")
13476    (set_attr "highpart" "depend")])
13477
13478 (define_insn "ussubv8qi3"
13479   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13480         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13481                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13482   "TARGET_SHMEDIA"
13483   "msubs.ub     %N1, %2, %0"
13484   [(set_attr "type" "mcmp_media")
13485    (set_attr "highpart" "depend")])
13486
13487 (define_insn "sssubv4hi3"
13488   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13489         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13490                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13491   "TARGET_SHMEDIA"
13492   "msubs.w      %N1, %2, %0"
13493   [(set_attr "type" "mcmp_media")
13494    (set_attr "highpart" "depend")])
13495
13496 ;; Floating Point Intrinsics
13497
13498 (define_insn "fcosa_s"
13499   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13500         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13501                    UNSPEC_FCOSA))]
13502   "TARGET_SHMEDIA"
13503   "fcosa.s      %1, %0"
13504   [(set_attr "type" "atrans_media")])
13505
13506 (define_insn "fsina_s"
13507   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13508         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13509                    UNSPEC_FSINA))]
13510   "TARGET_SHMEDIA"
13511   "fsina.s      %1, %0"
13512   [(set_attr "type" "atrans_media")])
13513
13514 (define_insn "fipr"
13515   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13516         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13517                                                     "fp_arith_reg_operand" "f")
13518                                                    (match_operand:V4SF 2
13519                                                     "fp_arith_reg_operand" "f"))
13520                                          (parallel [(const_int 0)]))
13521                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13522                                          (parallel [(const_int 1)])))
13523                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13524                                          (parallel [(const_int 2)]))
13525                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13526                                          (parallel [(const_int 3)])))))]
13527   "TARGET_SHMEDIA"
13528   "fipr.s       %1, %2, %0"
13529   [(set_attr "type" "fparith_media")])
13530
13531 (define_insn "fsrra_s"
13532   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13533         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13534                    UNSPEC_FSRRA))]
13535   "TARGET_SHMEDIA"
13536   "fsrra.s      %1, %0"
13537   [(set_attr "type" "atrans_media")])
13538
13539 (define_insn "ftrv"
13540   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13541         (plus:V4SF
13542          (plus:V4SF
13543           (mult:V4SF
13544            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13545                             (parallel [(const_int 0) (const_int 5)
13546                                        (const_int 10) (const_int 15)]))
13547            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13548           (mult:V4SF
13549            (vec_select:V4SF (match_dup 1)
13550                             (parallel [(const_int 4) (const_int 9)
13551                                        (const_int 14) (const_int 3)]))
13552            (vec_select:V4SF (match_dup 2)
13553                             (parallel [(const_int 1) (const_int 2)
13554                                        (const_int 3) (const_int 0)]))))
13555          (plus:V4SF
13556           (mult:V4SF
13557            (vec_select:V4SF (match_dup 1)
13558                             (parallel [(const_int 8) (const_int 13)
13559                                        (const_int 2) (const_int 7)]))
13560            (vec_select:V4SF (match_dup 2)
13561                             (parallel [(const_int 2) (const_int 3)
13562                                        (const_int 0) (const_int 1)])))
13563           (mult:V4SF
13564            (vec_select:V4SF (match_dup 1)
13565                             (parallel [(const_int 12) (const_int 1)
13566                                        (const_int 6) (const_int 11)]))
13567            (vec_select:V4SF (match_dup 2)
13568                             (parallel [(const_int 3) (const_int 0)
13569                                        (const_int 1) (const_int 2)]))))))]
13570   "TARGET_SHMEDIA"
13571   "ftrv.s %1, %2, %0"
13572   [(set_attr "type" "fparith_media")])
13573
13574 (define_insn "ldhi_l"
13575   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13576         (zero_extract:SI
13577          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13578                                   (const_int 3))
13579                           (const_int -3)))
13580          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13581          (const_int 0)))]
13582   "TARGET_SHMEDIA32"
13583   "ldhi.l       %U1, %0"
13584   [(set_attr "type" "load_media")])
13585
13586 (define_insn "ldhi_q"
13587   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13588         (zero_extract:DI
13589          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13590                                   (const_int 7))
13591                           (const_int -7)))
13592          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13593          (const_int 0)))]
13594   "TARGET_SHMEDIA32"
13595   "ldhi.q       %U1, %0"
13596   [(set_attr "type" "load_media")])
13597
13598 (define_insn_and_split "*ldhi_q_comb0"
13599   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13600         (zero_extract:DI
13601          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13602                                             "register_operand" "r")
13603                                            (match_operand:SI 2
13604                                             "ua_offset" "I06"))
13605                                   (const_int 7))
13606                           (const_int -7)))
13607          (plus:SI (and:SI (match_dup 1) (const_int 7))
13608                   (const_int 1))
13609          (const_int 0)))]
13610   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13611   "#"
13612   ""
13613   [(pc)]
13614   "emit_insn (gen_ldhi_q (operands[0],
13615                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13616    DONE;")
13617
13618
13619 (define_insn_and_split "*ldhi_q_comb1"
13620   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13621         (zero_extract:DI
13622          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13623                                             "register_operand" "r")
13624                                            (match_operand:SI 2
13625                                             "ua_offset" "I06"))
13626                                   (const_int 7))
13627                           (const_int -7)))
13628          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13629                                                    "ua_offset" "I06"))
13630                           (const_int 7))
13631                   (const_int 1))
13632          (const_int 0)))]
13633   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13634    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13635   "#"
13636   ""
13637   [(pc)]
13638   "emit_insn (gen_ldhi_q (operands[0],
13639                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13640    DONE;")
13641
13642
13643 (define_insn "ldlo_l"
13644   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13645         (zero_extract:SI
13646          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13647                          (const_int -4)))
13648          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13649          (and:SI (match_dup 1) (const_int 3))))]
13650   "TARGET_SHMEDIA32"
13651   "ldlo.l       %U1, %0"
13652   [(set_attr "type" "load_media")])
13653
13654 (define_insn "ldlo_q"
13655   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13656         (zero_extract:DI
13657          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13658                          (const_int -8)))
13659          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13660          (and:SI (match_dup 1) (const_int 7))))]
13661   "TARGET_SHMEDIA32"
13662   "ldlo.q       %U1, %0"
13663   [(set_attr "type" "load_media")])
13664
13665 (define_insn_and_split "*ldlo_q_comb0"
13666   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13667         (zero_extract:DI
13668          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13669                                   (match_operand:SI 2 "ua_offset" "I06"))
13670                          (const_int -8)))
13671          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13672          (and:SI (match_dup 1) (const_int 7))))]
13673   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13674   "#"
13675   ""
13676   [(pc)]
13677   "emit_insn (gen_ldlo_q (operands[0],
13678                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13679    DONE;")
13680
13681 (define_insn_and_split "*ldlo_q_comb1"
13682   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13683         (zero_extract:DI
13684          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13685                                   (match_operand:SI 2 "ua_offset" "I06"))
13686                          (const_int -8)))
13687          (minus:SI (const_int 8)
13688                    (and:SI (plus:SI (match_dup 1)
13689                                     (match_operand:SI 3 "ua_offset" "I06"))
13690                            (const_int 7)))
13691          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13692   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13693    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13694   "#"
13695   ""
13696   [(pc)]
13697   "emit_insn (gen_ldlo_q (operands[0],
13698                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13699    DONE;")
13700
13701 (define_insn "sthi_l"
13702   [(set (zero_extract:SI
13703          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13704                                   (const_int 3))
13705                           (const_int -3)))
13706          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13707          (const_int 0))
13708         (match_operand:SI 1 "arith_reg_operand" "r"))]
13709   "TARGET_SHMEDIA32"
13710   "sthi.l       %U0, %1"
13711   [(set_attr "type" "ustore_media")])
13712
13713 ;; All unaligned stores are considered to be 'narrow' because they typically
13714 ;; operate on less that a quadword, and when they operate on a full quadword,
13715 ;; the vanilla store high / store low sequence will cause a stall if not
13716 ;; scheduled apart.
13717 (define_insn "sthi_q"
13718   [(set (zero_extract:DI
13719          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13720                                   (const_int 7))
13721                           (const_int -7)))
13722          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13723          (const_int 0))
13724         (match_operand:DI 1 "arith_reg_operand" "r"))]
13725   "TARGET_SHMEDIA32"
13726   "sthi.q       %U0, %1"
13727   [(set_attr "type" "ustore_media")])
13728
13729 (define_insn_and_split "*sthi_q_comb0"
13730   [(set (zero_extract:DI
13731          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13732                                             "register_operand" "r")
13733                                            (match_operand:SI 1 "ua_offset"
13734                                             "I06"))
13735                                   (const_int 7))
13736                           (const_int -7)))
13737          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13738          (const_int 0))
13739         (match_operand:DI 2 "arith_reg_operand" "r"))]
13740   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13741   "#"
13742   ""
13743   [(pc)]
13744   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13745                           operands[2]));
13746    DONE;")
13747
13748 (define_insn_and_split "*sthi_q_comb1"
13749   [(set (zero_extract:DI
13750          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13751                                             "register_operand" "r")
13752                                            (match_operand:SI 1 "ua_offset"
13753                                             "I06"))
13754                                   (const_int 7))
13755                           (const_int -7)))
13756          (plus:SI (and:SI (plus:SI (match_dup 0)
13757                                    (match_operand:SI 2 "ua_offset" "I06"))
13758                           (const_int 7))
13759                   (const_int 1))
13760          (const_int 0))
13761         (match_operand:DI 3 "arith_reg_operand" "r"))]
13762   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13763    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13764   "#"
13765   ""
13766   [(pc)]
13767   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13768                           operands[3]));
13769    DONE;")
13770
13771 ;; This is highpart user because the address is used as full 64 bit.
13772 (define_insn "stlo_l"
13773   [(set (zero_extract:SI
13774          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13775                          (const_int -4)))
13776          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13777          (and:SI (match_dup 0) (const_int 3)))
13778         (match_operand:SI 1 "arith_reg_operand" "r"))]
13779   "TARGET_SHMEDIA32"
13780   "stlo.l       %U0, %1"
13781   [(set_attr "type" "ustore_media")])
13782
13783 (define_insn "stlo_q"
13784   [(set (zero_extract:DI
13785          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13786                          (const_int -8)))
13787          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13788          (and:SI (match_dup 0) (const_int 7)))
13789         (match_operand:DI 1 "arith_reg_operand" "r"))]
13790   "TARGET_SHMEDIA32"
13791   "stlo.q       %U0, %1"
13792   [(set_attr "type" "ustore_media")])
13793
13794 (define_insn_and_split "*stlo_q_comb0"
13795   [(set (zero_extract:DI
13796          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13797                                   (match_operand:SI 1 "ua_offset" "I06"))
13798                          (const_int -8)))
13799          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13800          (and:SI (match_dup 0) (const_int 7)))
13801         (match_operand:DI 2 "arith_reg_operand" "r"))]
13802   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13803   "#"
13804   ""
13805   [(pc)]
13806   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13807                           operands[2]));
13808    DONE;")
13809
13810 (define_insn_and_split "*stlo_q_comb1"
13811   [(set (zero_extract:DI
13812          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13813                                   (match_operand:SI 1 "ua_offset" "I06"))
13814                          (const_int -8)))
13815          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13816                                                   (match_operand:SI 2
13817                                                    "ua_offset" "I06"))
13818                                          (const_int 7)))
13819          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13820         (match_operand:DI 3 "arith_reg_operand" "r"))]
13821   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13822   "#"
13823   ""
13824   [(pc)]
13825   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13826                           operands[3]));
13827    DONE;")
13828
13829 (define_insn "ldhi_l64"
13830   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13831         (zero_extract:SI
13832          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13833                                   (const_int 3))
13834                           (const_int -3)))
13835          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13836          (const_int 0)))]
13837   "TARGET_SHMEDIA64"
13838   "ldhi.l       %U1, %0"
13839   [(set_attr "type" "load_media")])
13840
13841 (define_insn "ldhi_q64"
13842   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13843         (zero_extract:DI
13844          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13845                                   (const_int 7))
13846                           (const_int -7)))
13847          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13848          (const_int 0)))]
13849   "TARGET_SHMEDIA64"
13850   "ldhi.q       %U1, %0"
13851   [(set_attr "type" "load_media")])
13852
13853 (define_insn "ldlo_l64"
13854   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13855         (zero_extract:SI
13856          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13857                          (const_int -4)))
13858          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13859          (and:DI (match_dup 1) (const_int 3))))]
13860   "TARGET_SHMEDIA64"
13861   "ldlo.l       %U1, %0"
13862   [(set_attr "type" "load_media")])
13863
13864 (define_insn "ldlo_q64"
13865   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13866         (zero_extract:DI
13867          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13868                          (const_int -8)))
13869          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13870          (and:DI (match_dup 1) (const_int 7))))]
13871   "TARGET_SHMEDIA64"
13872   "ldlo.q       %U1, %0"
13873   [(set_attr "type" "load_media")])
13874
13875 (define_insn "sthi_l64"
13876   [(set (zero_extract:SI
13877          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13878                                   (const_int 3))
13879                           (const_int -3)))
13880          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13881          (const_int 0))
13882         (match_operand:SI 1 "arith_reg_operand" "r"))]
13883   "TARGET_SHMEDIA64"
13884   "sthi.l       %U0, %1"
13885   [(set_attr "type" "ustore_media")])
13886
13887 (define_insn "sthi_q64"
13888   [(set (zero_extract:DI
13889          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13890                                   (const_int 7))
13891                           (const_int -7)))
13892          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13893          (const_int 0))
13894         (match_operand:DI 1 "arith_reg_operand" "r"))]
13895   "TARGET_SHMEDIA64"
13896   "sthi.q       %U0, %1"
13897   [(set_attr "type" "ustore_media")])
13898
13899 (define_insn "stlo_l64"
13900   [(set (zero_extract:SI
13901          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13902                          (const_int -4)))
13903          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13904          (and:DI (match_dup 0) (const_int 3)))
13905         (match_operand:SI 1 "arith_reg_operand" "r"))]
13906   "TARGET_SHMEDIA64"
13907   "stlo.l       %U0, %1"
13908   [(set_attr "type" "ustore_media")])
13909
13910 (define_insn "stlo_q64"
13911   [(set (zero_extract:DI
13912          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13913                          (const_int -8)))
13914          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13915          (and:DI (match_dup 0) (const_int 7)))
13916         (match_operand:DI 1 "arith_reg_operand" "r"))]
13917   "TARGET_SHMEDIA64"
13918   "stlo.q       %U0, %1"
13919   [(set_attr "type" "ustore_media")])
13920
13921 (define_insn "nsb"
13922   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13923         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13924                    UNSPEC_NSB))]
13925   "TARGET_SHMEDIA"
13926   "nsb  %1, %0"
13927   [(set_attr "type" "arith_media")])
13928
13929 (define_insn "nsbsi"
13930   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13931         (zero_extend:SI
13932          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13933                     UNSPEC_NSB)))]
13934   "TARGET_SHMEDIA"
13935   "nsb  %1, %0"
13936   [(set_attr "type" "arith_media")])
13937
13938 (define_insn "nsbdi"
13939   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13940         (zero_extend:DI
13941          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13942                     UNSPEC_NSB)))]
13943   "TARGET_SHMEDIA"
13944   "nsb  %1, %0"
13945   [(set_attr "type" "arith_media")])
13946
13947 (define_expand "ffsdi2"
13948   [(set (match_operand:DI 0 "arith_reg_dest" "")
13949         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13950   "TARGET_SHMEDIA"
13951   "
13952 {
13953   rtx scratch = gen_reg_rtx (DImode);
13954   rtx last;
13955
13956   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13957   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13958   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13959   emit_insn (gen_nsbdi (scratch, scratch));
13960   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13961   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13962   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13963   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13964
13965   DONE;
13966 }")
13967
13968 (define_expand "ffssi2"
13969   [(set (match_operand:SI 0 "arith_reg_dest" "")
13970         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13971   "TARGET_SHMEDIA"
13972   "
13973 {
13974   rtx scratch = gen_reg_rtx (SImode);
13975   rtx discratch = gen_reg_rtx (DImode);
13976   rtx last;
13977
13978   emit_insn (gen_adddi3 (discratch,
13979                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13980                          constm1_rtx));
13981   emit_insn (gen_andcdi3 (discratch,
13982                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13983                           discratch));
13984   emit_insn (gen_nsbsi (scratch, discratch));
13985   last = emit_insn (gen_subsi3 (operands[0],
13986                                 force_reg (SImode, GEN_INT (63)), scratch));
13987   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13988
13989   DONE;
13990 }")
13991
13992 (define_insn "byterev"
13993   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13994         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13995                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13996                                     (const_int 4) (const_int 3) (const_int 2)
13997                                     (const_int 1) (const_int 0)])))]
13998   "TARGET_SHMEDIA"
13999   "byterev      %1, %0"
14000   [(set_attr "type" "arith_media")])
14001
14002 (define_insn "*prefetch_media"
14003   [(prefetch (match_operand:QI 0 "address_operand" "p")
14004              (match_operand:SI 1 "const_int_operand" "n")
14005              (match_operand:SI 2 "const_int_operand" "n"))]
14006   "TARGET_SHMEDIA"
14007   "*
14008 {
14009   operands[0] = gen_rtx_MEM (QImode, operands[0]);
14010   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
14011   return \"\";
14012 }"
14013   [(set_attr "type" "other")])
14014
14015 (define_insn "*prefetch_i4"
14016   [(prefetch (match_operand:SI 0 "register_operand" "r")
14017              (match_operand:SI 1 "const_int_operand" "n")
14018              (match_operand:SI 2 "const_int_operand" "n"))]
14019   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
14020   "*
14021 {
14022   return \"pref @%0\";
14023 }"
14024   [(set_attr "type" "other")])
14025
14026 ;; In user mode, the "pref" instruction will raise a RADDERR exception
14027 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
14028 ;; implementation of __builtin_prefetch for VxWorks RTPs.
14029 (define_expand "prefetch"
14030   [(prefetch (match_operand 0 "address_operand" "p")
14031              (match_operand:SI 1 "const_int_operand" "n")
14032              (match_operand:SI 2 "const_int_operand" "n"))]
14033   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
14034    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
14035   "
14036 {
14037   if (GET_MODE (operands[0]) != Pmode
14038       || GET_CODE (operands[1]) != CONST_INT
14039       || GET_CODE (operands[2]) != CONST_INT)
14040     FAIL;
14041   if (! TARGET_SHMEDIA)
14042     operands[0] = force_reg (Pmode, operands[0]);
14043 }")
14044
14045 (define_insn "prefetch_m2a"
14046   [(prefetch (match_operand:SI 0 "register_operand" "r")
14047              (match_operand:SI 1 "const_int_operand" "n")
14048              (match_operand:SI 2 "const_int_operand" "n"))]
14049   "TARGET_SH2A"
14050   "pref\\t@%0"
14051   [(set_attr "type" "other")])
14052
14053 (define_insn "alloco_i"
14054   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
14055         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
14056   "TARGET_SHMEDIA32"
14057   "*
14058 {
14059   rtx xops[2];
14060
14061   if (GET_CODE (operands[0]) == PLUS)
14062     {
14063       xops[0] = XEXP (operands[0], 0);
14064       xops[1] = XEXP (operands[0], 1);
14065     }
14066   else
14067     {
14068       xops[0] = operands[0];
14069       xops[1] = const0_rtx;
14070     }
14071   output_asm_insn (\"alloco   %0, %1\", xops);
14072   return \"\";
14073 }"
14074   [(set_attr "type" "other")])
14075
14076 (define_split
14077   [(set (match_operand 0 "any_register_operand" "")
14078         (match_operand 1 "" ""))]
14079   "TARGET_SHMEDIA && reload_completed"
14080   [(set (match_dup 0) (match_dup 1))]
14081   "
14082 {
14083   int n_changes = 0;
14084
14085   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
14086   if (!n_changes)
14087     FAIL;
14088 }")
14089
14090 ; Stack Protector Patterns
14091
14092 (define_expand "stack_protect_set"
14093   [(set (match_operand 0 "memory_operand" "")
14094         (match_operand 1 "memory_operand" ""))]
14095   ""
14096 {
14097   if (TARGET_SHMEDIA)
14098     {
14099       if (TARGET_SHMEDIA64)
14100         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
14101       else
14102         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
14103     }
14104   else
14105     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
14106
14107   DONE;
14108 })
14109
14110 (define_insn "stack_protect_set_si"
14111   [(set (match_operand:SI 0 "memory_operand" "=m")
14112         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14113    (set (match_scratch:SI 2 "=&r") (const_int 0))]
14114   "!TARGET_SHMEDIA"
14115   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
14116   [(set_attr "type" "other")
14117    (set_attr "length" "6")])
14118
14119 (define_insn "stack_protect_set_si_media"
14120   [(set (match_operand:SI 0 "memory_operand" "=m")
14121         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14122    (set (match_scratch:SI 2 "=&r") (const_int 0))]
14123   "TARGET_SHMEDIA"
14124   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
14125   [(set_attr "type" "other")
14126    (set_attr "length" "12")])
14127
14128 (define_insn "stack_protect_set_di_media"
14129   [(set (match_operand:DI 0 "memory_operand" "=m")
14130         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14131    (set (match_scratch:DI 2 "=&r") (const_int 0))]
14132   "TARGET_SHMEDIA64"
14133   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
14134   [(set_attr "type" "other")
14135    (set_attr "length" "12")])
14136
14137 (define_expand "stack_protect_test"
14138   [(match_operand 0 "memory_operand" "")
14139    (match_operand 1 "memory_operand" "")
14140    (match_operand 2 "" "")]
14141   ""
14142 {
14143   if (TARGET_SHMEDIA)
14144     {
14145       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
14146
14147       if (TARGET_SHMEDIA64)
14148         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
14149                                                     operands[1]));
14150       else
14151         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
14152                                                     operands[1]));
14153
14154       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
14155     }
14156   else
14157     {
14158       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
14159       emit_jump_insn (gen_branch_true (operands[2]));
14160     }
14161
14162   DONE;
14163 })
14164
14165 (define_insn "stack_protect_test_si"
14166   [(set (reg:SI T_REG)
14167         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
14168                     (match_operand:SI 1 "memory_operand" "m")]
14169                    UNSPEC_SP_TEST))
14170   (set (match_scratch:SI 2 "=&r") (const_int 0))
14171   (set (match_scratch:SI 3 "=&r") (const_int 0))]
14172   "!TARGET_SHMEDIA"
14173   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
14174   [(set_attr "type" "other")
14175    (set_attr "length" "10")])
14176
14177 (define_insn "stack_protect_test_si_media"
14178   [(set (match_operand:SI 0 "register_operand" "=&r")
14179         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
14180                     (match_operand:SI 2 "memory_operand" "m")]
14181                    UNSPEC_SP_TEST))
14182   (set (match_scratch:SI 3 "=&r") (const_int 0))]
14183   "TARGET_SHMEDIA"
14184   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14185   [(set_attr "type" "other")
14186    (set_attr "length" "16")])
14187
14188 (define_insn "stack_protect_test_di_media"
14189   [(set (match_operand:DI 0 "register_operand" "=&r")
14190         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
14191                     (match_operand:DI 2 "memory_operand" "m")]
14192                    UNSPEC_SP_TEST))
14193   (set (match_scratch:DI 3 "=&r") (const_int 0))]
14194   "TARGET_SHMEDIA64"
14195   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14196   [(set_attr "type" "other")
14197    (set_attr "length" "16")])