OSDN Git Service

4b53129a419ce0ae3546a27a68d930b9a11ef9bf
[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 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 2, 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 COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146   (UNSPEC_DIV_INV_M0    30)
147   (UNSPEC_DIV_INV_M1    31)
148   (UNSPEC_DIV_INV_M2    32)
149   (UNSPEC_DIV_INV_M3    33)
150   (UNSPEC_DIV_INV20     34)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153
154   ;; These are used with unspec_volatile.
155   (UNSPECV_BLOCKAGE     0)
156   (UNSPECV_ALIGN        1)
157   (UNSPECV_CONST2       2)
158   (UNSPECV_CONST4       4)
159   (UNSPECV_CONST8       6)
160   (UNSPECV_WINDOW_END   10)
161   (UNSPECV_CONST_END    11)
162 ])
163
164 ;; -------------------------------------------------------------------------
165 ;; Attributes
166 ;; -------------------------------------------------------------------------
167
168 ;; Target CPU.
169
170 (define_attr "cpu"
171  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
172   (const (symbol_ref "sh_cpu_attr")))
173
174 (define_attr "endian" "big,little"
175  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
176                       (const_string "little") (const_string "big"))))
177
178 ;; Indicate if the default fpu mode is single precision.
179 (define_attr "fpu_single" "yes,no"
180   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
181                          (const_string "yes") (const_string "no"))))
182
183 (define_attr "fmovd" "yes,no"
184   (const (if_then_else (symbol_ref "TARGET_FMOVD")
185                        (const_string "yes") (const_string "no"))))
186 ;; pipeline model
187 (define_attr "pipe_model" "sh1,sh4,sh5media"
188   (const
189    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
190           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
191          (const_string "sh1"))))
192
193 ;; cbranch      conditional branch instructions
194 ;; jump         unconditional jumps
195 ;; arith        ordinary arithmetic
196 ;; arith3       a compound insn that behaves similarly to a sequence of
197 ;;              three insns of type arith
198 ;; arith3b      like above, but might end with a redirected branch
199 ;; load         from memory
200 ;; load_si      Likewise, SImode variant for general register.
201 ;; fload        Likewise, but load to fp register.
202 ;; store        to memory
203 ;; move         general purpose register to register
204 ;; mt_group     other sh4 mt instructions
205 ;; fmove        register to register, floating point
206 ;; smpy         word precision integer multiply
207 ;; dmpy         longword or doublelongword precision integer multiply
208 ;; return       rts
209 ;; pload        load of pr reg, which can't be put into delay slot of rts
210 ;; prset        copy register to pr reg, ditto
211 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
212 ;; prget        copy pr to register, ditto
213 ;; pcload       pc relative load of constant value
214 ;; pcfload      Likewise, but load to fp register.
215 ;; pcload_si    Likewise, SImode variant for general register.
216 ;; rte          return from exception
217 ;; sfunc        special function call with known used registers
218 ;; call         function call
219 ;; fp           floating point
220 ;; fdiv         floating point divide (or square root)
221 ;; gp_fpul      move from general purpose register to fpul
222 ;; fpul_gp      move from fpul to general purpose register
223 ;; mac_gp       move from mac[lh] to general purpose register
224 ;; dfp_arith, dfp_cmp,dfp_conv
225 ;; ftrc_s       fix_truncsfsi2_i4
226 ;; dfdiv        double precision floating point divide (or square root)
227 ;; cwb          ic_invalidate_line_i
228 ;; movua        SH4a unaligned load
229 ;; fsrra        square root reciprocal approximate
230 ;; fsca         sine and cosine approximate
231 ;; tls_load     load TLS related address
232 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
233 ;; cbranch_media SHmedia conditional branch instructions
234 ;; cmp_media    SHmedia compare instructions
235 ;; dfdiv_media  SHmedia double precision divide and square root
236 ;; dfmul_media  SHmedia double precision multiply instruction
237 ;; dfparith_media SHmedia double precision floating point arithmetic
238 ;; dfpconv_media SHmedia double precision floating point conversions
239 ;; dmpy_media   SHmedia longword multiply
240 ;; fcmp_media   SHmedia floating point compare instructions
241 ;; fdiv_media   SHmedia single precision divide and square root
242 ;; fload_media  SHmedia floating point register load instructions
243 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
244 ;; fparith_media SHmedia single precision floating point arithmetic
245 ;; fpconv_media SHmedia single precision floating point conversions
246 ;; fstore_media SHmedia floating point register store instructions
247 ;; gettr_media  SHmedia gettr instruction
248 ;; invalidate_line_media SHmedia invalidate_line sequence
249 ;; jump_media   SHmedia unconditional branch instructions
250 ;; load_media   SHmedia general register load instructions
251 ;; pt_media     SHmedia pt instruction (expanded by assembler)
252 ;; ptabs_media  SHmedia ptabs instruction
253 ;; store_media  SHmedia general register store instructions
254 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
255 ;; mac_media    SHmedia mac-style fixed point operations
256 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
257 ;; atrans_media SHmedia approximate transcendental functions
258 ;; ustore_media SHmedia unaligned stores
259 ;; nil          no-op move, will be deleted.
260
261 (define_attr "type"
262  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,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"
263   (const_string "other"))
264
265 ;; We define a new attribute namely "insn_class".We use
266 ;; this for the DFA based pipeline description.
267 ;;
268 ;; mt_group      SH4 "mt" group instructions.
269 ;;
270 ;; ex_group      SH4 "ex" group instructions.
271 ;;
272 ;; ls_group      SH4 "ls" group instructions.
273 ;;
274
275 (define_attr "insn_class"
276   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
277   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
278          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
279          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
280          (eq_attr "type" "cbranch,jump") (const_string "br_group")
281          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
282            (const_string "fe_group")
283          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
284         (const_string "none")))
285 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
286 ;; so these do not belong in an insn group, although they are modeled
287 ;; with their own define_insn_reservations.
288
289 ;; Indicate what precision must be selected in fpscr for this insn, if any.
290
291 (define_attr "fp_mode" "single,double,none" (const_string "none"))
292
293 ;; Indicate if the fpu mode is set by this instruction
294 ;; "unknown" must have the value as "none" in fp_mode, and means
295 ;; that the instruction/abi has left the processor in an unknown
296 ;; state.
297 ;; "none" means that nothing has changed and no mode is set.
298 ;; This attribute is only used for the Renesas ABI.
299 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
300
301 ; If a conditional branch destination is within -252..258 bytes away
302 ; from the instruction it can be 2 bytes long.  Something in the
303 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
304 ; branches are initially assumed to be 16 bytes long.
305 ; In machine_dependent_reorg, we split all branches that are longer than
306 ; 2 bytes.
307
308 ;; The maximum range used for SImode constant pool entries is 1018.  A final
309 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
310 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
311 ;; instruction around the pool table, 2 bytes of alignment before the table,
312 ;; and 30 bytes of alignment after the table.  That gives a maximum total
313 ;; pool size of 1058 bytes.
314 ;; Worst case code/pool content size ratio is 1:2 (using asms).
315 ;; Thus, in the worst case, there is one instruction in front of a maximum
316 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
317 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
318 ;; If we have a forward branch, the initial table will be put after the
319 ;; unconditional branch.
320 ;;
321 ;; ??? We could do much better by keeping track of the actual pcloads within
322 ;; the branch range and in the pcload range in front of the branch range.
323
324 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
325 ;; inside an le.
326 (define_attr "short_cbranch_p" "no,yes"
327   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
328          (const_string "no")
329          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
330          (const_string "yes")
331          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
332          (const_string "no")
333          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
334          (const_string "yes")
335          ] (const_string "no")))
336
337 (define_attr "med_branch_p" "no,yes"
338   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
339               (const_int 1988))
340          (const_string "yes")
341          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
342          (const_string "no")
343          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
344               (const_int 8186))
345          (const_string "yes")
346          ] (const_string "no")))
347
348 (define_attr "med_cbranch_p" "no,yes"
349   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
350               (const_int 1986))
351          (const_string "yes")
352          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353          (const_string "no")
354          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
355                (const_int 8184))
356          (const_string "yes")
357          ] (const_string "no")))
358
359 (define_attr "braf_branch_p" "no,yes"
360   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
361          (const_string "no")
362          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
363               (const_int 20660))
364          (const_string "yes")
365          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
366          (const_string "no")
367          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
368               (const_int 65530))
369          (const_string "yes")
370          ] (const_string "no")))
371
372 (define_attr "braf_cbranch_p" "no,yes"
373   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
374          (const_string "no")
375          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
376               (const_int 20658))
377          (const_string "yes")
378          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
379          (const_string "no")
380          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
381               (const_int 65528))
382          (const_string "yes")
383          ] (const_string "no")))
384
385 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
386 ; For wider ranges, we need a combination of a code and a data part.
387 ; If we can get a scratch register for a long range jump, the code
388 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
389 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
390 ; long; otherwise, it must be 6 bytes long.
391
392 ; All other instructions are two bytes long by default.
393
394 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
395 ;; but getattrtab doesn't understand this.
396 (define_attr "length" ""
397   (cond [(eq_attr "type" "cbranch")
398          (cond [(eq_attr "short_cbranch_p" "yes")
399                 (const_int 2)
400                 (eq_attr "med_cbranch_p" "yes")
401                 (const_int 6)
402                 (eq_attr "braf_cbranch_p" "yes")
403                 (const_int 12)
404 ;; ??? using pc is not computed transitively.
405                 (ne (match_dup 0) (match_dup 0))
406                 (const_int 14)
407                 (ne (symbol_ref ("flag_pic")) (const_int 0))
408                 (const_int 24)
409                 ] (const_int 16))
410          (eq_attr "type" "jump")
411          (cond [(eq_attr "med_branch_p" "yes")
412                 (const_int 2)
413                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
414                          (symbol_ref "INSN"))
415                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
416                          (symbol_ref "code_for_indirect_jump_scratch")))
417                 (cond [(eq_attr "braf_branch_p" "yes")
418                        (const_int 6)
419                        (eq (symbol_ref "flag_pic") (const_int 0))
420                        (const_int 10)
421                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
422                        (const_int 10)] (const_int 18))
423                 (eq_attr "braf_branch_p" "yes")
424                 (const_int 10)
425 ;; ??? using pc is not computed transitively.
426                 (ne (match_dup 0) (match_dup 0))
427                 (const_int 12)
428                 (ne (symbol_ref ("flag_pic")) (const_int 0))
429                 (const_int 22)
430                 ] (const_int 14))
431          (eq_attr "type" "pt_media")
432          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
433                        (const_int 20) (const_int 12))
434          (and (eq_attr "type" "jump_media")
435               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
436          (const_int 8)
437          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
438                          (const_int 4)
439                          (const_int 2))))
440
441 ;; DFA descriptions for the pipelines
442
443 (include "sh1.md")
444 (include "shmedia.md")
445 (include "sh4.md")
446
447 (include "predicates.md")
448
449 ;; Definitions for filling delay slots
450
451 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
452
453 ;; ??? This should be (nil) instead of (const_int 0)
454 (define_attr "hit_stack" "yes,no"
455         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
456                    (const_int 0))
457                (const_string "no")]
458               (const_string "yes")))
459
460 (define_attr "interrupt_function" "no,yes"
461   (const (symbol_ref "current_function_interrupt")))
462
463 (define_attr "in_delay_slot" "yes,no"
464   (cond [(eq_attr "type" "cbranch") (const_string "no")
465          (eq_attr "type" "pcload,pcload_si") (const_string "no")
466          (eq_attr "needs_delay_slot" "yes") (const_string "no")
467          (eq_attr "length" "2") (const_string "yes")
468          ] (const_string "no")))
469
470 (define_attr "cond_delay_slot" "yes,no"
471   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
472          ] (const_string "no")))
473
474 (define_attr "is_sfunc" ""
475   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
476
477 (define_attr "is_mac_media" ""
478   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
479
480 (define_attr "branch_zero" "yes,no"
481   (cond [(eq_attr "type" "!cbranch") (const_string "no")
482          (ne (symbol_ref "(next_active_insn (insn)\
483                            == (prev_active_insn\
484                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
485                           && get_attr_length (next_active_insn (insn)) == 2")
486              (const_int 0))
487          (const_string "yes")]
488         (const_string "no")))
489
490 ;; SH4 Double-precision computation with double-precision result -
491 ;; the two halves are ready at different times.
492 (define_attr "dfp_comp" "yes,no"
493   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
494         (const_string "no")))
495
496 ;; Insns for which the latency of a preceding fp insn is decreased by one.
497 (define_attr "late_fp_use" "yes,no" (const_string "no"))
498 ;; And feeding insns for which this relevant.
499 (define_attr "any_fp_comp" "yes,no"
500   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
501          (const_string "yes")]
502         (const_string "no")))
503
504 (define_attr "any_int_load" "yes,no"
505   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
506          (const_string "yes")]
507         (const_string "no")))
508
509 (define_attr "highpart" "user, ignore, extend, depend, must_split"
510   (const_string "user"))
511
512 (define_delay
513   (eq_attr "needs_delay_slot" "yes")
514   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
515
516 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
517 ;; and thus we can't put a pop instruction in its delay slot.
518 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
519 ;; instruction can go in the delay slot.
520
521 ;; Since a normal return (rts) implicitly uses the PR register,
522 ;; we can't allow PR register loads in an rts delay slot.
523
524 (define_delay
525   (eq_attr "type" "return")
526   [(and (eq_attr "in_delay_slot" "yes")
527         (ior (and (eq_attr "interrupt_function" "no")
528                   (eq_attr "type" "!pload,prset"))
529              (and (eq_attr "interrupt_function" "yes")
530                   (ior
531                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
532                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
533
534 ;; Since a call implicitly uses the PR register, we can't allow
535 ;; a PR register store in a jsr delay slot.
536
537 (define_delay
538   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
539   [(and (eq_attr "in_delay_slot" "yes")
540         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
541
542 ;; Say that we have annulled true branches, since this gives smaller and
543 ;; faster code when branches are predicted as not taken.
544
545 ;; ??? The non-annulled condition should really be "in_delay_slot",
546 ;; but insns that can be filled in non-annulled get priority over insns
547 ;; that can only be filled in anulled.
548
549 (define_delay
550   (and (eq_attr "type" "cbranch")
551        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
552   ;; SH2e has a hardware bug that pretty much prohibits the use of
553   ;; annuled delay slots.
554   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
555                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
556 \f
557 ;; -------------------------------------------------------------------------
558 ;; SImode signed integer comparisons
559 ;; -------------------------------------------------------------------------
560
561 (define_insn ""
562   [(set (reg:SI T_REG)
563         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
564                        (match_operand:SI 1 "arith_operand" "K08,r"))
565                (const_int 0)))]
566   "TARGET_SH1"
567   "tst  %1,%0"
568   [(set_attr "type" "mt_group")])
569
570 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
571 ;; That would still allow reload to create cmpi instructions, but would
572 ;; perhaps allow forcing the constant into a register when that is better.
573 ;; Probably should use r0 for mem/imm compares, but force constant into a
574 ;; register for pseudo/imm compares.
575
576 (define_insn "cmpeqsi_t"
577   [(set (reg:SI T_REG)
578         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
579                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
580   "TARGET_SH1"
581   "@
582         tst     %0,%0
583         cmp/eq  %1,%0
584         cmp/eq  %1,%0"
585    [(set_attr "type" "mt_group")])
586
587 (define_insn "cmpgtsi_t"
588   [(set (reg:SI T_REG)
589         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
590                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
591   "TARGET_SH1"
592   "@
593         cmp/gt  %1,%0
594         cmp/pl  %0"
595    [(set_attr "type" "mt_group")])
596
597 (define_insn "cmpgesi_t"
598   [(set (reg:SI T_REG)
599         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
600                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
601   "TARGET_SH1"
602   "@
603         cmp/ge  %1,%0
604         cmp/pz  %0"
605    [(set_attr "type" "mt_group")])
606
607 ;; -------------------------------------------------------------------------
608 ;; SImode unsigned integer comparisons
609 ;; -------------------------------------------------------------------------
610
611 (define_insn "cmpgeusi_t"
612   [(set (reg:SI T_REG)
613         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
614                 (match_operand:SI 1 "arith_reg_operand" "r")))]
615   "TARGET_SH1"
616   "cmp/hs       %1,%0"
617    [(set_attr "type" "mt_group")])
618
619 (define_insn "cmpgtusi_t"
620   [(set (reg:SI T_REG)
621         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
622                 (match_operand:SI 1 "arith_reg_operand" "r")))]
623   "TARGET_SH1"
624   "cmp/hi       %1,%0"
625    [(set_attr "type" "mt_group")])
626
627 ;; We save the compare operands in the cmpxx patterns and use them when
628 ;; we generate the branch.
629
630 (define_expand "cmpsi"
631   [(set (reg:SI T_REG)
632         (compare (match_operand:SI 0 "cmpsi_operand" "")
633                  (match_operand:SI 1 "arith_operand" "")))]
634   "TARGET_SH1 || TARGET_SHMEDIA"
635   "
636 {
637   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
638       && GET_CODE (operands[1]) != CONST_INT)
639     operands[0] = copy_to_mode_reg (SImode, operands[0]);
640   sh_compare_op0 = operands[0];
641   sh_compare_op1 = operands[1];
642   DONE;
643 }")
644 \f
645 ;; -------------------------------------------------------------------------
646 ;; DImode signed integer comparisons
647 ;; -------------------------------------------------------------------------
648
649 ;; ??? Could get better scheduling by splitting the initial test from the
650 ;; rest of the insn after reload.  However, the gain would hardly justify
651 ;; the sh.md size increase necessary to do that.
652
653 (define_insn ""
654   [(set (reg:SI T_REG)
655         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
656                        (match_operand:DI 1 "arith_operand" "r"))
657                (const_int 0)))]
658   "TARGET_SH1"
659   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
660                                  insn, operands);"
661   [(set_attr "length" "6")
662    (set_attr "type" "arith3b")])
663
664 (define_insn "cmpeqdi_t"
665   [(set (reg:SI T_REG)
666         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
667                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
668   "TARGET_SH1"
669   "@
670         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
671         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
672   [(set_attr "length" "6")
673    (set_attr "type" "arith3b")])
674
675 (define_split
676   [(set (reg:SI T_REG)
677         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
678                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
679 ;; If we applied this split when not optimizing, it would only be
680 ;; applied during the machine-dependent reorg, when no new basic blocks
681 ;; may be created.
682   "TARGET_SH1 && reload_completed && optimize"
683   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
684    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
685                            (label_ref (match_dup 6))
686                            (pc)))
687    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
688    (match_dup 6)]
689   "
690 {
691   operands[2]
692     = gen_rtx_REG (SImode,
693                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
694   operands[3]
695     = (operands[1] == const0_rtx
696        ? const0_rtx
697        : gen_rtx_REG (SImode,
698                       true_regnum (operands[1])
699                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
700   operands[4] = gen_lowpart (SImode, operands[0]);
701   operands[5] = gen_lowpart (SImode, operands[1]);
702   operands[6] = gen_label_rtx ();
703 }")
704
705 (define_insn "cmpgtdi_t"
706   [(set (reg:SI T_REG)
707         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
708                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
709   "TARGET_SH2"
710   "@
711         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
712         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
713   [(set_attr "length" "8")
714    (set_attr "type" "arith3")])
715
716 (define_insn "cmpgedi_t"
717   [(set (reg:SI T_REG)
718         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
719                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
720   "TARGET_SH2"
721   "@
722         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
723         cmp/pz\\t%S0"
724   [(set_attr "length" "8,2")
725    (set_attr "type" "arith3,mt_group")])
726 \f
727 ;; -------------------------------------------------------------------------
728 ;; DImode unsigned integer comparisons
729 ;; -------------------------------------------------------------------------
730
731 (define_insn "cmpgeudi_t"
732   [(set (reg:SI T_REG)
733         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
734                 (match_operand:DI 1 "arith_reg_operand" "r")))]
735   "TARGET_SH2"
736   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
737   [(set_attr "length" "8")
738    (set_attr "type" "arith3")])
739
740 (define_insn "cmpgtudi_t"
741   [(set (reg:SI T_REG)
742         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
743                 (match_operand:DI 1 "arith_reg_operand" "r")))]
744   "TARGET_SH2"
745   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
746   [(set_attr "length" "8")
747    (set_attr "type" "arith3")])
748
749 (define_insn "cmpeqsi_media"
750   [(set (match_operand:DI 0 "register_operand" "=r")
751         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
752                (match_operand:SI 2 "cmp_operand" "Nr")))]
753   "TARGET_SHMEDIA"
754   "cmpeq        %1, %N2, %0"
755   [(set_attr "type" "cmp_media")])
756
757 (define_insn "cmpeqdi_media"
758   [(set (match_operand:DI 0 "register_operand" "=r")
759         (eq:DI (match_operand:DI 1 "register_operand" "%r")
760                (match_operand:DI 2 "cmp_operand" "Nr")))]
761   "TARGET_SHMEDIA"
762   "cmpeq        %1, %N2, %0"
763   [(set_attr "type" "cmp_media")])
764
765 (define_insn "cmpgtsi_media"
766   [(set (match_operand:DI 0 "register_operand" "=r")
767         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
768                (match_operand:SI 2 "cmp_operand" "rN")))]
769   "TARGET_SHMEDIA"
770   "cmpgt        %N1, %N2, %0"
771   [(set_attr "type" "cmp_media")])
772
773 (define_insn "cmpgtdi_media"
774   [(set (match_operand:DI 0 "register_operand" "=r")
775         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
776                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
777   "TARGET_SHMEDIA"
778   "cmpgt        %N1, %N2, %0"
779   [(set_attr "type" "cmp_media")])
780
781 (define_insn "cmpgtusi_media"
782   [(set (match_operand:DI 0 "register_operand" "=r")
783         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
784                 (match_operand:SI 2 "cmp_operand" "rN")))]
785   "TARGET_SHMEDIA"
786   "cmpgtu       %N1, %N2, %0"
787   [(set_attr "type" "cmp_media")])
788
789 (define_insn "cmpgtudi_media"
790   [(set (match_operand:DI 0 "register_operand" "=r")
791         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
792                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
793   "TARGET_SHMEDIA"
794   "cmpgtu       %N1, %N2, %0"
795   [(set_attr "type" "cmp_media")])
796
797 (define_insn "cmpsieqsi_media"
798   [(set (match_operand:SI 0 "register_operand" "=r")
799         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
800                (match_operand:SI 2 "cmp_operand" "Nr")))]
801   "TARGET_SHMEDIA"
802   "cmpeq        %1, %N2, %0"
803   [(set_attr "type" "cmp_media")])
804
805 (define_insn "cmpsieqdi_media"
806   [(set (match_operand:SI 0 "register_operand" "=r")
807         (eq:SI (match_operand:DI 1 "register_operand" "%r")
808                (match_operand:DI 2 "cmp_operand" "Nr")))]
809   "TARGET_SHMEDIA"
810   "cmpeq        %1, %N2, %0"
811   [(set_attr "type" "cmp_media")])
812
813 (define_insn "cmpsigtsi_media"
814   [(set (match_operand:SI 0 "register_operand" "=r")
815         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
816                (match_operand:SI 2 "cmp_operand" "rN")))]
817   "TARGET_SHMEDIA"
818   "cmpgt        %N1, %N2, %0"
819   [(set_attr "type" "cmp_media")])
820
821 (define_insn "cmpsigtdi_media"
822   [(set (match_operand:SI 0 "register_operand" "=r")
823         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
824                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
825   "TARGET_SHMEDIA"
826   "cmpgt        %N1, %N2, %0"
827   [(set_attr "type" "cmp_media")])
828
829 (define_insn "cmpsigtusi_media"
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
832                 (match_operand:SI 2 "cmp_operand" "rN")))]
833   "TARGET_SHMEDIA"
834   "cmpgtu       %N1, %N2, %0"
835   [(set_attr "type" "cmp_media")])
836
837 (define_insn "cmpsigtudi_media"
838   [(set (match_operand:SI 0 "register_operand" "=r")
839         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
840                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
841   "TARGET_SHMEDIA"
842   "cmpgtu       %N1, %N2, %0"
843   [(set_attr "type" "cmp_media")])
844
845 ; These two patterns are for combine.
846 (define_insn "*cmpne0si_media"
847   [(set (match_operand:DI 0 "register_operand" "=r")
848         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
849   "TARGET_SHMEDIA"
850   "cmpgtu       %1,r63,%0"
851   [(set_attr "type" "cmp_media")])
852
853 (define_insn "*cmpne0sisi_media"
854   [(set (match_operand:SI 0 "register_operand" "=r")
855         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
856   "TARGET_SHMEDIA"
857   "cmpgtu       %1,r63,%0"
858   [(set_attr "type" "cmp_media")])
859
860 ;; We save the compare operands in the cmpxx patterns and use them when
861 ;; we generate the branch.
862
863 (define_expand "cmpdi"
864   [(set (reg:SI T_REG)
865         (compare (match_operand:DI 0 "arith_operand" "")
866                  (match_operand:DI 1 "arith_operand" "")))]
867   "TARGET_SH2 || TARGET_SHMEDIA"
868   "
869 {
870   sh_compare_op0 = operands[0];
871   sh_compare_op1 = operands[1];
872   DONE;
873 }")
874 ;; -------------------------------------------------------------------------
875 ;; Conditional move instructions
876 ;; -------------------------------------------------------------------------
877
878 ;; The insn names may seem reversed, but note that cmveq performs the move
879 ;; if op1 == 0, and cmvne does it if op1 != 0.
880
881 (define_insn "movdicc_false"
882   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
883         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
884                              (const_int 0))
885          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
886          (match_operand:DI 3 "arith_reg_operand" "0")))]
887   "TARGET_SHMEDIA"
888   "cmveq        %1, %N2, %0"
889   [(set_attr "type" "arith_media")])
890
891 (define_insn "movdicc_true"
892   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
893         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
894                              (const_int 0))
895          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
896          (match_operand:DI 3 "arith_reg_operand" "0")))]
897   "TARGET_SHMEDIA"
898   "cmvne        %1, %N2, %0"
899   [(set_attr "type" "arith_media")])
900
901 (define_peephole2
902   [(set (match_operand:DI 0 "arith_reg_dest" "")
903         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
904                            [(match_operand:DI 1 "arith_reg_operand" "")
905                             (const_int 0)])
906          (match_operand:DI 2 "arith_reg_dest" "")
907          (match_dup 0)))
908    (set (match_dup 2) (match_dup 0))]
909   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
910   [(set (match_dup 2)
911         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
912   "
913 {
914   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
915                                 VOIDmode, operands[1], CONST0_RTX (DImode));
916 }")
917
918 (define_peephole2
919   [(set (match_operand:DI 0 "general_movdst_operand" "")
920         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
921    (set (match_operand:DI 2 "arith_reg_dest" "")
922         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
923                            [(match_operand:DI 3 "arith_reg_operand" "")
924                             (const_int 0)])
925          (match_dup 0)
926          (match_dup 2)))]
927   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
928   [(set (match_dup 2)
929         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
930   "")
931
932 (define_expand "movdicc"
933   [(set (match_operand:DI 0 "register_operand" "")
934         (if_then_else:DI (match_operand 1 "comparison_operator" "")
935                          (match_operand:DI 2 "register_operand" "")
936                          (match_operand:DI 3 "register_operand" "")))]
937   "TARGET_SHMEDIA"
938   "
939 {
940   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
941       && GET_MODE (sh_compare_op0) == DImode
942       && sh_compare_op1 == const0_rtx)
943     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
944                                   sh_compare_op0, sh_compare_op1);
945   else
946     {
947       rtx tmp;
948
949       if (no_new_pseudos)
950         FAIL;
951
952       tmp = gen_reg_rtx (DImode);
953
954       switch (GET_CODE (operands[1]))
955         {
956         case EQ:
957           emit_insn (gen_seq (tmp));
958           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
959           break;
960
961         case NE:
962           emit_insn (gen_seq (tmp));
963           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
964           break;
965
966         case GT:
967           emit_insn (gen_sgt (tmp));
968           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
969           break;
970
971         case LT:
972           emit_insn (gen_slt (tmp));
973           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
974           break;
975
976         case GE:
977           emit_insn (gen_slt (tmp));
978           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
979           break;
980
981         case LE:
982           emit_insn (gen_sgt (tmp));
983           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
984           break;
985
986         case GTU:
987           emit_insn (gen_sgtu (tmp));
988           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
989           break;
990
991         case LTU:
992           emit_insn (gen_sltu (tmp));
993           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
994           break;
995
996         case GEU:
997           emit_insn (gen_sltu (tmp));
998           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
999           break;
1000
1001         case LEU:
1002           emit_insn (gen_sgtu (tmp));
1003           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1004           break;
1005
1006         case UNORDERED:
1007           emit_insn (gen_sunordered (tmp));
1008           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1009           break;
1010
1011         case ORDERED:
1012           emit_insn (gen_sunordered (tmp));
1013           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1014           break;
1015
1016         case UNEQ:
1017         case UNGE:
1018         case UNGT:
1019         case UNLE:
1020         case UNLT:
1021         case LTGT:
1022           FAIL;
1023
1024         default:
1025           gcc_unreachable ();
1026         }
1027     }
1028 }")
1029
1030 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1031 ;; SImode to DImode.
1032 (define_insn "movsicc_false"
1033   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1034         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1035                           (const_int 0))
1036          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1037          (match_operand:SI 3 "arith_reg_operand" "0")))]
1038   "TARGET_SHMEDIA"
1039   "cmveq        %1, %N2, %0"
1040   [(set_attr "type" "arith_media")])
1041
1042 (define_insn "movsicc_true"
1043   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1044         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1045                           (const_int 0))
1046          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1047          (match_operand:SI 3 "arith_reg_operand" "0")))]
1048   "TARGET_SHMEDIA"
1049   "cmvne        %1, %N2, %0"
1050   [(set_attr "type" "arith_media")])
1051
1052 (define_peephole2
1053   [(set (match_operand:SI 0 "arith_reg_dest" "")
1054         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1055                            [(match_operand:SI 1 "arith_reg_operand" "")
1056                             (const_int 0)])
1057          (match_operand:SI 2 "arith_reg_dest" "")
1058          (match_dup 0)))
1059    (set (match_dup 2) (match_dup 0))]
1060   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1061   [(set (match_dup 2)
1062         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1063   "
1064 {
1065   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1066                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1067 }")
1068
1069 (define_peephole2
1070   [(set (match_operand:SI 0 "general_movdst_operand" "")
1071         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1072    (set (match_operand:SI 2 "arith_reg_dest" "")
1073         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1074                            [(match_operand:SI 3 "arith_reg_operand" "")
1075                             (const_int 0)])
1076          (match_dup 0)
1077          (match_dup 2)))]
1078   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1079    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1080   [(set (match_dup 2)
1081         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1082   "
1083 {
1084   replace_rtx (operands[4], operands[0], operands[1]);
1085 }")
1086
1087 (define_peephole2
1088   [(set (match_operand 0 "any_register_operand" "")
1089         (match_operand 1 "any_register_operand" ""))
1090    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1091    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1092   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1093     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1094    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1095    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1096    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1097    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1098    && (REGNO_REG_CLASS (REGNO (operands[0]))
1099        == REGNO_REG_CLASS (REGNO (operands[2])))
1100    && (REGNO_REG_CLASS (REGNO (operands[1]))
1101        == REGNO_REG_CLASS (REGNO (operands[0])))"
1102   [(set (match_dup 0) (match_dup 3))
1103    (set (match_dup 4) (match_dup 5))]
1104   "
1105 {
1106   rtx set1, set2;
1107   rtx replacements[4];
1108
1109   /* We want to replace occurrences of operands[0] with operands[1] and
1110      operands[2] with operands[0] in operands[4]/operands[5].
1111      Doing just two replace_rtx calls naively would result in the second
1112      replacement undoing all that the first did if operands[1] and operands[2]
1113      are identical, so we must do this simultaneously.  */
1114   replacements[0] = operands[0];
1115   replacements[1] = operands[1];
1116   replacements[2] = operands[2];
1117   replacements[3] = operands[0];
1118   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1119       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1120       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1121     FAIL;
1122
1123   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1124   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1125   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1126   /* The operands array is aliased to recog_data.operand, which gets
1127      clobbered by extract_insn, so finish with it now.  */
1128   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1129   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1130   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1131      always uses emit_insn.  */
1132   /* Check that we don't violate matching constraints or earlyclobbers.  */
1133   extract_insn (emit_insn (set1));
1134   if (! constrain_operands (1))
1135     goto failure;
1136   extract_insn (emit (set2));
1137   if (! constrain_operands (1))
1138     {
1139       rtx tmp;
1140     failure:
1141       tmp = replacements[0];
1142       replacements[0] = replacements[1];
1143       replacements[1] = tmp;
1144       tmp = replacements[2];
1145       replacements[2] = replacements[3];
1146       replacements[3] = tmp;
1147       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1148       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1149       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1150       FAIL;
1151     }
1152   DONE;
1153 }")
1154
1155 ;; The register allocator is rather clumsy in handling multi-way conditional
1156 ;; moves, so allow the combiner to make them, and we split them up after
1157 ;; reload.  */
1158 (define_insn_and_split "*movsicc_umin"
1159   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1160         (umin:SI (if_then_else:SI
1161                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1162                        (const_int 0))
1163                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1164                    (match_operand:SI 3 "register_operand" "0"))
1165                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1166    (clobber (match_scratch:SI 5 "=&r"))]
1167   "TARGET_SHMEDIA && no_new_pseudos"
1168   "#"
1169   "TARGET_SHMEDIA && reload_completed"
1170   [(pc)]
1171   "
1172 {
1173   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1174                                 operands[3]));
1175   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1176   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1177                                 operands[0]));
1178   DONE;
1179 }")
1180
1181 (define_expand "movsicc"
1182   [(set (match_operand:SI 0 "register_operand" "")
1183         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1184                          (match_operand:SI 2 "register_operand" "")
1185                          (match_operand:SI 3 "register_operand" "")))]
1186   "TARGET_SHMEDIA"
1187   "
1188 {
1189   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1190       && GET_MODE (sh_compare_op0) == SImode
1191       && sh_compare_op1 == const0_rtx)
1192     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1193                                   sh_compare_op0, sh_compare_op1);
1194   else
1195     {
1196       rtx tmp;
1197
1198       if (no_new_pseudos)
1199         FAIL;
1200
1201       tmp = gen_reg_rtx (SImode);
1202
1203       switch (GET_CODE (operands[1]))
1204         {
1205         case EQ:
1206           emit_insn (gen_seq (tmp));
1207           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1208           break;
1209
1210         case NE:
1211           emit_insn (gen_seq (tmp));
1212           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1213           break;
1214
1215         case GT:
1216           emit_insn (gen_sgt (tmp));
1217           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1218           break;
1219
1220         case LT:
1221           emit_insn (gen_slt (tmp));
1222           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1223           break;
1224
1225         case GE:
1226           emit_insn (gen_slt (tmp));
1227           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1228           break;
1229
1230         case LE:
1231           emit_insn (gen_sgt (tmp));
1232           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1233           break;
1234
1235         case GTU:
1236           emit_insn (gen_sgtu (tmp));
1237           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1238           break;
1239
1240         case LTU:
1241           emit_insn (gen_sltu (tmp));
1242           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1243           break;
1244
1245         case GEU:
1246           emit_insn (gen_sltu (tmp));
1247           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1248           break;
1249
1250         case LEU:
1251           emit_insn (gen_sgtu (tmp));
1252           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1253           break;
1254
1255         case UNORDERED:
1256           emit_insn (gen_sunordered (tmp));
1257           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1258           break;
1259
1260         case ORDERED:
1261           emit_insn (gen_sunordered (tmp));
1262           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1263           break;
1264
1265         case UNEQ:
1266         case UNGE:
1267         case UNGT:
1268         case UNLE:
1269         case UNLT:
1270         case LTGT:
1271           FAIL;
1272
1273         default:
1274           abort ();
1275         }
1276     }
1277 }")
1278
1279 (define_expand "movqicc"
1280   [(set (match_operand:QI 0 "register_operand" "")
1281         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1282                          (match_operand:QI 2 "register_operand" "")
1283                          (match_operand:QI 3 "register_operand" "")))]
1284   "TARGET_SHMEDIA"
1285   "
1286 {
1287   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1288   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1289   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1290   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1291   DONE;
1292 }")
1293 \f
1294 ;; -------------------------------------------------------------------------
1295 ;; Addition instructions
1296 ;; -------------------------------------------------------------------------
1297
1298 (define_expand "adddi3"
1299   [(set (match_operand:DI 0 "arith_reg_operand" "")
1300         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1301                  (match_operand:DI 2 "arith_operand" "")))]
1302   ""
1303   "
1304 {
1305   if (TARGET_SH1)
1306     {
1307       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1308         FAIL;
1309       operands[2] = force_reg (DImode, operands[2]);
1310       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1311       DONE;
1312     }
1313 }")
1314
1315 (define_insn "*adddi3_media"
1316   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1317         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1318                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1319   "TARGET_SHMEDIA"
1320   "@
1321         add     %1, %2, %0
1322         addi    %1, %2, %0"
1323   [(set_attr "type" "arith_media")])
1324
1325 (define_insn "*adddisi3_media"
1326   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1327         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1328                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1329   "TARGET_SHMEDIA"
1330   "@
1331         add.l   %1, %2, %0
1332         addi.l  %1, %2, %0"
1333   [(set_attr "type" "arith_media")
1334    (set_attr "highpart" "ignore")])
1335
1336 (define_insn "adddi3z_media"
1337   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1338         (zero_extend:DI
1339          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1340                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1341   "TARGET_SHMEDIA"
1342   "addz.l       %1, %N2, %0"
1343   [(set_attr "type" "arith_media")
1344    (set_attr "highpart" "ignore")])
1345
1346 (define_insn "adddi3_compact"
1347   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1348         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1349                  (match_operand:DI 2 "arith_reg_operand" "r")))
1350    (clobber (reg:SI T_REG))]
1351   "TARGET_SH1"
1352   "#"
1353   [(set_attr "length" "6")])
1354
1355 (define_split
1356   [(set (match_operand:DI 0 "arith_reg_dest" "")
1357         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1358                  (match_operand:DI 2 "arith_reg_operand" "")))
1359    (clobber (reg:SI T_REG))]
1360   "TARGET_SH1 && reload_completed"
1361   [(const_int 0)]
1362   "
1363 {
1364   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1365   high0 = gen_rtx_REG (SImode,
1366                        true_regnum (operands[0])
1367                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1368   high2 = gen_rtx_REG (SImode,
1369                        true_regnum (operands[2])
1370                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1371   emit_insn (gen_clrt ());
1372   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1373   emit_insn (gen_addc1 (high0, high0, high2));
1374   DONE;
1375 }")
1376
1377 (define_insn "addc"
1378   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1379         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1380                           (match_operand:SI 2 "arith_reg_operand" "r"))
1381                  (reg:SI T_REG)))
1382    (set (reg:SI T_REG)
1383         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1384   "TARGET_SH1"
1385   "addc %2,%0"
1386   [(set_attr "type" "arith")])
1387
1388 (define_insn "addc1"
1389   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1390         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1391                           (match_operand:SI 2 "arith_reg_operand" "r"))
1392                  (reg:SI T_REG)))
1393    (clobber (reg:SI T_REG))]
1394   "TARGET_SH1"
1395   "addc %2,%0"
1396   [(set_attr "type" "arith")])
1397
1398 (define_expand "addsi3"
1399   [(set (match_operand:SI 0 "arith_reg_operand" "")
1400         (plus:SI (match_operand:SI 1 "arith_operand" "")
1401                  (match_operand:SI 2 "arith_operand" "")))]
1402   ""
1403   "
1404 {
1405   if (TARGET_SHMEDIA)
1406     operands[1] = force_reg (SImode, operands[1]);
1407 }")
1408
1409 (define_insn "addsi3_media"
1410   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1411         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1412                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1413   "TARGET_SHMEDIA"
1414   "@
1415         add.l   %1, %2, %0
1416         addi.l  %1, %2, %0"
1417   [(set_attr "type" "arith_media")
1418    (set_attr "highpart" "ignore")])
1419
1420 (define_insn "addsidi3_media"
1421   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1422         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1423                                   "%r,r")
1424                                  (match_operand:SI 2 "arith_operand"
1425                                   "r,I10"))))]
1426   "TARGET_SHMEDIA"
1427   "@
1428         add.l   %1, %2, %0
1429         addi.l  %1, %2, %0"
1430   [(set_attr "type" "arith_media")
1431    (set_attr "highpart" "ignore")])
1432
1433 (define_insn "*addsi3_compact"
1434   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1435         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1436                  (match_operand:SI 2 "arith_operand" "rI08")))]
1437   "TARGET_SH1"
1438   "add  %2,%0"
1439   [(set_attr "type" "arith")])
1440
1441 ;; -------------------------------------------------------------------------
1442 ;; Subtraction instructions
1443 ;; -------------------------------------------------------------------------
1444
1445 (define_expand "subdi3"
1446   [(set (match_operand:DI 0 "arith_reg_operand" "")
1447         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1448                   (match_operand:DI 2 "arith_reg_operand" "")))]
1449   ""
1450   "
1451 {
1452   if (TARGET_SH1)
1453     {
1454       operands[1] = force_reg (DImode, operands[1]);
1455       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1456       DONE;
1457     }
1458 }")
1459
1460 (define_insn "*subdi3_media"
1461   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1462         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1463                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1464   "TARGET_SHMEDIA"
1465   "sub  %N1, %2, %0"
1466   [(set_attr "type" "arith_media")])
1467   
1468 (define_insn "subdisi3_media"
1469   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1470         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1471                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1472   "TARGET_SHMEDIA"
1473   "sub.l        %N1, %2, %0"
1474   [(set_attr "type" "arith_media")
1475    (set_attr "highpart" "ignore")])
1476
1477 (define_insn "subdi3_compact"
1478   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1479         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1480                  (match_operand:DI 2 "arith_reg_operand" "r")))
1481    (clobber (reg:SI T_REG))]
1482   "TARGET_SH1"
1483   "#"
1484   [(set_attr "length" "6")])
1485
1486 (define_split
1487   [(set (match_operand:DI 0 "arith_reg_dest" "")
1488         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1489                   (match_operand:DI 2 "arith_reg_operand" "")))
1490    (clobber (reg:SI T_REG))]
1491   "TARGET_SH1 && reload_completed"
1492   [(const_int 0)]
1493   "
1494 {
1495   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1496   high0 = gen_rtx_REG (SImode,
1497                        true_regnum (operands[0])
1498                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1499   high2 = gen_rtx_REG (SImode,
1500                        true_regnum (operands[2])
1501                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1502   emit_insn (gen_clrt ());
1503   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1504   emit_insn (gen_subc1 (high0, high0, high2));
1505   DONE;
1506 }")
1507
1508 (define_insn "subc"
1509   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1510         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1511                             (match_operand:SI 2 "arith_reg_operand" "r"))
1512                   (reg:SI T_REG)))
1513    (set (reg:SI T_REG)
1514         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1515                           (reg:SI T_REG))
1516                 (match_dup 1)))]
1517   "TARGET_SH1"
1518   "subc %2,%0"
1519   [(set_attr "type" "arith")])
1520
1521 (define_insn "subc1"
1522   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1523         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1524                             (match_operand:SI 2 "arith_reg_operand" "r"))
1525                   (reg:SI T_REG)))
1526    (clobber (reg:SI T_REG))]
1527   "TARGET_SH1"
1528   "subc %2,%0"
1529   [(set_attr "type" "arith")])
1530
1531 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1532 ;; pattern for this case.  This helps multimedia applications that compute
1533 ;; the sum of absolute differences.
1534 (define_insn "mov_neg_si_t"
1535   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1536   "TARGET_SH1"
1537   "subc %0,%0"
1538   [(set_attr "type" "arith")])
1539
1540 (define_insn "*subsi3_internal"
1541   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1542         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1543                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1544   "TARGET_SH1"
1545   "sub  %2,%0"
1546   [(set_attr "type" "arith")])
1547
1548 (define_insn_and_split "*subsi3_media"
1549   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1550         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1551                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1552   "TARGET_SHMEDIA
1553    && (operands[1] != constm1_rtx
1554        || (GET_CODE (operands[2]) != TRUNCATE
1555            && GET_CODE (operands[2]) != SUBREG))"
1556   "sub.l        %N1, %2, %0"
1557   "operands[1] == constm1_rtx"
1558   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1559   ""
1560   [(set_attr "type" "arith_media")
1561    (set_attr "highpart" "ignore")])
1562
1563 (define_split
1564   [(set (match_operand:SI 0 "arith_reg_dest" "")
1565         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1566                                                        "general_extend_operand"
1567                                                        "") 0)) 0)))]
1568   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1569   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1570    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1571   "")
1572
1573 (define_split
1574   [(set (match_operand:SI 0 "arith_reg_dest" "")
1575         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1576                                                        "general_extend_operand"
1577                                                        "") 0)) 3)))]
1578   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1579   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1580    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1581   "")
1582 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1583 ;; will sometimes save one instruction.  Otherwise we might get
1584 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1585 ;; are the same.
1586
1587 (define_expand "subsi3"
1588   [(set (match_operand:SI 0 "arith_reg_operand" "")
1589         (minus:SI (match_operand:SI 1 "arith_operand" "")
1590                   (match_operand:SI 2 "arith_reg_operand" "")))]
1591   ""
1592   "
1593 {
1594   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1595     {
1596       emit_insn (gen_negsi2 (operands[0], operands[2]));
1597       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1598       DONE;
1599     }
1600   if (TARGET_SHMEDIA)
1601     {
1602       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1603         FAIL;
1604       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1605         operands[1] = force_reg (SImode, operands[1]);
1606     }
1607 }")
1608 \f
1609 ;; -------------------------------------------------------------------------
1610 ;; Division instructions
1611 ;; -------------------------------------------------------------------------
1612
1613 ;; We take advantage of the library routines which don't clobber as many
1614 ;; registers as a normal function call would.
1615
1616 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1617 ;; also has an effect on the register that holds the address of the sfunc.
1618 ;; To make this work, we have an extra dummy insn that shows the use
1619 ;; of this register for reorg.
1620
1621 (define_insn "use_sfunc_addr"
1622   [(set (reg:SI PR_REG)
1623         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1624   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1625   ""
1626   [(set_attr "length" "0")])
1627
1628 (define_insn "udivsi3_sh2a"
1629   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1630         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1631                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1632   "TARGET_SH2A"
1633   "divu %2,%1"
1634   [(set_attr "type" "arith")
1635    (set_attr "in_delay_slot" "no")])
1636
1637 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1638 ;; hard register 0.  If we used hard register 0, then the next instruction
1639 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1640 ;; gets allocated to a stack slot that needs its address reloaded, then
1641 ;; there is nothing to prevent reload from using r0 to reload the address.
1642 ;; This reload would clobber the value in r0 we are trying to store.
1643 ;; If we let reload allocate r0, then this problem can never happen.
1644
1645 (define_insn "udivsi3_i1"
1646   [(set (match_operand:SI 0 "register_operand" "=z")
1647         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1648    (clobber (reg:SI T_REG))
1649    (clobber (reg:SI PR_REG))
1650    (clobber (reg:SI R4_REG))
1651    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1652   "TARGET_SH1 && ! TARGET_SH4"
1653   "jsr  @%1%#"
1654   [(set_attr "type" "sfunc")
1655    (set_attr "needs_delay_slot" "yes")])
1656
1657 ; Since shmedia-nofpu code could be linked against shcompact code, and
1658 ; the udivsi3 libcall has the same name, we must consider all registers
1659 ; clobbered that are in the union of the registers clobbered by the
1660 ; shmedia and the shcompact implementation.  Note, if the shcompact
1661 ; implementation actually used shcompact code, we'd need to clobber
1662 ; also r23 and fr23.
1663 (define_insn "udivsi3_i1_media"
1664   [(set (match_operand:SI 0 "register_operand" "=z")
1665         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1666    (clobber (reg:SI T_MEDIA_REG))
1667    (clobber (reg:SI PR_MEDIA_REG))
1668    (clobber (reg:SI R20_REG))
1669    (clobber (reg:SI R21_REG))
1670    (clobber (reg:SI R22_REG))
1671    (clobber (reg:DI TR0_REG))
1672    (clobber (reg:DI TR1_REG))
1673    (clobber (reg:DI TR2_REG))
1674    (use (match_operand 1 "target_operand" "b"))]
1675   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1676   "blink        %1, r18"
1677   [(set_attr "type" "sfunc")
1678    (set_attr "needs_delay_slot" "yes")])
1679
1680 (define_expand "udivsi3_i4_media"
1681   [(set (match_dup 3)
1682         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1683    (set (match_dup 4)
1684         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1685    (set (match_dup 5) (float:DF (match_dup 3)))
1686    (set (match_dup 6) (float:DF (match_dup 4)))
1687    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1688    (set (match_dup 8) (fix:DI (match_dup 7)))
1689    (set (match_operand:SI 0 "register_operand" "")
1690         (truncate:SI (match_dup 8)))]
1691   "TARGET_SHMEDIA_FPU"
1692   "
1693 {
1694   operands[3] = gen_reg_rtx (DImode);
1695   operands[4] = gen_reg_rtx (DImode);
1696   operands[5] = gen_reg_rtx (DFmode);
1697   operands[6] = gen_reg_rtx (DFmode);
1698   operands[7] = gen_reg_rtx (DFmode);
1699   operands[8] = gen_reg_rtx (DImode);
1700 }")
1701
1702 (define_insn "udivsi3_i4"
1703   [(set (match_operand:SI 0 "register_operand" "=y")
1704         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1705    (clobber (reg:SI T_REG))
1706    (clobber (reg:SI PR_REG))
1707    (clobber (reg:DF DR0_REG))
1708    (clobber (reg:DF DR2_REG))
1709    (clobber (reg:DF DR4_REG))
1710    (clobber (reg:SI R0_REG))
1711    (clobber (reg:SI R1_REG))
1712    (clobber (reg:SI R4_REG))
1713    (clobber (reg:SI R5_REG))
1714    (use (reg:PSI FPSCR_REG))
1715    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1716   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1717   "jsr  @%1%#"
1718   [(set_attr "type" "sfunc")
1719    (set_attr "fp_mode" "double")
1720    (set_attr "needs_delay_slot" "yes")])
1721
1722 (define_insn "udivsi3_i4_single"
1723   [(set (match_operand:SI 0 "register_operand" "=y")
1724         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1725    (clobber (reg:SI T_REG))
1726    (clobber (reg:SI PR_REG))
1727    (clobber (reg:DF DR0_REG))
1728    (clobber (reg:DF DR2_REG))
1729    (clobber (reg:DF DR4_REG))
1730    (clobber (reg:SI R0_REG))
1731    (clobber (reg:SI R1_REG))
1732    (clobber (reg:SI R4_REG))
1733    (clobber (reg:SI R5_REG))
1734    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1735   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1736   "jsr  @%1%#"
1737   [(set_attr "type" "sfunc")
1738    (set_attr "needs_delay_slot" "yes")])
1739
1740 (define_expand "udivsi3"
1741   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1742    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1743    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1744    (parallel [(set (match_operand:SI 0 "register_operand" "")
1745                    (udiv:SI (reg:SI R4_REG)
1746                             (reg:SI R5_REG)))
1747               (clobber (reg:SI T_REG))
1748               (clobber (reg:SI PR_REG))
1749               (clobber (reg:SI R4_REG))
1750               (use (match_dup 3))])]
1751   ""
1752   "
1753 {
1754   rtx first, last;
1755
1756   operands[3] = gen_reg_rtx (Pmode);
1757   /* Emit the move of the address to a pseudo outside of the libcall.  */
1758   if (TARGET_HARD_SH4 && TARGET_SH2E)
1759     {
1760       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1761       if (TARGET_FPU_SINGLE)
1762         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1763       else
1764         last = gen_udivsi3_i4 (operands[0], operands[3]);
1765     }
1766   else if (TARGET_SHMEDIA_FPU)
1767     {
1768       operands[1] = force_reg (SImode, operands[1]);
1769       operands[2] = force_reg (SImode, operands[2]);
1770       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1771       DONE;
1772     }
1773   else if (TARGET_SH2A)
1774     {
1775       operands[1] = force_reg (SImode, operands[1]);
1776       operands[2] = force_reg (SImode, operands[2]);
1777       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1778       DONE;
1779     }
1780   else if (TARGET_SH5)
1781     {
1782       function_symbol (operands[3],
1783                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1784                        SFUNC_STATIC);
1785
1786       if (TARGET_SHMEDIA)
1787         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1788       else if (TARGET_FPU_ANY)
1789         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1790       else
1791         last = gen_udivsi3_i1 (operands[0], operands[3]);
1792     }
1793   else
1794     {
1795       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1796       last = gen_udivsi3_i1 (operands[0], operands[3]);
1797     }
1798   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1799   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1800   last = emit_insn (last);
1801   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1802      invariant code motion can move it.  */
1803   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1804   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1805   DONE;
1806 }")
1807
1808 (define_insn "divsi3_sh2a"
1809   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1810         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1811                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1812   "TARGET_SH2A"
1813   "divs %2,%1"
1814   [(set_attr "type" "arith")
1815    (set_attr "in_delay_slot" "no")])
1816
1817 (define_insn "divsi3_i1"
1818   [(set (match_operand:SI 0 "register_operand" "=z")
1819         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1820    (clobber (reg:SI T_REG))
1821    (clobber (reg:SI PR_REG))
1822    (clobber (reg:SI R1_REG))
1823    (clobber (reg:SI R2_REG))
1824    (clobber (reg:SI R3_REG))
1825    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1826   "TARGET_SH1 && ! TARGET_SH4"
1827   "jsr  @%1%#"
1828   [(set_attr "type" "sfunc")
1829    (set_attr "needs_delay_slot" "yes")])
1830
1831 (define_insn "divsi3_i1_media"
1832   [(set (match_operand:SI 0 "register_operand" "=z")
1833         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1834    (clobber (reg:SI T_MEDIA_REG))
1835    (clobber (reg:SI PR_MEDIA_REG))
1836    (clobber (reg:SI R1_REG))
1837    (clobber (reg:SI R20_REG))
1838    (clobber (reg:SI R21_REG))
1839    (clobber (reg:SI TR0_REG))
1840    (use (match_operand 1 "target_operand" "b"))]
1841   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1842   "blink        %1, r18"
1843   [(set_attr "type" "sfunc")])
1844
1845 (define_insn "divsi3_media_2"
1846   [(set (match_operand:SI 0 "register_operand" "=z")
1847         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1848    (clobber (reg:SI T_MEDIA_REG))
1849    (clobber (reg:SI PR_MEDIA_REG))
1850    (clobber (reg:SI R1_REG))
1851    (clobber (reg:SI R21_REG))
1852    (clobber (reg:SI TR0_REG))
1853    (use (reg:SI R20_REG))
1854    (use (match_operand 1 "target_operand" "b"))]
1855   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1856   "blink        %1, r18"
1857   [(set_attr "type" "sfunc")])
1858
1859 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1860 ;; hard reg clobbers and data dependencies that we need when we want
1861 ;; to rematerialize the division into a call.
1862 (define_insn_and_split "divsi_inv_call"
1863   [(set (match_operand:SI 0 "register_operand" "=r")
1864         (div:SI (match_operand:SI 1 "register_operand" "r")
1865                 (match_operand:SI 2 "register_operand" "r")))
1866    (clobber (reg:SI R4_REG))
1867    (clobber (reg:SI R5_REG))
1868    (clobber (reg:SI T_MEDIA_REG))
1869    (clobber (reg:SI PR_MEDIA_REG))
1870    (clobber (reg:SI R1_REG))
1871    (clobber (reg:SI R21_REG))
1872    (clobber (reg:SI TR0_REG))
1873    (clobber (reg:SI R20_REG))
1874    (use (match_operand:SI 3 "register_operand" "r"))]
1875   "TARGET_SHMEDIA"
1876   "#"
1877   "&& (high_life_started || reload_completed)"
1878   [(set (match_dup 0) (match_dup 3))]
1879   ""
1880   [(set_attr "highpart" "must_split")])
1881
1882 ;; This is the combiner pattern for -mdiv=inv:call .
1883 (define_insn_and_split "*divsi_inv_call_combine"
1884   [(set (match_operand:SI 0 "register_operand" "=z")
1885         (div:SI (match_operand:SI 1 "register_operand" "r")
1886                 (match_operand:SI 2 "register_operand" "r")))
1887    (clobber (reg:SI R4_REG))
1888    (clobber (reg:SI R5_REG))
1889    (clobber (reg:SI T_MEDIA_REG))
1890    (clobber (reg:SI PR_MEDIA_REG))
1891    (clobber (reg:SI R1_REG))
1892    (clobber (reg:SI R21_REG))
1893    (clobber (reg:SI TR0_REG))
1894    (clobber (reg:SI R20_REG))
1895    (use (unspec:SI [(match_dup 1)
1896                     (match_operand:SI 3 "" "")
1897                     (unspec:SI [(match_operand:SI 4 "" "")
1898                                 (match_dup 3)
1899                                 (match_operand:DI 5 "" "")]
1900                      UNSPEC_DIV_INV_M2)
1901                     (match_operand:DI 6 "" "")
1902                     (const_int 0)
1903                     (const_int 0)]
1904          UNSPEC_DIV_INV_M3))]
1905   "TARGET_SHMEDIA"
1906   "#"
1907   "&& (high_life_started || reload_completed)"
1908   [(pc)]
1909   "
1910 {
1911   const char *name = sh_divsi3_libfunc;
1912   enum sh_function_kind kind = SFUNC_GOT;
1913   rtx sym;
1914
1915   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1916   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1917   while (TARGET_DIVIDE_INV_CALL2)
1918     {
1919       rtx x = operands[3];
1920
1921       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1922         break;
1923       x = XVECEXP (x, 0, 0);
1924       name = \"__sdivsi3_2\";
1925       kind = SFUNC_STATIC;
1926       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1927       break;
1928     }
1929   sym = function_symbol (NULL, name, kind);
1930   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1931   DONE;
1932 }"
1933   [(set_attr "highpart" "must_split")])
1934
1935 (define_expand "divsi3_i4_media"
1936   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1937    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1938    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1939    (set (match_operand:SI 0 "register_operand" "=r")
1940         (fix:SI (match_dup 5)))]
1941   "TARGET_SHMEDIA_FPU"
1942   "
1943 {
1944   operands[3] = gen_reg_rtx (DFmode);
1945   operands[4] = gen_reg_rtx (DFmode);
1946   operands[5] = gen_reg_rtx (DFmode);
1947 }")
1948
1949 (define_insn "divsi3_i4"
1950   [(set (match_operand:SI 0 "register_operand" "=y")
1951         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1952    (clobber (reg:SI PR_REG))
1953    (clobber (reg:DF DR0_REG))
1954    (clobber (reg:DF DR2_REG))
1955    (use (reg:PSI FPSCR_REG))
1956    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1957   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1958   "jsr  @%1%#"
1959   [(set_attr "type" "sfunc")
1960    (set_attr "fp_mode" "double")
1961    (set_attr "needs_delay_slot" "yes")])
1962
1963 (define_insn "divsi3_i4_single"
1964   [(set (match_operand:SI 0 "register_operand" "=y")
1965         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1966    (clobber (reg:SI PR_REG))
1967    (clobber (reg:DF DR0_REG))
1968    (clobber (reg:DF DR2_REG))
1969    (clobber (reg:SI R2_REG))
1970    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1971   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1972   "jsr  @%1%#"
1973   [(set_attr "type" "sfunc")
1974    (set_attr "needs_delay_slot" "yes")])
1975
1976 (define_expand "divsi3"
1977   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1978    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1979    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1980    (parallel [(set (match_operand:SI 0 "register_operand" "")
1981                    (div:SI (reg:SI R4_REG)
1982                            (reg:SI R5_REG)))
1983               (clobber (reg:SI T_REG))
1984               (clobber (reg:SI PR_REG))
1985               (clobber (reg:SI R1_REG))
1986               (clobber (reg:SI R2_REG))
1987               (clobber (reg:SI R3_REG))
1988               (use (match_dup 3))])]
1989   ""
1990   "
1991 {
1992   rtx first, last;
1993
1994   operands[3] = gen_reg_rtx (Pmode);
1995   /* Emit the move of the address to a pseudo outside of the libcall.  */
1996   if (TARGET_HARD_SH4 && TARGET_SH2E)
1997     {
1998       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
1999       if (TARGET_FPU_SINGLE)
2000         last = gen_divsi3_i4_single (operands[0], operands[3]);
2001       else
2002         last = gen_divsi3_i4 (operands[0], operands[3]);
2003     }
2004   else if (TARGET_SH2A)
2005     {
2006       operands[1] = force_reg (SImode, operands[1]);
2007       operands[2] = force_reg (SImode, operands[2]);
2008       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2009       DONE;
2010     }
2011   else if (TARGET_DIVIDE_INV)
2012     {
2013       rtx dividend = operands[1];
2014       rtx divisor = operands[2];
2015       rtx tab_base;
2016       rtx nsb_res = gen_reg_rtx (DImode);
2017       rtx norm64 = gen_reg_rtx (DImode);
2018       rtx tab_ix = gen_reg_rtx (DImode);
2019       rtx norm32 = gen_reg_rtx (SImode);
2020       rtx i92 = force_reg (DImode, GEN_INT (92));
2021       rtx scratch0a = gen_reg_rtx (DImode);
2022       rtx scratch0b = gen_reg_rtx (DImode);
2023       rtx inv0 = gen_reg_rtx (SImode);
2024       rtx scratch1a = gen_reg_rtx (DImode);
2025       rtx scratch1b = gen_reg_rtx (DImode);
2026       rtx shift = gen_reg_rtx (DImode);
2027       rtx i2p27, i43;
2028       rtx inv1 = gen_reg_rtx (SImode);
2029       rtx scratch2a = gen_reg_rtx (DImode);
2030       rtx scratch2b = gen_reg_rtx (SImode);
2031       rtx inv2 = gen_reg_rtx (SImode);
2032       rtx scratch3a = gen_reg_rtx (DImode);
2033       rtx scratch3b = gen_reg_rtx (DImode);
2034       rtx scratch3c = gen_reg_rtx (DImode);
2035       rtx scratch3d = gen_reg_rtx (SImode);
2036       rtx scratch3e = gen_reg_rtx (DImode);
2037       rtx result = gen_reg_rtx (SImode);
2038
2039       if (! arith_reg_or_0_operand (dividend, SImode))
2040         dividend = force_reg (SImode, dividend);
2041       if (! arith_reg_operand (divisor, SImode))
2042         divisor = force_reg (SImode, divisor);
2043       if (flag_pic && Pmode != DImode)
2044         {
2045           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2046           tab_base = gen_datalabel_ref (tab_base);
2047           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2048         }
2049       else
2050         {
2051           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2052           tab_base = gen_datalabel_ref (tab_base);
2053           tab_base = force_reg (DImode, tab_base);
2054         }
2055       if (TARGET_DIVIDE_INV20U)
2056         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2057       else
2058         i2p27 = GEN_INT (0);
2059       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2060         i43 = force_reg (DImode, GEN_INT (43));
2061       else
2062         i43 = GEN_INT (0);
2063       emit_insn (gen_nsbdi (nsb_res,
2064                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2065       emit_insn (gen_ashldi3_media (norm64,
2066                                     gen_rtx_SUBREG (DImode, divisor, 0),
2067                                     nsb_res));
2068       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2069       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2070       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2071                                    inv0, scratch0a, scratch0b,
2072                                    scratch1a, scratch1b));
2073       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2074       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2075                                    scratch2a));
2076       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2077                                    i2p27, i43,
2078                                    scratch3a, scratch3b, scratch3c,
2079                                    scratch2a, scratch2b, scratch3d, scratch3e));
2080       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2081         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2082       else if (TARGET_DIVIDE_INV_FP)
2083         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2084                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2085                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2086                                      gen_reg_rtx (DFmode)));
2087       else
2088         emit_move_insn (operands[0], result);
2089       DONE;
2090     }
2091   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2092     {
2093       operands[1] = force_reg (SImode, operands[1]);
2094       operands[2] = force_reg (SImode, operands[2]);
2095       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2096       DONE;
2097     }
2098   else if (TARGET_SH5)
2099     {
2100       if (TARGET_DIVIDE_CALL2)
2101         {
2102           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2103           tab_base = gen_datalabel_ref (tab_base);
2104           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2105         }
2106       if (TARGET_FPU_ANY && TARGET_SH1)
2107         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2108       else if (TARGET_DIVIDE_CALL2)
2109         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2110       else
2111         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2112
2113       if (TARGET_SHMEDIA)
2114         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2115                 (operands[0], operands[3]));
2116       else if (TARGET_FPU_ANY)
2117         last = gen_divsi3_i4_single (operands[0], operands[3]);
2118       else
2119         last = gen_divsi3_i1 (operands[0], operands[3]);
2120     }
2121   else
2122     {
2123       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2124       last = gen_divsi3_i1 (operands[0], operands[3]);
2125     }
2126   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2127   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2128   last = emit_insn (last);
2129   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2130      invariant code motion can move it.  */
2131   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2132   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2133   DONE;
2134 }")
2135
2136 ;; operands: inv0, tab_base, tab_ix, norm32
2137 ;; scratch equiv in sdivsi3_2: r19, r21
2138 (define_expand "divsi_inv_m0"
2139   [(set (match_operand:SI 0 "register_operand" "=r")
2140         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2141                     (match_operand:DI 2 "register_operand" "r")
2142                     (match_operand:SI 3 "register_operand" "r")]
2143          UNSPEC_DIV_INV_M0))
2144    (clobber (match_operand:DI 4 "register_operand" "=r"))
2145    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2146   "TARGET_SHMEDIA"
2147   "
2148 {
2149 /*
2150 tab_base: r20
2151 tab_ix: r21
2152 norm32: r25
2153  ldx.ub r20, r21, r19 // u0.8
2154  shlli r21, 1, r21
2155  muls.l r25, r19, r19 // s2.38
2156  ldx.w r20, r21, r21  // s2.14
2157  shari r19, 24, r19   // truncate to s2.14
2158  sub r21, r19, r19    // some 11 bit inverse in s1.14
2159 */
2160
2161   rtx inv0 = operands[0];
2162   rtx tab_base = operands[1];
2163   rtx tab_ix = operands[2];
2164   rtx norm32 = operands[3];
2165   rtx scratch0 = operands[4];
2166   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2167   rtx scratch1 = operands[5];
2168   rtx mem;
2169
2170   mem = gen_rtx_MEM (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2171   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2172   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2173   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2174   mem = gen_rtx_MEM (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2175   emit_insn (gen_extendhidi2 (scratch1, mem));
2176   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2177   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2178   DONE;
2179 }")
2180
2181 ;; operands: inv1, tab_base, tab_ix, norm32
2182 (define_insn_and_split "divsi_inv_m1"
2183   [(set (match_operand:SI 0 "register_operand" "=r")
2184         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2185                     (match_operand:DI 2 "register_operand" "r")
2186                     (match_operand:SI 3 "register_operand" "r")]
2187          UNSPEC_DIV_INV_M1))
2188    (clobber (match_operand:SI 4 "register_operand" "=r"))
2189    (clobber (match_operand:DI 5 "register_operand" "=r"))
2190    (clobber (match_operand:DI 6 "register_operand" "=r"))
2191    (clobber (match_operand:DI 7 "register_operand" "=r"))
2192    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2193   "TARGET_SHMEDIA"
2194   "#"
2195   "&& no_new_pseudos"
2196   [(pc)]
2197   "
2198 {
2199 /* inv0: r19
2200  muls.l r19, r19, r18 // u0.28
2201  muls.l r25, r18, r18 // s2.58
2202  shlli r19, 45, r0    // multiply by two and convert to s2.58
2203  sub r0, r18, r18
2204  shari r18, 28, r18   // some 18 bit inverse in s1.30
2205 */
2206
2207   rtx inv1 = operands[0];
2208   rtx tab_base = operands[1];
2209   rtx tab_ix = operands[2];
2210   rtx norm32 = operands[3];
2211   rtx inv0 = operands[4];
2212   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2213   rtx scratch0a = operands[5];
2214   rtx scratch0b = operands[6];
2215   rtx scratch0 = operands[7];
2216   rtx scratch1 = operands[8];
2217   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2218
2219   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2220                                scratch0a, scratch0b));
2221   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2222   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2223   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2224   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2225   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2226   DONE;
2227 }")
2228
2229 ;; operands: inv2, norm32, inv1, i92
2230 (define_insn_and_split "divsi_inv_m2"
2231   [(set (match_operand:SI 0 "register_operand" "=r")
2232         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2233                     (match_operand:SI 2 "register_operand" "r")
2234                     (match_operand:DI 3 "register_operand" "r")]
2235          UNSPEC_DIV_INV_M2))
2236    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2237   "TARGET_SHMEDIA"
2238   "#"
2239   "&& no_new_pseudos"
2240   [(pc)]
2241   "
2242 {
2243 /*
2244  muls.l r18, r25, r0  // s2.60
2245  shari r0, 16, r0     // s-16.44
2246   sub
2247  muls.l r0, r18, r19  // s-16.74
2248  shari r19, 30, r19   // s-16.44
2249 */
2250   rtx inv2 = operands[0];
2251   rtx norm32 = operands[1];
2252   rtx inv1 = operands[2];
2253   rtx i92 = operands[3];
2254   rtx scratch0 = operands[4];
2255   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2256
2257   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2258   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2259   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2260   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2261   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2262   DONE;
2263 }")
2264
2265 (define_insn_and_split "divsi_inv_m3"
2266   [(set (match_operand:SI 0 "register_operand" "=r")
2267         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2268                     (match_operand:SI 2 "register_operand" "r")
2269                     (match_operand:SI 3 "register_operand" "r")
2270                     (match_operand:DI 4 "register_operand" "r")
2271                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2272                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2273          UNSPEC_DIV_INV_M3))
2274    (clobber (match_operand:DI 7 "register_operand" "=r"))
2275    (clobber (match_operand:DI 8 "register_operand" "=r"))
2276    (clobber (match_operand:DI 9 "register_operand" "=r"))
2277    (clobber (match_operand:DI 10 "register_operand" "=r"))
2278    (clobber (match_operand:SI 11 "register_operand" "=r"))
2279    (clobber (match_operand:SI 12 "register_operand" "=r"))
2280    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2281   "TARGET_SHMEDIA"
2282   "#"
2283   "&& no_new_pseudos"
2284   [(pc)]
2285   "
2286 {
2287 /*
2288   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2289   r0: scratch0  r19: scratch1 r21: scratch2
2290
2291   muls.l r18, r4, r25 // s32.30
2292  muls.l r19, r4, r19  // s15.30
2293  shari r25, 63, r21
2294   shari r19, 14, r19  // s18.-14
2295  sub r25, r19, r0
2296  shard r0, r1, r0
2297  sub r0, r21, r0
2298 */
2299
2300   rtx result = operands[0];
2301   rtx dividend = operands[1];
2302   rtx inv1 = operands[2];
2303   rtx inv2 = operands[3];
2304   rtx shift = operands[4];
2305   rtx scratch0 = operands[7];
2306   rtx scratch1 = operands[8];
2307   rtx scratch2 = operands[9];
2308
2309   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2310   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2311   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2312   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2313   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2314   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2315   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2316   DONE;
2317 }")
2318
2319 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2320 ;; inv1: tab_base, tab_ix, norm32
2321 ;; inv2: norm32, inv1, i92
2322 (define_insn_and_split "divsi_inv_m1_3"
2323   [(set (match_operand:SI 0 "register_operand" "=r")
2324         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2325                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2326                                 (match_operand:DI 3 "register_operand" "r")
2327                                 (match_operand:SI 4 "register_operand" "r")]
2328                      UNSPEC_DIV_INV_M1)
2329                     (unspec:SI [(match_dup 4)
2330                                 (unspec:SI [(match_dup 2)
2331                                             (match_dup 3)
2332                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2333                                 (match_operand:SI 5 "" "")]
2334                      UNSPEC_DIV_INV_M2)
2335                     (match_operand:DI 6 "register_operand" "r")
2336                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2337                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2338          UNSPEC_DIV_INV_M3))
2339    (clobber (match_operand:DI 9 "register_operand" "=r"))
2340    (clobber (match_operand:DI 10 "register_operand" "=r"))
2341    (clobber (match_operand:DI 11 "register_operand" "=r"))
2342    (clobber (match_operand:DI 12 "register_operand" "=r"))
2343    (clobber (match_operand:SI 13 "register_operand" "=r"))
2344    (clobber (match_operand:SI 14 "register_operand" "=r"))
2345    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2346   "TARGET_SHMEDIA
2347    && (TARGET_DIVIDE_INV_MINLAT
2348        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2349   "#"
2350   "&& no_new_pseudos"
2351   [(pc)]
2352   "
2353 {
2354   rtx result = operands[0];
2355   rtx dividend = operands[1];
2356   rtx tab_base = operands[2];
2357   rtx tab_ix = operands[3];
2358   rtx norm32 = operands[4];
2359   /* rtx i92 = operands[5]; */
2360   rtx shift = operands[6];
2361   rtx i2p27 = operands[7];
2362   rtx i43 = operands[8];
2363   rtx scratch0 = operands[9];
2364   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2365   rtx scratch1 = operands[10];
2366   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2367   rtx scratch2 = operands[11];
2368   rtx scratch3 = operands[12];
2369   rtx scratch4 = operands[13];
2370   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2371   rtx scratch5 = operands[14];
2372   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2373   rtx scratch6 = operands[15];
2374
2375   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2376                                scratch0, scratch1));
2377   /* inv0 == scratch4 */
2378   if (! TARGET_DIVIDE_INV20U)
2379     {
2380       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2381       i2p27 = scratch0;
2382       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2383     }
2384   else
2385     {
2386       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2387       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388     }
2389   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2390   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2391   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2392   /* inv1 == scratch4 */
2393
2394   if (TARGET_DIVIDE_INV_MINLAT)
2395     {
2396       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2397       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2398       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2399       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2400       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2401       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2402       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2403       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2404       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2405       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2406       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2407     }
2408   else
2409     {
2410       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2411       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2412       emit_insn (gen_nsbdi (scratch6,
2413                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2414       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2415       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2416       emit_insn (gen_divsi_inv20 (scratch2,
2417                                   norm32, scratch4, dividend,
2418                                   scratch6, scratch3, i43,
2419                                   /* scratch0 may be shared with i2p27.  */
2420                                   scratch0, scratch1, scratch5,
2421                                   label, label, i2p27));
2422     }
2423   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2424   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2425   DONE;
2426 }")
2427
2428 (define_insn "divsi_inv20"
2429   [(set (match_operand:DI 0 "register_operand" "=&r")
2430         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2431                     (match_operand:SI 2 "register_operand" "r")
2432                     (match_operand:SI 3 "register_operand" "r")
2433                     (match_operand:DI 4 "register_operand" "r")
2434                     (match_operand:DI 5 "register_operand" "r")
2435                     (match_operand:DI 6 "register_operand" "r")
2436                     (match_operand:DI 12 "register_operand" "r")
2437                     (match_operand 10 "target_operand" "b")
2438                     (match_operand 11 "immediate_operand" "i")]
2439          UNSPEC_DIV_INV20))
2440    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2441    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2442    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2443   "TARGET_SHMEDIA
2444    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2445   "*
2446 {
2447 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2448              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2449              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2450              %10 label (tr), %11 label (imm)
2451
2452  muls.l inv1, norm32, scratch0  // s2.60
2453   muls.l inv1, dividend, result // s32.30
2454   xor i2p27, result_sign, round_scratch
2455  bge/u dividend_nsb, i43, tr.. (label)
2456  shari scratch0, 16, scratch0   // s-16.44
2457  muls.l sratch0_si, inv1, scratch0 // s-16.74
2458   sub result, round_scratch, result
2459   shari dividend, 14, scratch1   // s19.-14
2460  shari scratch0, 30, scratch0   // s-16.44
2461  muls.l scratch0, scratch1, round_scratch // s15.30
2462 label:
2463  sub result, round_scratch, result */
2464
2465   int likely = TARGET_DIVIDE_INV20L;
2466
2467   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2468   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2469   output_asm_insn (likely
2470                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2471                    : \"bge/u\t%4, %6, %10\", operands);
2472   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2473   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2474   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2475   return (likely
2476           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2477           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2478 }")
2479
2480 (define_insn_and_split "divsi_inv_fp"
2481   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2482         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2483                 (match_operand:SI 2 "register_operand" "rf")))
2484    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2485    (clobber (match_operand:SI 4 "register_operand" "=r"))
2486    (clobber (match_operand:SI 5 "register_operand" "=r"))
2487    (clobber (match_operand:DF 6 "register_operand" "=r"))
2488    (clobber (match_operand:DF 7 "register_operand" "=r"))
2489    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2490   "TARGET_SHMEDIA_FPU"
2491   "#"
2492   "&& (high_life_started || reload_completed)"
2493   [(set (match_dup 0) (match_dup 3))]
2494   ""
2495   [(set_attr "highpart" "must_split")])
2496
2497 ;; If a matching group of divide-by-inverse instructions is in the same
2498 ;; basic block after gcse & loop optimizations, we want to transform them
2499 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2500 (define_insn_and_split "*divsi_inv_fp_combine"
2501   [(set (match_operand:SI 0 "register_operand" "=f")
2502         (div:SI (match_operand:SI 1 "register_operand" "f")
2503                 (match_operand:SI 2 "register_operand" "f")))
2504    (use (unspec:SI [(match_dup 1)
2505                     (match_operand:SI 3 "" "")
2506                     (unspec:SI [(match_operand:SI 4 "" "")
2507                                 (match_dup 3)
2508                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2509                     (match_operand:DI 6 "" "")
2510                     (const_int 0)
2511                     (const_int 0)] UNSPEC_DIV_INV_M3))
2512    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2513    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2514    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2515    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2516    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2517   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2518   "#"
2519   "&& 1"
2520   [(set (match_dup 9) (float:DF (match_dup 1)))
2521    (set (match_dup 10) (float:DF (match_dup 2)))
2522    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2523    (set (match_dup 8)
2524         (fix:SI (match_dup 11)))
2525    (set (match_dup 0) (match_dup 8))]
2526   "
2527 {
2528   if (! fp_arith_reg_operand (operands[1], SImode))
2529     {
2530       emit_move_insn (operands[7], operands[1]);
2531       operands[1] = operands[7];
2532     }
2533   if (! fp_arith_reg_operand (operands[2], SImode))
2534     {
2535       emit_move_insn (operands[8], operands[2]);
2536       operands[2] = operands[8];
2537     }
2538 }"
2539   [(set_attr "highpart" "must_split")])
2540 \f
2541 ;; -------------------------------------------------------------------------
2542 ;; Multiplication instructions
2543 ;; -------------------------------------------------------------------------
2544
2545 (define_insn "umulhisi3_i"
2546   [(set (reg:SI MACL_REG)
2547         (mult:SI (zero_extend:SI
2548                   (match_operand:HI 0 "arith_reg_operand" "r"))
2549                  (zero_extend:SI
2550                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2551   "TARGET_SH1"
2552   "mulu.w       %1,%0"
2553   [(set_attr "type" "smpy")])
2554
2555 (define_insn "mulhisi3_i"
2556   [(set (reg:SI MACL_REG)
2557         (mult:SI (sign_extend:SI
2558                   (match_operand:HI 0 "arith_reg_operand" "r"))
2559                  (sign_extend:SI
2560                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2561   "TARGET_SH1"
2562   "muls.w       %1,%0"
2563   [(set_attr "type" "smpy")])
2564
2565 (define_expand "mulhisi3"
2566   [(set (reg:SI MACL_REG)
2567         (mult:SI (sign_extend:SI
2568                   (match_operand:HI 1 "arith_reg_operand" ""))
2569                  (sign_extend:SI
2570                   (match_operand:HI 2 "arith_reg_operand" ""))))
2571    (set (match_operand:SI 0 "arith_reg_operand" "")
2572         (reg:SI MACL_REG))]
2573   "TARGET_SH1"
2574   "
2575 {
2576   rtx first, last;
2577
2578   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2579   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2580   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2581      invariant code motion can move it.  */
2582   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2583   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2584   /* expand_binop can't find a suitable code in umul_widen_optab to
2585      make a REG_EQUAL note from, so make one here.
2586      See also smulsi3_highpart.
2587      ??? Alternatively, we could put this at the calling site of expand_binop,
2588      i.e. expand_expr.  */
2589   REG_NOTES (last)
2590     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2591                          REG_NOTES (last));
2592   DONE;
2593 }")
2594
2595 (define_expand "umulhisi3"
2596   [(set (reg:SI MACL_REG)
2597         (mult:SI (zero_extend:SI
2598                   (match_operand:HI 1 "arith_reg_operand" ""))
2599                  (zero_extend:SI
2600                   (match_operand:HI 2 "arith_reg_operand" ""))))
2601    (set (match_operand:SI 0 "arith_reg_operand" "")
2602         (reg:SI MACL_REG))]
2603   "TARGET_SH1"
2604   "
2605 {
2606   rtx first, last;
2607
2608   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2609   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2610   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2611      invariant code motion can move it.  */
2612   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2613   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2614   /* expand_binop can't find a suitable code in umul_widen_optab to
2615      make a REG_EQUAL note from, so make one here.
2616      See also smulsi3_highpart.
2617      ??? Alternatively, we could put this at the calling site of expand_binop,
2618      i.e. expand_expr.  */
2619   REG_NOTES (last)
2620     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2621                          REG_NOTES (last));
2622   DONE;
2623 }")
2624
2625 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2626 ;; a call to a routine which clobbers known registers.
2627
2628 (define_insn ""
2629   [(set (match_operand:SI 1 "register_operand" "=z")
2630         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2631    (clobber (reg:SI MACL_REG))
2632    (clobber (reg:SI T_REG))
2633    (clobber (reg:SI PR_REG))
2634    (clobber (reg:SI R3_REG))
2635    (clobber (reg:SI R2_REG))
2636    (clobber (reg:SI R1_REG))
2637    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2638   "TARGET_SH1"
2639   "jsr  @%0%#"
2640   [(set_attr "type" "sfunc")
2641    (set_attr "needs_delay_slot" "yes")])
2642
2643 (define_expand "mulsi3_call"
2644   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2645    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2646    (parallel[(set (match_operand:SI 0 "register_operand" "")
2647                   (mult:SI (reg:SI R4_REG)
2648                            (reg:SI R5_REG)))
2649              (clobber (reg:SI MACL_REG))
2650              (clobber (reg:SI T_REG))
2651              (clobber (reg:SI PR_REG))
2652              (clobber (reg:SI R3_REG))
2653              (clobber (reg:SI R2_REG))
2654              (clobber (reg:SI R1_REG))
2655              (use (match_operand:SI 3 "register_operand" ""))])]
2656   "TARGET_SH1"
2657   "")
2658
2659 (define_insn "mul_r"
2660   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2661         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2662                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2663   "TARGET_SH2A"
2664   "mulr %2,%0"
2665   [(set_attr "type" "dmpy")])
2666
2667 (define_insn "mul_l"
2668   [(set (reg:SI MACL_REG)
2669         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2670                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2671   "TARGET_SH2"
2672   "mul.l        %1,%0"
2673   [(set_attr "type" "dmpy")])
2674
2675 (define_expand "mulsi3"
2676   [(set (reg:SI MACL_REG)
2677         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2678                   (match_operand:SI 2 "arith_reg_operand" "")))
2679    (set (match_operand:SI 0 "arith_reg_operand" "")
2680         (reg:SI MACL_REG))]
2681   "TARGET_SH1"
2682   "
2683 {
2684   rtx first, last;
2685
2686   if (!TARGET_SH2)
2687     {
2688       /* The address must be set outside the libcall,
2689          since it goes into a pseudo.  */
2690       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2691       rtx addr = force_reg (SImode, sym);
2692       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2693                                    operands[2], addr);
2694       first = insns;
2695       last = emit_insn (insns);
2696     }
2697   else
2698     {
2699       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2700
2701       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2702       /* consec_sets_giv can only recognize the first insn that sets a
2703          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2704          note.  */
2705       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2706     }
2707   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2708      invariant code motion can move it.  */
2709   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2710   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2711   DONE;
2712 }")
2713
2714 (define_insn "mulsidi3_i"
2715   [(set (reg:SI MACH_REG)
2716         (truncate:SI
2717          (lshiftrt:DI
2718           (mult:DI
2719            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2720            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2721           (const_int 32))))
2722    (set (reg:SI MACL_REG)
2723         (mult:SI (match_dup 0)
2724                  (match_dup 1)))]
2725   "TARGET_SH2"
2726   "dmuls.l      %1,%0"
2727   [(set_attr "type" "dmpy")])
2728
2729 (define_expand "mulsidi3"
2730   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2731         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2732                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2733   "TARGET_SH2 || TARGET_SHMEDIA"
2734   "
2735 {
2736   if (TARGET_SH2)
2737     {
2738        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2739                                         operands[2]));
2740        DONE;
2741     }
2742 }")
2743
2744 (define_insn "mulsidi3_media"
2745   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2746         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2747                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2748   "TARGET_SHMEDIA"
2749   "muls.l       %1, %2, %0"
2750   [(set_attr "type" "dmpy_media")
2751    (set_attr "highpart" "ignore")])
2752
2753 (define_insn "mulsidi3_compact"
2754   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2755         (mult:DI
2756          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2757          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2758    (clobber (reg:SI MACH_REG))
2759    (clobber (reg:SI MACL_REG))]
2760   "TARGET_SH2"
2761   "#")
2762
2763 (define_split
2764   [(set (match_operand:DI 0 "arith_reg_dest" "")
2765         (mult:DI
2766          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2767          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2768    (clobber (reg:SI MACH_REG))
2769    (clobber (reg:SI MACL_REG))]
2770   "TARGET_SH2"
2771   [(const_int 0)]
2772   "
2773 {
2774   rtx low_dst = gen_lowpart (SImode, operands[0]);
2775   rtx high_dst = gen_highpart (SImode, operands[0]);
2776
2777   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2778
2779   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2780   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2781   /* We need something to tag the possible REG_EQUAL notes on to.  */
2782   emit_move_insn (operands[0], operands[0]);
2783   DONE;
2784 }")
2785
2786 (define_insn "umulsidi3_i"
2787   [(set (reg:SI MACH_REG)
2788         (truncate:SI
2789          (lshiftrt:DI
2790           (mult:DI
2791            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2792            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2793           (const_int 32))))
2794    (set (reg:SI MACL_REG)
2795         (mult:SI (match_dup 0)
2796                  (match_dup 1)))]
2797   "TARGET_SH2"
2798   "dmulu.l      %1,%0"
2799   [(set_attr "type" "dmpy")])
2800
2801 (define_expand "umulsidi3"
2802   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2803         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2804                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2805   "TARGET_SH2 || TARGET_SHMEDIA"
2806   "
2807 {
2808   if (TARGET_SH2)
2809     {
2810        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2811                                          operands[2]));
2812        DONE;
2813     }
2814 }")
2815
2816 (define_insn "umulsidi3_media"
2817   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2818         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2819                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2820   "TARGET_SHMEDIA"
2821   "mulu.l       %1, %2, %0"
2822   [(set_attr "type" "dmpy_media")
2823    (set_attr "highpart" "ignore")])
2824
2825 (define_insn "umulsidi3_compact"
2826   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2827         (mult:DI
2828          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2829          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2830    (clobber (reg:SI MACH_REG))
2831    (clobber (reg:SI MACL_REG))]
2832   "TARGET_SH2"
2833   "#")
2834
2835 (define_split
2836   [(set (match_operand:DI 0 "arith_reg_dest" "")
2837         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2838                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2839    (clobber (reg:SI MACH_REG))
2840    (clobber (reg:SI MACL_REG))]
2841   "TARGET_SH2"
2842   [(const_int 0)]
2843   "
2844 {
2845   rtx low_dst = gen_lowpart (SImode, operands[0]);
2846   rtx high_dst = gen_highpart (SImode, operands[0]);
2847
2848   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2849
2850   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2851   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2852   /* We need something to tag the possible REG_EQUAL notes on to.  */
2853   emit_move_insn (operands[0], operands[0]);
2854   DONE;
2855 }")
2856
2857 (define_insn "smulsi3_highpart_i"
2858   [(set (reg:SI MACH_REG)
2859         (truncate:SI
2860          (lshiftrt:DI
2861           (mult:DI
2862            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2863            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2864           (const_int 32))))
2865    (clobber (reg:SI MACL_REG))]
2866   "TARGET_SH2"
2867   "dmuls.l      %1,%0"
2868   [(set_attr "type" "dmpy")])
2869
2870 (define_expand "smulsi3_highpart"
2871   [(parallel
2872     [(set (reg:SI MACH_REG)
2873           (truncate:SI
2874            (lshiftrt:DI
2875             (mult:DI
2876              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2877              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2878             (const_int 32))))
2879     (clobber (reg:SI MACL_REG))])
2880    (set (match_operand:SI 0 "arith_reg_operand" "")
2881         (reg:SI MACH_REG))]
2882   "TARGET_SH2"
2883   "
2884 {
2885   rtx first, last;
2886
2887   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2888   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2889   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2890      invariant code motion can move it.  */
2891   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2892   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2893   /* expand_binop can't find a suitable code in mul_highpart_optab to
2894      make a REG_EQUAL note from, so make one here.
2895      See also {,u}mulhisi.
2896      ??? Alternatively, we could put this at the calling site of expand_binop,
2897      i.e. expand_mult_highpart.  */
2898   REG_NOTES (last)
2899     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2900                          REG_NOTES (last));
2901   DONE;
2902 }")
2903
2904 (define_insn "umulsi3_highpart_i"
2905   [(set (reg:SI MACH_REG)
2906         (truncate:SI
2907          (lshiftrt:DI
2908           (mult:DI
2909            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2910            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2911           (const_int 32))))
2912    (clobber (reg:SI MACL_REG))]
2913   "TARGET_SH2"
2914   "dmulu.l      %1,%0"
2915   [(set_attr "type" "dmpy")])
2916
2917 (define_expand "umulsi3_highpart"
2918   [(parallel
2919     [(set (reg:SI MACH_REG)
2920           (truncate:SI
2921            (lshiftrt:DI
2922             (mult:DI
2923              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2924              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2925             (const_int 32))))
2926     (clobber (reg:SI MACL_REG))])
2927    (set (match_operand:SI 0 "arith_reg_operand" "")
2928         (reg:SI MACH_REG))]
2929   "TARGET_SH2"
2930   "
2931 {
2932   rtx first, last;
2933
2934   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2935   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2936   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2937      invariant code motion can move it.  */
2938   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2939   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2940   DONE;
2941 }")
2942
2943 (define_insn_and_split "muldi3"
2944   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2945         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2946                  (match_operand:DI 2 "arith_reg_operand" "r")))
2947    (clobber (match_scratch:DI 3 "=&r"))
2948    (clobber (match_scratch:DI 4 "=r"))]
2949   "TARGET_SHMEDIA"
2950   "#"
2951   "reload_completed"
2952   [(const_int 0)]
2953   "
2954 {
2955   rtx op3_v2si, op2_v2si;
2956
2957   op3_v2si = operands[3];
2958   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2959     {
2960       op3_v2si = XEXP (op3_v2si, 0);
2961       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2962     }
2963   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2964   op2_v2si = operands[2];
2965   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2966     {
2967       op2_v2si = XEXP (op2_v2si, 0);
2968       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2969     }
2970   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2971   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2972   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2973   emit_insn (gen_umulsidi3_media (operands[4],
2974                                  sh_gen_truncate (SImode, operands[1], 0),
2975                                  sh_gen_truncate (SImode, operands[2], 0)));
2976   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2977   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2978   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2979   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2980   DONE;
2981 }")
2982
2983 \f
2984 ;; -------------------------------------------------------------------------
2985 ;; Logical operations
2986 ;; -------------------------------------------------------------------------
2987
2988 (define_insn "*andsi3_compact"
2989   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2990         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2991                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2992   "TARGET_SH1"
2993   "and  %2,%0"
2994   [(set_attr "type" "arith")])
2995
2996 (define_insn "*andsi3_media"
2997   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2998         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
2999                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3000   "TARGET_SHMEDIA"
3001   "@
3002         and     %1, %2, %0
3003         andi    %1, %2, %0"
3004   [(set_attr "type" "arith_media")])
3005
3006 ;; If the constant is 255, then emit an extu.b instruction instead of an
3007 ;; and, since that will give better code.
3008
3009 (define_expand "andsi3"
3010   [(set (match_operand:SI 0 "arith_reg_operand" "")
3011         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3012                 (match_operand:SI 2 "logical_operand" "")))]
3013   ""
3014   "
3015 {
3016   if (TARGET_SH1
3017       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3018     {
3019       emit_insn (gen_zero_extendqisi2 (operands[0],
3020                                        gen_lowpart (QImode, operands[1])));
3021       DONE;
3022     }
3023 }")
3024
3025 (define_insn_and_split "anddi3"
3026   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3027         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3028                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3029   "TARGET_SHMEDIA"
3030   "@
3031         and     %1, %2, %0
3032         andi    %1, %2, %0
3033         #"
3034   "reload_completed
3035    && ! logical_operand (operands[2], DImode)"
3036   [(const_int 0)]
3037   "
3038 {
3039   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3040     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3041   else
3042     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3043   DONE;
3044 }"
3045   [(set_attr "type" "arith_media")])
3046
3047 (define_insn "andcsi3"
3048   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3049         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3050                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3051   "TARGET_SHMEDIA"
3052   "andc %1,%2,%0"
3053   [(set_attr "type" "arith_media")])
3054
3055 (define_insn "andcdi3"
3056   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3057         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3058                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3059   "TARGET_SHMEDIA"
3060   "andc %1,%2,%0"
3061   [(set_attr "type" "arith_media")])
3062
3063 (define_expand "iorsi3"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "")
3065         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3066                 (match_operand:SI 2 "logical_operand" "")))]
3067   ""
3068   "")
3069
3070 (define_insn "*iorsi3_compact"
3071   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3072         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3073                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3074   "TARGET_SH1"
3075   "or   %2,%0"
3076   [(set_attr "type" "arith")])
3077
3078 (define_insn "*iorsi3_media"
3079   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3080         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3081                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3082   "TARGET_SHMEDIA"
3083   "@
3084         or      %1, %2, %0
3085         ori     %1, %2, %0"
3086   [(set_attr "type" "arith_media")])
3087
3088 (define_insn "iordi3"
3089   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3090         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3091                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3092   "TARGET_SHMEDIA"
3093   "@
3094         or      %1, %2, %0
3095         ori     %1, %2, %0"
3096   [(set_attr "type" "arith_media")])
3097
3098 (define_insn_and_split "*logical_sidi3"
3099   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3100         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3101                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3102                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3103   "TARGET_SHMEDIA"
3104   "#"
3105   "&& reload_completed"
3106   [(set (match_dup 0) (match_dup 3))]
3107   "
3108 {
3109   operands[3]
3110     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3111                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3112                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3113 }")
3114
3115 (define_insn_and_split "*logical_sidisi3"
3116   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3117         (truncate:SI (sign_extend:DI
3118                         (match_operator:SI 3 "logical_operator"
3119                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3120                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3121   "TARGET_SHMEDIA"
3122   "#"
3123   "&& 1"
3124   [(set (match_dup 0) (match_dup 3))])
3125
3126 (define_insn_and_split "*logical_sidi3_2"
3127   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3128         (sign_extend:DI (truncate:SI (sign_extend:DI
3129                         (match_operator:SI 3 "logical_operator"
3130                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3131                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3132   "TARGET_SHMEDIA"
3133   "#"
3134   "&& 1"
3135   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3136
3137 (define_expand "xorsi3"
3138   [(set (match_operand:SI 0 "arith_reg_operand" "")
3139         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3140                 (match_operand:SI 2 "xor_operand" "")))]
3141   ""
3142   "")
3143
3144 (define_insn "*xorsi3_compact"
3145   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3146         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3147                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3148   "TARGET_SH1"
3149   "xor  %2,%0"
3150   [(set_attr "type" "arith")])
3151
3152 (define_insn "*xorsi3_media"
3153   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3154         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3155                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3156   "TARGET_SHMEDIA"
3157   "@
3158         xor     %1, %2, %0
3159         xori    %1, %2, %0"
3160   [(set_attr "type" "arith_media")])
3161
3162 (define_insn "xordi3"
3163   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3164         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3165                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3166   "TARGET_SHMEDIA"
3167   "@
3168         xor     %1, %2, %0
3169         xori    %1, %2, %0"
3170   [(set_attr "type" "arith_media")])
3171
3172 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3173 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3174 (define_split
3175   [(set (match_operand:DI 0 "arith_reg_dest" "")
3176         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3177                           [(match_operand 1 "any_register_operand" "")
3178                            (match_operand 2 "any_register_operand" "")])))]
3179   "TARGET_SHMEDIA"
3180   [(set (match_dup 5) (match_dup 4))
3181    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3182 "
3183 {
3184   enum machine_mode inmode = GET_MODE (operands[1]);
3185   int offset = 0;
3186
3187   if (GET_CODE (operands[0]) == SUBREG)
3188     {
3189       offset = SUBREG_BYTE (operands[0]);
3190       operands[0] = SUBREG_REG (operands[0]);
3191     }
3192   gcc_assert (GET_CODE (operands[0]) == REG);
3193   if (! TARGET_LITTLE_ENDIAN)
3194     offset += 8 - GET_MODE_SIZE (inmode);
3195   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3196 }")
3197 \f
3198 ;; -------------------------------------------------------------------------
3199 ;; Shifts and rotates
3200 ;; -------------------------------------------------------------------------
3201
3202 (define_expand "rotldi3"
3203   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3204         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3205                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3206   "TARGET_SHMEDIA"
3207   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3208
3209 (define_insn "rotldi3_mextr"
3210   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3211         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3212                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3213   "TARGET_SHMEDIA"
3214   "*
3215 {
3216   static char templ[16];
3217
3218   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3219            8 - (int) (INTVAL (operands[2]) >> 3));
3220   return templ;
3221 }"
3222   [(set_attr "type" "arith_media")])
3223
3224 (define_expand "rotrdi3"
3225   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3226         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3227                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3228   "TARGET_SHMEDIA"
3229   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3230
3231 (define_insn "rotrdi3_mextr"
3232   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3233         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3234                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3235   "TARGET_SHMEDIA"
3236   "*
3237 {
3238   static char templ[16];
3239
3240   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3241   return templ;
3242 }"
3243   [(set_attr "type" "arith_media")])
3244
3245 (define_split
3246   [(set (match_operand:DI 0 "arith_reg_dest" "")
3247         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3248                                          "ua_address_operand" "")))
3249                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3250                            (const_int 8))))
3251    (clobber (match_operand:DI 3 "register_operand" ""))]
3252   "TARGET_SHMEDIA"
3253   [(match_dup 4) (match_dup 5)]
3254   "
3255 {
3256   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3257                  (operands[3], operands[1]));
3258   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3259                               GEN_INT (56), GEN_INT (8));
3260 }")
3261
3262 (define_insn "rotlsi3_1"
3263   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3264         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3265                    (const_int 1)))
3266    (set (reg:SI T_REG)
3267         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3268   "TARGET_SH1"
3269   "rotl %0"
3270   [(set_attr "type" "arith")])
3271
3272 (define_insn "rotlsi3_31"
3273   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3274         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3275                    (const_int 31)))
3276    (clobber (reg:SI T_REG))]
3277   "TARGET_SH1"
3278   "rotr %0"
3279   [(set_attr "type" "arith")])
3280
3281 (define_insn "rotlsi3_16"
3282   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3283         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3284                    (const_int 16)))]
3285   "TARGET_SH1"
3286   "swap.w       %1,%0"
3287   [(set_attr "type" "arith")])
3288
3289 (define_expand "rotlsi3"
3290   [(set (match_operand:SI 0 "arith_reg_dest" "")
3291         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3292                    (match_operand:SI 2 "immediate_operand" "")))]
3293   "TARGET_SH1"
3294   "
3295 {
3296   static const char rot_tab[] = {
3297     000, 000, 000, 000, 000, 000, 010, 001,
3298     001, 001, 011, 013, 003, 003, 003, 003,
3299     003, 003, 003, 003, 003, 013, 012, 002,
3300     002, 002, 010, 000, 000, 000, 000, 000,
3301   };
3302
3303   int count, choice;
3304
3305   if (GET_CODE (operands[2]) != CONST_INT)
3306     FAIL;
3307   count = INTVAL (operands[2]);
3308   choice = rot_tab[count];
3309   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3310     FAIL;
3311   choice &= 7;
3312   switch (choice)
3313     {
3314     case 0:
3315       emit_move_insn (operands[0], operands[1]);
3316       count -= (count & 16) * 2;
3317       break;
3318     case 3:
3319      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3320      count -= 16;
3321      break;
3322     case 1:
3323     case 2:
3324       {
3325         rtx parts[2];
3326         parts[0] = gen_reg_rtx (SImode);
3327         parts[1] = gen_reg_rtx (SImode);
3328         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3329         emit_move_insn (parts[choice-1], operands[1]);
3330         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3331         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3332         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3333         count = (count & ~16) - 8;
3334       }
3335     }
3336
3337   for (; count > 0; count--)
3338     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3339   for (; count < 0; count++)
3340     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3341
3342   DONE;
3343 }")
3344
3345 (define_insn "*rotlhi3_8"
3346   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3347         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3348                    (const_int 8)))]
3349   "TARGET_SH1"
3350   "swap.b       %1,%0"
3351   [(set_attr "type" "arith")])
3352
3353 (define_expand "rotlhi3"
3354   [(set (match_operand:HI 0 "arith_reg_operand" "")
3355         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3356                    (match_operand:HI 2 "immediate_operand" "")))]
3357   "TARGET_SH1"
3358   "
3359 {
3360   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3361     FAIL;
3362 }")
3363
3364 ;;
3365 ;; shift left
3366
3367 (define_insn "ashlsi3_sh2a"
3368   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3369         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3370                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3371   "TARGET_SH2A"
3372   "shad %2,%0"
3373   [(set_attr "type" "arith")
3374    (set_attr "length" "4")])
3375
3376 ;; This pattern is used by init_expmed for computing the costs of shift
3377 ;; insns.
3378
3379 (define_insn_and_split "ashlsi3_std"
3380   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3381         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3382                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3383    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3384   "TARGET_SH3
3385    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3386        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3387   "@
3388    shld %2,%0
3389    add  %0,%0
3390    shll%O2      %0
3391    #"
3392   "TARGET_SH3
3393    && reload_completed
3394    && GET_CODE (operands[2]) == CONST_INT
3395    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3396   [(set (match_dup 3) (match_dup 2))
3397    (parallel
3398     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3399      (clobber (match_dup 4))])]
3400   "operands[4] = gen_rtx_SCRATCH (SImode);"
3401   [(set_attr "length" "*,*,*,4")
3402    (set_attr "type" "dyn_shift,arith,arith,arith")])
3403
3404 (define_insn "ashlhi3_k"
3405   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3406         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3407                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3408   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3409   "@
3410         add     %0,%0
3411         shll%O2 %0"
3412   [(set_attr "type" "arith")])
3413
3414 (define_insn "ashlsi3_n"
3415   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3417                    (match_operand:SI 2 "const_int_operand" "n")))
3418    (clobber (reg:SI T_REG))]
3419   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3420   "#"
3421   [(set (attr "length")
3422         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3423                (const_string "2")
3424                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3425                (const_string "4")
3426                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3427                (const_string "6")]
3428               (const_string "8")))
3429    (set_attr "type" "arith")])
3430
3431 (define_split
3432   [(set (match_operand:SI 0 "arith_reg_dest" "")
3433         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3434                    (match_operand:SI 2 "const_int_operand" "")))
3435    (clobber (reg:SI T_REG))]
3436   "TARGET_SH1 && reload_completed"
3437   [(use (reg:SI R0_REG))]
3438   "
3439 {
3440   gen_shifty_op (ASHIFT, operands);
3441   DONE;
3442 }")
3443
3444 (define_insn "ashlsi3_media"
3445   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3446         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3447                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3448   "TARGET_SHMEDIA"
3449   "@
3450         shlld.l %1, %2, %0
3451         shlli.l %1, %2, %0"
3452   [(set_attr "type" "arith_media")
3453    (set_attr "highpart" "ignore")])
3454
3455 (define_expand "ashlsi3"
3456   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3457                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3458                               (match_operand:SI 2 "nonmemory_operand" "")))
3459               (clobber (reg:SI T_REG))])]
3460   ""
3461   "
3462 {
3463   if (TARGET_SHMEDIA)
3464     {
3465       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3466       DONE;
3467     }
3468   if (GET_CODE (operands[2]) == CONST_INT
3469       && sh_dynamicalize_shift_p (operands[2]))
3470     operands[2] = force_reg (SImode, operands[2]);
3471   if (TARGET_SH3)
3472     {
3473       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3474       DONE;
3475     }
3476   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3477     FAIL;
3478 }")
3479
3480 (define_insn "*ashlhi3_n"
3481   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3482         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3483                    (match_operand:HI 2 "const_int_operand" "n")))
3484    (clobber (reg:SI T_REG))]
3485   "TARGET_SH1"
3486   "#"
3487   [(set (attr "length")
3488         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3489                (const_string "2")
3490                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3491                (const_string "4")]
3492               (const_string "6")))
3493    (set_attr "type" "arith")])
3494
3495 (define_expand "ashlhi3"
3496   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3497                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3498                               (match_operand:SI 2 "nonmemory_operand" "")))
3499               (clobber (reg:SI T_REG))])]
3500   "TARGET_SH1"
3501   "
3502 {
3503   if (GET_CODE (operands[2]) != CONST_INT)
3504     FAIL;
3505   /* It may be possible to call gen_ashlhi3 directly with more generic
3506      operands.  Make sure operands[1] is a HImode register here.  */
3507   if (!arith_reg_operand (operands[1], HImode))
3508     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3509 }")
3510
3511 (define_split
3512   [(set (match_operand:HI 0 "arith_reg_dest" "")
3513         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3514                    (match_operand:HI 2 "const_int_operand" "")))
3515    (clobber (reg:SI T_REG))]
3516   "TARGET_SH1 && reload_completed"
3517   [(use (reg:SI R0_REG))]
3518   "
3519 {
3520   gen_shifty_hi_op (ASHIFT, operands);
3521   DONE;
3522 }")
3523
3524 ;
3525 ; arithmetic shift right
3526 ;
3527
3528 (define_insn "ashrsi3_sh2a"
3529   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3532   "TARGET_SH2A"
3533   "shad %2,%0"
3534   [(set_attr "type" "dyn_shift")
3535    (set_attr "length" "4")])
3536
3537 (define_insn "ashrsi3_k"
3538   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3539         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3540                      (match_operand:SI 2 "const_int_operand" "M")))
3541    (clobber (reg:SI T_REG))]
3542   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3543   "shar %0"
3544   [(set_attr "type" "arith")])
3545
3546 ;; We can't do HImode right shifts correctly unless we start out with an
3547 ;; explicit zero / sign extension; doing that would result in worse overall
3548 ;; code, so just let the machine independent code widen the mode.
3549 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3550
3551
3552 ;; ??? This should be a define expand.
3553
3554 (define_insn "ashrsi2_16"
3555   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3556         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3557                      (const_int 16)))]
3558   "TARGET_SH1"
3559   "#"
3560   [(set_attr "length" "4")])
3561
3562 (define_split
3563   [(set (match_operand:SI 0 "arith_reg_dest" "")
3564         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3565                      (const_int 16)))]
3566   "TARGET_SH1"
3567   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3568    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3569   "operands[2] = gen_lowpart (HImode, operands[0]);")
3570
3571 ;; ??? This should be a define expand.
3572
3573 (define_insn "ashrsi2_31"
3574   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3575         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3576                      (const_int 31)))
3577    (clobber (reg:SI T_REG))]
3578   "TARGET_SH1"
3579   "#"
3580   [(set_attr "length" "4")])
3581
3582 (define_split
3583   [(set (match_operand:SI 0 "arith_reg_dest" "")
3584         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3585                      (const_int 31)))
3586    (clobber (reg:SI T_REG))]
3587   "TARGET_SH1"
3588   [(const_int 0)]
3589   "
3590 {
3591   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3592   emit_insn (gen_mov_neg_si_t (operands[0]));
3593   DONE;
3594 }")
3595
3596 (define_peephole2
3597   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3598    (set (reg:SI T_REG)
3599         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3600   "TARGET_SH1
3601    && peep2_reg_dead_p (2, operands[0])
3602    && peep2_reg_dead_p (2, operands[1])"
3603   [(const_int 0)]
3604   "
3605 {
3606   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3607   DONE;
3608 }")
3609
3610 (define_insn "ashlsi_c"
3611   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3612         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3613    (set (reg:SI T_REG)
3614         (lt:SI (match_dup 1) (const_int 0)))]
3615   "TARGET_SH1"
3616   "shll %0"
3617   [(set_attr "type" "arith")])
3618
3619 (define_insn "*ashlsi_c_void"
3620   [(set (reg:SI T_REG)
3621         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3622    (clobber (match_scratch:SI 1 "=0"))]
3623   "TARGET_SH1 && cse_not_expected"
3624   "shll %0"
3625   [(set_attr "type" "arith")])
3626
3627 (define_insn "ashrsi3_d"
3628   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3629         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3630                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3631   "TARGET_SH3"
3632   "shad %2,%0"
3633   [(set_attr "type" "dyn_shift")])
3634
3635 (define_insn "ashrsi3_n"
3636   [(set (reg:SI R4_REG)
3637         (ashiftrt:SI (reg:SI R4_REG)
3638                      (match_operand:SI 0 "const_int_operand" "i")))
3639    (clobber (reg:SI T_REG))
3640    (clobber (reg:SI PR_REG))
3641    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3642   "TARGET_SH1"
3643   "jsr  @%1%#"
3644   [(set_attr "type" "sfunc")
3645    (set_attr "needs_delay_slot" "yes")])
3646
3647 (define_insn "ashrsi3_media"
3648   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3649         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3650                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3651   "TARGET_SHMEDIA"
3652   "@
3653         shard.l %1, %2, %0
3654         shari.l %1, %2, %0"
3655   [(set_attr "type" "arith_media")
3656    (set_attr "highpart" "ignore")])
3657
3658 (define_expand "ashrsi3"
3659   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3660                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3661                                 (match_operand:SI 2 "nonmemory_operand" "")))
3662               (clobber (reg:SI T_REG))])]
3663   ""
3664   "
3665 {
3666   if (TARGET_SHMEDIA)
3667     {
3668       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3669       DONE;
3670     }
3671   if (expand_ashiftrt (operands))
3672     DONE;
3673   else
3674     FAIL;
3675 }")
3676
3677 ;; logical shift right
3678
3679 (define_insn "lshrsi3_sh2a"
3680   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3681         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3682                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3683   "TARGET_SH2A"
3684   "shld %2,%0"
3685   [(set_attr "type" "dyn_shift")
3686    (set_attr "length" "4")])
3687
3688 (define_insn "lshrsi3_d"
3689   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692   "TARGET_SH3"
3693   "shld %2,%0"
3694   [(set_attr "type" "dyn_shift")])
3695
3696 ;;  Only the single bit shift clobbers the T bit.
3697
3698 (define_insn "lshrsi3_m"
3699   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3700         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3701                      (match_operand:SI 2 "const_int_operand" "M")))
3702    (clobber (reg:SI T_REG))]
3703   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3704   "shlr %0"
3705   [(set_attr "type" "arith")])
3706
3707 (define_insn "lshrsi3_k"
3708   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3709         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3710                      (match_operand:SI 2 "const_int_operand" "P27")))]
3711   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3712    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3713   "shlr%O2      %0"
3714   [(set_attr "type" "arith")])
3715
3716 (define_insn "lshrsi3_n"
3717   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3718         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3719                      (match_operand:SI 2 "const_int_operand" "n")))
3720    (clobber (reg:SI T_REG))]
3721   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3722   "#"
3723   [(set (attr "length")
3724         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3725                (const_string "2")
3726                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3727                (const_string "4")
3728                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3729                (const_string "6")]
3730               (const_string "8")))
3731    (set_attr "type" "arith")])
3732
3733 (define_split
3734   [(set (match_operand:SI 0 "arith_reg_dest" "")
3735         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3736                      (match_operand:SI 2 "const_int_operand" "")))
3737    (clobber (reg:SI T_REG))]
3738   "TARGET_SH1 && reload_completed"
3739   [(use (reg:SI R0_REG))]
3740   "
3741 {
3742   gen_shifty_op (LSHIFTRT, operands);
3743   DONE;
3744 }")
3745
3746 (define_insn "lshrsi3_media"
3747   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3748         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3749                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3750   "TARGET_SHMEDIA"
3751   "@
3752         shlrd.l %1, %2, %0
3753         shlri.l %1, %2, %0"
3754   [(set_attr "type" "arith_media")
3755    (set_attr "highpart" "ignore")])
3756
3757 (define_expand "lshrsi3"
3758   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3759                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3760                                 (match_operand:SI 2 "nonmemory_operand" "")))
3761               (clobber (reg:SI T_REG))])]
3762   ""
3763   "
3764 {
3765   if (TARGET_SHMEDIA)
3766     {
3767       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3768       DONE;
3769     }
3770   if (GET_CODE (operands[2]) == CONST_INT
3771       && sh_dynamicalize_shift_p (operands[2]))
3772     operands[2] = force_reg (SImode, operands[2]);
3773   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3774     {
3775       rtx count = copy_to_mode_reg (SImode, operands[2]);
3776       emit_insn (gen_negsi2 (count, count));
3777       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3778       DONE;
3779     }
3780   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3781     FAIL;
3782 }")
3783
3784 ;; ??? This should be a define expand.
3785
3786 (define_insn "ashldi3_k"
3787   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3788         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3789                    (const_int 1)))
3790    (clobber (reg:SI T_REG))]
3791   "TARGET_SH1"
3792   "shll %R0\;rotcl      %S0"
3793   [(set_attr "length" "4")
3794    (set_attr "type" "arith")])
3795
3796 (define_insn "ashldi3_media"
3797   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3798         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3799                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3800   "TARGET_SHMEDIA"
3801   "@
3802         shlld   %1, %2, %0
3803         shlli   %1, %2, %0"
3804   [(set_attr "type" "arith_media")])
3805
3806 (define_insn "*ashldisi3_media"
3807   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3808         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3809                    (match_operand:DI 2 "const_int_operand" "n")))]
3810   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3811   "shlli.l      %1, %2, %0"
3812   [(set_attr "type" "arith_media")
3813    (set_attr "highpart" "ignore")])
3814
3815 (define_expand "ashldi3"
3816   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3817                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3818                               (match_operand:DI 2 "immediate_operand" "")))
3819               (clobber (reg:SI T_REG))])]
3820   ""
3821   "
3822 {
3823   if (TARGET_SHMEDIA)
3824     {
3825       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3826       DONE;
3827     }
3828   if (GET_CODE (operands[2]) != CONST_INT
3829       || INTVAL (operands[2]) != 1)
3830     FAIL;
3831 }")
3832
3833 ;; ??? This should be a define expand.
3834
3835 (define_insn "lshrdi3_k"
3836   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3837         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3838                      (const_int 1)))
3839    (clobber (reg:SI T_REG))]
3840   "TARGET_SH1"
3841   "shlr %S0\;rotcr      %R0"
3842   [(set_attr "length" "4")
3843    (set_attr "type" "arith")])
3844
3845 (define_insn "lshrdi3_media"
3846   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3847         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3848                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3849   "TARGET_SHMEDIA
3850    && (arith_reg_dest (operands[0], DImode)
3851        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3852   "@
3853         shlrd   %1, %2, %0
3854         shlri   %1, %2, %0"
3855   [(set_attr "type" "arith_media")])
3856
3857 (define_insn "*lshrdisi3_media"
3858   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3859         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3860                      (match_operand:DI 2 "const_int_operand" "n")))]
3861   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3862   "shlri.l      %1, %2, %0"
3863   [(set_attr "type" "arith_media")
3864    (set_attr "highpart" "ignore")])
3865
3866 (define_expand "lshrdi3"
3867   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3868                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3869                                (match_operand:DI 2 "immediate_operand" "")))
3870              (clobber (reg:SI T_REG))])]
3871   ""
3872   "
3873 {
3874   if (TARGET_SHMEDIA)
3875     {
3876       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3877       DONE;
3878     }
3879   if (GET_CODE (operands[2]) != CONST_INT
3880       || INTVAL (operands[2]) != 1)
3881     FAIL;
3882 }")
3883
3884 ;; ??? This should be a define expand.
3885
3886 (define_insn "ashrdi3_k"
3887   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3888         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3889                      (const_int 1)))
3890    (clobber (reg:SI T_REG))]
3891   "TARGET_SH1"
3892   "shar %S0\;rotcr      %R0"
3893   [(set_attr "length" "4")
3894    (set_attr "type" "arith")])
3895
3896 (define_insn "ashrdi3_media"
3897   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3898         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3899                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3900   "TARGET_SHMEDIA
3901    && (arith_reg_dest (operands[0], DImode)
3902        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3903   "@
3904         shard   %1, %2, %0
3905         shari   %1, %2, %0"
3906   [(set_attr "type" "arith_media")])
3907
3908 (define_insn "*ashrdisi3_media"
3909   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3910         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3911                      (match_operand:DI 2 "const_int_operand" "n")))]
3912   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3913   "shari.l      %1, %2, %0"
3914   [(set_attr "type" "arith_media")
3915    (set_attr "highpart" "ignore")])
3916
3917 (define_insn "ashrdisi3_media_high"
3918   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3919         (truncate:SI
3920            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3921                         (match_operand:DI 2 "const_int_operand" "n"))))]
3922   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3923   "shari        %1, %2, %0"
3924   [(set_attr "type" "arith_media")])
3925
3926 (define_insn "ashrdisi3_media_opaque"
3927   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3928         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3929                     (match_operand:DI 2 "const_int_operand" "n")]
3930          UNSPEC_ASHIFTRT))]
3931   "TARGET_SHMEDIA"
3932   "shari        %1, %2, %0"
3933   [(set_attr "type" "arith_media")])
3934
3935 (define_expand "ashrdi3"
3936   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3937                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3938                                 (match_operand:DI 2 "immediate_operand" "")))
3939               (clobber (reg:SI T_REG))])]
3940   ""
3941   "
3942 {
3943   if (TARGET_SHMEDIA)
3944     {
3945       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3946       DONE;
3947     }
3948   if (GET_CODE (operands[2]) != CONST_INT
3949       || INTVAL (operands[2]) != 1)
3950     FAIL;
3951 }")
3952
3953 ;; combined left/right shift
3954
3955 (define_split
3956   [(set (match_operand:SI 0 "register_operand" "")
3957         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3958                            (match_operand:SI 2 "const_int_operand" ""))
3959                 (match_operand:SI 3 "const_int_operand" "")))]
3960   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3961   [(use (reg:SI R0_REG))]
3962   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3963    DONE;")
3964
3965 (define_split
3966   [(set (match_operand:SI 0 "register_operand" "")
3967         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3968                            (match_operand:SI 2 "const_int_operand" ""))
3969                 (match_operand:SI 3 "const_int_operand" "")))
3970    (clobber (reg:SI T_REG))]
3971   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3972   [(use (reg:SI R0_REG))]
3973   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3974    DONE;")
3975
3976 (define_insn ""
3977   [(set (match_operand:SI 0 "register_operand" "=r")
3978         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3979                            (match_operand:SI 2 "const_int_operand" "n"))
3980                 (match_operand:SI 3 "const_int_operand" "n")))
3981    (clobber (reg:SI T_REG))]
3982   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3983  "#"
3984   [(set (attr "length")
3985         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3986                (const_string "4")
3987                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3988                (const_string "6")
3989                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3990                (const_string "8")
3991                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3992                (const_string "10")
3993                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3994                (const_string "12")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3996                (const_string "14")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
3998                (const_string "16")]
3999               (const_string "18")))
4000    (set_attr "type" "arith")])
4001
4002 (define_insn ""
4003   [(set (match_operand:SI 0 "register_operand" "=z")
4004         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4005                            (match_operand:SI 2 "const_int_operand" "n"))
4006                 (match_operand:SI 3 "const_int_operand" "n")))
4007    (clobber (reg:SI T_REG))]
4008   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4009  "#"
4010   [(set (attr "length")
4011         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4012                (const_string "4")
4013                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4014                (const_string "6")
4015                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4016                (const_string "8")]
4017               (const_string "10")))
4018    (set_attr "type" "arith")])
4019
4020 ;; shift left / and combination with a scratch register: The combine pass
4021 ;; does not accept the individual instructions, even though they are
4022 ;; cheap.  But it needs a precise description so that it is usable after
4023 ;; reload.
4024 (define_insn "and_shl_scratch"
4025   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4026         (lshiftrt:SI
4027          (ashift:SI
4028           (and:SI
4029            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4030                         (match_operand:SI 2 "const_int_operand" "N,n"))
4031            (match_operand:SI 3 "" "0,r"))
4032           (match_operand:SI 4 "const_int_operand" "n,n"))
4033          (match_operand:SI 5 "const_int_operand" "n,n")))
4034    (clobber (reg:SI T_REG))]
4035   "TARGET_SH1"
4036   "#"
4037   [(set (attr "length")
4038         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4039                (const_string "4")
4040                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4041                (const_string "6")
4042                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4043                (const_string "8")
4044                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4045                (const_string "10")]
4046               (const_string "12")))
4047    (set_attr "type" "arith")])
4048
4049 (define_split
4050   [(set (match_operand:SI 0 "register_operand" "")
4051         (lshiftrt:SI
4052          (ashift:SI
4053           (and:SI
4054            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4055                         (match_operand:SI 2 "const_int_operand" ""))
4056            (match_operand:SI 3 "register_operand" ""))
4057           (match_operand:SI 4 "const_int_operand" ""))
4058          (match_operand:SI 5 "const_int_operand" "")))
4059    (clobber (reg:SI T_REG))]
4060   "TARGET_SH1"
4061   [(use (reg:SI R0_REG))]
4062   "
4063 {
4064   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4065
4066   if (INTVAL (operands[2]))
4067     {
4068       gen_shifty_op (LSHIFTRT, operands);
4069     }
4070   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4071   operands[2] = operands[4];
4072   gen_shifty_op (ASHIFT, operands);
4073   if (INTVAL (operands[5]))
4074     {
4075       operands[2] = operands[5];
4076       gen_shifty_op (LSHIFTRT, operands);
4077     }
4078   DONE;
4079 }")
4080
4081 ;; signed left/right shift combination.
4082 (define_split
4083   [(set (match_operand:SI 0 "register_operand" "")
4084         (sign_extract:SI
4085          (ashift:SI (match_operand:SI 1 "register_operand" "")
4086                     (match_operand:SI 2 "const_int_operand" ""))
4087          (match_operand:SI 3 "const_int_operand" "")
4088          (const_int 0)))
4089    (clobber (reg:SI T_REG))]
4090   "TARGET_SH1"
4091   [(use (reg:SI R0_REG))]
4092   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4093    DONE;")
4094
4095 (define_insn "shl_sext_ext"
4096   [(set (match_operand:SI 0 "register_operand" "=r")
4097         (sign_extract:SI
4098          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4099                     (match_operand:SI 2 "const_int_operand" "n"))
4100          (match_operand:SI 3 "const_int_operand" "n")
4101          (const_int 0)))
4102    (clobber (reg:SI T_REG))]
4103   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4104   "#"
4105   [(set (attr "length")
4106         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4107                (const_string "2")
4108                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4109                (const_string "4")
4110                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4111                (const_string "6")
4112                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4113                (const_string "8")
4114                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4115                (const_string "10")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4117                (const_string "12")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4119                (const_string "14")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4121                (const_string "16")]
4122               (const_string "18")))
4123     (set_attr "type" "arith")])
4124
4125 (define_insn "shl_sext_sub"
4126   [(set (match_operand:SI 0 "register_operand" "=z")
4127         (sign_extract:SI
4128          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4129                     (match_operand:SI 2 "const_int_operand" "n"))
4130          (match_operand:SI 3 "const_int_operand" "n")
4131          (const_int 0)))
4132    (clobber (reg:SI T_REG))]
4133   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4134   "#"
4135   [(set (attr "length")
4136         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4137                (const_string "6")
4138                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4139                (const_string "8")
4140                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4141                (const_string "10")
4142                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4143                (const_string "12")]
4144               (const_string "14")))
4145     (set_attr "type" "arith")])
4146
4147 ;; These patterns are found in expansions of DImode shifts by 16, and
4148 ;; allow the xtrct instruction to be generated from C source.
4149
4150 (define_insn "xtrct_left"
4151   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4152         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4153                            (const_int 16))
4154                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4155                              (const_int 16))))]
4156   "TARGET_SH1"
4157   "xtrct        %1,%0"
4158   [(set_attr "type" "arith")])
4159
4160 (define_insn "xtrct_right"
4161   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4162         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4163                              (const_int 16))
4164                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4165                            (const_int 16))))]
4166   "TARGET_SH1"
4167   "xtrct        %2,%0"
4168   [(set_attr "type" "arith")])
4169
4170 ;; -------------------------------------------------------------------------
4171 ;; Unary arithmetic
4172 ;; -------------------------------------------------------------------------
4173
4174 (define_insn "negc"
4175   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4176         (neg:SI (plus:SI (reg:SI T_REG)
4177                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4178    (set (reg:SI T_REG)
4179         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4180                (const_int 0)))]
4181   "TARGET_SH1"
4182   "negc %1,%0"
4183   [(set_attr "type" "arith")])
4184
4185 (define_insn "*negdi_media"
4186   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4187         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4188   "TARGET_SHMEDIA"
4189   "sub  r63, %1, %0"
4190   [(set_attr "type" "arith_media")])
4191
4192 (define_expand "negdi2"
4193   [(set (match_operand:DI 0 "arith_reg_operand" "")
4194         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4195   ""
4196   "
4197 {
4198   if (TARGET_SH1)
4199     {
4200       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4201       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4202
4203       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4204       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4205
4206       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4207       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4208
4209       emit_insn (gen_clrt ());
4210       emit_insn (gen_negc (low_dst, low_src));
4211       emit_insn (gen_negc (high_dst, high_src));
4212       DONE;
4213     }
4214 }")
4215
4216 (define_insn "negsi2"
4217   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4218         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4219   "TARGET_SH1"
4220   "neg  %1,%0"
4221   [(set_attr "type" "arith")])
4222
4223 (define_insn "one_cmplsi2"
4224   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4225         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4226   "TARGET_SH1"
4227   "not  %1,%0"
4228   [(set_attr "type" "arith")])
4229
4230 (define_expand "one_cmpldi2"
4231   [(set (match_operand:DI 0 "arith_reg_dest" "")
4232         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4233                 (const_int -1)))]
4234   "TARGET_SHMEDIA" "")
4235
4236 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4237    This can be used as some kind of conditional execution, which is useful
4238    for abs.  */
4239 (define_split
4240   [(set (match_operand:SI 0 "arith_reg_dest" "")
4241         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4242                          (match_operand:SI 1 "arith_reg_operand" ""))
4243                  (reg:SI T_REG)))]
4244   "TARGET_HARD_SH4"
4245   [(const_int 0)]
4246   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4247    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4248    DONE;")
4249
4250 (define_insn "cneg"
4251   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4252         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4253                       (match_operand:SI 1 "arith_reg_operand" "0")
4254                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4255   "TARGET_HARD_SH4"
4256   "bf 0f\;neg %2,%0\\n0:"
4257   [(set_attr "type" "arith") ;; poor approximation
4258    (set_attr "length" "4")])
4259
4260 \f
4261 ;; -------------------------------------------------------------------------
4262 ;; Zero extension instructions
4263 ;; -------------------------------------------------------------------------
4264
4265 (define_insn "zero_extendsidi2"
4266   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4267         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4268   "TARGET_SHMEDIA"
4269   "addz.l       %1, r63, %0"
4270   [(set_attr "type" "arith_media")
4271    (set_attr "highpart" "extend")])
4272
4273 (define_insn "zero_extendhidi2"
4274   [(set (match_operand:DI 0 "register_operand" "=r,r")
4275         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4276   "TARGET_SHMEDIA"
4277   "@
4278         #
4279         ld%M1.uw        %m1, %0"
4280   [(set_attr "type" "*,load_media")
4281    (set (attr "highpart")
4282         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4283                (const_string "user")]
4284               (const_string "ignore")))])
4285
4286 (define_split
4287   [(set (match_operand:DI 0 "register_operand" "")
4288         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4289   "TARGET_SHMEDIA && reload_completed"
4290   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4291    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4292   "
4293 {
4294   if (GET_CODE (operands[1]) == TRUNCATE)
4295     operands[1] = XEXP (operands[1], 0);
4296 }")
4297
4298 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4299 ;; reload the entire truncate expression.
4300 (define_insn_and_split "*loaddi_trunc"
4301   [(set (match_operand 0 "any_register_operand" "=r")
4302         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4303   "TARGET_SHMEDIA && reload_completed"
4304   "#"
4305   "TARGET_SHMEDIA && reload_completed"
4306   [(set (match_dup 0) (match_dup 1))]
4307   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4308
4309 (define_insn "zero_extendqidi2"
4310   [(set (match_operand:DI 0 "register_operand" "=r,r")
4311         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4312   "TARGET_SHMEDIA"
4313   "@
4314         andi    %1, 255, %0
4315         ld%M1.ub        %m1, %0"
4316   [(set_attr "type" "arith_media,load_media")
4317    (set (attr "highpart")
4318         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4319                (const_string "user")]
4320               (const_string "ignore")))])
4321
4322 (define_expand "zero_extendhisi2"
4323   [(set (match_operand:SI 0 "arith_reg_operand" "")
4324         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4325   ""
4326   "
4327 {
4328   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4329     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4330 }")
4331
4332 (define_insn "*zero_extendhisi2_compact"
4333   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4334         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4335   "TARGET_SH1"
4336   "extu.w       %1,%0"
4337   [(set_attr "type" "arith")])
4338
4339 (define_insn "*zero_extendhisi2_media"
4340   [(set (match_operand:SI 0 "register_operand" "=r,r")
4341         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4342   "TARGET_SHMEDIA"
4343   "@
4344         #
4345         ld%M1.uw        %m1, %0"
4346   [(set_attr "type" "arith_media,load_media")
4347    (set (attr "highpart")
4348         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4349                (const_string "user")]
4350               (const_string "ignore")))])
4351
4352 (define_split
4353   [(set (match_operand:SI 0 "register_operand" "")
4354         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4355   "TARGET_SHMEDIA && reload_completed"
4356   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4357    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4358   "
4359 {
4360   rtx op1 = operands[1];
4361
4362   if (GET_CODE (op1) == TRUNCATE)
4363     op1 = XEXP (op1, 0);
4364   operands[2]
4365     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4366                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4367 }")
4368
4369 (define_expand "zero_extendqisi2"
4370   [(set (match_operand:SI 0 "arith_reg_operand" "")
4371         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4372   ""
4373   "
4374 {
4375   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4376     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4377 }")
4378
4379 (define_insn "*zero_extendqisi2_compact"
4380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4381         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4382   "TARGET_SH1"
4383   "extu.b       %1,%0"
4384   [(set_attr "type" "arith")])
4385
4386 (define_insn "*zero_extendqisi2_media"
4387   [(set (match_operand:SI 0 "register_operand" "=r,r")
4388         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4389   "TARGET_SHMEDIA"
4390   "@
4391         andi    %1, 255, %0
4392         ld%M1.ub        %m1, %0"
4393   [(set_attr "type" "arith_media,load_media")
4394    (set (attr "highpart")
4395         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4396                (const_string "user")]
4397               (const_string "ignore")))])
4398
4399 (define_insn "zero_extendqihi2"
4400   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4401         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4402   "TARGET_SH1"
4403   "extu.b       %1,%0"
4404   [(set_attr "type" "arith")])
4405
4406 ;; -------------------------------------------------------------------------
4407 ;; Sign extension instructions
4408 ;; -------------------------------------------------------------------------
4409
4410 ;; ??? This should be a define expand.
4411 ;; ??? Or perhaps it should be dropped?
4412
4413 ;; convert_move generates good code for SH[1-4].
4414 (define_insn "extendsidi2"
4415   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4416         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4417   "TARGET_SHMEDIA"
4418   "@
4419         add.l   %1, r63, %0
4420         ld%M1.l %m1, %0
4421         fmov.sl %1, %0"
4422   [(set_attr "type" "arith_media,load_media,fpconv_media")
4423    (set (attr "highpart")
4424         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4425                (const_string "user")]
4426               (const_string "extend")))])
4427
4428 (define_insn "extendhidi2"
4429   [(set (match_operand:DI 0 "register_operand" "=r,r")
4430         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4431   "TARGET_SHMEDIA"
4432   "@
4433         #
4434         ld%M1.w %m1, %0"
4435   [(set_attr "type" "*,load_media")
4436    (set (attr "highpart")
4437         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4438                (const_string "user")]
4439               (const_string "ignore")))])
4440
4441 (define_split
4442   [(set (match_operand:DI 0 "register_operand" "")
4443         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4444   "TARGET_SHMEDIA && reload_completed"
4445   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4446    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4447   "
4448 {
4449   if (GET_CODE (operands[1]) == TRUNCATE)
4450     operands[1] = XEXP (operands[1], 0);
4451 }")
4452
4453 (define_insn "extendqidi2"
4454   [(set (match_operand:DI 0 "register_operand" "=r,r")
4455         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4456   "TARGET_SHMEDIA"
4457   "@
4458         #
4459         ld%M1.b %m1, %0"
4460   [(set_attr "type" "*,load_media")
4461    (set (attr "highpart")
4462         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4463                (const_string "user")]
4464               (const_string "ignore")))])
4465
4466 (define_split
4467   [(set (match_operand:DI 0 "register_operand" "")
4468         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4469   "TARGET_SHMEDIA && reload_completed"
4470   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4471    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4472   "
4473 {
4474   if (GET_CODE (operands[1]) == TRUNCATE)
4475     operands[1] = XEXP (operands[1], 0);
4476 }")
4477
4478 (define_expand "extendhisi2"
4479   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4480         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4481   ""
4482   "")
4483
4484 (define_insn "*extendhisi2_compact"
4485   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4486         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4487   "TARGET_SH1"
4488   "@
4489         exts.w  %1,%0
4490         mov.w   %1,%0"
4491   [(set_attr "type" "arith,load")])
4492
4493 (define_insn "*extendhisi2_media"
4494   [(set (match_operand:SI 0 "register_operand" "=r,r")
4495         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4496   "TARGET_SHMEDIA"
4497   "@
4498         #
4499         ld%M1.w %m1, %0"
4500   [(set_attr "type" "arith_media,load_media")
4501    (set (attr "highpart")
4502         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4503                (const_string "user")]
4504               (const_string "ignore")))])
4505
4506 (define_split
4507   [(set (match_operand:SI 0 "register_operand" "")
4508         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4509   "TARGET_SHMEDIA && reload_completed"
4510   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4511    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4512   "
4513 {
4514   rtx op1 = operands[1];
4515   if (GET_CODE (op1) == TRUNCATE)
4516     op1 = XEXP (op1, 0);
4517   operands[2]
4518     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4519                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4520 }")
4521
4522 (define_expand "extendqisi2"
4523   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4524         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4525   ""
4526   "")
4527
4528 (define_insn "*extendqisi2_compact"
4529   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4530         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4531   "TARGET_SH1"
4532   "@
4533         exts.b  %1,%0
4534         mov.b   %1,%0"
4535   [(set_attr "type" "arith,load")])
4536
4537 (define_insn "*extendqisi2_media"
4538   [(set (match_operand:SI 0 "register_operand" "=r,r")
4539         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4540   "TARGET_SHMEDIA"
4541   "@
4542         #
4543         ld%M1.b %m1, %0"
4544   [(set_attr "type" "arith_media,load_media")
4545    (set (attr "highpart")
4546         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4547                (const_string "user")]
4548               (const_string "ignore")))])
4549
4550 (define_split
4551   [(set (match_operand:SI 0 "register_operand" "")
4552         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4553   "TARGET_SHMEDIA && reload_completed"
4554   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4555    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4556    "
4557 {
4558   rtx op1 = operands[1];
4559   if (GET_CODE (op1) == TRUNCATE)
4560     op1 = XEXP (op1, 0);
4561   operands[2]
4562     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4563                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4564 }")
4565
4566 (define_insn "extendqihi2"
4567   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4568         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4569   "TARGET_SH1"
4570   "@
4571         exts.b  %1,%0
4572         mov.b   %1,%0"
4573   [(set_attr "type" "arith,load")])
4574
4575 /* It would seem useful to combine the truncXi patterns into the movXi
4576    patterns, but unary operators are ignored when matching constraints,
4577    so we need separate patterns.  */
4578 (define_insn "truncdisi2"
4579   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4580         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4581   "TARGET_SHMEDIA"
4582   "@
4583         add.l   %1, r63, %0
4584         st%M0.l %m0, %1
4585         fst%M0.s        %m0, %T1
4586         fmov.ls %1, %0
4587         fmov.sl %T1, %0
4588         fmov.s  %T1, %0"
4589   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4590    (set (attr "highpart")
4591         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4592                (const_string "user")]
4593               (const_string "extend")))])
4594
4595 (define_insn "truncdihi2"
4596   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4597         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4598   "TARGET_SHMEDIA"
4599   "@
4600         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4601         st%M0.w %m0, %1"
4602   [(set_attr "type"   "arith_media,store_media")
4603    (set_attr "length" "8,4")
4604    (set (attr "highpart")
4605         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4606                (const_string "user")]
4607               (const_string "extend")))])
4608
4609 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4610 ; Because we use zero extension, we can't provide signed QImode compares
4611 ; using a simple compare or conditional banch insn.
4612 (define_insn "truncdiqi2"
4613   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4614         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4615   "TARGET_SHMEDIA"
4616   "@
4617         andi    %1, 255, %0
4618         st%M0.b %m0, %1"
4619   [(set_attr "type"   "arith_media,store")
4620    (set (attr "highpart")
4621         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4622                (const_string "user")]
4623               (const_string "extend")))])
4624 ;; -------------------------------------------------------------------------
4625 ;; Move instructions
4626 ;; -------------------------------------------------------------------------
4627
4628 ;; define push and pop so it is easy for sh.c
4629 ;; We can't use push and pop on SHcompact because the stack must always
4630 ;; be 8-byte aligned.
4631
4632 (define_expand "push"
4633   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4634         (match_operand:SI 0 "register_operand" "r,l,x"))]
4635   "TARGET_SH1 && ! TARGET_SH5"
4636   "")
4637
4638 (define_expand "pop"
4639   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4640         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4641   "TARGET_SH1 && ! TARGET_SH5"
4642   "")
4643
4644 (define_expand "push_e"
4645   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4646                    (match_operand:SF 0 "" ""))
4647               (use (reg:PSI FPSCR_REG))
4648               (clobber (scratch:SI))])]
4649   "TARGET_SH1 && ! TARGET_SH5"
4650   "")
4651
4652 (define_insn "push_fpul"
4653   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4654   "TARGET_SH2E && ! TARGET_SH5"
4655   "sts.l        fpul,@-r15"
4656   [(set_attr "type" "store")
4657    (set_attr "late_fp_use" "yes")
4658    (set_attr "hit_stack" "yes")])
4659
4660 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4661 ;; so use that.
4662 (define_expand "push_4"
4663   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4664                    (match_operand:DF 0 "" ""))
4665               (use (reg:PSI FPSCR_REG))
4666               (clobber (scratch:SI))])]
4667   "TARGET_SH1 && ! TARGET_SH5"
4668   "")
4669
4670 (define_expand "pop_e"
4671   [(parallel [(set (match_operand:SF 0 "" "")
4672               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4673               (use (reg:PSI FPSCR_REG))
4674               (clobber (scratch:SI))])]
4675   "TARGET_SH1 && ! TARGET_SH5"
4676   "")
4677
4678 (define_insn "pop_fpul"
4679   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4680   "TARGET_SH2E && ! TARGET_SH5"
4681   "lds.l        @r15+,fpul"
4682   [(set_attr "type" "load")
4683    (set_attr "hit_stack" "yes")])
4684
4685 (define_expand "pop_4"
4686   [(parallel [(set (match_operand:DF 0 "" "")
4687                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4688               (use (reg:PSI FPSCR_REG))
4689               (clobber (scratch:SI))])]
4690   "TARGET_SH1 && ! TARGET_SH5"
4691   "")
4692
4693 (define_expand "push_fpscr"
4694   [(const_int 0)]
4695   "TARGET_SH2E"
4696   "
4697 {
4698   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
4699                                                  gen_rtx_PRE_DEC (Pmode,
4700                                                           stack_pointer_rtx)),
4701                                         get_fpscr_rtx ()));
4702   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4703   DONE;
4704 }")
4705
4706 (define_expand "pop_fpscr"
4707   [(const_int 0)]
4708   "TARGET_SH2E"
4709   "
4710 {
4711   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4712                                         gen_rtx_MEM (PSImode,
4713                                                  gen_rtx_POST_INC (Pmode,
4714                                                           stack_pointer_rtx))));
4715   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4716   DONE;
4717 }")
4718
4719 ;; These two patterns can happen as the result of optimization, when
4720 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4721 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4722
4723 (define_insn "clrt"
4724   [(set (reg:SI T_REG) (const_int 0))]
4725   "TARGET_SH1"
4726   "clrt")
4727
4728 (define_insn "sett"
4729   [(set (reg:SI T_REG) (const_int 1))]
4730   "TARGET_SH1"
4731   "sett")
4732
4733 ;; t/r must come after r/r, lest reload will try to reload stuff like
4734 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4735 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4736 (define_insn "movsi_i"
4737   [(set (match_operand:SI 0 "general_movdst_operand"
4738             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4739         (match_operand:SI 1 "general_movsrc_operand"
4740          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4741   "TARGET_SH1
4742    && ! TARGET_SH2E
4743    && ! TARGET_SH2A
4744    && (register_operand (operands[0], SImode)
4745        || register_operand (operands[1], SImode))"
4746   "@
4747         mov.l   %1,%0
4748         mov     %1,%0
4749         cmp/pl  %1
4750         mov.l   %1,%0
4751         sts     %1,%0
4752         sts     %1,%0
4753         movt    %0
4754         mov.l   %1,%0
4755         sts.l   %1,%0
4756         sts.l   %1,%0
4757         lds     %1,%0
4758         lds     %1,%0
4759         lds.l   %1,%0
4760         lds.l   %1,%0
4761         fake    %1,%0"
4762   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4763    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4764
4765 ;; t/r must come after r/r, lest reload will try to reload stuff like
4766 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4767 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4768 ;; will require a reload.
4769 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4770 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4771 (define_insn "movsi_ie"
4772   [(set (match_operand:SI 0 "general_movdst_operand"
4773             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4774         (match_operand:SI 1 "general_movsrc_operand"
4775          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4776   "(TARGET_SH2E || TARGET_SH2A)
4777    && (register_operand (operands[0], SImode)
4778        || register_operand (operands[1], SImode))"
4779   "@
4780         mov.l   %1,%0
4781         mov     %1,%0
4782         movi20  %1,%0
4783         cmp/pl  %1
4784         mov.l   %1,%0
4785         sts     %1,%0
4786         sts     %1,%0
4787         movt    %0
4788         mov.l   %1,%0
4789         sts.l   %1,%0
4790         sts.l   %1,%0
4791         lds     %1,%0
4792         lds     %1,%0
4793         lds.l   %1,%0
4794         lds.l   %1,%0
4795         lds.l   %1,%0
4796         sts.l   %1,%0
4797         fake    %1,%0
4798         lds     %1,%0
4799         sts     %1,%0
4800         fsts    fpul,%0
4801         flds    %1,fpul
4802         fmov    %1,%0
4803         ! move optimized away"
4804   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4805    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4806    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4807
4808 (define_insn "movsi_i_lowpart"
4809   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4810         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4811    "TARGET_SH1
4812     && (register_operand (operands[0], SImode)
4813         || register_operand (operands[1], SImode))"
4814   "@
4815         mov.l   %1,%0
4816         mov     %1,%0
4817         mov.l   %1,%0
4818         sts     %1,%0
4819         sts     %1,%0
4820         movt    %0
4821         mov.l   %1,%0
4822         fake    %1,%0"
4823   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4824
4825 (define_insn_and_split "load_ra"
4826   [(set (match_operand:SI 0 "general_movdst_operand" "")
4827         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4828   "TARGET_SH1"
4829   "#"
4830   "&& ! currently_expanding_to_rtl"
4831   [(set (match_dup 0) (match_dup 1))]
4832   "
4833 {
4834   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4835     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
4836 }")
4837
4838 ;; The '?'s in the following constraints may not reflect the time taken
4839 ;; to perform the move. They are there to discourage the use of floating-
4840 ;; point registers for storing integer values.
4841 (define_insn "*movsi_media"
4842   [(set (match_operand:SI 0 "general_movdst_operand"
4843                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4844         (match_operand:SI 1 "general_movsrc_operand"
4845          "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4846   "TARGET_SHMEDIA_FPU
4847    && (register_operand (operands[0], SImode)
4848        || sh_register_operand (operands[1], SImode)
4849        || GET_CODE (operands[1]) == TRUNCATE)"
4850   "@
4851         add.l   %1, r63, %0
4852         movi    %1, %0
4853         #
4854         ld%M1.l %m1, %0
4855         st%M0.l %m0, %N1
4856         fld%M1.s        %m1, %0
4857         fst%M0.s        %m0, %1
4858         fmov.ls %N1, %0
4859         fmov.sl %1, %0
4860         fmov.s  %1, %0
4861         ptabs   %1, %0
4862         gettr   %1, %0
4863         pt      %1, %0"
4864   [(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")
4865    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4866    (set (attr "highpart")
4867         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4868                (const_string "user")]
4869               (const_string "ignore")))])
4870
4871 (define_insn "*movsi_media_nofpu"
4872   [(set (match_operand:SI 0 "general_movdst_operand"
4873                 "=r,r,r,r,m,*b,r,*b")
4874         (match_operand:SI 1 "general_movsrc_operand"
4875          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4876   "TARGET_SHMEDIA
4877    && (register_operand (operands[0], SImode)
4878        || sh_register_operand (operands[1], SImode)
4879        || GET_CODE (operands[1]) == TRUNCATE)"
4880   "@
4881         add.l   %1, r63, %0
4882         movi    %1, %0
4883         #
4884         ld%M1.l %m1, %0
4885         st%M0.l %m0, %N1
4886         ptabs   %1, %0
4887         gettr   %1, %0
4888         pt      %1, %0"
4889   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4890    (set_attr "length" "4,4,8,4,4,4,4,12")
4891    (set (attr "highpart")
4892         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4893                (const_string "user")]
4894               (const_string "ignore")))])
4895
4896 (define_expand "movsi_const"
4897   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4898         (const:SI (sign_extend:SI
4899                    (truncate:HI
4900                     (ashiftrt:SI
4901                      (match_operand:DI 1 "immediate_operand" "s")
4902                      (const_int 16))))))
4903    (set (match_dup 0)
4904         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4905                 (zero_extend:SI
4906                  (truncate:HI
4907                   (const:SI
4908                    (sign_extend:SI
4909                     (truncate:HI (match_dup 1))))))))]
4910   "TARGET_SHMEDIA && reload_completed
4911    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4912   "
4913 {
4914   if (GET_CODE (operands[1]) == LABEL_REF
4915       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4916     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4917   else if (GOTOFF_P (operands[1]))
4918     {
4919       rtx unspec = XEXP (operands[1], 0);
4920
4921       if (! UNSPEC_GOTOFF_P (unspec))
4922         {
4923           unspec = XEXP (unspec, 0);
4924           if (! UNSPEC_GOTOFF_P (unspec))
4925             abort ();
4926         }
4927       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4928           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4929         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4930     }
4931 }")
4932
4933 (define_expand "movsi_const_16bit"
4934   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4935         (const:SI (sign_extend:SI
4936                    (truncate:HI
4937                     (match_operand:DI 1 "immediate_operand" "s")))))]
4938   "TARGET_SHMEDIA && flag_pic && reload_completed
4939    && GET_CODE (operands[1]) == SYMBOL_REF"
4940   "")
4941
4942 (define_split
4943   [(set (match_operand:SI 0 "arith_reg_dest" "")
4944         (match_operand:SI 1 "immediate_operand" ""))]
4945   "TARGET_SHMEDIA && reload_completed
4946    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4947   [(const_int 0)]
4948   "
4949 {
4950   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4951
4952   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4953                                         REG_NOTES (insn));
4954
4955   DONE;
4956 }")
4957
4958 (define_split
4959   [(set (match_operand:SI 0 "register_operand" "")
4960         (match_operand:SI 1 "immediate_operand" ""))]
4961   "TARGET_SHMEDIA && reload_completed
4962    && ((GET_CODE (operands[1]) == CONST_INT
4963         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4964        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4965   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4966
4967 (define_expand "movsi"
4968   [(set (match_operand:SI 0 "general_movdst_operand" "")
4969         (match_operand:SI 1 "general_movsrc_operand" ""))]
4970   ""
4971   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4972
4973 (define_expand "ic_invalidate_line"
4974   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4975                                 (match_dup 1)] UNSPEC_ICACHE)
4976               (clobber (scratch:SI))])]
4977   "TARGET_HARD_SH4 || TARGET_SH5"
4978   "
4979 {
4980   if (TARGET_SHMEDIA)
4981     {
4982       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4983       DONE;
4984     }
4985   else if (TARGET_SHCOMPACT)
4986     {
4987       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4988       operands[1] = force_reg (Pmode, operands[1]);
4989       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4990       DONE;
4991     }
4992   else if (TARGET_SH4A_ARCH)
4993     {
4994       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4995       DONE;
4996     }
4997   operands[0] = force_reg (Pmode, operands[0]);
4998   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
4999                                                                Pmode)));
5000 }")
5001
5002 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5003 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5004 ;; the requirement *1*00 for associative address writes.  The alignment of
5005 ;; %0 implies that its least significant bit is cleared,
5006 ;; thus we clear the V bit of a matching entry if there is one.
5007 (define_insn "ic_invalidate_line_i"
5008   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5009                      (match_operand:SI 1 "register_operand" "r")]
5010                      UNSPEC_ICACHE)
5011    (clobber (match_scratch:SI 2 "=&r"))]
5012   "TARGET_HARD_SH4"
5013   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5014   [(set_attr "length" "8")
5015    (set_attr "type" "cwb")])
5016
5017 (define_insn "ic_invalidate_line_sh4a"
5018   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5019                     UNSPEC_ICACHE)]
5020   "TARGET_SH4A_ARCH"
5021   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5022   [(set_attr "length" "16")
5023    (set_attr "type" "cwb")])
5024
5025 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5026 ;; an add in the code that calculates the address.
5027 (define_insn "ic_invalidate_line_media"
5028   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5029                     UNSPEC_ICACHE)]
5030   "TARGET_SHMEDIA"
5031   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5032   [(set_attr "length" "16")
5033    (set_attr "type" "invalidate_line_media")])
5034
5035 (define_insn "ic_invalidate_line_compact"
5036   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5037                      (match_operand:SI 1 "register_operand" "r")]
5038                     UNSPEC_ICACHE)
5039    (clobber (reg:SI PR_REG))]
5040   "TARGET_SHCOMPACT"
5041   "jsr @%1%#"
5042   [(set_attr "type" "sfunc")
5043    (set_attr "needs_delay_slot" "yes")])
5044
5045 (define_expand "initialize_trampoline"
5046   [(match_operand:SI 0 "" "")
5047    (match_operand:SI 1 "" "")
5048    (match_operand:SI 2 "" "")]
5049   "TARGET_SHCOMPACT"
5050   "
5051 {
5052   rtx sfun, tramp;
5053
5054   tramp = force_reg (Pmode, operands[0]);
5055   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5056                                             SFUNC_STATIC));
5057   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5058   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5059
5060   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5061   DONE;
5062 }")
5063
5064 (define_insn "initialize_trampoline_compact"
5065   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5066                      (match_operand:SI 1 "register_operand" "r")
5067                      (reg:SI R2_REG) (reg:SI R3_REG)]
5068                     UNSPEC_INIT_TRAMP)
5069
5070    (clobber (reg:SI PR_REG))]
5071   "TARGET_SHCOMPACT"
5072   "jsr @%1%#"
5073   [(set_attr "type" "sfunc")
5074    (set_attr "needs_delay_slot" "yes")])
5075
5076 (define_insn "movqi_i"
5077   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5078         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5079   "TARGET_SH1
5080    && (arith_reg_operand (operands[0], QImode)
5081        || arith_reg_operand (operands[1], QImode))"
5082   "@
5083         mov     %1,%0
5084         mov.b   %1,%0
5085         mov.b   %1,%0
5086         movt    %0
5087         sts     %1,%0
5088         lds     %1,%0"
5089  [(set_attr "type" "move,load,store,move,move,move")])
5090
5091 (define_insn "*movqi_media"
5092   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5093         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5094   "TARGET_SHMEDIA
5095    && (arith_reg_operand (operands[0], QImode)
5096        || extend_reg_or_0_operand (operands[1], QImode))"
5097   "@
5098         add.l   %1, r63, %0
5099         movi    %1, %0
5100         ld%M1.ub        %m1, %0
5101         st%M0.b %m0, %N1"
5102   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5103    (set (attr "highpart")
5104         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5105                (const_string "user")]
5106               (const_string "ignore")))])
5107
5108 (define_expand "movqi"
5109   [(set (match_operand:QI 0 "general_operand" "")
5110         (match_operand:QI 1 "general_operand"  ""))]
5111   ""
5112   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5113
5114 (define_expand "reload_inqi"
5115   [(set (match_operand:SI 2 "" "=&r")
5116         (match_operand:QI 1 "inqhi_operand" ""))
5117    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5118         (truncate:QI (match_dup 3)))]
5119   "TARGET_SHMEDIA"
5120   "
5121 {
5122   rtx inner = XEXP (operands[1], 0);
5123   int regno = REGNO (inner);
5124
5125   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5126   operands[1] = gen_rtx_REG (SImode, regno);
5127   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5128 }")
5129
5130 /* When storing r0, we have to avoid reg+reg addressing.  */
5131 (define_insn "movhi_i"
5132   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5133         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5134   "TARGET_SH1
5135    && (arith_reg_operand (operands[0], HImode)
5136        || arith_reg_operand (operands[1], HImode))
5137    && (GET_CODE (operands[0]) != MEM
5138        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5139        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5140        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5141   "@
5142         mov.w   %1,%0
5143         mov     %1,%0
5144         mov.w   %1,%0
5145         movt    %0
5146         mov.w   %1,%0
5147         sts     %1,%0
5148         lds     %1,%0
5149         fake    %1,%0"
5150   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5151
5152 (define_insn "*movhi_media"
5153   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5154         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5155   "TARGET_SHMEDIA
5156    && (arith_reg_operand (operands[0], HImode)
5157        || arith_reg_or_0_operand (operands[1], HImode))"
5158   "@
5159         add.l   %1, r63, %0
5160         movi    %1, %0
5161         #
5162         ld%M1.w %m1, %0
5163         st%M0.w %m0, %N1"
5164   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5165    (set (attr "highpart")
5166         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5167                (const_string "user")]
5168               (const_string "ignore")))])
5169
5170 (define_split
5171   [(set (match_operand:HI 0 "register_operand" "")
5172         (match_operand:HI 1 "immediate_operand" ""))]
5173   "TARGET_SHMEDIA && reload_completed
5174    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5175   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5176
5177 (define_expand "movhi"
5178   [(set (match_operand:HI 0 "general_movdst_operand" "")
5179         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5180   ""
5181   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5182
5183 (define_expand "reload_inhi"
5184   [(set (match_operand:SI 2 "" "=&r")
5185         (match_operand:HI 1 "inqhi_operand" ""))
5186    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5187         (truncate:HI (match_dup 3)))]
5188   "TARGET_SHMEDIA"
5189   "
5190 {
5191   rtx inner = XEXP (operands[1], 0);
5192   int regno = REGNO (inner);
5193
5194   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5195   operands[1] = gen_rtx_REG (SImode, regno);
5196   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5197 }")
5198
5199 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5200 ;; compiled with -m2 -ml -O3 -funroll-loops
5201 (define_insn "*movdi_i"
5202   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5203         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5204   "TARGET_SH1
5205    && (arith_reg_operand (operands[0], DImode)
5206        || arith_reg_operand (operands[1], DImode))"
5207   "* return output_movedouble (insn, operands, DImode);"
5208   [(set_attr "length" "4")
5209    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5210
5211 ;; If the output is a register and the input is memory or a register, we have
5212 ;; to be careful and see which word needs to be loaded first.
5213
5214 (define_split
5215   [(set (match_operand:DI 0 "general_movdst_operand" "")
5216         (match_operand:DI 1 "general_movsrc_operand" ""))]
5217   "TARGET_SH1 && reload_completed"
5218   [(set (match_dup 2) (match_dup 3))
5219    (set (match_dup 4) (match_dup 5))]
5220   "
5221 {
5222   int regno;
5223
5224   if ((GET_CODE (operands[0]) == MEM
5225        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5226       || (GET_CODE (operands[1]) == MEM
5227           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5228     FAIL;
5229
5230   switch (GET_CODE (operands[0]))
5231     {
5232     case REG:
5233       regno = REGNO (operands[0]);
5234       break;
5235     case SUBREG:
5236       regno = subreg_regno (operands[0]);
5237       break;
5238     case MEM:
5239       regno = -1;
5240       break;
5241     default:
5242       gcc_unreachable ();
5243     }
5244
5245   if (regno == -1
5246       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5247     {
5248       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5249       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5250       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5251       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5252     }
5253   else
5254     {
5255       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5256       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5257       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5258       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5259     }
5260
5261   if (operands[2] == 0 || operands[3] == 0
5262       || operands[4] == 0 || operands[5] == 0)
5263     FAIL;
5264 }")
5265
5266 ;; The '?'s in the following constraints may not reflect the time taken
5267 ;; to perform the move. They are there to discourage the use of floating-
5268 ;; point registers for storing integer values.
5269 (define_insn "*movdi_media"
5270   [(set (match_operand:DI 0 "general_movdst_operand"
5271                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5272         (match_operand:DI 1 "general_movsrc_operand"
5273          "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5274   "TARGET_SHMEDIA_FPU
5275    && (register_operand (operands[0], DImode)
5276        || sh_register_operand (operands[1], DImode))"
5277   "@
5278         add     %1, r63, %0
5279         movi    %1, %0
5280         #
5281         ld%M1.q %m1, %0
5282         st%M0.q %m0, %N1
5283         fld%M1.d        %m1, %0
5284         fst%M0.d        %m0, %1
5285         fmov.qd %N1, %0
5286         fmov.dq %1, %0
5287         fmov.d  %1, %0
5288         ptabs   %1, %0
5289         gettr   %1, %0
5290         pt      %1, %0"
5291   [(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")
5292    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5293
5294 (define_insn "*movdi_media_nofpu"
5295   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5296         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5297   "TARGET_SHMEDIA
5298    && (register_operand (operands[0], DImode)
5299        || sh_register_operand (operands[1], DImode))"
5300   "@
5301         add     %1, r63, %0
5302         movi    %1, %0
5303         #
5304         ld%M1.q %m1, %0
5305         st%M0.q %m0, %N1
5306         ptabs   %1, %0
5307         gettr   %1, %0
5308         pt      %1, %0"
5309   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5310    (set_attr "length" "4,4,16,4,4,4,4,*")])
5311
5312 (define_insn "*movdi_media_I16"
5313   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5314         (match_operand:DI 1 "const_int_operand" "I16"))]
5315   "TARGET_SHMEDIA && reload_completed"
5316   "movi %1, %0"
5317   [(set_attr "type" "arith_media")
5318    (set_attr "length" "4")])
5319
5320 (define_split
5321   [(set (match_operand:DI 0 "arith_reg_dest" "")
5322         (match_operand:DI 1 "immediate_operand" ""))]
5323   "TARGET_SHMEDIA && reload_completed
5324    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5325   [(set (match_dup 0) (match_dup 1))]
5326   "
5327 {
5328   rtx insn;
5329
5330   if (TARGET_SHMEDIA64)
5331     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5332   else
5333     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5334
5335   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5336                                         REG_NOTES (insn));
5337
5338   DONE;
5339 }")
5340
5341 (define_expand "movdi_const"
5342   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5343         (const:DI (sign_extend:DI
5344                    (truncate:HI
5345                     (ashiftrt:DI
5346                      (match_operand:DI 1 "immediate_operand" "s")
5347                      (const_int 48))))))
5348    (set (match_dup 0)
5349         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5350                 (zero_extend:DI
5351                  (truncate:HI
5352                   (const:DI
5353                    (sign_extend:DI
5354                     (truncate:HI
5355                      (ashiftrt:SI
5356                       (match_dup 1)
5357                       (const_int 32)))))))))
5358    (set (match_dup 0)
5359         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5360                 (zero_extend:DI
5361                  (truncate:HI
5362                   (const:DI
5363                    (sign_extend:DI
5364                     (truncate:HI
5365                      (ashiftrt:SI
5366                       (match_dup 1)
5367                       (const_int 16)))))))))
5368    (set (match_dup 0)
5369         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5370                 (zero_extend:DI
5371                  (truncate:HI
5372                   (const:DI
5373                    (sign_extend:DI
5374                     (truncate:HI
5375                      (match_dup 1))))))))]
5376   "TARGET_SHMEDIA64 && reload_completed
5377    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5378   "
5379 {
5380   sh_mark_label (operands[1], 4);
5381 }")
5382
5383 (define_expand "movdi_const_32bit"
5384   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5385         (const:DI (sign_extend:DI
5386                    (truncate:HI
5387                     (ashiftrt:DI
5388                      (match_operand:DI 1 "immediate_operand" "s")
5389                      (const_int 16))))))
5390    (set (match_dup 0)
5391         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5392                 (zero_extend:DI
5393                  (truncate:HI
5394                   (const:DI
5395                    (sign_extend:DI
5396                     (truncate:HI
5397                      (match_dup 1))))))))]
5398   "TARGET_SHMEDIA32 && reload_completed
5399    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5400   "
5401 {
5402   sh_mark_label (operands[1], 2);
5403 }")
5404
5405 (define_expand "movdi_const_16bit"
5406   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5407         (const:DI (sign_extend:DI
5408                    (truncate:HI
5409                     (match_operand:DI 1 "immediate_operand" "s")))))]
5410   "TARGET_SHMEDIA && flag_pic && reload_completed
5411    && GET_CODE (operands[1]) == SYMBOL_REF"
5412   "")
5413
5414 (define_split
5415   [(set (match_operand:DI 0 "ext_dest_operand" "")
5416         (match_operand:DI 1 "immediate_operand" ""))]
5417   "TARGET_SHMEDIA && reload_completed
5418    && GET_CODE (operands[1]) == CONST_INT
5419    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5420   [(set (match_dup 0) (match_dup 2))
5421    (match_dup 1)]
5422   "
5423 {
5424   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5425   unsigned HOST_WIDE_INT low = val;
5426   unsigned HOST_WIDE_INT high = val;
5427   unsigned HOST_WIDE_INT sign;
5428   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5429
5430   /* Sign-extend the 16 least-significant bits.  */
5431   low &= 0xffff;
5432   low ^= 0x8000;
5433   low -= 0x8000;
5434
5435   /* Arithmetic shift right the word by 16 bits.  */
5436   high >>= 16;
5437   if (GET_CODE (operands[0]) == SUBREG
5438       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5439     {
5440       high &= 0xffff;
5441       high ^= 0x8000;
5442       high -= 0x8000;
5443     }
5444   else
5445     {
5446       sign = 1;
5447       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5448       high ^= sign;
5449       high -= sign;
5450     }
5451   do
5452     {
5453       /* If we can't generate the constant with a two-insn movi / shori
5454          sequence, try some other strategies.  */
5455       if (! CONST_OK_FOR_I16 (high))
5456         {
5457           /* Try constant load / left shift.  We know VAL != 0.  */
5458           val2 = val ^ (val-1);
5459           if (val2 > 0x1ffff)
5460             {
5461               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5462
5463               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5464                   || (! CONST_OK_FOR_I16 (high >> 16)
5465                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5466                 {
5467                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5468                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5469                                                    GEN_INT (trailing_zeroes));
5470                   break;
5471                 }
5472             }
5473           /* Try constant load / right shift.  */
5474           val2 = (val >> 15) + 1;
5475           if (val2 == (val2 & -val2))
5476             {
5477               int shift = 49 - exact_log2 (val2);
5478
5479               val2 = trunc_int_for_mode (val << shift, DImode);
5480               if (CONST_OK_FOR_I16 (val2))
5481                 {
5482                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5483                                                    GEN_INT (shift));
5484                   break;
5485                 }
5486             }
5487           /* Try mperm.w .  */
5488           val2 = val & 0xffff;
5489           if ((val >> 16 & 0xffff) == val2
5490               && (val >> 32 & 0xffff) == val2
5491               && (val >> 48 & 0xffff) == val2)
5492             {
5493               val2 = (HOST_WIDE_INT) val >> 48;
5494               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5495               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5496               break;
5497             }
5498           /* Try movi / mshflo.l  */
5499           val2 = (HOST_WIDE_INT) val >> 32;
5500           if (val2 == ((unsigned HOST_WIDE_INT)
5501                         trunc_int_for_mode (val, SImode)))
5502             {
5503               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5504                                              operands[0]);
5505               break;
5506             }
5507           /* Try movi / mshflo.l w/ r63.  */
5508           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5509           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5510             {
5511               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5512                                              const0_rtx);
5513               break;
5514             }
5515         }
5516       val2 = high;
5517       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5518     }
5519   while (0);
5520   operands[2] = GEN_INT (val2);
5521 }")
5522
5523 (define_split
5524   [(set (match_operand:DI 0 "ext_dest_operand" "")
5525         (match_operand:DI 1 "immediate_operand" ""))]
5526   "TARGET_SHMEDIA && reload_completed
5527    && GET_CODE (operands[1]) == CONST_DOUBLE"
5528   [(set (match_dup 0) (match_dup 2))
5529   (set (match_dup 0)
5530        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5531                (zero_extend:DI (truncate:HI (match_dup 1)))))]
5532   "
5533 {
5534   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5535   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5536   unsigned HOST_WIDE_INT val = low;
5537   unsigned HOST_WIDE_INT sign;
5538
5539   /* Sign-extend the 16 least-significant bits.  */
5540   val &= 0xffff;
5541   val ^= 0x8000;
5542   val -= 0x8000;
5543   operands[1] = GEN_INT (val);
5544
5545   /* Arithmetic shift right the double-word by 16 bits.  */
5546   low >>= 16;
5547   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5548   high >>= 16;
5549   sign = 1;
5550   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5551   high ^= sign;
5552   high -= sign;
5553
5554   /* This will only be true if high is a sign-extension of low, i.e.,
5555      it must be either 0 or (unsigned)-1, and be zero iff the
5556      most-significant bit of low is set.  */
5557   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5558     operands[2] = GEN_INT (low);
5559   else
5560     operands[2] = immed_double_const (low, high, DImode);
5561 }")
5562
5563 (define_insn "shori_media"
5564   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5565         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5566                            (const_int 16))
5567                 (zero_extend:DI
5568                  (truncate:HI
5569                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5570   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5571   "@
5572         shori   %u2, %0
5573         #"
5574   [(set_attr "type" "arith_media,*")])
5575
5576 (define_insn "*shori_media_si"
5577   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5578         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5579                            (const_int 16))
5580                 (zero_extend:SI
5581                  (truncate:HI
5582                   (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5583   "TARGET_SHMEDIA"
5584   "shori        %u2, %0")
5585
5586 (define_expand "movdi"
5587   [(set (match_operand:DI 0 "general_movdst_operand" "")
5588         (match_operand:DI 1 "general_movsrc_operand" ""))]
5589   ""
5590   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5591
5592 (define_insn "movdf_media"
5593   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5594         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5595   "TARGET_SHMEDIA_FPU
5596    && (register_operand (operands[0], DFmode)
5597        || sh_register_operand (operands[1], DFmode))"
5598   "@
5599         fmov.d  %1, %0
5600         fmov.qd %N1, %0
5601         fmov.dq %1, %0
5602         add     %1, r63, %0
5603         #
5604         fld%M1.d        %m1, %0
5605         fst%M0.d        %m0, %1
5606         ld%M1.q %m1, %0
5607         st%M0.q %m0, %N1"
5608   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5609
5610 (define_insn "movdf_media_nofpu"
5611   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5612         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5613   "TARGET_SHMEDIA
5614    && (register_operand (operands[0], DFmode)
5615        || sh_register_operand (operands[1], DFmode))"
5616   "@
5617         add     %1, r63, %0
5618         #
5619         ld%M1.q %m1, %0
5620         st%M0.q %m0, %N1"
5621   [(set_attr "type" "arith_media,*,load_media,store_media")])
5622
5623 (define_split
5624   [(set (match_operand:DF 0 "arith_reg_dest" "")
5625         (match_operand:DF 1 "immediate_operand" ""))]
5626   "TARGET_SHMEDIA && reload_completed"
5627   [(set (match_dup 3) (match_dup 2))]
5628   "
5629 {
5630   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5631   long values[2];
5632   REAL_VALUE_TYPE value;
5633
5634   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5635   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5636
5637   if (HOST_BITS_PER_WIDE_INT >= 64)
5638     operands[2] = immed_double_const ((unsigned long) values[endian]
5639                                       | ((HOST_WIDE_INT) values[1 - endian]
5640                                          << 32), 0, DImode);
5641   else
5642     {
5643       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5644       operands[2] = immed_double_const (values[endian], values[1 - endian],
5645                                         DImode);
5646     }
5647
5648   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5649 }")
5650
5651 ;; ??? This should be a define expand.
5652
5653 (define_insn "movdf_k"
5654   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5655         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5656   "TARGET_SH1
5657    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5658        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5659        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5660        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5661    && (arith_reg_operand (operands[0], DFmode)
5662        || arith_reg_operand (operands[1], DFmode))"
5663   "* return output_movedouble (insn, operands, DFmode);"
5664   [(set_attr "length" "4")
5665    (set_attr "type" "move,pcload,load,store")])
5666
5667 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5668 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5669 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5670 ;; the d/m/c/X alternative, which is split later into single-precision
5671 ;; instructions.  And when not optimizing, no splits are done before fixing
5672 ;; up pcloads, so we need usable length information for that.
5673 (define_insn "movdf_i4"
5674   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5675         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5676    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5677    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5678   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5679    && (arith_reg_operand (operands[0], DFmode)
5680        || arith_reg_operand (operands[1], DFmode))"
5681   "@
5682         fmov    %1,%0
5683         #
5684         #
5685         fmov.d  %1,%0
5686         fmov.d  %1,%0
5687         #
5688         #
5689         #
5690         #
5691         #"
5692   [(set_attr_alternative "length"
5693      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5694       (const_int 4)
5695       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5696       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5697       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5698       (const_int 4)
5699       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5700       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5701       ;; increment or decrement r15 explicitly.
5702       (if_then_else
5703        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5704        (const_int 10) (const_int 8))
5705       (if_then_else
5706        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5707        (const_int 10) (const_int 8))])
5708    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5709    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5710    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5711                                            (const_string "double")
5712                                            (const_string "none")))])
5713
5714 ;; Moving DFmode between fp/general registers through memory
5715 ;; (the top of the stack) is faster than moving through fpul even for
5716 ;; little endian.  Because the type of an instruction is important for its
5717 ;; scheduling,  it is beneficial to split these operations, rather than
5718 ;; emitting them in one single chunk, even if this will expose a stack
5719 ;; use that will prevent scheduling of other stack accesses beyond this
5720 ;; instruction.
5721 (define_split
5722   [(set (match_operand:DF 0 "register_operand" "")
5723         (match_operand:DF 1 "register_operand" ""))
5724    (use (match_operand:PSI 2 "fpscr_operand" ""))
5725    (clobber (match_scratch:SI 3 "=X"))]
5726   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5727    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5728   [(const_int 0)]
5729   "
5730 {
5731   rtx insn, tos;
5732
5733   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5734     {
5735       emit_move_insn (stack_pointer_rtx,
5736                       plus_constant (stack_pointer_rtx, -8));
5737       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5738     }
5739   else
5740     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5741   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5742   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5743     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5744   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5745     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5746   else
5747     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5748   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5749   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5750     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5751   else
5752     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5753   DONE;
5754 }")
5755
5756 ;; local-alloc sometimes allocates scratch registers even when not required,
5757 ;; so we must be prepared to handle these.
5758
5759 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5760 (define_split
5761   [(set (match_operand:DF 0 "general_movdst_operand" "")
5762         (match_operand:DF 1 "general_movsrc_operand"  ""))
5763    (use (match_operand:PSI 2 "fpscr_operand" ""))
5764    (clobber (match_scratch:SI 3 ""))]
5765   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5766    && reload_completed
5767    && true_regnum (operands[0]) < 16
5768    && true_regnum (operands[1]) < 16"
5769   [(set (match_dup 0) (match_dup 1))]
5770   "
5771 {
5772   /* If this was a reg <-> mem operation with base + index reg addressing,
5773      we have to handle this in a special way.  */
5774   rtx mem = operands[0];
5775   int store_p = 1;
5776   if (! memory_operand (mem, DFmode))
5777     {
5778       mem = operands[1];
5779       store_p = 0;
5780     }
5781   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5782     mem = SUBREG_REG (mem);
5783   if (GET_CODE (mem) == MEM)
5784     {
5785       rtx addr = XEXP (mem, 0);
5786       if (GET_CODE (addr) == PLUS
5787           && GET_CODE (XEXP (addr, 0)) == REG
5788           && GET_CODE (XEXP (addr, 1)) == REG)
5789         {
5790           int offset;
5791           rtx reg0 = gen_rtx_REG (Pmode, 0);
5792           rtx regop = operands[store_p], word0 ,word1;
5793
5794           if (GET_CODE (regop) == SUBREG)
5795             alter_subreg (&regop);
5796           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5797             offset = 2;
5798           else
5799             offset = 4;
5800           mem = copy_rtx (mem);
5801           PUT_MODE (mem, SImode);
5802           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5803           alter_subreg (&word0);
5804           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5805           alter_subreg (&word1);
5806           if (store_p || ! refers_to_regno_p (REGNO (word0),
5807                                               REGNO (word0) + 1, addr, 0))
5808             {
5809               emit_insn (store_p
5810                          ? gen_movsi_ie (mem, word0)
5811                          : gen_movsi_ie (word0, mem));
5812               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5813               mem = copy_rtx (mem);
5814               emit_insn (store_p
5815                          ? gen_movsi_ie (mem, word1)
5816                          : gen_movsi_ie (word1, mem));
5817               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5818             }
5819           else
5820             {
5821               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5822               emit_insn (gen_movsi_ie (word1, mem));
5823               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5824               mem = copy_rtx (mem);
5825               emit_insn (gen_movsi_ie (word0, mem));
5826             }
5827           DONE;
5828         }
5829     }
5830 }")
5831
5832 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5833 (define_split
5834   [(set (match_operand:DF 0 "register_operand" "")
5835         (match_operand:DF 1 "memory_operand"  ""))
5836    (use (match_operand:PSI 2 "fpscr_operand" ""))
5837    (clobber (reg:SI R0_REG))]
5838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5839   [(parallel [(set (match_dup 0) (match_dup 1))
5840               (use (match_dup 2))
5841               (clobber (scratch:SI))])]
5842   "")
5843
5844 (define_expand "reload_indf"
5845   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5846                    (match_operand:DF 1 "immediate_operand" "FQ"))
5847               (use (reg:PSI FPSCR_REG))
5848               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5849   "TARGET_SH1"
5850   "")
5851
5852 (define_expand "reload_outdf"
5853   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5854                    (match_operand:DF 1 "register_operand" "af,r"))
5855               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5856   "TARGET_SH1"
5857   "")
5858
5859 ;; Simplify no-op moves.
5860 (define_split
5861   [(set (match_operand:SF 0 "register_operand" "")
5862         (match_operand:SF 1 "register_operand" ""))
5863    (use (match_operand:PSI 2 "fpscr_operand" ""))
5864    (clobber (match_scratch:SI 3 ""))]
5865   "TARGET_SH2E && reload_completed
5866    && true_regnum (operands[0]) == true_regnum (operands[1])"
5867   [(set (match_dup 0) (match_dup 0))]
5868   "")
5869
5870 ;; fmovd substitute post-reload splits
5871 (define_split
5872   [(set (match_operand:DF 0 "register_operand" "")
5873         (match_operand:DF 1 "register_operand" ""))
5874    (use (match_operand:PSI 2 "fpscr_operand" ""))
5875    (clobber (match_scratch:SI 3 ""))]
5876   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5877    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5878    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5879   [(const_int 0)]
5880   "
5881 {
5882   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5883   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5884                            gen_rtx_REG (SFmode, src), operands[2]));
5885   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5886                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5887   DONE;
5888 }")
5889
5890 (define_split
5891   [(set (match_operand:DF 0 "register_operand" "")
5892         (mem:DF (match_operand:SI 1 "register_operand" "")))
5893    (use (match_operand:PSI 2 "fpscr_operand" ""))
5894    (clobber (match_scratch:SI 3 ""))]
5895   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5896    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5897    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5898   [(const_int 0)]
5899   "
5900 {
5901   int regno = true_regnum (operands[0]);
5902   rtx insn;
5903   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5904
5905   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5906                                            regno + !! TARGET_LITTLE_ENDIAN),
5907                                   mem2, operands[2]));
5908   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5909   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5910                                            regno + ! TARGET_LITTLE_ENDIAN),
5911                                   gen_rtx_MEM (SFmode, operands[1]),
5912                                   operands[2]));
5913   DONE;
5914 }")
5915
5916 (define_split
5917   [(set (match_operand:DF 0 "register_operand" "")
5918         (match_operand:DF 1 "memory_operand" ""))
5919    (use (match_operand:PSI 2 "fpscr_operand" ""))
5920    (clobber (match_scratch:SI 3 ""))]
5921   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5922    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5923   [(const_int 0)]
5924   "
5925 {
5926   int regno = true_regnum (operands[0]);
5927   rtx addr, insn, adjust = NULL_RTX;
5928   rtx mem2 = copy_rtx (operands[1]);
5929   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5930   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5931
5932   PUT_MODE (mem2, SFmode);
5933   operands[1] = copy_rtx (mem2);
5934   addr = XEXP (mem2, 0);
5935   if (GET_CODE (addr) != POST_INC)
5936     {
5937       /* If we have to modify the stack pointer, the value that we have
5938          read with post-increment might be modified by an interrupt,
5939          so write it back.  */
5940       if (REGNO (addr) == STACK_POINTER_REGNUM)
5941         adjust = gen_push_e (reg0);
5942       else
5943         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5944       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5945     }
5946   addr = XEXP (addr, 0);
5947   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5948   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5949   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5950   if (adjust)
5951     emit_insn (adjust);
5952   else
5953     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5954   DONE;
5955 }")
5956
5957 (define_split
5958   [(set (match_operand:DF 0 "memory_operand" "")
5959         (match_operand:DF 1 "register_operand" ""))
5960    (use (match_operand:PSI 2 "fpscr_operand" ""))
5961    (clobber (match_scratch:SI 3 ""))]
5962   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5963    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5964   [(const_int 0)]
5965   "
5966 {
5967   int regno = true_regnum (operands[1]);
5968   rtx insn, addr, adjust = NULL_RTX;
5969
5970   operands[0] = copy_rtx (operands[0]);
5971   PUT_MODE (operands[0], SFmode);
5972   insn = emit_insn (gen_movsf_ie (operands[0],
5973                                   gen_rtx_REG (SFmode,
5974                                            regno + ! TARGET_LITTLE_ENDIAN),
5975                                   operands[2]));
5976   operands[0] = copy_rtx (operands[0]);
5977   addr = XEXP (operands[0], 0);
5978   if (GET_CODE (addr) != PRE_DEC)
5979     {
5980       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5981       emit_insn_before (adjust, insn);
5982       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5983     }
5984   addr = XEXP (addr, 0);
5985   if (! adjust)
5986     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5987   insn = emit_insn (gen_movsf_ie (operands[0],
5988                                   gen_rtx_REG (SFmode,
5989                                            regno + !! TARGET_LITTLE_ENDIAN),
5990                                   operands[2]));
5991   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5992   DONE;
5993 }")
5994
5995 ;; If the output is a register and the input is memory or a register, we have
5996 ;; to be careful and see which word needs to be loaded first.
5997
5998 (define_split
5999   [(set (match_operand:DF 0 "general_movdst_operand" "")
6000         (match_operand:DF 1 "general_movsrc_operand" ""))]
6001   "TARGET_SH1 && reload_completed"
6002   [(set (match_dup 2) (match_dup 3))
6003    (set (match_dup 4) (match_dup 5))]
6004   "
6005 {
6006   int regno;
6007
6008   if ((GET_CODE (operands[0]) == MEM
6009        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6010       || (GET_CODE (operands[1]) == MEM
6011           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6012     FAIL;
6013
6014   switch (GET_CODE (operands[0]))
6015     {
6016     case REG:
6017       regno = REGNO (operands[0]);
6018       break;
6019     case SUBREG:
6020       regno = subreg_regno (operands[0]);
6021       break;
6022     case MEM:
6023       regno = -1;
6024       break;
6025     default:
6026       gcc_unreachable ();
6027     }
6028
6029   if (regno == -1
6030       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6031     {
6032       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6033       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6034       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6035       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6036     }
6037   else
6038     {
6039       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6040       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6041       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6042       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6043     }
6044
6045   if (operands[2] == 0 || operands[3] == 0
6046       || operands[4] == 0 || operands[5] == 0)
6047     FAIL;
6048 }")
6049
6050 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6051 ;; used only once, let combine add in the index again.
6052
6053 (define_split
6054   [(set (match_operand:SI 0 "register_operand" "")
6055         (match_operand:SI 1 "" ""))
6056    (clobber (match_operand 2 "register_operand" ""))]
6057   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6058    && ALLOW_INDEXED_ADDRESS"
6059   [(use (reg:SI R0_REG))]
6060   "
6061 {
6062   rtx addr, reg, const_int;
6063
6064   if (GET_CODE (operands[1]) != MEM)
6065     FAIL;
6066   addr = XEXP (operands[1], 0);
6067   if (GET_CODE (addr) != PLUS)
6068     FAIL;
6069   reg = XEXP (addr, 0);
6070   const_int = XEXP (addr, 1);
6071   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6072          && GET_CODE (const_int) == CONST_INT))
6073     FAIL;
6074   emit_move_insn (operands[2], const_int);
6075   emit_move_insn (operands[0],
6076                   change_address (operands[1], VOIDmode,
6077                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6078   DONE;
6079 }")
6080
6081 (define_split
6082   [(set (match_operand:SI 1 "" "")
6083         (match_operand:SI 0 "register_operand" ""))
6084    (clobber (match_operand 2 "register_operand" ""))]
6085   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6086    && ALLOW_INDEXED_ADDRESS"
6087   [(use (reg:SI R0_REG))]
6088   "
6089 {
6090   rtx addr, reg, const_int;
6091
6092   if (GET_CODE (operands[1]) != MEM)
6093     FAIL;
6094   addr = XEXP (operands[1], 0);
6095   if (GET_CODE (addr) != PLUS)
6096     FAIL;
6097   reg = XEXP (addr, 0);
6098   const_int = XEXP (addr, 1);
6099   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6100          && GET_CODE (const_int) == CONST_INT))
6101     FAIL;
6102   emit_move_insn (operands[2], const_int);
6103   emit_move_insn (change_address (operands[1], VOIDmode,
6104                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6105                   operands[0]);
6106   DONE;
6107 }")
6108
6109 (define_expand "movdf"
6110   [(set (match_operand:DF 0 "general_movdst_operand" "")
6111         (match_operand:DF 1 "general_movsrc_operand" ""))]
6112   ""
6113   "
6114 {
6115   if (prepare_move_operands (operands, DFmode)) DONE;
6116   if (TARGET_SHMEDIA)
6117     {
6118       if (TARGET_SHMEDIA_FPU)
6119         emit_insn (gen_movdf_media (operands[0], operands[1]));
6120       else
6121         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6122       DONE;
6123     }
6124   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6125     {
6126       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6127       DONE;
6128     }
6129 }")
6130
6131 ;;This is incompatible with the way gcc uses subregs.
6132 ;;(define_insn "movv2sf_i"
6133 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6134 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6135 ;;  "TARGET_SHMEDIA_FPU
6136 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6137 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6138 ;;  "@
6139 ;;      #
6140 ;;      fld%M1.p        %m1, %0
6141 ;;      fst%M0.p        %m0, %1"
6142 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6143
6144 (define_insn_and_split "movv2sf_i"
6145   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6146         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6147   "TARGET_SHMEDIA_FPU"
6148   "#"
6149   "TARGET_SHMEDIA_FPU && reload_completed"
6150   [(set (match_dup 0) (match_dup 1))]
6151   "
6152 {
6153   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6154   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6155 }")
6156
6157 (define_expand "movv2sf"
6158   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6159         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6160   "TARGET_SHMEDIA_FPU"
6161   "
6162 {
6163   if (prepare_move_operands (operands, V2SFmode))
6164     DONE;
6165 }")
6166
6167 (define_expand "addv2sf3"
6168   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6169    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6170    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6171   "TARGET_SHMEDIA_FPU"
6172   "
6173 {
6174   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6175   DONE;
6176 }")
6177
6178 (define_expand "subv2sf3"
6179   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6180    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6181    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6182   "TARGET_SHMEDIA_FPU"
6183   "
6184 {
6185   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6186   DONE;
6187 }")
6188
6189 (define_expand "mulv2sf3"
6190   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6191    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6192    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6193   "TARGET_SHMEDIA_FPU"
6194   "
6195 {
6196   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6197   DONE;
6198 }")
6199
6200 (define_expand "divv2sf3"
6201   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6202    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6203    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6204   "TARGET_SHMEDIA_FPU"
6205   "
6206 {
6207   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6208   DONE;
6209 }")
6210
6211 (define_insn_and_split "*movv4sf_i"
6212   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
6213         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
6214   "TARGET_SHMEDIA_FPU"
6215   "#"
6216   "&& reload_completed"
6217   [(const_int 0)]
6218   "
6219 {
6220   int i;
6221
6222   for (i = 0; i < 4/2; i++)
6223     {
6224       rtx x, y;
6225
6226       if (GET_CODE (operands[0]) == MEM)
6227         x = gen_rtx_MEM (V2SFmode,
6228                          plus_constant (XEXP (operands[0], 0),
6229                                         i * GET_MODE_SIZE (V2SFmode)));
6230       else
6231         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6232
6233       if (GET_CODE (operands[1]) == MEM)
6234         y = gen_rtx_MEM (V2SFmode,
6235                          plus_constant (XEXP (operands[1], 0),
6236                                         i * GET_MODE_SIZE (V2SFmode)));
6237       else
6238         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6239
6240       emit_insn (gen_movv2sf_i (x, y));
6241     }
6242
6243   DONE;
6244 }"
6245   [(set_attr "length" "8")])
6246
6247 (define_expand "movv4sf"
6248   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6249         (match_operand:V4SF 1 "general_operand" ""))]
6250   "TARGET_SHMEDIA_FPU"
6251   "
6252 {
6253   if (prepare_move_operands (operands, V4SFmode))
6254     DONE;
6255 }")
6256
6257 (define_insn_and_split "*movv16sf_i"
6258   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6259         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6260   "TARGET_SHMEDIA_FPU"
6261   "#"
6262   "&& reload_completed"
6263   [(const_int 0)]
6264   "
6265 {
6266   int i;
6267
6268   for (i = 0; i < 16/2; i++)
6269     {
6270       rtx x,y;
6271
6272       if (GET_CODE (operands[0]) == MEM)
6273         x = gen_rtx_MEM (V2SFmode,
6274                          plus_constant (XEXP (operands[0], 0),
6275                                         i * GET_MODE_SIZE (V2SFmode)));
6276       else
6277         {
6278           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6279           alter_subreg (&x);
6280         }
6281
6282       if (GET_CODE (operands[1]) == MEM)
6283         y = gen_rtx_MEM (V2SFmode,
6284                          plus_constant (XEXP (operands[1], 0),
6285                                         i * GET_MODE_SIZE (V2SFmode)));
6286       else
6287         {
6288           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6289           alter_subreg (&y);
6290         }
6291
6292       emit_insn (gen_movv2sf_i (x, y));
6293     }
6294
6295   DONE;
6296 }"
6297   [(set_attr "length" "32")])
6298
6299 (define_expand "movv16sf"
6300   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6301         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6302   "TARGET_SHMEDIA_FPU"
6303   "
6304 {
6305   if (prepare_move_operands (operands, V16SFmode))
6306     DONE;
6307 }")
6308
6309 (define_insn "movsf_media"
6310   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6311         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6312   "TARGET_SHMEDIA_FPU
6313    && (register_operand (operands[0], SFmode)
6314        || sh_register_operand (operands[1], SFmode))"
6315   "@
6316         fmov.s  %1, %0
6317         fmov.ls %N1, %0
6318         fmov.sl %1, %0
6319         add.l   %1, r63, %0
6320         #
6321         fld%M1.s        %m1, %0
6322         fst%M0.s        %m0, %1
6323         ld%M1.l %m1, %0
6324         st%M0.l %m0, %N1"
6325   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6326    (set (attr "highpart")
6327         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6328                (const_string "user")]
6329               (const_string "ignore")))])
6330
6331 (define_insn "movsf_media_nofpu"
6332   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6333         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6334   "TARGET_SHMEDIA
6335    && (register_operand (operands[0], SFmode)
6336        || sh_register_operand (operands[1], SFmode))"
6337   "@
6338         add.l   %1, r63, %0
6339         #
6340         ld%M1.l %m1, %0
6341         st%M0.l %m0, %N1"
6342   [(set_attr "type" "arith_media,*,load_media,store_media")
6343    (set (attr "highpart")
6344         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6345                (const_string "user")]
6346               (const_string "ignore")))])
6347
6348 (define_split
6349   [(set (match_operand:SF 0 "arith_reg_dest" "")
6350         (match_operand:SF 1 "immediate_operand" ""))]
6351   "TARGET_SHMEDIA && reload_completed
6352    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6353   [(set (match_dup 3) (match_dup 2))]
6354   "
6355 {
6356   long values;
6357   REAL_VALUE_TYPE value;
6358
6359   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6360   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6361   operands[2] = GEN_INT (values);
6362
6363   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6364 }")
6365
6366 (define_insn "movsf_i"
6367   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6368         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6369   "TARGET_SH1
6370    && (! TARGET_SH2E
6371        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6372        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6373        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6374    && (arith_reg_operand (operands[0], SFmode)
6375        || arith_reg_operand (operands[1], SFmode))"
6376   "@
6377         mov     %1,%0
6378         mov     #0,%0
6379         mov.l   %1,%0
6380         mov.l   %1,%0
6381         mov.l   %1,%0
6382         lds     %1,%0
6383         sts     %1,%0"
6384   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6385
6386 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6387 ;; update_flow_info would not know where to put REG_EQUAL notes
6388 ;; when the destination changes mode.
6389 (define_insn "movsf_ie"
6390   [(set (match_operand:SF 0 "general_movdst_operand"
6391          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6392         (match_operand:SF 1 "general_movsrc_operand"
6393           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6394    (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"))
6395    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6396
6397   "TARGET_SH2E
6398    && (arith_reg_operand (operands[0], SFmode)
6399        || arith_reg_operand (operands[1], SFmode)
6400        || arith_reg_operand (operands[3], SImode)
6401        || (fpul_operand (operands[0], SFmode)
6402            && memory_operand (operands[1], SFmode)
6403            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6404        || (fpul_operand (operands[1], SFmode)
6405            && memory_operand (operands[0], SFmode)
6406            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6407   "@
6408         fmov    %1,%0
6409         mov     %1,%0
6410         fldi0   %0
6411         fldi1   %0
6412         #
6413         fmov.s  %1,%0
6414         fmov.s  %1,%0
6415         mov.l   %1,%0
6416         mov.l   %1,%0
6417         mov.l   %1,%0
6418         fsts    fpul,%0
6419         flds    %1,fpul
6420         lds.l   %1,%0
6421         #
6422         sts     %1,%0
6423         lds     %1,%0
6424         sts.l   %1,%0
6425         lds.l   %1,%0
6426         ! move optimized away"
6427   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6428    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6429    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6430    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6431                                            (const_string "single")
6432                                            (const_string "none")))])
6433
6434 (define_split
6435   [(set (match_operand:SF 0 "register_operand" "")
6436         (match_operand:SF 1 "register_operand" ""))
6437    (use (match_operand:PSI 2 "fpscr_operand" ""))
6438    (clobber (reg:SI FPUL_REG))]
6439   "TARGET_SH1"
6440   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6441               (use (match_dup 2))
6442               (clobber (scratch:SI))])
6443    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6444               (use (match_dup 2))
6445               (clobber (scratch:SI))])]
6446   "")
6447
6448 (define_expand "movsf"
6449   [(set (match_operand:SF 0 "general_movdst_operand" "")
6450         (match_operand:SF 1 "general_movsrc_operand" ""))]
6451   ""
6452   "
6453 {
6454   if (prepare_move_operands (operands, SFmode))
6455     DONE;
6456   if (TARGET_SHMEDIA)
6457     {
6458       if (TARGET_SHMEDIA_FPU)
6459         emit_insn (gen_movsf_media (operands[0], operands[1]));
6460       else
6461         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6462       DONE;
6463     }
6464   if (TARGET_SH2E)
6465     {
6466       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6467       DONE;
6468     }
6469 }")
6470
6471 (define_insn "mov_nop"
6472   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6473   "TARGET_SH2E"
6474   ""
6475   [(set_attr "length" "0")
6476    (set_attr "type" "nil")])
6477
6478 (define_expand "reload_insf"
6479   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6480                    (match_operand:SF 1 "immediate_operand" "FQ"))
6481               (use (reg:PSI FPSCR_REG))
6482               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6483   "TARGET_SH1"
6484   "")
6485
6486 (define_expand "reload_insi"
6487   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6488                    (match_operand:SI 1 "immediate_operand" "i"))
6489               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6490   "TARGET_SH1"
6491   "")
6492
6493 (define_expand "ptabs"
6494   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6495   "TARGET_SHMEDIA"
6496   "
6497 {
6498   if (!TARGET_PT_FIXED)
6499     {
6500       rtx eq = operands[1];
6501
6502       /* ??? For canonical RTL we really should remove any CONST from EQ
6503          before wrapping it in the AND, and finally wrap the EQ into a
6504          const if is constant.  However, for reload we must expose the
6505          input register or symbolic constant, and we can't have
6506          different insn structures outside of the operands for different
6507          alternatives of the same pattern.  */
6508       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6509                        GEN_INT (3));
6510       operands[1]
6511         = (gen_rtx_IF_THEN_ELSE
6512             (PDImode,
6513              eq,
6514              gen_rtx_MEM (PDImode, operands[1]),
6515              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6516                             PDImode, operands[1])));
6517     }
6518 }")
6519
6520 ;; expanded by ptabs expander.
6521 (define_insn "*extendsipdi_media"
6522   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6523         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6524                                                           "r,Csy")
6525                                       (const_int 3))
6526                               (const_int 3))
6527                           (mem:PDI (match_dup 1))
6528                           (sign_extend:PDI (match_dup 1))))]
6529   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6530   "@
6531         ptabs   %1, %0
6532         pt      %1, %0"
6533   [(set_attr "type"   "ptabs_media,pt_media")
6534    (set_attr "length" "4,*")])
6535
6536 (define_insn "*truncdipdi_media"
6537   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6538         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6539                                                           "r,Csy")
6540                                       (const_int 3))
6541                               (const_int 3))
6542                           (mem:PDI (match_dup 1))
6543                           (truncate:PDI (match_dup 1))))]
6544   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6545   "@
6546         ptabs   %1, %0
6547         pt      %1, %0"
6548   [(set_attr "type"   "ptabs_media,pt_media")
6549    (set_attr "length" "4,*")])
6550
6551 (define_insn "*movsi_y"
6552   [(set (match_operand:SI 0 "register_operand" "=y,y")
6553         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6554    (clobber (match_scratch:SI 2 "=&z,r"))]
6555   "TARGET_SH2E
6556    && (reload_in_progress || reload_completed)"
6557   "#"
6558   [(set_attr "length" "4")
6559    (set_attr "type" "pcload,move")])
6560
6561 (define_split
6562   [(set (match_operand:SI 0 "register_operand" "")
6563         (match_operand:SI 1 "immediate_operand" ""))
6564    (clobber (match_operand:SI 2 "register_operand" ""))]
6565   "TARGET_SH1"
6566   [(set (match_dup 2) (match_dup 1))
6567    (set (match_dup 0) (match_dup 2))]
6568   "")
6569
6570 (define_split
6571   [(set (match_operand:SI 0 "register_operand" "")
6572         (match_operand:SI 1 "memory_operand" ""))
6573    (clobber (reg:SI R0_REG))]
6574   "TARGET_SH1"
6575   [(set (match_dup 0) (match_dup 1))]
6576   "")
6577 \f
6578 ;; ------------------------------------------------------------------------
6579 ;; Define the real conditional branch instructions.
6580 ;; ------------------------------------------------------------------------
6581
6582 (define_insn "branch_true"
6583   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6584                            (label_ref (match_operand 0 "" ""))
6585                            (pc)))]
6586   "TARGET_SH1"
6587   "* return output_branch (1, insn, operands);"
6588   [(set_attr "type" "cbranch")])
6589
6590 (define_insn "branch_false"
6591   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6592                            (label_ref (match_operand 0 "" ""))
6593                            (pc)))]
6594   "TARGET_SH1"
6595   "* return output_branch (0, insn, operands);"
6596   [(set_attr "type" "cbranch")])
6597
6598 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6599 ;; which destination is too far away.
6600 ;; The const_int_operand is distinct for each branch target; it avoids
6601 ;; unwanted matches with redundant_insn.
6602 (define_insn "block_branch_redirect"
6603   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6604   "TARGET_SH1"
6605   ""
6606   [(set_attr "length" "0")])
6607
6608 ;; This one has the additional purpose to record a possible scratch register
6609 ;; for the following branch.
6610 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6611 ;; because the insn then might be deemed dead and deleted.  And we can't
6612 ;; make the use in the jump insn explicit because that would disable
6613 ;; delay slot scheduling from the target.
6614 (define_insn "indirect_jump_scratch"
6615   [(set (match_operand:SI 0 "register_operand" "=r")
6616         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6617    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6618   "TARGET_SH1"
6619   ""
6620   [(set_attr "length" "0")])
6621
6622 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6623 ;; being pulled into the delay slot of a condbranch that has been made to
6624 ;; jump around the unconditional jump because it was out of range.
6625 (define_insn "stuff_delay_slot"
6626   [(set (pc)
6627         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6628    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6629   "TARGET_SH1"
6630   ""
6631   [(set_attr "length" "0")
6632    (set_attr "cond_delay_slot" "yes")])
6633 \f
6634 ;; Conditional branch insns
6635
6636 (define_expand "beq_media"
6637   [(set (pc)
6638         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6639                           (match_operand:DI 2 "arith_operand" "r,I06"))
6640                       (match_operand 0 "" "")
6641                       (pc)))]
6642   "TARGET_SHMEDIA"
6643   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6644
6645 (define_insn "*beq_media_i"
6646   [(set (pc)
6647         (if_then_else (match_operator 3 "equality_comparison_operator"
6648                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6649                          (match_operand:DI 2 "arith_operand" "r,I06")])
6650                       (match_operand 0 "target_operand" "b,b")
6651                       (pc)))]
6652   "TARGET_SHMEDIA"
6653   "@
6654         b%o3%'  %1, %2, %0%>
6655         b%o3i%' %1, %2, %0%>"
6656   [(set_attr "type" "cbranch_media")])
6657
6658 (define_insn "*beq_media_i32"
6659   [(set (pc)
6660         (if_then_else (match_operator 3 "equality_comparison_operator"
6661                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6662                          (match_operand:SI 2 "arith_operand" "r,I06")])
6663                       (match_operand 0 "target_operand" "b,b")
6664                       (pc)))]
6665   "TARGET_SHMEDIA"
6666   "@
6667         b%o3%'  %1, %2, %0%>
6668         b%o3i%' %1, %2, %0%>"
6669   [(set_attr "type" "cbranch_media")])
6670
6671 (define_expand "bne_media"
6672   [(set (pc)
6673         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6674                           (match_operand:DI 2 "arith_operand" "r,I06"))
6675                       (match_operand 0 "" "")
6676                       (pc)))]
6677   "TARGET_SHMEDIA"
6678   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6679
6680 (define_expand "bgt_media"
6681   [(set (pc)
6682         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6683                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6684                       (match_operand 0 "" "")
6685                       (pc)))]
6686   "TARGET_SHMEDIA"
6687   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6688
6689 (define_expand "bge_media"
6690   [(set (pc)
6691         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6692                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6693                       (match_operand 0 "" "")
6694                       (pc)))]
6695   "TARGET_SHMEDIA"
6696   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6697
6698 (define_expand "bgtu_media"
6699   [(set (pc)
6700         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6701                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6702                       (match_operand 0 "" "")
6703                       (pc)))]
6704   "TARGET_SHMEDIA"
6705   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6706
6707 (define_expand "bgeu_media"
6708   [(set (pc)
6709         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6710                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6711                       (match_operand 0 "" "")
6712                       (pc)))]
6713   "TARGET_SHMEDIA"
6714   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6715
6716 (define_insn "*bgt_media_i"
6717   [(set (pc)
6718         (if_then_else (match_operator 3 "greater_comparison_operator"
6719                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6720                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6721                       (match_operand 0 "target_operand" "b")
6722                       (pc)))]
6723   "TARGET_SHMEDIA"
6724   "b%o3%'       %N1, %N2, %0%>"
6725   [(set_attr "type" "cbranch_media")])
6726
6727 (define_insn "*bgt_media_i32"
6728   [(set (pc)
6729         (if_then_else (match_operator 3 "greater_comparison_operator"
6730                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6731                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6732                       (match_operand 0 "target_operand" "b")
6733                       (pc)))]
6734   "TARGET_SHMEDIA"
6735   "b%o3%'       %N1, %N2, %0%>"
6736   [(set_attr "type" "cbranch_media")])
6737
6738 ;; These are only needed to make invert_jump() happy - otherwise, jump
6739 ;; optimization will be silently disabled.
6740 (define_insn "*blt_media_i"
6741   [(set (pc)
6742         (if_then_else (match_operator 3 "less_comparison_operator"
6743                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6744                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6745                       (match_operand 0 "target_operand" "b")
6746                       (pc)))]
6747   "TARGET_SHMEDIA"
6748   "b%o3%'       %N2, %N1, %0%>"
6749   [(set_attr "type" "cbranch_media")])
6750
6751 (define_insn "*blt_media_i32"
6752   [(set (pc)
6753         (if_then_else (match_operator 3 "less_comparison_operator"
6754                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6755                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6756                       (match_operand 0 "target_operand" "b")
6757                       (pc)))]
6758   "TARGET_SHMEDIA"
6759   "b%o3%'       %N2, %N1, %0%>"
6760   [(set_attr "type" "cbranch_media")])
6761
6762 (define_expand "beq"
6763   [(set (pc)
6764         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6765                       (label_ref (match_operand 0 "" ""))
6766                       (pc)))]
6767   ""
6768   "
6769 {
6770   if (TARGET_SHMEDIA)
6771     {
6772       enum machine_mode mode = GET_MODE (sh_compare_op0);
6773
6774       if (mode != DImode && mode != SImode)
6775         {
6776           rtx tmp = gen_reg_rtx (DImode);
6777
6778           emit_insn (gen_seq (tmp));
6779           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6780           DONE;
6781         }
6782
6783       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6784       if (CONSTANT_P (sh_compare_op1)
6785           && (GET_CODE (sh_compare_op1) != CONST_INT
6786               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6787         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6788       emit_jump_insn (gen_beq_media (operands[0],
6789                                      sh_compare_op0, sh_compare_op1));
6790       DONE;
6791     }
6792
6793   from_compare (operands, EQ);
6794 }")
6795
6796 (define_expand "bne"
6797   [(set (pc)
6798         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6799                       (label_ref (match_operand 0 "" ""))
6800                       (pc)))]
6801   ""
6802   "
6803 {
6804   if (TARGET_SHMEDIA)
6805     {
6806       enum machine_mode mode = GET_MODE (sh_compare_op0);
6807
6808       if (mode != DImode && mode != SImode)
6809         {
6810           rtx tmp = gen_reg_rtx (DImode);
6811
6812           emit_insn (gen_seq (tmp));
6813           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6814           DONE;
6815         }
6816
6817       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6818       if (CONSTANT_P (sh_compare_op1)
6819           && (GET_CODE (sh_compare_op1) != CONST_INT
6820               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6821         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6822       emit_jump_insn (gen_bne_media (operands[0],
6823                                      sh_compare_op0, sh_compare_op1));
6824       DONE;
6825     }
6826
6827   from_compare (operands, EQ);
6828 }")
6829
6830 (define_expand "bgt"
6831   [(set (pc)
6832         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6833                       (label_ref (match_operand 0 "" ""))
6834                       (pc)))]
6835   ""
6836   "
6837 {
6838   if (TARGET_SHMEDIA)
6839     {
6840       enum machine_mode mode = GET_MODE (sh_compare_op0);
6841
6842       if (mode != DImode && mode != SImode)
6843         {
6844           rtx tmp = gen_reg_rtx (DImode);
6845
6846           emit_insn (gen_sgt (tmp));
6847           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6848           DONE;
6849         }
6850
6851       if (sh_compare_op0 != const0_rtx)
6852         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853       if (sh_compare_op1 != const0_rtx)
6854         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6855       emit_jump_insn (gen_bgt_media (operands[0],
6856                                      sh_compare_op0, sh_compare_op1));
6857       DONE;
6858     }
6859
6860   from_compare (operands, GT);
6861 }")
6862
6863 (define_expand "blt"
6864   [(set (pc)
6865         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6866                       (label_ref (match_operand 0 "" ""))
6867                       (pc)))]
6868   ""
6869   "
6870 {
6871   if (TARGET_SHMEDIA)
6872     {
6873       enum machine_mode mode = GET_MODE (sh_compare_op0);
6874
6875       if (mode != DImode && mode != SImode)
6876         {
6877           rtx tmp = gen_reg_rtx (DImode);
6878
6879           emit_insn (gen_slt (tmp));
6880           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6881           DONE;
6882         }
6883
6884       if (sh_compare_op0 != const0_rtx)
6885         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6886       if (sh_compare_op1 != const0_rtx)
6887         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6888       emit_jump_insn (gen_bgt_media (operands[0],
6889                                      sh_compare_op1, sh_compare_op0));
6890       DONE;
6891     }
6892
6893   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6894     {
6895       rtx tmp = sh_compare_op0;
6896       sh_compare_op0 = sh_compare_op1;
6897       sh_compare_op1 = tmp;
6898       emit_insn (gen_bgt (operands[0]));
6899       DONE;
6900     }
6901   from_compare (operands, GE);
6902 }")
6903
6904 (define_expand "ble"
6905   [(set (pc)
6906         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6907                       (label_ref (match_operand 0 "" ""))
6908                       (pc)))]
6909   ""
6910   "
6911 {
6912   if (TARGET_SHMEDIA)
6913     {
6914       enum machine_mode mode = GET_MODE (sh_compare_op0);
6915
6916       if (mode != DImode && mode != SImode)
6917         {
6918           rtx tmp = gen_reg_rtx (DImode);
6919
6920           emit_insn (gen_sle (tmp));
6921           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6922           DONE;
6923         }
6924
6925       if (sh_compare_op0 != const0_rtx)
6926         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6927       if (sh_compare_op1 != const0_rtx)
6928         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6929       emit_jump_insn (gen_bge_media (operands[0],
6930                                      sh_compare_op1, sh_compare_op0));
6931       DONE;
6932     }
6933
6934   if (TARGET_SH2E
6935       && TARGET_IEEE
6936       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6937     {
6938       rtx tmp = sh_compare_op0;
6939       sh_compare_op0 = sh_compare_op1;
6940       sh_compare_op1 = tmp;
6941       emit_insn (gen_bge (operands[0]));
6942       DONE;
6943     }
6944   from_compare (operands, GT);
6945 }")
6946
6947 (define_expand "bge"
6948   [(set (pc)
6949         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6950                       (label_ref (match_operand 0 "" ""))
6951                       (pc)))]
6952   ""
6953   "
6954 {
6955   if (TARGET_SHMEDIA)
6956     {
6957       enum machine_mode mode = GET_MODE (sh_compare_op0);
6958
6959       if (mode != DImode && mode != SImode)
6960         {
6961           rtx tmp = gen_reg_rtx (DImode);
6962
6963           emit_insn (gen_sge (tmp));
6964           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6965           DONE;
6966         }
6967
6968       if (sh_compare_op0 != const0_rtx)
6969         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6970       if (sh_compare_op1 != const0_rtx)
6971         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6972       emit_jump_insn (gen_bge_media (operands[0],
6973                                      sh_compare_op0, sh_compare_op1));
6974       DONE;
6975     }
6976
6977   if (TARGET_SH2E
6978       && ! TARGET_IEEE
6979       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6980     {
6981       rtx tmp = sh_compare_op0;
6982       sh_compare_op0 = sh_compare_op1;
6983       sh_compare_op1 = tmp;
6984       emit_insn (gen_ble (operands[0]));
6985       DONE;
6986     }
6987   from_compare (operands, GE);
6988 }")
6989
6990 (define_expand "bgtu"
6991   [(set (pc)
6992         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6993                       (label_ref (match_operand 0 "" ""))
6994                       (pc)))]
6995   ""
6996   "
6997 {
6998   if (TARGET_SHMEDIA)
6999     {
7000       enum machine_mode mode = GET_MODE (sh_compare_op0);
7001
7002       if (sh_compare_op0 != const0_rtx)
7003         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7004       if (sh_compare_op1 != const0_rtx)
7005         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7006       emit_jump_insn (gen_bgtu_media (operands[0],
7007                                       sh_compare_op0, sh_compare_op1));
7008       DONE;
7009     }
7010
7011   from_compare (operands, GTU);
7012 }")
7013
7014 (define_expand "bltu"
7015   [(set (pc)
7016         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7017                       (label_ref (match_operand 0 "" ""))
7018                       (pc)))]
7019   ""
7020   "
7021 {
7022   if (TARGET_SHMEDIA)
7023     {
7024       enum machine_mode mode = GET_MODE (sh_compare_op0);
7025
7026       if (sh_compare_op0 != const0_rtx)
7027         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7028       if (sh_compare_op1 != const0_rtx)
7029         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030       emit_jump_insn (gen_bgtu_media (operands[0],
7031                                       sh_compare_op1, sh_compare_op0));
7032       DONE;
7033     }
7034
7035   from_compare (operands, GEU);
7036 }")
7037
7038 (define_expand "bgeu"
7039   [(set (pc)
7040         (if_then_else (ne (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 (sh_compare_op0 != const0_rtx)
7051         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052       if (sh_compare_op1 != const0_rtx)
7053         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054       emit_jump_insn (gen_bgeu_media (operands[0],
7055                                       sh_compare_op0, sh_compare_op1));
7056       DONE;
7057     }
7058
7059   from_compare (operands, GEU);
7060 }")
7061
7062 (define_expand "bleu"
7063   [(set (pc)
7064         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065                       (label_ref (match_operand 0 "" ""))
7066                       (pc)))]
7067   ""
7068   "
7069 {
7070   if (TARGET_SHMEDIA)
7071     {
7072       enum machine_mode mode = GET_MODE (sh_compare_op0);
7073
7074       if (sh_compare_op0 != const0_rtx)
7075         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7076       if (sh_compare_op1 != const0_rtx)
7077         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7078       emit_jump_insn (gen_bgeu_media (operands[0],
7079                                       sh_compare_op1, sh_compare_op0));
7080       DONE;
7081     }
7082
7083   from_compare (operands, GTU);
7084 }")
7085
7086 (define_expand "bunordered"
7087   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7088    (set (pc)
7089         (if_then_else (ne (match_dup 1) (const_int 0))
7090                       (match_operand 0 "" "")
7091                       (pc)))]
7092   "TARGET_SHMEDIA"
7093   "
7094 {
7095   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7096   operands[1] = gen_reg_rtx (DImode);
7097   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7098   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7099 }")
7100
7101 ;; combiner splitter for test-and-branch on single bit in register.  This
7102 ;; is endian dependent because the non-paradoxical subreg looks different
7103 ;; on big endian.
7104 (define_split
7105   [(set (pc)
7106         (if_then_else
7107           (match_operator 3 "equality_comparison_operator"
7108             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7109                                                       "extend_reg_operand" "")
7110                                                     0)
7111                                          (const_int 1)
7112                                          (match_operand 2
7113                                           "const_int_operand" "")) 0)
7114              (const_int 0)])
7115           (match_operand 0 "target_operand" "")
7116           (pc)))
7117    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7118   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7119   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7120    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7121
7122   "
7123 {
7124   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7125   operands[6] = (GET_CODE (operands[3]) == EQ
7126                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7127                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7128 }")
7129 \f
7130 ;; ------------------------------------------------------------------------
7131 ;; Jump and linkage insns
7132 ;; ------------------------------------------------------------------------
7133
7134 (define_insn "jump_compact"
7135   [(set (pc)
7136         (label_ref (match_operand 0 "" "")))]
7137   "TARGET_SH1"
7138   "*
7139 {
7140   /* The length is 16 if the delay slot is unfilled.  */
7141   if (get_attr_length(insn) > 4)
7142     return output_far_jump(insn, operands[0]);
7143   else
7144     return   \"bra      %l0%#\";
7145 }"
7146   [(set_attr "type" "jump")
7147    (set_attr "needs_delay_slot" "yes")])
7148
7149 ;; ??? It would be much saner to explicitly use the scratch register
7150 ;; in the jump insn, and have indirect_jump_scratch only set it,
7151 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7152 ;; from the target then, as it uses simplejump_p.
7153 ;;(define_insn "jump_compact_far"
7154 ;;  [(set (pc)
7155 ;;      (label_ref (match_operand 0 "" "")))
7156 ;;   (use (match_operand 1 "register_operand" "r")]
7157 ;;  "TARGET_SH1"
7158 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7159 ;;  [(set_attr "type" "jump")
7160 ;;   (set_attr "needs_delay_slot" "yes")])
7161
7162 (define_insn "jump_media"
7163   [(set (pc)
7164         (match_operand 0 "target_operand" "b"))]
7165   "TARGET_SHMEDIA"
7166   "blink        %0, r63%>"
7167   [(set_attr "type" "jump_media")])
7168
7169 (define_expand "jump"
7170   [(set (pc)
7171         (label_ref (match_operand 0 "" "")))]
7172   ""
7173   "
7174 {
7175   if (TARGET_SH1)
7176     emit_jump_insn (gen_jump_compact (operands[0]));
7177   else if (TARGET_SHMEDIA)
7178     {
7179       if (reload_in_progress || reload_completed)
7180         FAIL;
7181       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7182                                                          operands[0])));
7183     }
7184   DONE;
7185 }")
7186
7187 (define_insn "force_mode_for_call"
7188   [(use (reg:PSI FPSCR_REG))]
7189   "TARGET_SHCOMPACT"
7190   ""
7191   [(set_attr "length" "0")
7192    (set (attr "fp_mode")
7193         (if_then_else (eq_attr "fpu_single" "yes")
7194                       (const_string "single") (const_string "double")))])
7195
7196 (define_insn "calli"
7197   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7198          (match_operand 1 "" ""))
7199    (use (reg:PSI FPSCR_REG))
7200    (clobber (reg:SI PR_REG))]
7201   "TARGET_SH1"
7202   "jsr  @%0%#"
7203   [(set_attr "type" "call")
7204    (set (attr "fp_mode")
7205         (if_then_else (eq_attr "fpu_single" "yes")
7206                       (const_string "single") (const_string "double")))
7207    (set_attr "needs_delay_slot" "yes")
7208    (set_attr "fp_set" "unknown")])
7209
7210 ;; This is a pc-rel call, using bsrf, for use with PIC.
7211
7212 (define_insn "calli_pcrel"
7213   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7214          (match_operand 1 "" ""))
7215    (use (reg:PSI FPSCR_REG))
7216    (use (reg:SI PIC_REG))
7217    (use (match_operand 2 "" ""))
7218    (clobber (reg:SI PR_REG))]
7219   "TARGET_SH2"
7220   "bsrf %0\\n%O2:%#"
7221   [(set_attr "type" "call")
7222    (set (attr "fp_mode")
7223         (if_then_else (eq_attr "fpu_single" "yes")
7224                       (const_string "single") (const_string "double")))
7225    (set_attr "needs_delay_slot" "yes")
7226    (set_attr "fp_set" "unknown")])
7227
7228 (define_insn_and_split "call_pcrel"
7229   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7230          (match_operand 1 "" ""))
7231    (use (reg:PSI FPSCR_REG))
7232    (use (reg:SI PIC_REG))
7233    (clobber (reg:SI PR_REG))
7234    (clobber (match_scratch:SI 2 "=r"))]
7235   "TARGET_SH2"
7236   "#"
7237   "reload_completed"
7238   [(const_int 0)]
7239   "
7240 {
7241   rtx lab = PATTERN (gen_call_site ());
7242
7243   if (SYMBOL_REF_LOCAL_P (operands[0]))
7244     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7245   else
7246     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7247   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7248   DONE;
7249 }"
7250   [(set_attr "type" "call")
7251    (set (attr "fp_mode")
7252         (if_then_else (eq_attr "fpu_single" "yes")
7253                       (const_string "single") (const_string "double")))
7254    (set_attr "needs_delay_slot" "yes")
7255    (set_attr "fp_set" "unknown")])
7256
7257 (define_insn "call_compact"
7258   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7259          (match_operand 1 "" ""))
7260    (match_operand 2 "immediate_operand" "n")
7261    (use (reg:SI R0_REG))
7262    (use (reg:SI R1_REG))
7263    (use (reg:PSI FPSCR_REG))
7264    (clobber (reg:SI PR_REG))]
7265   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7266   "jsr  @%0%#"
7267   [(set_attr "type" "call")
7268    (set (attr "fp_mode")
7269         (if_then_else (eq_attr "fpu_single" "yes")
7270                       (const_string "single") (const_string "double")))
7271    (set_attr "needs_delay_slot" "yes")])
7272
7273 (define_insn "call_compact_rettramp"
7274   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7275          (match_operand 1 "" ""))
7276    (match_operand 2 "immediate_operand" "n")
7277    (use (reg:SI R0_REG))
7278    (use (reg:SI R1_REG))
7279    (use (reg:PSI FPSCR_REG))
7280    (clobber (reg:SI R10_REG))
7281    (clobber (reg:SI PR_REG))]
7282   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7283   "jsr  @%0%#"
7284   [(set_attr "type" "call")
7285    (set (attr "fp_mode")
7286         (if_then_else (eq_attr "fpu_single" "yes")
7287                       (const_string "single") (const_string "double")))
7288    (set_attr "needs_delay_slot" "yes")])
7289
7290 (define_insn "call_media"
7291   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7292          (match_operand 1 "" ""))
7293    (clobber (reg:DI PR_MEDIA_REG))]
7294   "TARGET_SHMEDIA"
7295   "blink        %0, r18"
7296   [(set_attr "type" "jump_media")])
7297
7298 (define_insn "call_valuei"
7299   [(set (match_operand 0 "" "=rf")
7300         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7301               (match_operand 2 "" "")))
7302    (use (reg:PSI FPSCR_REG))
7303    (clobber (reg:SI PR_REG))]
7304   "TARGET_SH1"
7305   "jsr  @%1%#"
7306   [(set_attr "type" "call")
7307    (set (attr "fp_mode")
7308         (if_then_else (eq_attr "fpu_single" "yes")
7309                       (const_string "single") (const_string "double")))
7310    (set_attr "needs_delay_slot" "yes")
7311    (set_attr "fp_set" "unknown")])
7312
7313 (define_insn "call_valuei_pcrel"
7314   [(set (match_operand 0 "" "=rf")
7315         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7316               (match_operand 2 "" "")))
7317    (use (reg:PSI FPSCR_REG))
7318    (use (reg:SI PIC_REG))
7319    (use (match_operand 3 "" ""))
7320    (clobber (reg:SI PR_REG))]
7321   "TARGET_SH2"
7322   "bsrf %1\\n%O3:%#"
7323   [(set_attr "type" "call")
7324    (set (attr "fp_mode")
7325         (if_then_else (eq_attr "fpu_single" "yes")
7326                       (const_string "single") (const_string "double")))
7327    (set_attr "needs_delay_slot" "yes")
7328    (set_attr "fp_set" "unknown")])
7329
7330 (define_insn_and_split "call_value_pcrel"
7331   [(set (match_operand 0 "" "=rf")
7332         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7333               (match_operand 2 "" "")))
7334    (use (reg:PSI FPSCR_REG))
7335    (use (reg:SI PIC_REG))
7336    (clobber (reg:SI PR_REG))
7337    (clobber (match_scratch:SI 3 "=r"))]
7338   "TARGET_SH2"
7339   "#"
7340   "reload_completed"
7341   [(const_int 0)]
7342   "
7343 {
7344   rtx lab = PATTERN (gen_call_site ());
7345
7346   if (SYMBOL_REF_LOCAL_P (operands[1]))
7347     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7348   else
7349     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7350   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7351                                          operands[2], lab));
7352   DONE;
7353 }"
7354   [(set_attr "type" "call")
7355    (set (attr "fp_mode")
7356         (if_then_else (eq_attr "fpu_single" "yes")
7357                       (const_string "single") (const_string "double")))
7358    (set_attr "needs_delay_slot" "yes")
7359    (set_attr "fp_set" "unknown")])
7360
7361 (define_insn "call_value_compact"
7362   [(set (match_operand 0 "" "=rf")
7363         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7364               (match_operand 2 "" "")))
7365    (match_operand 3 "immediate_operand" "n")
7366    (use (reg:SI R0_REG))
7367    (use (reg:SI R1_REG))
7368    (use (reg:PSI FPSCR_REG))
7369    (clobber (reg:SI PR_REG))]
7370   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7371   "jsr  @%1%#"
7372   [(set_attr "type" "call")
7373    (set (attr "fp_mode")
7374         (if_then_else (eq_attr "fpu_single" "yes")
7375                       (const_string "single") (const_string "double")))
7376    (set_attr "needs_delay_slot" "yes")])
7377
7378 (define_insn "call_value_compact_rettramp"
7379   [(set (match_operand 0 "" "=rf")
7380         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7381               (match_operand 2 "" "")))
7382    (match_operand 3 "immediate_operand" "n")
7383    (use (reg:SI R0_REG))
7384    (use (reg:SI R1_REG))
7385    (use (reg:PSI FPSCR_REG))
7386    (clobber (reg:SI R10_REG))
7387    (clobber (reg:SI PR_REG))]
7388   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7389   "jsr  @%1%#"
7390   [(set_attr "type" "call")
7391    (set (attr "fp_mode")
7392         (if_then_else (eq_attr "fpu_single" "yes")
7393                       (const_string "single") (const_string "double")))
7394    (set_attr "needs_delay_slot" "yes")])
7395
7396 (define_insn "call_value_media"
7397   [(set (match_operand 0 "" "=rf")
7398         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7399               (match_operand 2 "" "")))
7400    (clobber (reg:DI PR_MEDIA_REG))]
7401   "TARGET_SHMEDIA"
7402   "blink        %1, r18"
7403   [(set_attr "type" "jump_media")])
7404
7405 (define_expand "call"
7406   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7407                             (match_operand 1 "" ""))
7408               (match_operand 2 "" "")
7409               (use (reg:PSI FPSCR_REG))
7410               (clobber (reg:SI PR_REG))])]
7411   ""
7412   "
7413 {
7414   if (TARGET_SHMEDIA)
7415     {
7416       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7417       emit_call_insn (gen_call_media (operands[0], operands[1]));
7418       DONE;
7419     }
7420   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7421     {
7422       rtx cookie_rtx = operands[2];
7423       long cookie = INTVAL (cookie_rtx);
7424       rtx func = XEXP (operands[0], 0);
7425       rtx r0, r1;
7426
7427       if (flag_pic)
7428         {
7429           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7430             {
7431               rtx reg = gen_reg_rtx (Pmode);
7432
7433               emit_insn (gen_symGOTPLT2reg (reg, func));
7434               func = reg;
7435             }
7436           else
7437             func = legitimize_pic_address (func, Pmode, 0);
7438         }
7439
7440       r0 = gen_rtx_REG (SImode, R0_REG);
7441       r1 = gen_rtx_REG (SImode, R1_REG);
7442
7443       /* Since such a call function may use all call-clobbered
7444          registers, we force a mode switch earlier, so that we don't
7445          run out of registers when adjusting fpscr for the call.  */
7446       emit_insn (gen_force_mode_for_call ());
7447
7448       operands[0]
7449         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7450                            SFUNC_GOT);
7451       operands[0] = force_reg (SImode, operands[0]);
7452
7453       emit_move_insn (r0, func);
7454       emit_move_insn (r1, cookie_rtx);
7455
7456       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7457         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7458                                                    operands[2]));
7459       else
7460         emit_call_insn (gen_call_compact (operands[0], operands[1],
7461                                           operands[2]));
7462
7463       DONE;
7464     }
7465   else if (TARGET_SHCOMPACT && flag_pic
7466            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7467            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7468     {
7469       rtx reg = gen_reg_rtx (Pmode);
7470
7471       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7472       XEXP (operands[0], 0) = reg;
7473     }
7474   if (flag_pic && TARGET_SH2
7475       && GET_CODE (operands[0]) == MEM
7476       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7477     {
7478       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7479       DONE;
7480     }
7481   else
7482   {
7483     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7484     operands[1] = operands[2];
7485   }
7486
7487   emit_call_insn (gen_calli (operands[0], operands[1]));
7488   DONE;
7489 }")
7490
7491 (define_insn "call_pop_compact"
7492   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7493          (match_operand 1 "" ""))
7494    (match_operand 2 "immediate_operand" "n")
7495    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7496                                  (match_operand 3 "immediate_operand" "n")))
7497    (use (reg:SI R0_REG))
7498    (use (reg:SI R1_REG))
7499    (use (reg:PSI FPSCR_REG))
7500    (clobber (reg:SI PR_REG))]
7501   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7502   "jsr  @%0%#"
7503   [(set_attr "type" "call")
7504    (set (attr "fp_mode")
7505         (if_then_else (eq_attr "fpu_single" "yes")
7506                       (const_string "single") (const_string "double")))
7507    (set_attr "needs_delay_slot" "yes")])
7508
7509 (define_insn "call_pop_compact_rettramp"
7510   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511          (match_operand 1 "" ""))
7512    (match_operand 2 "immediate_operand" "n")
7513    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514                                  (match_operand 3 "immediate_operand" "n")))
7515    (use (reg:SI R0_REG))
7516    (use (reg:SI R1_REG))
7517    (use (reg:PSI FPSCR_REG))
7518    (clobber (reg:SI R10_REG))
7519    (clobber (reg:SI PR_REG))]
7520   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521   "jsr  @%0%#"
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" "yes")])
7527
7528 (define_expand "call_pop"
7529   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7530                     (match_operand 1 "" ""))
7531              (match_operand 2 "" "")
7532              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533                                            (match_operand 3 "" "")))])]
7534   "TARGET_SHCOMPACT"
7535   "
7536 {
7537   rtx cookie_rtx;
7538   long cookie;
7539   rtx func;
7540   rtx r0, r1;
7541
7542   gcc_assert (operands[2] && INTVAL (operands[2]));
7543   cookie_rtx = operands[2];
7544   cookie = INTVAL (cookie_rtx);
7545   func = XEXP (operands[0], 0);
7546
7547   if (flag_pic)
7548     {
7549       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7550         {
7551           rtx reg = gen_reg_rtx (Pmode);
7552           emit_insn (gen_symGOTPLT2reg (reg, func));
7553           func = reg;
7554         }
7555       else
7556         func = legitimize_pic_address (func, Pmode, 0);
7557     }
7558
7559   r0 = gen_rtx_REG (SImode, R0_REG);
7560   r1 = gen_rtx_REG (SImode, R1_REG);
7561
7562   /* Since such a call function may use all call-clobbered
7563      registers, we force a mode switch earlier, so that we don't
7564      run out of registers when adjusting fpscr for the call.  */
7565   emit_insn (gen_force_mode_for_call ());
7566
7567   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7568                                  SFUNC_GOT);
7569   operands[0] = force_reg (SImode, operands[0]);
7570
7571   emit_move_insn (r0, func);
7572   emit_move_insn (r1, cookie_rtx);
7573
7574   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7575     emit_call_insn (gen_call_pop_compact_rettramp
7576                      (operands[0], operands[1], operands[2], operands[3]));
7577   else
7578     emit_call_insn (gen_call_pop_compact
7579                      (operands[0], operands[1], operands[2], operands[3]));
7580
7581   DONE;
7582 }")
7583
7584 (define_expand "call_value"
7585   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7586                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7587                                  (match_operand 2 "" "")))
7588               (match_operand 3 "" "")
7589               (use (reg:PSI FPSCR_REG))
7590               (clobber (reg:SI PR_REG))])]
7591   ""
7592   "
7593 {
7594   if (TARGET_SHMEDIA)
7595     {
7596       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7597       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7598                                             operands[2]));
7599       DONE;
7600     }
7601   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7602     {
7603       rtx cookie_rtx = operands[3];
7604       long cookie = INTVAL (cookie_rtx);
7605       rtx func = XEXP (operands[1], 0);
7606       rtx r0, r1;
7607
7608       if (flag_pic)
7609         {
7610           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7611             {
7612               rtx reg = gen_reg_rtx (Pmode);
7613
7614               emit_insn (gen_symGOTPLT2reg (reg, func));
7615               func = reg;
7616             }
7617           else
7618             func = legitimize_pic_address (func, Pmode, 0);
7619         }
7620
7621       r0 = gen_rtx_REG (SImode, R0_REG);
7622       r1 = gen_rtx_REG (SImode, R1_REG);
7623
7624       /* Since such a call function may use all call-clobbered
7625          registers, we force a mode switch earlier, so that we don't
7626          run out of registers when adjusting fpscr for the call.  */
7627       emit_insn (gen_force_mode_for_call ());
7628
7629       operands[1]
7630         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7631                            SFUNC_GOT);
7632       operands[1] = force_reg (SImode, operands[1]);
7633
7634       emit_move_insn (r0, func);
7635       emit_move_insn (r1, cookie_rtx);
7636
7637       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7638         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7639                                                          operands[1],
7640                                                          operands[2],
7641                                                          operands[3]));
7642       else
7643         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7644                                                 operands[2], operands[3]));
7645
7646       DONE;
7647     }
7648   else if (TARGET_SHCOMPACT && flag_pic
7649            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7650            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7651     {
7652       rtx reg = gen_reg_rtx (Pmode);
7653
7654       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7655       XEXP (operands[1], 0) = reg;
7656     }
7657   if (flag_pic && TARGET_SH2
7658       && GET_CODE (operands[1]) == MEM
7659       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7660     {
7661       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7662                                             operands[2]));
7663       DONE;
7664     }
7665   else
7666     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7667
7668   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7669   DONE;
7670 }")
7671
7672 (define_insn "sibcalli"
7673   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7674          (match_operand 1 "" ""))
7675    (use (reg:PSI FPSCR_REG))
7676    (return)]
7677   "TARGET_SH1"
7678   "jmp  @%0%#"
7679   [(set_attr "needs_delay_slot" "yes")
7680    (set (attr "fp_mode")
7681         (if_then_else (eq_attr "fpu_single" "yes")
7682                       (const_string "single") (const_string "double")))
7683    (set_attr "type" "jump_ind")])
7684
7685 (define_insn "sibcalli_pcrel"
7686   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7687          (match_operand 1 "" ""))
7688    (use (match_operand 2 "" ""))
7689    (use (reg:PSI FPSCR_REG))
7690    (return)]
7691   "TARGET_SH2"
7692   "braf %0\\n%O2:%#"
7693   [(set_attr "needs_delay_slot" "yes")
7694    (set (attr "fp_mode")
7695         (if_then_else (eq_attr "fpu_single" "yes")
7696                       (const_string "single") (const_string "double")))
7697    (set_attr "type" "jump_ind")])
7698
7699 ;; This uses an unspec to describe that the symbol_ref is very close.
7700 (define_insn "sibcalli_thunk"
7701   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7702                              UNSPEC_THUNK))
7703          (match_operand 1 "" ""))
7704    (use (reg:PSI FPSCR_REG))
7705    (return)]
7706   "TARGET_SH1"
7707   "bra  %O0"
7708   [(set_attr "needs_delay_slot" "yes")
7709    (set (attr "fp_mode")
7710         (if_then_else (eq_attr "fpu_single" "yes")
7711                       (const_string "single") (const_string "double")))
7712    (set_attr "type" "jump")
7713    (set_attr "length" "2")])
7714
7715 (define_insn_and_split "sibcall_pcrel"
7716   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7717          (match_operand 1 "" ""))
7718    (use (reg:PSI FPSCR_REG))
7719    (clobber (match_scratch:SI 2 "=k"))
7720    (return)]
7721   "TARGET_SH2"
7722   "#"
7723   "reload_completed"
7724   [(const_int 0)]
7725   "
7726 {
7727   rtx lab = PATTERN (gen_call_site ());
7728   rtx call_insn;
7729
7730   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7731   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7732                                                   lab));
7733   SIBLING_CALL_P (call_insn) = 1;
7734   DONE;
7735 }"
7736   [(set_attr "needs_delay_slot" "yes")
7737    (set (attr "fp_mode")
7738         (if_then_else (eq_attr "fpu_single" "yes")
7739                       (const_string "single") (const_string "double")))
7740    (set_attr "type" "jump_ind")])
7741
7742 (define_insn "sibcall_compact"
7743   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7744          (match_operand 1 "" ""))
7745    (return)
7746    (use (match_operand:SI 2 "register_operand" "z,x"))
7747    (use (reg:SI R1_REG))
7748    (use (reg:PSI FPSCR_REG))
7749    ;; We want to make sure the `x' above will only match MACH_REG
7750    ;; because sibcall_epilogue may clobber MACL_REG.
7751    (clobber (reg:SI MACL_REG))]
7752   "TARGET_SHCOMPACT"
7753   "@
7754         jmp     @%0%#
7755         jmp     @%0\\n  sts     %2, r0"
7756   [(set_attr "needs_delay_slot" "yes,no")
7757    (set_attr "length" "2,4")
7758    (set (attr "fp_mode") (const_string "single"))
7759    (set_attr "type" "jump_ind")])
7760
7761 (define_insn "sibcall_media"
7762   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7763          (match_operand 1 "" ""))
7764    (use (reg:SI PR_MEDIA_REG))
7765    (return)]
7766   "TARGET_SHMEDIA"
7767   "blink        %0, r63"
7768   [(set_attr "type" "jump_media")])
7769
7770 (define_expand "sibcall"
7771   [(parallel
7772     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773            (match_operand 1 "" ""))
7774      (match_operand 2 "" "")
7775      (use (reg:PSI FPSCR_REG))
7776      (return)])]
7777   ""
7778   "
7779 {
7780   if (TARGET_SHMEDIA)
7781     {
7782       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7783       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7784       DONE;
7785     }
7786   else if (TARGET_SHCOMPACT && operands[2]
7787            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7788     {
7789       rtx cookie_rtx = operands[2];
7790       long cookie = INTVAL (cookie_rtx);
7791       rtx func = XEXP (operands[0], 0);
7792       rtx mach, r1;
7793
7794       if (flag_pic)
7795         {
7796           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7797             {
7798               rtx reg = gen_reg_rtx (Pmode);
7799
7800               emit_insn (gen_symGOT2reg (reg, func));
7801               func = reg;
7802             }
7803           else
7804             func = legitimize_pic_address (func, Pmode, 0);
7805         }
7806
7807       /* FIXME: if we could tell whether all argument registers are
7808          already taken, we could decide whether to force the use of
7809          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7810          simple way to tell.  We could use the CALL_COOKIE, but we
7811          can't currently tell a register used for regular argument
7812          passing from one that is unused.  If we leave it up to reload
7813          to decide which register to use, it seems to always choose
7814          R0_REG, which leaves no available registers in SIBCALL_REGS
7815          to hold the address of the trampoline.  */
7816       mach = gen_rtx_REG (SImode, MACH_REG);
7817       r1 = gen_rtx_REG (SImode, R1_REG);
7818
7819       /* Since such a call function may use all call-clobbered
7820          registers, we force a mode switch earlier, so that we don't
7821          run out of registers when adjusting fpscr for the call.  */
7822       emit_insn (gen_force_mode_for_call ());
7823
7824       operands[0]
7825         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7826                            SFUNC_GOT);
7827       operands[0] = force_reg (SImode, operands[0]);
7828
7829       /* We don't need a return trampoline, since the callee will
7830          return directly to the upper caller.  */
7831       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7832         {
7833           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7834           cookie_rtx = GEN_INT (cookie);
7835         }
7836
7837       emit_move_insn (mach, func);
7838       emit_move_insn (r1, cookie_rtx);
7839
7840       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7841       DONE;
7842     }
7843   else if (TARGET_SHCOMPACT && flag_pic
7844            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7845            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7846     {
7847       rtx reg = gen_reg_rtx (Pmode);
7848
7849       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7850       XEXP (operands[0], 0) = reg;
7851     }
7852   if (flag_pic && TARGET_SH2
7853       && GET_CODE (operands[0]) == MEM
7854       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7855       /* The PLT needs the PIC register, but the epilogue would have
7856          to restore it, so we can only use PC-relative PIC calls for
7857          static functions.  */
7858       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7859     {
7860       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7861       DONE;
7862     }
7863   else
7864     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7865
7866   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7867   DONE;
7868 }")
7869
7870 (define_expand "sibcall_value"
7871   [(set (match_operand 0 "" "")
7872         (call (match_operand 1 "" "")
7873               (match_operand 2 "" "")))
7874    (match_operand 3 "" "")]
7875   ""
7876   "
7877 {
7878   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7879   DONE;
7880 }")
7881
7882 (define_insn "call_value_pop_compact"
7883   [(set (match_operand 0 "" "=rf")
7884         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885               (match_operand 2 "" "")))
7886    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887                                  (match_operand 4 "immediate_operand" "n")))
7888    (match_operand 3 "immediate_operand" "n")
7889    (use (reg:SI R0_REG))
7890    (use (reg:SI R1_REG))
7891    (use (reg:PSI FPSCR_REG))
7892    (clobber (reg:SI PR_REG))]
7893   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7894   "jsr  @%1%#"
7895   [(set_attr "type" "call")
7896    (set (attr "fp_mode")
7897         (if_then_else (eq_attr "fpu_single" "yes")
7898                       (const_string "single") (const_string "double")))
7899    (set_attr "needs_delay_slot" "yes")])
7900
7901 (define_insn "call_value_pop_compact_rettramp"
7902   [(set (match_operand 0 "" "=rf")
7903         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7904               (match_operand 2 "" "")))
7905    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7906                                  (match_operand 4 "immediate_operand" "n")))
7907    (match_operand 3 "immediate_operand" "n")
7908    (use (reg:SI R0_REG))
7909    (use (reg:SI R1_REG))
7910    (use (reg:PSI FPSCR_REG))
7911    (clobber (reg:SI R10_REG))
7912    (clobber (reg:SI PR_REG))]
7913   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7914   "jsr  @%1%#"
7915   [(set_attr "type" "call")
7916    (set (attr "fp_mode")
7917         (if_then_else (eq_attr "fpu_single" "yes")
7918                       (const_string "single") (const_string "double")))
7919    (set_attr "needs_delay_slot" "yes")])
7920
7921 (define_expand "call_value_pop"
7922   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7923                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7924                                  (match_operand 2 "" "")))
7925               (match_operand 3 "" "")
7926               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7927                                             (match_operand 4 "" "")))])]
7928   "TARGET_SHCOMPACT"
7929   "
7930 {
7931   rtx cookie_rtx;
7932   long cookie;
7933   rtx func;
7934   rtx r0, r1;
7935
7936   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7937   cookie_rtx = operands[3];
7938   cookie = INTVAL (cookie_rtx);
7939   func = XEXP (operands[1], 0);
7940
7941   if (flag_pic)
7942     {
7943       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7944         {
7945           rtx reg = gen_reg_rtx (Pmode);
7946
7947           emit_insn (gen_symGOTPLT2reg (reg, func));
7948           func = reg;
7949         }
7950       else
7951         func = legitimize_pic_address (func, Pmode, 0);
7952     }
7953
7954   r0 = gen_rtx_REG (SImode, R0_REG);
7955   r1 = gen_rtx_REG (SImode, R1_REG);
7956
7957   /* Since such a call function may use all call-clobbered
7958      registers, we force a mode switch earlier, so that we don't
7959      run out of registers when adjusting fpscr for the call.  */
7960   emit_insn (gen_force_mode_for_call ());
7961
7962   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7963                                  SFUNC_GOT);
7964   operands[1] = force_reg (SImode, operands[1]);
7965
7966   emit_move_insn (r0, func);
7967   emit_move_insn (r1, cookie_rtx);
7968
7969   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7970     emit_call_insn (gen_call_value_pop_compact_rettramp
7971                         (operands[0], operands[1], operands[2],
7972                          operands[3], operands[4]));
7973   else
7974     emit_call_insn (gen_call_value_pop_compact
7975                         (operands[0], operands[1], operands[2],
7976                          operands[3], operands[4]));
7977
7978   DONE;
7979 }")
7980
7981 (define_expand "sibcall_epilogue"
7982   [(return)]
7983   ""
7984   "
7985 {
7986   sh_expand_epilogue (1);
7987   if (TARGET_SHCOMPACT)
7988     {
7989       rtx insn, set;
7990
7991       /* If epilogue clobbers r0, preserve it in macl.  */
7992       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7993         if ((set = single_set (insn))
7994             && GET_CODE (SET_DEST (set)) == REG
7995             && REGNO (SET_DEST (set)) == R0_REG)
7996           {
7997             rtx r0 = gen_rtx_REG (SImode, R0_REG);
7998             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
7999             rtx i;
8000
8001             /* We can't tell at this point whether the sibcall is a
8002                sibcall_compact and, if it is, whether it uses r0 or
8003                mach as operand 2, so let the instructions that
8004                preserve r0 be optimized away if r0 turns out to be
8005                dead.  */
8006             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8007             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8008                                                REG_NOTES (i));
8009             i = emit_move_insn (r0, tmp);
8010             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8011                                                REG_NOTES (i));
8012             break;
8013           }
8014     }
8015   DONE;
8016 }")
8017
8018 (define_insn "indirect_jump_compact"
8019   [(set (pc)
8020         (match_operand:SI 0 "arith_reg_operand" "r"))]
8021   "TARGET_SH1"
8022   "jmp  @%0%#"
8023   [(set_attr "needs_delay_slot" "yes")
8024    (set_attr "type" "jump_ind")])
8025
8026 (define_expand "indirect_jump"
8027   [(set (pc)
8028         (match_operand 0 "register_operand" ""))]
8029   ""
8030   "
8031 {
8032   if (GET_MODE (operands[0]) != Pmode)
8033     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8034 }")
8035
8036 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8037 ;; which can be present in structured code from indirect jumps which can not
8038 ;; be present in structured code.  This allows -fprofile-arcs to work.
8039
8040 ;; For SH1 processors.
8041 (define_insn "casesi_jump_1"
8042   [(set (pc)
8043         (match_operand:SI 0 "register_operand" "r"))
8044    (use (label_ref (match_operand 1 "" "")))]
8045   "TARGET_SH1"
8046   "jmp  @%0%#"
8047   [(set_attr "needs_delay_slot" "yes")
8048    (set_attr "type" "jump_ind")])
8049
8050 ;; For all later processors.
8051 (define_insn "casesi_jump_2"
8052   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8053                       (label_ref (match_operand 1 "" ""))))
8054    (use (label_ref (match_operand 2 "" "")))]
8055   "TARGET_SH2
8056    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8057   "braf %0%#"
8058   [(set_attr "needs_delay_slot" "yes")
8059    (set_attr "type" "jump_ind")])
8060
8061 (define_insn "casesi_jump_media"
8062   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8063    (use (label_ref (match_operand 1 "" "")))]
8064   "TARGET_SHMEDIA"
8065   "blink        %0, r63"
8066   [(set_attr "type" "jump_media")])
8067
8068 ;; Call subroutine returning any type.
8069 ;; ??? This probably doesn't work.
8070
8071 (define_expand "untyped_call"
8072   [(parallel [(call (match_operand 0 "" "")
8073                     (const_int 0))
8074               (match_operand 1 "" "")
8075               (match_operand 2 "" "")])]
8076   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8077   "
8078 {
8079   int i;
8080
8081   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8082
8083   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8084     {
8085       rtx set = XVECEXP (operands[2], 0, i);
8086       emit_move_insn (SET_DEST (set), SET_SRC (set));
8087     }
8088
8089   /* The optimizer does not know that the call sets the function value
8090      registers we stored in the result block.  We avoid problems by
8091      claiming that all hard registers are used and clobbered at this
8092      point.  */
8093   emit_insn (gen_blockage ());
8094
8095   DONE;
8096 }")
8097 \f
8098 ;; ------------------------------------------------------------------------
8099 ;; Misc insns
8100 ;; ------------------------------------------------------------------------
8101
8102 (define_insn "dect"
8103   [(set (reg:SI T_REG)
8104         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8105    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8106   "TARGET_SH2"
8107   "dt   %0"
8108   [(set_attr "type" "arith")])
8109
8110 (define_insn "nop"
8111   [(const_int 0)]
8112   ""
8113   "nop")
8114
8115 ;; Load address of a label. This is only generated by the casesi expand,
8116 ;; and by machine_dependent_reorg (fixing up fp moves).
8117 ;; This must use unspec, because this only works for labels that are
8118 ;; within range,
8119
8120 (define_insn "mova"
8121   [(set (reg:SI R0_REG)
8122         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8123   "TARGET_SH1"
8124   "mova %O0,r0"
8125   [(set_attr "in_delay_slot" "no")
8126    (set_attr "type" "arith")])
8127
8128 ;; machine_dependent_reorg will make this a `mova'.
8129 (define_insn "mova_const"
8130   [(set (reg:SI R0_REG)
8131         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8132   "TARGET_SH1"
8133   "#"
8134   [(set_attr "in_delay_slot" "no")
8135    (set_attr "type" "arith")])
8136
8137 (define_expand "GOTaddr2picreg"
8138   [(set (reg:SI R0_REG)
8139         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8140                    UNSPEC_MOVA))
8141    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8142    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8143   "" "
8144 {
8145   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8146   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8147
8148   if (TARGET_SHMEDIA)
8149     {
8150       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8151       rtx pic = operands[0];
8152       rtx lab = PATTERN (gen_call_site ());
8153       rtx insn, equiv;
8154
8155       equiv = operands[1];
8156       operands[1] = gen_rtx_MINUS (Pmode,
8157                                    operands[1],
8158                                    gen_rtx_CONST
8159                                    (Pmode,
8160                                     gen_rtx_MINUS (Pmode,
8161                                                    gen_rtx_CONST (Pmode,
8162                                                                   lab),
8163                                                    pc_rtx)));
8164       operands[1] = gen_sym2PIC (operands[1]);
8165       PUT_MODE (operands[1], Pmode);
8166
8167       if (Pmode == SImode)
8168         {
8169           emit_insn (gen_movsi_const (pic, operands[1]));
8170           emit_insn (gen_ptrel_si (tr, pic, lab));
8171         }
8172       else
8173         {
8174           emit_insn (gen_movdi_const (pic, operands[1]));
8175           emit_insn (gen_ptrel_di (tr, pic, lab));
8176         }
8177
8178       insn = emit_move_insn (operands[0], tr);
8179
8180       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8181                                             REG_NOTES (insn));
8182
8183       DONE;
8184     }
8185 }
8186 ")
8187
8188 (define_insn "*ptb"
8189   [(set (match_operand 0 "target_reg_operand" "=b")
8190         (const (unspec [(match_operand 1 "" "Csy")]
8191                              UNSPEC_DATALABEL)))]
8192   "TARGET_SHMEDIA && flag_pic
8193    && EXTRA_CONSTRAINT_Csy (operands[1])"
8194   "ptb/u        datalabel %1, %0"
8195   [(set_attr "type" "ptabs_media")
8196    (set_attr "length" "*")])
8197
8198 (define_insn "ptrel_si"
8199   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8200         (plus:SI (match_operand:SI 1 "register_operand" "r")
8201               (pc)))
8202    (match_operand:SI 2 "" "")]
8203   "TARGET_SHMEDIA"
8204   "%O2: ptrel/u %1, %0"
8205   [(set_attr "type" "ptabs_media")])
8206
8207 (define_insn "ptrel_di"
8208   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8209         (plus:DI (match_operand:DI 1 "register_operand" "r")
8210               (pc)))
8211    (match_operand:DI 2 "" "")]
8212   "TARGET_SHMEDIA"
8213   "%O2: ptrel/u %1, %0"
8214   [(set_attr "type" "ptabs_media")])
8215
8216 (define_expand "builtin_setjmp_receiver"
8217   [(match_operand 0 "" "")]
8218   "flag_pic"
8219   "
8220 {
8221   emit_insn (gen_GOTaddr2picreg ());
8222   DONE;
8223 }")
8224
8225 (define_expand "call_site"
8226   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8227   "TARGET_SH1"
8228   "
8229 {
8230   static HOST_WIDE_INT i = 0;
8231   operands[0] = GEN_INT (i);
8232   i++;
8233 }")
8234
8235 (define_expand "sym_label2reg"
8236   [(set (match_operand:SI 0 "" "")
8237         (const:SI (minus:SI
8238                    (const:SI
8239                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8240                    (const:SI
8241                     (plus:SI
8242                      (match_operand:SI 2 "" "")
8243                      (const_int 2))))))]
8244   "TARGET_SH1" "")
8245
8246 (define_expand "symGOT_load"
8247   [(set (match_dup 2) (match_operand 1 "" ""))
8248    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8249    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8250   ""
8251   "
8252 {
8253   rtx insn;
8254
8255   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8256   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8257
8258   if (TARGET_SHMEDIA)
8259     {
8260       rtx reg = operands[2];
8261
8262       if (Pmode == DImode)
8263         {      
8264           if (flag_pic > 1)
8265             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8266           else
8267             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8268         }
8269       else
8270         {
8271           if (flag_pic > 1)
8272             emit_insn (gen_movsi_const (reg, operands[1]));
8273           else
8274             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8275         }
8276     }
8277   else
8278     emit_move_insn (operands[2], operands[1]);
8279
8280   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8281                                              operands[2],
8282                                              gen_rtx_REG (Pmode, PIC_REG)));
8283
8284   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
8285
8286   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8287                                                                   0), 0, 0),
8288                                         REG_NOTES (insn));
8289
8290   DONE;
8291 }")
8292
8293 (define_expand "sym2GOT"
8294   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8295   ""
8296   "")
8297
8298 (define_expand "symGOT2reg"
8299   [(match_operand 0 "" "") (match_operand 1 "" "")]
8300   ""
8301   "
8302 {
8303   rtx gotsym, insn;
8304
8305   gotsym = gen_sym2GOT (operands[1]);
8306   PUT_MODE (gotsym, Pmode);
8307   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8308
8309   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8310
8311   DONE;
8312 }")
8313
8314 (define_expand "sym2GOTPLT"
8315   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8316   ""
8317   "")
8318
8319 (define_expand "symGOTPLT2reg"
8320   [(match_operand 0 "" "") (match_operand 1 "" "")]
8321   ""
8322   "
8323 {
8324   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8325   DONE;
8326 }")
8327
8328 (define_expand "sym2GOTOFF"
8329   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8330   ""
8331   "")
8332
8333 (define_expand "symGOTOFF2reg"
8334   [(match_operand 0 "" "") (match_operand 1 "" "")]
8335   ""
8336   "
8337 {
8338   rtx gotoffsym, insn;
8339   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8340
8341   gotoffsym = gen_sym2GOTOFF (operands[1]);
8342   PUT_MODE (gotoffsym, Pmode);
8343   emit_move_insn (t, gotoffsym);
8344   insn = emit_move_insn (operands[0],
8345                          gen_rtx_PLUS (Pmode, t,
8346                                        gen_rtx_REG (Pmode, PIC_REG)));
8347
8348   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8349                                         REG_NOTES (insn));
8350
8351   DONE;
8352 }")
8353
8354 (define_expand "symPLT_label2reg"
8355   [(set (match_operand:SI 0 "" "")
8356         (const:SI (minus:SI
8357                    (const:SI
8358                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8359                    (const:SI
8360                     (minus:SI
8361                      (const:SI (plus:SI
8362                                 (match_operand:SI 2 "" "")
8363                                 (const_int 2)))
8364                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8365    ;; Even though the PIC register is not really used by the call
8366    ;; sequence in which this is expanded, the PLT code assumes the PIC
8367    ;; register is set, so we must not skip its initialization.  Since
8368    ;; we only use this expand as part of calling sequences, and never
8369    ;; to take the address of a function, this is the best point to
8370    ;; insert the (use).  Using the PLT to take the address of a
8371    ;; function would be wrong, not only because the PLT entry could
8372    ;; then be called from a function that doesn't initialize the PIC
8373    ;; register to the proper GOT, but also because pointers to the
8374    ;; same function might not compare equal, should they be set by
8375    ;; different shared libraries.
8376    (use (reg:SI PIC_REG))]
8377   "TARGET_SH1"
8378   "")
8379
8380 (define_expand "sym2PIC"
8381   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8382   ""
8383   "")
8384
8385 ;; TLS code generation.
8386 ;; ??? this should be a define_insn_and_split
8387 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8388 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8389 ;; for details.
8390
8391 (define_insn "tls_global_dynamic"
8392   [(set (match_operand:SI 0 "register_operand" "=&z")
8393         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8394                                   UNSPEC_TLSGD))
8395               (const_int 0)))
8396    (use (reg:PSI FPSCR_REG))
8397    (use (reg:SI PIC_REG))
8398    (clobber (reg:SI PR_REG))
8399    (clobber (scratch:SI))]
8400   "TARGET_SH1"
8401   "*
8402 {
8403   return \"\\
8404 mov.l\\t1f,r4\\n\\
8405 \\tmova\\t2f,r0\\n\\
8406 \\tmov.l\\t2f,r1\\n\\
8407 \\tadd\\tr0,r1\\n\\
8408 \\tjsr\\t@r1\\n\\
8409 \\tadd\\tr12,r4\\n\\
8410 \\tbra\\t3f\\n\\
8411 \\tnop\\n\\
8412 \\t.align\\t2\\n\\
8413 1:\\t.long\\t%a1@TLSGD\\n\\
8414 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8415 3:\";
8416 }"
8417   [(set_attr "type" "tls_load")
8418    (set_attr "length" "26")])
8419
8420 (define_insn "tls_local_dynamic"
8421   [(set (match_operand:SI 0 "register_operand" "=&z")
8422         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8423                                   UNSPEC_TLSLDM))
8424               (const_int 0)))
8425    (use (reg:PSI FPSCR_REG))
8426    (use (reg:SI PIC_REG))
8427    (clobber (reg:SI PR_REG))
8428    (clobber (scratch:SI))]
8429   "TARGET_SH1"
8430   "*
8431 {
8432   return \"\\
8433 mov.l\\t1f,r4\\n\\
8434 \\tmova\\t2f,r0\\n\\
8435 \\tmov.l\\t2f,r1\\n\\
8436 \\tadd\\tr0,r1\\n\\
8437 \\tjsr\\t@r1\\n\\
8438 \\tadd\\tr12,r4\\n\\
8439 \\tbra\\t3f\\n\\
8440 \\tnop\\n\\
8441 \\t.align\\t2\\n\\
8442 1:\\t.long\\t%a1@TLSLDM\\n\\
8443 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8444 3:\";
8445 }"
8446   [(set_attr "type" "tls_load")
8447    (set_attr "length" "26")])
8448
8449 (define_expand "sym2DTPOFF"
8450   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8451   ""
8452   "")
8453
8454 (define_expand "symDTPOFF2reg"
8455   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8456   ""
8457   "
8458 {
8459   rtx dtpoffsym, insn;
8460   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8461
8462   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8463   PUT_MODE (dtpoffsym, Pmode);
8464   emit_move_insn (t, dtpoffsym);
8465   insn = emit_move_insn (operands[0],
8466                          gen_rtx_PLUS (Pmode, t, operands[2]));
8467   DONE;
8468 }")
8469
8470 (define_expand "sym2GOTTPOFF"
8471   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8472   ""
8473   "")
8474
8475 (define_insn "tls_initial_exec"
8476   [(set (match_operand:SI 0 "register_operand" "=&r")
8477         (unspec:SI [(match_operand:SI 1 "" "")]
8478                     UNSPEC_TLSIE))
8479    (use (reg:SI GBR_REG))
8480    (use (reg:SI PIC_REG))
8481    (clobber (reg:SI R0_REG))]
8482   ""
8483   "*
8484 {
8485   return \"\\
8486 mov.l\\t1f,r0\\n\\
8487 \\tstc\\tgbr,%0\\n\\
8488 \\tmov.l\\t@(r0,r12),r0\\n\\
8489 \\tbra\\t2f\\n\\
8490 \\tadd\\tr0,%0\\n\\
8491 \\t.align\\t2\\n\\
8492 1:\\t.long\\t%a1\\n\\
8493 2:\";
8494 }"
8495   [(set_attr "type" "tls_load")
8496    (set_attr "length" "16")])
8497
8498 (define_expand "sym2TPOFF"
8499   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8500   ""
8501   "")
8502
8503 (define_expand "symTPOFF2reg"
8504   [(match_operand 0 "" "") (match_operand 1 "" "")]
8505   ""
8506   "
8507 {
8508   rtx tpoffsym, insn;
8509
8510   tpoffsym = gen_sym2TPOFF (operands[1]);
8511   PUT_MODE (tpoffsym, Pmode);
8512   insn = emit_move_insn (operands[0], tpoffsym);
8513   DONE;
8514 }")
8515
8516 (define_insn "load_gbr"
8517   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8518    (use (reg:SI GBR_REG))]
8519   ""
8520   "stc  gbr,%0"
8521   [(set_attr "type" "tls_load")])
8522
8523 ;; case instruction for switch statements.
8524
8525 ;; Operand 0 is index
8526 ;; operand 1 is the minimum bound
8527 ;; operand 2 is the maximum bound - minimum bound + 1
8528 ;; operand 3 is CODE_LABEL for the table;
8529 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8530
8531 (define_expand "casesi"
8532   [(match_operand:SI 0 "arith_reg_operand" "")
8533    (match_operand:SI 1 "arith_reg_operand" "")
8534    (match_operand:SI 2 "arith_reg_operand" "")
8535    (match_operand 3 "" "") (match_operand 4 "" "")]
8536   ""
8537   "
8538 {
8539   rtx reg = gen_reg_rtx (SImode);
8540   rtx reg2 = gen_reg_rtx (SImode);
8541   if (TARGET_SHMEDIA)
8542     {
8543       rtx reg = gen_reg_rtx (DImode);
8544       rtx reg2 = gen_reg_rtx (DImode);
8545       rtx reg3 = gen_reg_rtx (Pmode);
8546       rtx reg4 = gen_reg_rtx (Pmode);
8547       rtx reg5 = gen_reg_rtx (Pmode);
8548       rtx load;
8549
8550       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8551       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8552       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8553
8554       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8555       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8556       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8557       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8558       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8559                                                (Pmode, operands[3])));
8560       /* Messy: can we subreg to clean this up? */
8561       if (Pmode == DImode)
8562         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8563       else
8564         load = gen_casesi_load_media (reg4,
8565                                       gen_rtx_SUBREG (DImode, reg3, 0),
8566                                       reg2, operands[3]);
8567       PUT_MODE (SET_SRC (load), Pmode);
8568       emit_insn (load);
8569       /* ??? The following add could be eliminated if we used ptrel.  */
8570       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8571       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8572       emit_barrier ();
8573       DONE;
8574     }
8575   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8576   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8577   /* If optimizing, casesi_worker depends on the mode of the instruction
8578      before label it 'uses' - operands[3].  */
8579   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8580                            reg));
8581   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8582   if (TARGET_SH2)
8583     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8584   else
8585     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8586   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8587      operands[3], but to lab.  We will fix this up in
8588      machine_dependent_reorg.  */
8589   emit_barrier ();
8590   DONE;
8591 }")
8592
8593 (define_expand "casesi_0"
8594   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8595    (set (match_dup 4) (minus:SI (match_dup 4)
8596                                 (match_operand:SI 1 "arith_operand" "")))
8597    (set (reg:SI T_REG)
8598         (gtu:SI (match_dup 4)
8599                 (match_operand:SI 2 "arith_reg_operand" "")))
8600    (set (pc)
8601         (if_then_else (ne (reg:SI T_REG)
8602                           (const_int 0))
8603                       (label_ref (match_operand 3 "" ""))
8604                       (pc)))]
8605   "TARGET_SH1"
8606   "")
8607
8608 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8609 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8610 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8611
8612 (define_insn "casesi_worker_0"
8613   [(set (match_operand:SI 0 "register_operand" "=r,r")
8614         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8615                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8616    (clobber (match_scratch:SI 3 "=X,1"))
8617    (clobber (match_scratch:SI 4 "=&z,z"))]
8618   "TARGET_SH1"
8619   "#")
8620
8621 (define_split
8622   [(set (match_operand:SI 0 "register_operand" "")
8623         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8624                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8625    (clobber (match_scratch:SI 3 ""))
8626    (clobber (match_scratch:SI 4 ""))]
8627   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8628   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8629    (parallel [(set (match_dup 0)
8630               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8631                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8632               (clobber (match_dup 3))])
8633    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8634   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8635
8636 (define_split
8637   [(set (match_operand:SI 0 "register_operand" "")
8638         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8639                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8640    (clobber (match_scratch:SI 3 ""))
8641    (clobber (match_scratch:SI 4 ""))]
8642   "TARGET_SH2 && reload_completed"
8643   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8644    (parallel [(set (match_dup 0)
8645               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8646                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8647               (clobber (match_dup 3))])]
8648   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8649
8650 (define_insn "casesi_worker_1"
8651   [(set (match_operand:SI 0 "register_operand" "=r,r")
8652         (unspec:SI [(reg:SI R0_REG)
8653                     (match_operand:SI 1 "register_operand" "0,r")
8654                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8655    (clobber (match_scratch:SI 3 "=X,1"))]
8656   "TARGET_SH1"
8657   "*
8658 {
8659   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8660
8661   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8662
8663   switch (GET_MODE (diff_vec))
8664     {
8665     case SImode:
8666       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8667     case HImode:
8668       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8669     case QImode:
8670       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8671         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8672       return \"mov.b    @(r0,%1),%0\";
8673     default:
8674       gcc_unreachable ();
8675     }
8676 }"
8677   [(set_attr "length" "4")])
8678
8679 (define_insn "casesi_worker_2"
8680   [(set (match_operand:SI 0 "register_operand" "=r,r")
8681         (unspec:SI [(reg:SI R0_REG)
8682                     (match_operand:SI 1 "register_operand" "0,r")
8683                     (label_ref (match_operand 2 "" ""))
8684                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8685    (clobber (match_operand:SI 4 "" "=X,1"))]
8686   "TARGET_SH2 && reload_completed && flag_pic"
8687   "*
8688 {
8689   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8690   const char *load;
8691
8692   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8693
8694   switch (GET_MODE (diff_vec))
8695     {
8696     case SImode:
8697       output_asm_insn (\"shll2    %1\", operands);
8698       load = \"mov.l    @(r0,%1),%0\"; break;
8699     case HImode:
8700       output_asm_insn (\"add    %1,%1\", operands);
8701       load = \"mov.w    @(r0,%1),%0\"; break;
8702     case QImode:
8703       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8704         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8705       else
8706         load = \"mov.b  @(r0,%1),%0\";
8707       break;
8708     default:
8709       gcc_unreachable ();
8710     }
8711   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8712   return load;
8713 }"
8714   [(set_attr "length" "8")])
8715
8716 (define_insn "casesi_shift_media"
8717   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8718         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8719                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8720                     UNSPEC_CASESI)))]
8721   "TARGET_SHMEDIA"
8722   "*
8723 {
8724   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8725
8726   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8727
8728   switch (GET_MODE (diff_vec))
8729     {
8730     case SImode:
8731       return \"shlli    %1, 2, %0\";
8732     case HImode:
8733       return \"shlli    %1, 1, %0\";
8734     case QImode:
8735       if (rtx_equal_p (operands[0], operands[1]))
8736         return \"\";
8737       return \"add      %1, r63, %0\";
8738     default:
8739       gcc_unreachable ();
8740     }
8741 }"
8742   [(set_attr "type" "arith_media")])
8743
8744 (define_insn "casesi_load_media"
8745   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8746         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8747                          (match_operand:DI 2 "arith_reg_operand" "r")
8748                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8749   "TARGET_SHMEDIA"
8750   "*
8751 {
8752   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8753
8754   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8755
8756   switch (GET_MODE (diff_vec))
8757     {
8758     case SImode:
8759       return \"ldx.l    %1, %2, %0\";
8760     case HImode:
8761 #if 0
8762       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8763         return \"ldx.uw %1, %2, %0\";
8764 #endif
8765       return \"ldx.w    %1, %2, %0\";
8766     case QImode:
8767       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8768         return \"ldx.ub %1, %2, %0\";
8769       return \"ldx.b    %1, %2, %0\";
8770     default:
8771       gcc_unreachable ();
8772     }
8773 }"
8774   [(set_attr "type" "load_media")])
8775
8776 (define_expand "return"
8777   [(return)]
8778   "reload_completed && ! sh_need_epilogue ()"
8779   "
8780 {
8781   if (TARGET_SHMEDIA)
8782     {
8783       emit_jump_insn (gen_return_media ());
8784       DONE;
8785     }
8786
8787   if (TARGET_SHCOMPACT
8788       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8789     {
8790       emit_jump_insn (gen_shcompact_return_tramp ());
8791       DONE;
8792     }
8793 }")
8794
8795 (define_insn "*return_i"
8796   [(return)]
8797   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8798                     && (current_function_args_info.call_cookie
8799                         & CALL_COOKIE_RET_TRAMP (1)))
8800    && reload_completed"
8801   "%@   %#"
8802   [(set_attr "type" "return")
8803    (set_attr "needs_delay_slot" "yes")])
8804
8805 (define_expand "shcompact_return_tramp"
8806   [(return)]
8807   "TARGET_SHCOMPACT
8808    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8809   "
8810 {
8811   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8812
8813   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8814   emit_jump_insn (gen_shcompact_return_tramp_i ());
8815   DONE;
8816 }")
8817
8818 (define_insn "shcompact_return_tramp_i"
8819   [(parallel [(return) (use (reg:SI R0_REG))])]
8820   "TARGET_SHCOMPACT
8821    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8822   "jmp  @r0%#"
8823   [(set_attr "type" "jump_ind")
8824    (set_attr "needs_delay_slot" "yes")])
8825
8826 (define_insn "return_media_i"
8827   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8828   "TARGET_SHMEDIA && reload_completed"
8829   "blink        %0, r63"
8830   [(set_attr "type" "jump_media")])
8831
8832 (define_insn "return_media_rte"
8833   [(return)]
8834   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8835   "rte"
8836   [(set_attr "type" "jump_media")])
8837
8838 (define_expand "return_media"
8839   [(return)]
8840   "TARGET_SHMEDIA && reload_completed"
8841   "
8842 {
8843   int tr_regno = sh_media_register_for_return ();
8844   rtx tr;
8845
8846   if (current_function_interrupt)
8847     {
8848       emit_jump_insn (gen_return_media_rte ());
8849       DONE;
8850     }
8851   if (tr_regno < 0)
8852     {
8853       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8854
8855       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8856       tr_regno = TR0_REG;
8857       tr = gen_rtx_REG (Pmode, tr_regno);
8858       emit_move_insn (tr, r18);
8859     }
8860   else
8861     tr = gen_rtx_REG (Pmode, tr_regno);
8862
8863   emit_jump_insn (gen_return_media_i (tr));
8864   DONE;
8865 }")
8866
8867 (define_insn "shcompact_preserve_incoming_args"
8868   [(set (match_operand:SI 0 "register_operand" "+r")
8869         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8870   "TARGET_SHCOMPACT"
8871   ""
8872   [(set_attr "length" "0")])
8873
8874 (define_insn "shcompact_incoming_args"
8875   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8876    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8877    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8878    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8879    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8880    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8881    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8882    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8883    (set (mem:BLK (reg:SI MACL_REG))
8884         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8885    (use (reg:SI R0_REG))
8886    (clobber (reg:SI R0_REG))
8887    (clobber (reg:SI MACL_REG))
8888    (clobber (reg:SI MACH_REG))
8889    (clobber (reg:SI PR_REG))]
8890   "TARGET_SHCOMPACT"
8891   "jsr  @r0%#"
8892   [(set_attr "needs_delay_slot" "yes")])
8893
8894 (define_insn "shmedia_save_restore_regs_compact"
8895   [(set (reg:SI SP_REG)
8896         (plus:SI (reg:SI SP_REG)
8897                  (match_operand:SI 0 "immediate_operand" "i")))
8898    (use (reg:SI R0_REG))
8899    (clobber (reg:SI PR_REG))]
8900   "TARGET_SHCOMPACT
8901    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8902        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8903   "jsr @r0%#"
8904   [(set_attr "needs_delay_slot" "yes")])
8905
8906 (define_expand "prologue"
8907   [(const_int 0)]
8908   ""
8909   "sh_expand_prologue (); DONE;")
8910
8911 (define_expand "epilogue"
8912   [(return)]
8913   ""
8914   "
8915 {
8916   sh_expand_epilogue (0);
8917   emit_jump_insn (gen_return ());
8918   DONE;
8919 }")
8920
8921 (define_expand "eh_return"
8922   [(use (match_operand 0 "register_operand" ""))]
8923   ""
8924 {
8925   rtx ra = operands[0];
8926
8927   if (TARGET_SHMEDIA64)
8928     emit_insn (gen_eh_set_ra_di (ra));
8929   else
8930     emit_insn (gen_eh_set_ra_si (ra));
8931
8932   DONE;
8933 })
8934
8935 ;; Clobber the return address on the stack.  We can't expand this
8936 ;; until we know where it will be put in the stack frame.
8937
8938 (define_insn "eh_set_ra_si"
8939   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8940    (clobber (match_scratch:SI 1 "=&r"))]
8941   "! TARGET_SHMEDIA64"
8942   "#")
8943
8944 (define_insn "eh_set_ra_di"
8945   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8946    (clobber (match_scratch:DI 1 "=&r"))]
8947   "TARGET_SHMEDIA64"
8948   "#")
8949
8950 (define_split
8951   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8952    (clobber (match_scratch 1 ""))]
8953   "reload_completed"
8954   [(const_int 0)]
8955   "
8956 {
8957   sh_set_return_address (operands[0], operands[1]);
8958   DONE;
8959 }")
8960
8961 (define_insn "blockage"
8962   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8963   ""
8964   ""
8965   [(set_attr "length" "0")])
8966 \f
8967 ;; ------------------------------------------------------------------------
8968 ;; Scc instructions
8969 ;; ------------------------------------------------------------------------
8970
8971 (define_insn "movt"
8972   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8973         (eq:SI (reg:SI T_REG) (const_int 1)))]
8974   "TARGET_SH1"
8975   "movt %0"
8976   [(set_attr "type" "arith")])
8977
8978 (define_expand "seq"
8979   [(set (match_operand:SI 0 "arith_reg_dest" "")
8980         (match_dup 1))]
8981   ""
8982   "
8983 {
8984   if (TARGET_SHMEDIA)
8985     {
8986       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8987       if (sh_compare_op1 != const0_rtx)
8988         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8989                                     ? GET_MODE (sh_compare_op0)
8990                                     : GET_MODE (sh_compare_op1),
8991                                     sh_compare_op1);
8992       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8993         {
8994           if (GET_MODE (operands[0]) != SImode)
8995             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
8996
8997           switch (GET_MODE (sh_compare_op0))
8998             {
8999             case SImode:
9000               emit_insn (gen_cmpsieqsi_media (operands[0],
9001                                               sh_compare_op0, sh_compare_op1));
9002               break;
9003
9004             case DImode:
9005               emit_insn (gen_cmpsieqdi_media (operands[0],
9006                                               sh_compare_op0, sh_compare_op1));
9007               break;
9008
9009             case SFmode:
9010               if (! TARGET_SHMEDIA_FPU)
9011                 FAIL;
9012               emit_insn (gen_cmpsieqsf_media (operands[0],
9013                                               sh_compare_op0, sh_compare_op1));
9014               break;
9015
9016             case DFmode:
9017               if (! TARGET_SHMEDIA_FPU)
9018                 FAIL;
9019               emit_insn (gen_cmpsieqdf_media (operands[0],
9020                                               sh_compare_op0, sh_compare_op1));
9021               break;
9022
9023             default:
9024               FAIL;
9025             }
9026           DONE;
9027         }
9028
9029       if (GET_MODE (operands[0]) != DImode)
9030         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9031
9032       switch (GET_MODE (sh_compare_op0))
9033         {
9034         case SImode:
9035           emit_insn (gen_cmpeqsi_media (operands[0],
9036                                         sh_compare_op0, sh_compare_op1));
9037           break;
9038
9039         case DImode:
9040           emit_insn (gen_cmpeqdi_media (operands[0],
9041                                         sh_compare_op0, sh_compare_op1));
9042           break;
9043
9044         case SFmode:
9045           if (! TARGET_SHMEDIA_FPU)
9046             FAIL;
9047           emit_insn (gen_cmpeqsf_media (operands[0],
9048                                         sh_compare_op0, sh_compare_op1));
9049           break;
9050
9051         case DFmode:
9052           if (! TARGET_SHMEDIA_FPU)
9053             FAIL;
9054           emit_insn (gen_cmpeqdf_media (operands[0],
9055                                         sh_compare_op0, sh_compare_op1));
9056           break;
9057
9058         default:
9059           FAIL;
9060         }
9061       DONE;
9062     }
9063   if (sh_expand_t_scc (EQ, operands[0]))
9064     DONE;
9065   if (! currently_expanding_to_rtl)
9066     FAIL;
9067   operands[1] = prepare_scc_operands (EQ);
9068 }")
9069
9070 (define_expand "slt"
9071   [(set (match_operand:SI 0 "arith_reg_operand" "")
9072         (match_dup 1))]
9073   ""
9074   "
9075 {
9076   if (TARGET_SHMEDIA)
9077     {
9078       if (GET_MODE (operands[0]) != DImode)
9079         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9080       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9081       if (sh_compare_op1 != const0_rtx)
9082         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9083                                     ? GET_MODE (sh_compare_op0)
9084                                     : GET_MODE (sh_compare_op1),
9085                                     sh_compare_op1);
9086
9087       switch (GET_MODE (sh_compare_op0))
9088         {
9089         case SImode:
9090           emit_insn (gen_cmpgtsi_media (operands[0],
9091                                         sh_compare_op1, sh_compare_op0));
9092           break;
9093
9094         case DImode:
9095           emit_insn (gen_cmpgtdi_media (operands[0],
9096                                         sh_compare_op1, sh_compare_op0));
9097           break;
9098
9099         case SFmode:
9100           if (! TARGET_SHMEDIA_FPU)
9101             FAIL;
9102           emit_insn (gen_cmpgtsf_media (operands[0],
9103                                         sh_compare_op1, sh_compare_op0));
9104           break;
9105
9106         case DFmode:
9107           if (! TARGET_SHMEDIA_FPU)
9108             FAIL;
9109           emit_insn (gen_cmpgtdf_media (operands[0],
9110                                         sh_compare_op1, sh_compare_op0));
9111           break;
9112
9113         default:
9114           FAIL;
9115         }
9116       DONE;
9117     }
9118   if (! currently_expanding_to_rtl)
9119     FAIL;
9120   operands[1] = prepare_scc_operands (LT);
9121 }")
9122
9123 (define_expand "sle"
9124   [(match_operand:SI 0 "arith_reg_operand" "")]
9125   ""
9126   "
9127 {
9128   rtx tmp = sh_compare_op0;
9129
9130   if (TARGET_SHMEDIA)
9131     {
9132       if (GET_MODE (operands[0]) != DImode)
9133         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9134       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9135       if (sh_compare_op1 != const0_rtx)
9136         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9137                                     ? GET_MODE (sh_compare_op0)
9138                                     : GET_MODE (sh_compare_op1),
9139                                     sh_compare_op1);
9140
9141       switch (GET_MODE (sh_compare_op0))
9142         {
9143         case SImode:
9144           {
9145             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9146
9147             emit_insn (gen_cmpgtsi_media (tmp,
9148                                           sh_compare_op0, sh_compare_op1));
9149             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9150             break;
9151           }
9152
9153         case DImode:
9154           {
9155             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9156
9157             emit_insn (gen_cmpgtdi_media (tmp,
9158                                           sh_compare_op0, sh_compare_op1));
9159             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9160             break;
9161           }
9162
9163         case SFmode:
9164           if (! TARGET_SHMEDIA_FPU)
9165             FAIL;
9166           emit_insn (gen_cmpgesf_media (operands[0],
9167                                         sh_compare_op1, sh_compare_op0));
9168           break;
9169
9170         case DFmode:
9171           if (! TARGET_SHMEDIA_FPU)
9172             FAIL;
9173           emit_insn (gen_cmpgedf_media (operands[0],
9174                                         sh_compare_op1, sh_compare_op0));
9175           break;
9176
9177         default:
9178           FAIL;
9179         }
9180       DONE;
9181     }
9182
9183   sh_compare_op0 = sh_compare_op1;
9184   sh_compare_op1 = tmp;
9185   emit_insn (gen_sge (operands[0]));
9186   DONE;
9187 }")
9188
9189 (define_expand "sgt"
9190   [(set (match_operand:SI 0 "arith_reg_operand" "")
9191         (match_dup 1))]
9192   ""
9193   "
9194 {
9195   if (TARGET_SHMEDIA)
9196     {
9197       if (GET_MODE (operands[0]) != DImode)
9198         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9199       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9200       if (sh_compare_op1 != const0_rtx)
9201         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9202                                     ? GET_MODE (sh_compare_op0)
9203                                     : GET_MODE (sh_compare_op1),
9204                                     sh_compare_op1);
9205
9206       switch (GET_MODE (sh_compare_op0))
9207         {
9208         case SImode:
9209           emit_insn (gen_cmpgtsi_media (operands[0],
9210                                         sh_compare_op0, sh_compare_op1));
9211           break;
9212
9213         case DImode:
9214           emit_insn (gen_cmpgtdi_media (operands[0],
9215                                         sh_compare_op0, sh_compare_op1));
9216           break;
9217
9218         case SFmode:
9219           if (! TARGET_SHMEDIA_FPU)
9220             FAIL;
9221           emit_insn (gen_cmpgtsf_media (operands[0],
9222                                         sh_compare_op0, sh_compare_op1));
9223           break;
9224
9225         case DFmode:
9226           if (! TARGET_SHMEDIA_FPU)
9227             FAIL;
9228           emit_insn (gen_cmpgtdf_media (operands[0],
9229                                         sh_compare_op0, sh_compare_op1));
9230           break;
9231
9232         default:
9233           FAIL;
9234         }
9235       DONE;
9236     }
9237   if (! currently_expanding_to_rtl)
9238     FAIL;
9239   operands[1] = prepare_scc_operands (GT);
9240 }")
9241
9242 (define_expand "sge"
9243   [(set (match_operand:SI 0 "arith_reg_operand" "")
9244         (match_dup 1))]
9245   ""
9246   "
9247 {
9248   if (TARGET_SHMEDIA)
9249     {
9250       enum machine_mode mode = GET_MODE (sh_compare_op0);
9251
9252       if ((mode) == VOIDmode)
9253         mode = GET_MODE (sh_compare_op1);
9254       if (GET_MODE (operands[0]) != DImode)
9255         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9256       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9257       if (sh_compare_op1 != const0_rtx)
9258         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9259
9260       switch (mode)
9261         {
9262         case SImode:
9263           {
9264             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9265
9266             emit_insn (gen_cmpgtsi_media (tmp,
9267                                           sh_compare_op1, sh_compare_op0));
9268             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9269             break;
9270           }
9271
9272         case DImode:
9273           {
9274             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9275
9276             emit_insn (gen_cmpgtdi_media (tmp,
9277                                           sh_compare_op1, sh_compare_op0));
9278             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9279             break;
9280           }
9281
9282         case SFmode:
9283           if (! TARGET_SHMEDIA_FPU)
9284             FAIL;
9285           emit_insn (gen_cmpgesf_media (operands[0],
9286                                         sh_compare_op0, sh_compare_op1));
9287           break;
9288
9289         case DFmode:
9290           if (! TARGET_SHMEDIA_FPU)
9291             FAIL;
9292           emit_insn (gen_cmpgedf_media (operands[0],
9293                                         sh_compare_op0, sh_compare_op1));
9294           break;
9295
9296         default:
9297           FAIL;
9298         }
9299       DONE;
9300     }
9301
9302   if (! currently_expanding_to_rtl)
9303     FAIL;
9304   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9305     {
9306       if (TARGET_IEEE)
9307         {
9308           rtx lab = gen_label_rtx ();
9309           prepare_scc_operands (EQ);
9310           emit_jump_insn (gen_branch_true (lab));
9311           prepare_scc_operands (GT);
9312           emit_label (lab);
9313           emit_insn (gen_movt (operands[0]));
9314         }
9315       else
9316         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9317       DONE;
9318     }
9319   operands[1] = prepare_scc_operands (GE);
9320 }")
9321
9322 (define_expand "sgtu"
9323   [(set (match_operand:SI 0 "arith_reg_operand" "")
9324         (match_dup 1))]
9325   ""
9326   "
9327 {
9328   if (TARGET_SHMEDIA)
9329     {
9330       if (GET_MODE (operands[0]) != DImode)
9331         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9332       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9333       if (sh_compare_op1 != const0_rtx)
9334         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9335                                     ? GET_MODE (sh_compare_op0)
9336                                     : GET_MODE (sh_compare_op1),
9337                                     sh_compare_op1);
9338
9339       emit_insn (gen_cmpgtudi_media (operands[0],
9340                                      sh_compare_op0, sh_compare_op1));
9341       DONE;
9342     }
9343   if (! currently_expanding_to_rtl)
9344     FAIL;
9345   operands[1] = prepare_scc_operands (GTU);
9346 }")
9347
9348 (define_expand "sltu"
9349   [(set (match_operand:SI 0 "arith_reg_operand" "")
9350         (match_dup 1))]
9351   ""
9352   "
9353 {
9354   if (TARGET_SHMEDIA)
9355     {
9356       if (GET_MODE (operands[0]) != DImode)
9357         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9358       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9359       if (sh_compare_op1 != const0_rtx)
9360         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9361                                     ? GET_MODE (sh_compare_op0)
9362                                     : GET_MODE (sh_compare_op1),
9363                                     sh_compare_op1);
9364
9365       emit_insn (gen_cmpgtudi_media (operands[0],
9366                                      sh_compare_op1, sh_compare_op0));
9367       DONE;
9368     }
9369   if (! currently_expanding_to_rtl)
9370     FAIL;
9371   operands[1] = prepare_scc_operands (LTU);
9372 }")
9373
9374 (define_expand "sleu"
9375   [(set (match_operand:SI 0 "arith_reg_operand" "")
9376         (match_dup 1))]
9377   ""
9378   "
9379 {
9380   if (TARGET_SHMEDIA)
9381     {
9382       rtx tmp;
9383
9384       if (GET_MODE (operands[0]) != DImode)
9385         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9386       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9387       if (sh_compare_op1 != const0_rtx)
9388         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9389                                     ? GET_MODE (sh_compare_op0)
9390                                     : GET_MODE (sh_compare_op1),
9391                                     sh_compare_op1);
9392
9393       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9394
9395       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9396       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9397
9398       DONE;
9399     }
9400   if (! currently_expanding_to_rtl)
9401     FAIL;
9402   operands[1] = prepare_scc_operands (LEU);
9403 }")
9404
9405 (define_expand "sgeu"
9406   [(set (match_operand:SI 0 "arith_reg_operand" "")
9407         (match_dup 1))]
9408   ""
9409   "
9410 {
9411   if (TARGET_SHMEDIA)
9412     {
9413       rtx tmp;
9414
9415       if (GET_MODE (operands[0]) != DImode)
9416         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9417       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9418       if (sh_compare_op1 != const0_rtx)
9419         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9420                                     ? GET_MODE (sh_compare_op0)
9421                                     : GET_MODE (sh_compare_op1),
9422                                     sh_compare_op1);
9423
9424       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9425
9426       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9427       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9428
9429       DONE;
9430     }
9431
9432   if (! currently_expanding_to_rtl)
9433     FAIL;
9434   operands[1] = prepare_scc_operands (GEU);
9435 }")
9436
9437 ;; sne moves the complement of the T reg to DEST like this:
9438 ;;      cmp/eq ...
9439 ;;      mov    #-1,temp
9440 ;;      negc   temp,dest
9441 ;;   This is better than xoring compare result with 1 because it does
9442 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9443 ;;   loop.
9444
9445 (define_expand "sne"
9446   [(set (match_dup 2) (const_int -1))
9447    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9448                    (neg:SI (plus:SI (match_dup 1)
9449                                     (match_dup 2))))
9450               (set (reg:SI T_REG)
9451                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9452                           (const_int 0)))])]
9453   ""
9454   "
9455 {
9456   if (TARGET_SHMEDIA)
9457     {
9458       rtx tmp;
9459
9460       if (GET_MODE (operands[0]) != DImode)
9461         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9462
9463       if (! TARGET_SHMEDIA_FPU
9464           && GET_MODE (sh_compare_op0) != DImode
9465           && GET_MODE (sh_compare_op0) != SImode)
9466         FAIL;
9467
9468       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9469       if (sh_compare_op1 != const0_rtx)
9470         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9471                                     ? GET_MODE (sh_compare_op0)
9472                                     : GET_MODE (sh_compare_op1),
9473                                     sh_compare_op1);
9474
9475       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9476
9477       emit_insn (gen_seq (tmp));
9478       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9479
9480       DONE;
9481     }
9482
9483   if (sh_expand_t_scc (NE, operands[0]))
9484     DONE;
9485   if (! currently_expanding_to_rtl)
9486     FAIL;
9487   operands[1] = prepare_scc_operands (EQ);
9488   operands[2] = gen_reg_rtx (SImode);
9489 }")
9490
9491 (define_expand "sunordered"
9492   [(set (match_operand:DI 0 "arith_reg_operand" "")
9493         (unordered:DI (match_dup 1) (match_dup 2)))]
9494   "TARGET_SHMEDIA_FPU"
9495   "
9496 {
9497   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9498   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9499 }")
9500
9501 ;; Use the same trick for FP sle / sge
9502
9503 ;; Apart from the constant use and the T setting, this is like movt,
9504 ;; except that it uses the logically negated value of T, i.e.
9505 ;; operand[0] := T ? 0 : 1.
9506 (define_expand "movnegt"
9507   [(set (match_dup 2) (const_int -1))
9508    (parallel [(set (match_operand 0 "" "")
9509                    (neg:SI (plus:SI (match_dup 1)
9510                                     (match_dup 2))))
9511               (set (reg:SI T_REG)
9512                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9513                           (const_int 0)))])]
9514   "TARGET_SH1"
9515   "operands[2] = gen_reg_rtx (SImode);")
9516
9517 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9518 ;; This prevents a regression that occurred when we switched from xor to
9519 ;; mov/neg for sne.
9520
9521 (define_split
9522   [(set (match_operand:SI 0 "arith_reg_dest" "")
9523         (plus:SI (reg:SI T_REG)
9524                  (const_int -1)))]
9525   "TARGET_SH1"
9526   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9527    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9528   "")
9529
9530 ;; -------------------------------------------------------------------------
9531 ;; Instructions to cope with inline literal tables
9532 ;; -------------------------------------------------------------------------
9533
9534 ; 2 byte integer in line
9535
9536 (define_insn "consttable_2"
9537  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9538                     (match_operand 1 "" "")]
9539                    UNSPECV_CONST2)]
9540  ""
9541  "*
9542 {
9543   if (operands[1] != const0_rtx)
9544     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9545   return \"\";
9546 }"
9547  [(set_attr "length" "2")
9548  (set_attr "in_delay_slot" "no")])
9549
9550 ; 4 byte integer in line
9551
9552 (define_insn "consttable_4"
9553  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9554                     (match_operand 1 "" "")]
9555                    UNSPECV_CONST4)]
9556  ""
9557  "*
9558 {
9559   if (operands[1] != const0_rtx)
9560     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9561   return \"\";
9562 }"
9563  [(set_attr "length" "4")
9564   (set_attr "in_delay_slot" "no")])
9565
9566 ; 8 byte integer in line
9567
9568 (define_insn "consttable_8"
9569  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9570                     (match_operand 1 "" "")]
9571                    UNSPECV_CONST8)]
9572  ""
9573  "*
9574 {
9575   if (operands[1] != const0_rtx)
9576     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9577   return \"\";
9578 }"
9579  [(set_attr "length" "8")
9580   (set_attr "in_delay_slot" "no")])
9581
9582 ; 4 byte floating point
9583
9584 (define_insn "consttable_sf"
9585  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9586                     (match_operand 1 "" "")]
9587                    UNSPECV_CONST4)]
9588  ""
9589  "*
9590 {
9591   if (operands[1] != const0_rtx)
9592     {
9593       REAL_VALUE_TYPE d;
9594       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9595       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9596     }
9597   return \"\";
9598 }"
9599  [(set_attr "length" "4")
9600   (set_attr "in_delay_slot" "no")])
9601
9602 ; 8 byte floating point
9603
9604 (define_insn "consttable_df"
9605  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9606                     (match_operand 1 "" "")]
9607                    UNSPECV_CONST8)]
9608  ""
9609  "*
9610 {
9611   if (operands[1] != const0_rtx)
9612     {
9613       REAL_VALUE_TYPE d;
9614       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9615       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9616     }
9617   return \"\";
9618 }"
9619  [(set_attr "length" "8")
9620   (set_attr "in_delay_slot" "no")])
9621
9622 ;; Alignment is needed for some constant tables; it may also be added for
9623 ;; Instructions at the start of loops, or after unconditional branches.
9624 ;; ??? We would get more accurate lengths if we did instruction
9625 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9626 ;; here is too conservative.
9627
9628 ; align to a two byte boundary
9629
9630 (define_expand "align_2"
9631  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9632  ""
9633  "")
9634
9635 ; align to a four byte boundary
9636 ;; align_4 and align_log are instructions for the starts of loops, or
9637 ;; after unconditional branches, which may take up extra room.
9638
9639 (define_expand "align_4"
9640  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9641  ""
9642  "")
9643
9644 ; align to a cache line boundary
9645
9646 (define_insn "align_log"
9647  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9648  ""
9649  ""
9650  [(set_attr "length" "0")
9651   (set_attr "in_delay_slot" "no")])
9652
9653 ; emitted at the end of the literal table, used to emit the
9654 ; 32bit branch labels if needed.
9655
9656 (define_insn "consttable_end"
9657   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9658   ""
9659   "* return output_jump_label_table ();"
9660   [(set_attr "in_delay_slot" "no")])
9661
9662 ; emitted at the end of the window in the literal table.
9663
9664 (define_insn "consttable_window_end"
9665   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9666   ""
9667   ""
9668   [(set_attr "length" "0")
9669    (set_attr "in_delay_slot" "no")])
9670
9671 ;; -------------------------------------------------------------------------
9672 ;; Misc
9673 ;; -------------------------------------------------------------------------
9674
9675 ;; String/block move insn.
9676
9677 (define_expand "movmemsi"
9678   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9679                    (mem:BLK (match_operand:BLK 1 "" "")))
9680               (use (match_operand:SI 2 "nonmemory_operand" ""))
9681               (use (match_operand:SI 3 "immediate_operand" ""))
9682               (clobber (reg:SI PR_REG))
9683               (clobber (reg:SI R4_REG))
9684               (clobber (reg:SI R5_REG))
9685               (clobber (reg:SI R0_REG))])]
9686   "TARGET_SH1 && ! TARGET_SH5"
9687   "
9688 {
9689   if(expand_block_move (operands))
9690      DONE;
9691   else FAIL;
9692 }")
9693
9694 (define_insn "block_move_real"
9695   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9696                    (mem:BLK (reg:SI R5_REG)))
9697               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9698               (clobber (reg:SI PR_REG))
9699               (clobber (reg:SI R0_REG))])]
9700   "TARGET_SH1 && ! TARGET_HARD_SH4"
9701   "jsr  @%0%#"
9702   [(set_attr "type" "sfunc")
9703    (set_attr "needs_delay_slot" "yes")])
9704
9705 (define_insn "block_lump_real"
9706   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9707                    (mem:BLK (reg:SI R5_REG)))
9708               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9709               (use (reg:SI R6_REG))
9710               (clobber (reg:SI PR_REG))
9711               (clobber (reg:SI T_REG))
9712               (clobber (reg:SI R4_REG))
9713               (clobber (reg:SI R5_REG))
9714               (clobber (reg:SI R6_REG))
9715               (clobber (reg:SI R0_REG))])]
9716   "TARGET_SH1 && ! TARGET_HARD_SH4"
9717   "jsr  @%0%#"
9718   [(set_attr "type" "sfunc")
9719    (set_attr "needs_delay_slot" "yes")])
9720
9721 (define_insn "block_move_real_i4"
9722   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9723                    (mem:BLK (reg:SI R5_REG)))
9724               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9725               (clobber (reg:SI PR_REG))
9726               (clobber (reg:SI R0_REG))
9727               (clobber (reg:SI R1_REG))
9728               (clobber (reg:SI R2_REG))])]
9729   "TARGET_HARD_SH4"
9730   "jsr  @%0%#"
9731   [(set_attr "type" "sfunc")
9732    (set_attr "needs_delay_slot" "yes")])
9733
9734 (define_insn "block_lump_real_i4"
9735   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9736                    (mem:BLK (reg:SI R5_REG)))
9737               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9738               (use (reg:SI R6_REG))
9739               (clobber (reg:SI PR_REG))
9740               (clobber (reg:SI T_REG))
9741               (clobber (reg:SI R4_REG))
9742               (clobber (reg:SI R5_REG))
9743               (clobber (reg:SI R6_REG))
9744               (clobber (reg:SI R0_REG))
9745               (clobber (reg:SI R1_REG))
9746               (clobber (reg:SI R2_REG))
9747               (clobber (reg:SI R3_REG))])]
9748   "TARGET_HARD_SH4"
9749   "jsr  @%0%#"
9750   [(set_attr "type" "sfunc")
9751    (set_attr "needs_delay_slot" "yes")])
9752 \f
9753 ;; -------------------------------------------------------------------------
9754 ;; Floating point instructions.
9755 ;; -------------------------------------------------------------------------
9756
9757 ;; ??? All patterns should have a type attribute.
9758
9759 (define_expand "fpu_switch0"
9760   [(set (match_operand:SI 0 "" "") (match_dup 2))
9761    (set (match_dup 1) (mem:PSI (match_dup 0)))]
9762   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9763   "
9764 {
9765   operands[1] = get_fpscr_rtx ();
9766   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9767   if (flag_pic)
9768     operands[2] = legitimize_pic_address (operands[2], SImode,
9769                                           no_new_pseudos ? operands[0] : 0);
9770 }")
9771
9772 (define_expand "fpu_switch1"
9773   [(set (match_operand:SI 0 "" "") (match_dup 2))
9774    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9775    (set (match_dup 1) (mem:PSI (match_dup 3)))]
9776   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9777   "
9778 {
9779   operands[1] = get_fpscr_rtx ();
9780   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9781   if (flag_pic)
9782     operands[2] = legitimize_pic_address (operands[2], SImode,
9783                                           no_new_pseudos ? operands[0] : 0);
9784   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9785 }")
9786
9787 (define_expand "movpsi"
9788   [(set (match_operand:PSI 0 "register_operand" "")
9789         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9791   "")
9792
9793 ;; The c / m alternative is a fake to guide reload to load directly into
9794 ;; fpscr, since reload doesn't know how to use post-increment.
9795 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9796 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9797 ;; predicate after reload.
9798 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9799 ;; like a mac -> gpr move.
9800 (define_insn "fpu_switch"
9801   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9802         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9803   "TARGET_SH2E
9804    && (! reload_completed
9805        || true_regnum (operands[0]) != FPSCR_REG
9806        || GET_CODE (operands[1]) != MEM
9807        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9808   "@
9809         ! precision stays the same
9810         lds.l   %1,fpscr
9811         mov.l   %1,%0
9812         #
9813         lds     %1,fpscr
9814         mov     %1,%0
9815         mov.l   %1,%0
9816         sts     fpscr,%0
9817         sts.l   fpscr,%0"
9818   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9819    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9820
9821 (define_split
9822   [(set (reg:PSI FPSCR_REG)
9823         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9824   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9825   [(set (match_dup 0) (match_dup 0))]
9826   "
9827 {
9828   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9829                                         gen_rtx_MEM (PSImode,
9830                                                  gen_rtx_POST_INC (Pmode,
9831                                                           operands[0]))));
9832   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9833 }")
9834
9835 (define_split
9836   [(set (reg:PSI FPSCR_REG)
9837         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9839   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9840   "
9841 {
9842   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9843                                         gen_rtx_MEM (PSImode,
9844                                                  gen_rtx_POST_INC (Pmode,
9845                                                           operands[0]))));
9846   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9847 }")
9848
9849 ;; ??? This uses the fp unit, but has no type indicating that.
9850 ;; If we did that, this would either give a bogus latency or introduce
9851 ;; a bogus FIFO constraint.
9852 ;; Since this insn is currently only used for prologues/epilogues,
9853 ;; it is probably best to claim no function unit, which matches the
9854 ;; current setting.
9855 (define_insn "toggle_sz"
9856   [(set (reg:PSI FPSCR_REG)
9857         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9858   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9859   "fschg"
9860   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9861
9862 ;; There's no way we can use it today, since optimize mode switching
9863 ;; doesn't enable us to know from which mode we're switching to the
9864 ;; mode it requests, to tell whether we can use a relative mode switch
9865 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9866 ;; memory).
9867 (define_insn "toggle_pr"
9868   [(set (reg:PSI FPSCR_REG)
9869         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9870   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9871   "fpchg"
9872   [(set_attr "type" "fp")])
9873
9874 (define_expand "addsf3"
9875   [(set (match_operand:SF 0 "arith_reg_operand" "")
9876         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9877                  (match_operand:SF 2 "arith_reg_operand" "")))]
9878   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9879   "
9880 {
9881   if (TARGET_SH2E)
9882     {
9883       expand_sf_binop (&gen_addsf3_i, operands);
9884       DONE;
9885     }
9886 }")
9887
9888 (define_insn "*addsf3_media"
9889   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9890         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9891                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9892   "TARGET_SHMEDIA_FPU"
9893   "fadd.s       %1, %2, %0"
9894   [(set_attr "type" "fparith_media")])
9895
9896 (define_insn_and_split "unary_sf_op"
9897   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9898         (vec_select:V2SF
9899          (vec_concat:V2SF
9900           (vec_select:SF
9901            (match_dup 0)
9902            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9903           (match_operator:SF 2 "unary_float_operator"
9904             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9905                             (parallel [(match_operand 4
9906                                         "const_int_operand" "n")]))]))
9907          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9908   "TARGET_SHMEDIA_FPU"
9909   "#"
9910   "TARGET_SHMEDIA_FPU && reload_completed"
9911   [(set (match_dup 5) (match_dup 6))]
9912   "
9913 {
9914   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9915   rtx op1 = gen_rtx_REG (SFmode,
9916                          (true_regnum (operands[1])
9917                           + (INTVAL (operands[4]) ^ endian)));
9918
9919   operands[7] = gen_rtx_REG (SFmode,
9920                              (true_regnum (operands[0])
9921                               + (INTVAL (operands[3]) ^ endian)));
9922   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9923 }"
9924   [(set_attr "type" "fparith_media")])
9925
9926 (define_insn_and_split "binary_sf_op"
9927   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9928         (vec_select:V2SF
9929          (vec_concat:V2SF
9930           (vec_select:SF
9931            (match_dup 0)
9932            (parallel [(match_operand 7 "const_int_operand" "n")]))
9933           (match_operator:SF 3 "binary_float_operator"
9934             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9935                             (parallel [(match_operand 5
9936                                         "const_int_operand" "n")]))
9937              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9938                             (parallel [(match_operand 6
9939                                         "const_int_operand" "n")]))]))
9940          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9941   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9942   "#"
9943   "&& reload_completed"
9944   [(set (match_dup 8) (match_dup 9))]
9945   "
9946 {
9947   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9948   rtx op1 = gen_rtx_REG (SFmode,
9949                          (true_regnum (operands[1])
9950                           + (INTVAL (operands[5]) ^ endian)));
9951   rtx op2 = gen_rtx_REG (SFmode,
9952                          (true_regnum (operands[2])
9953                           + (INTVAL (operands[6]) ^ endian)));
9954
9955   operands[8] = gen_rtx_REG (SFmode,
9956                              (true_regnum (operands[0])
9957                               + (INTVAL (operands[4]) ^ endian)));
9958   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9959 }"
9960   [(set_attr "type" "fparith_media")])
9961
9962 (define_insn "addsf3_i"
9963   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9964         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9965                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9966    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9967   "TARGET_SH2E"
9968   "fadd %2,%0"
9969   [(set_attr "type" "fp")
9970    (set_attr "fp_mode" "single")])
9971
9972 (define_expand "subsf3"
9973   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9974         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9975                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9976   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9977   "
9978 {
9979   if (TARGET_SH2E)
9980     {
9981       expand_sf_binop (&gen_subsf3_i, operands);
9982       DONE;
9983     }
9984 }")
9985
9986 (define_insn "*subsf3_media"
9987   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9988         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9989                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9990   "TARGET_SHMEDIA_FPU"
9991   "fsub.s       %1, %2, %0"
9992   [(set_attr "type" "fparith_media")])
9993
9994 (define_insn "subsf3_i"
9995   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9996         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9997                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9998    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9999   "TARGET_SH2E"
10000   "fsub %2,%0"
10001   [(set_attr "type" "fp")
10002    (set_attr "fp_mode" "single")])
10003
10004 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10005 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10006 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10007 ;; SH3E, we use a separate insn for SH3E mulsf3.
10008
10009 (define_expand "mulsf3"
10010   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10011         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10012                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10013   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10014   "
10015 {
10016   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10017     expand_sf_binop (&gen_mulsf3_i4, operands);
10018   else if (TARGET_SH2E)
10019     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10020   if (! TARGET_SHMEDIA)
10021     DONE;
10022 }")
10023
10024 (define_insn "*mulsf3_media"
10025   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10026         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10027                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10028   "TARGET_SHMEDIA_FPU"
10029   "fmul.s       %1, %2, %0"
10030   [(set_attr "type" "fparith_media")])
10031
10032 (define_insn "mulsf3_i4"
10033   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10034         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10035                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10036    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10037   "TARGET_SH2E"
10038   "fmul %2,%0"
10039   [(set_attr "type" "fp")
10040    (set_attr "fp_mode" "single")])
10041
10042 (define_insn "mulsf3_ie"
10043   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10044         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10045                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10046   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10047   "fmul %2,%0"
10048   [(set_attr "type" "fp")])
10049
10050 (define_insn "mac_media"
10051   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10052         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10053                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10054                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10055   "TARGET_SHMEDIA_FPU"
10056   "fmac.s %1, %2, %0"
10057   [(set_attr "type" "fparith_media")])
10058
10059 (define_insn "*macsf3"
10060   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10061         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10062                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10063                  (match_operand:SF 3 "arith_reg_operand" "0")))
10064    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10065   "TARGET_SH2E && ! TARGET_SH4"
10066   "fmac fr0,%2,%0"
10067   [(set_attr "type" "fp")
10068    (set_attr "fp_mode" "single")])
10069
10070 (define_expand "divsf3"
10071   [(set (match_operand:SF 0 "arith_reg_operand" "")
10072         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10073                 (match_operand:SF 2 "arith_reg_operand" "")))]
10074   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10075   "
10076 {
10077   if (TARGET_SH2E)
10078     {
10079       expand_sf_binop (&gen_divsf3_i, operands);
10080       DONE;
10081     }
10082 }")
10083
10084 (define_insn "*divsf3_media"
10085   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10086         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10087                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10088   "TARGET_SHMEDIA_FPU"
10089   "fdiv.s       %1, %2, %0"
10090   [(set_attr "type" "fdiv_media")])
10091
10092 (define_insn "divsf3_i"
10093   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10094         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10095                  (match_operand:SF 2 "arith_reg_operand" "f")))
10096    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10097   "TARGET_SH2E"
10098   "fdiv %2,%0"
10099   [(set_attr "type" "fdiv")
10100    (set_attr "fp_mode" "single")])
10101
10102 (define_insn "floatdisf2"
10103   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10104         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10105   "TARGET_SHMEDIA_FPU"
10106   "float.qs %1, %0"
10107   [(set_attr "type" "fpconv_media")])
10108
10109 (define_expand "floatsisf2"
10110   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10111         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10112   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10113   "
10114 {
10115   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10116     {
10117       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10118       DONE;
10119     }
10120 }")
10121
10122 (define_insn "*floatsisf2_media"
10123   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10124         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10125   "TARGET_SHMEDIA_FPU"
10126   "float.ls     %1, %0"
10127   [(set_attr "type" "fpconv_media")])
10128
10129 (define_insn "floatsisf2_i4"
10130   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10131         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10132    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10133   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10134   "float        %1,%0"
10135   [(set_attr "type" "fp")
10136    (set_attr "fp_mode" "single")])
10137
10138 (define_insn "*floatsisf2_ie"
10139   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10140         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10141   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10142   "float        %1,%0"
10143   [(set_attr "type" "fp")])
10144
10145 (define_insn "fix_truncsfdi2"
10146   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10147         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10148   "TARGET_SHMEDIA_FPU"
10149   "ftrc.sq %1, %0"
10150   [(set_attr "type" "fpconv_media")])
10151
10152 (define_expand "fix_truncsfsi2"
10153   [(set (match_operand:SI 0 "fpul_operand" "=y")
10154         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10155   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10156   "
10157 {
10158   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10159     {
10160       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10161       DONE;
10162     }
10163 }")
10164
10165 (define_insn "*fix_truncsfsi2_media"
10166   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10167         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10168   "TARGET_SHMEDIA_FPU"
10169   "ftrc.sl      %1, %0"
10170   [(set_attr "type" "fpconv_media")])
10171
10172 (define_insn "fix_truncsfsi2_i4"
10173   [(set (match_operand:SI 0 "fpul_operand" "=y")
10174         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10175    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10176   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10177   "ftrc %1,%0"
10178   [(set_attr "type" "ftrc_s")
10179    (set_attr "fp_mode" "single")])
10180
10181 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10182 ;; fix_truncsfsi2_i4.
10183 ;; (define_insn "fix_truncsfsi2_i4_2"
10184 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10185 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10186 ;;   (use (reg:PSI FPSCR_REG))
10187 ;;   (clobber (reg:SI FPUL_REG))]
10188 ;;  "TARGET_SH4"
10189 ;;  "#"
10190 ;;  [(set_attr "length" "4")
10191 ;;   (set_attr "fp_mode" "single")])
10192
10193 ;;(define_split
10194 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10195 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10196 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10197 ;;   (clobber (reg:SI FPUL_REG))]
10198 ;;  "TARGET_SH4"
10199 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10200 ;;            (use (match_dup 2))])
10201 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10202
10203 (define_insn "*fixsfsi"
10204   [(set (match_operand:SI 0 "fpul_operand" "=y")
10205         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10206   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10207   "ftrc %1,%0"
10208   [(set_attr "type" "fp")])
10209
10210 (define_insn "cmpgtsf_t"
10211   [(set (reg:SI T_REG)
10212         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10213                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10214   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10215   "fcmp/gt      %1,%0"
10216   [(set_attr "type" "fp")
10217    (set_attr "fp_mode" "single")])
10218
10219 (define_insn "cmpeqsf_t"
10220   [(set (reg:SI T_REG)
10221         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10222                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10223   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10224   "fcmp/eq      %1,%0"
10225   [(set_attr "type" "fp")
10226    (set_attr "fp_mode" "single")])
10227
10228 (define_insn "ieee_ccmpeqsf_t"
10229   [(set (reg:SI T_REG)
10230         (ior:SI (reg:SI T_REG)
10231                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10232                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10233   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10234   "* return output_ieee_ccmpeq (insn, operands);"
10235   [(set_attr "length" "4")])
10236
10237
10238 (define_insn "cmpgtsf_t_i4"
10239   [(set (reg:SI T_REG)
10240         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10241                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10242    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10243   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10244   "fcmp/gt      %1,%0"
10245   [(set_attr "type" "fp")
10246    (set_attr "fp_mode" "single")])
10247
10248 (define_insn "cmpeqsf_t_i4"
10249   [(set (reg:SI T_REG)
10250         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10251                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10252    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10253   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10254   "fcmp/eq      %1,%0"
10255   [(set_attr "type" "fp")
10256    (set_attr "fp_mode" "single")])
10257
10258 (define_insn "*ieee_ccmpeqsf_t_4"
10259   [(set (reg:SI T_REG)
10260         (ior:SI (reg:SI T_REG)
10261                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10262                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10263    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10264   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10265   "* return output_ieee_ccmpeq (insn, operands);"
10266   [(set_attr "length" "4")
10267    (set_attr "fp_mode" "single")])
10268
10269 (define_insn "cmpeqsf_media"
10270   [(set (match_operand:DI 0 "register_operand" "=r")
10271         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10272                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10273   "TARGET_SHMEDIA_FPU"
10274   "fcmpeq.s     %1, %2, %0"
10275   [(set_attr "type" "fcmp_media")])
10276
10277 (define_insn "cmpsieqsf_media"
10278   [(set (match_operand:SI 0 "register_operand" "=r")
10279         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10280                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10281   "TARGET_SHMEDIA_FPU"
10282   "fcmpeq.s     %1, %2, %0"
10283   [(set_attr "type" "fcmp_media")])
10284
10285 (define_insn "cmpgtsf_media"
10286   [(set (match_operand:DI 0 "register_operand" "=r")
10287         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10288                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10289   "TARGET_SHMEDIA_FPU"
10290   "fcmpgt.s     %1, %2, %0"
10291   [(set_attr "type" "fcmp_media")])
10292
10293 (define_insn "cmpgesf_media"
10294   [(set (match_operand:DI 0 "register_operand" "=r")
10295         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10296                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10297   "TARGET_SHMEDIA_FPU"
10298   "fcmpge.s     %1, %2, %0"
10299   [(set_attr "type" "fcmp_media")])
10300
10301 (define_insn "cmpunsf_media"
10302   [(set (match_operand:DI 0 "register_operand" "=r")
10303         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10304                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10305   "TARGET_SHMEDIA_FPU"
10306   "fcmpun.s     %1, %2, %0"
10307   [(set_attr "type" "fcmp_media")])
10308
10309 (define_expand "cmpsf"
10310   [(set (reg:SI T_REG)
10311         (compare (match_operand:SF 0 "arith_operand" "")
10312                  (match_operand:SF 1 "arith_operand" "")))]
10313   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10314   "
10315 {
10316   sh_compare_op0 = operands[0];
10317   sh_compare_op1 = operands[1];
10318   DONE;
10319 }")
10320
10321 (define_expand "negsf2"
10322   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10323         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10324   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10325   "
10326 {
10327   if (TARGET_SH2E)
10328     {
10329       expand_sf_unop (&gen_negsf2_i, operands);
10330       DONE;
10331     }
10332 }")
10333
10334 (define_insn "*negsf2_media"
10335   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10337   "TARGET_SHMEDIA_FPU"
10338   "fneg.s       %1, %0"
10339   [(set_attr "type" "fmove_media")])
10340
10341 (define_insn "negsf2_i"
10342   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10343         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10344    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10345   "TARGET_SH2E"
10346   "fneg %0"
10347   [(set_attr "type" "fmove")
10348    (set_attr "fp_mode" "single")])
10349
10350 (define_expand "sqrtsf2"
10351   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10352         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10353   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10354   "
10355 {
10356   if (TARGET_SH3E)
10357     {
10358       expand_sf_unop (&gen_sqrtsf2_i, operands);
10359       DONE;
10360     }
10361 }")
10362
10363 (define_insn "*sqrtsf2_media"
10364   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10365         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10366   "TARGET_SHMEDIA_FPU"
10367   "fsqrt.s      %1, %0"
10368   [(set_attr "type" "fdiv_media")])
10369
10370 (define_insn "sqrtsf2_i"
10371   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10372         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10373    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10374   "TARGET_SH3E"
10375   "fsqrt        %0"
10376   [(set_attr "type" "fdiv")
10377    (set_attr "fp_mode" "single")])
10378
10379 (define_insn "rsqrtsf2"
10380   [(set (match_operand:SF 0 "register_operand" "=f")
10381         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10382                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10383    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10384   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10385    && operands[1] == CONST1_RTX (SFmode)"
10386   "fsrra        %0"
10387   [(set_attr "type" "fsrra")
10388    (set_attr "fp_mode" "single")])
10389
10390 (define_insn "fsca"
10391   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10392         (vec_concat:V2SF
10393          (unspec:SF [(mult:SF
10394                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10395                       (match_operand:SF 2 "immediate_operand" "i"))
10396                     ] UNSPEC_FSINA)
10397          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10398                     ] UNSPEC_FCOSA)))
10399    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10400   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10401    && operands[2] == sh_fsca_int2sf ()"
10402   "fsca fpul,%d0"
10403   [(set_attr "type" "fsca")
10404    (set_attr "fp_mode" "single")])
10405
10406 (define_expand "sinsf2"
10407   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10408         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10409                    UNSPEC_FSINA))]
10410   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10411   "
10412 {
10413   rtx scaled = gen_reg_rtx (SFmode);
10414   rtx truncated = gen_reg_rtx (SImode);
10415   rtx fsca = gen_reg_rtx (V2SFmode);
10416   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10417
10418   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10419   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10420   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10421                           get_fpscr_rtx ()));
10422   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10423   DONE;
10424 }")
10425
10426 (define_expand "cossf2"
10427   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10428         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10429                    UNSPEC_FCOSA))]
10430   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10431   "
10432 {
10433   rtx scaled = gen_reg_rtx (SFmode);
10434   rtx truncated = gen_reg_rtx (SImode);
10435   rtx fsca = gen_reg_rtx (V2SFmode);
10436   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10437
10438   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10439   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10440   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10441                           get_fpscr_rtx ()));
10442   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10443   DONE;
10444 }")
10445
10446 (define_expand "sindf2"
10447   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10448         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10449                    UNSPEC_FSINA))]
10450   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10451   "
10452 {
10453   rtx scaled = gen_reg_rtx (DFmode);
10454   rtx truncated = gen_reg_rtx (SImode);
10455   rtx fsca = gen_reg_rtx (V2SFmode);
10456   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10457   rtx sfresult = gen_reg_rtx (SFmode);
10458
10459   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10460   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10461   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10462                           get_fpscr_rtx ()));
10463   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10464   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10465   DONE;
10466 }")
10467
10468 (define_expand "cosdf2"
10469   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10470         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10471                    UNSPEC_FCOSA))]
10472   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10473   "
10474 {
10475   rtx scaled = gen_reg_rtx (DFmode);
10476   rtx truncated = gen_reg_rtx (SImode);
10477   rtx fsca = gen_reg_rtx (V2SFmode);
10478   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10479   rtx sfresult = gen_reg_rtx (SFmode);
10480
10481   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10482   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10483   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10484                           get_fpscr_rtx ()));
10485   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10486   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10487   DONE;
10488 }")
10489
10490 (define_expand "abssf2"
10491   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10492         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10493   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10494   "
10495 {
10496   if (TARGET_SH2E)
10497     {
10498       expand_sf_unop (&gen_abssf2_i, operands);
10499       DONE;
10500     }
10501 }")
10502
10503 (define_insn "*abssf2_media"
10504   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10505         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10506   "TARGET_SHMEDIA_FPU"
10507   "fabs.s       %1, %0"
10508   [(set_attr "type" "fmove_media")])
10509
10510 (define_insn "abssf2_i"
10511   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10512         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10513    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10514   "TARGET_SH2E"
10515   "fabs %0"
10516   [(set_attr "type" "fmove")
10517    (set_attr "fp_mode" "single")])
10518
10519 (define_expand "adddf3"
10520   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10521         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10522                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10523   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10524   "
10525 {
10526   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10527     {
10528       expand_df_binop (&gen_adddf3_i, operands);
10529       DONE;
10530     }
10531 }")
10532
10533 (define_insn "*adddf3_media"
10534   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10535         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10536                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10537   "TARGET_SHMEDIA_FPU"
10538   "fadd.d       %1, %2, %0"
10539   [(set_attr "type" "dfparith_media")])
10540
10541 (define_insn "adddf3_i"
10542   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10543         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10544                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10545    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10546   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10547   "fadd %2,%0"
10548   [(set_attr "type" "dfp_arith")
10549    (set_attr "fp_mode" "double")])
10550
10551 (define_expand "subdf3"
10552   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10553         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10554                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10555   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10556   "
10557 {
10558   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10559     {
10560       expand_df_binop (&gen_subdf3_i, operands);
10561       DONE;
10562     }
10563 }")
10564
10565 (define_insn "*subdf3_media"
10566   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10567         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10568                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10569   "TARGET_SHMEDIA_FPU"
10570   "fsub.d       %1, %2, %0"
10571   [(set_attr "type" "dfparith_media")])
10572
10573 (define_insn "subdf3_i"
10574   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10576                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10577    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10578   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10579   "fsub %2,%0"
10580   [(set_attr "type" "dfp_arith")
10581    (set_attr "fp_mode" "double")])
10582
10583 (define_expand "muldf3"
10584   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10585         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10586                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10587   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10588   "
10589 {
10590   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10591     {
10592       expand_df_binop (&gen_muldf3_i, operands);
10593       DONE;
10594     }
10595 }")
10596
10597 (define_insn "*muldf3_media"
10598   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10599         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10600                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10601   "TARGET_SHMEDIA_FPU"
10602   "fmul.d       %1, %2, %0"
10603   [(set_attr "type" "dfmul_media")])
10604
10605 (define_insn "muldf3_i"
10606   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10607         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10608                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10609    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10610   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10611   "fmul %2,%0"
10612   [(set_attr "type" "dfp_arith")
10613    (set_attr "fp_mode" "double")])
10614
10615 (define_expand "divdf3"
10616   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10617         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10618                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10619   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10620   "
10621 {
10622   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10623     {
10624       expand_df_binop (&gen_divdf3_i, operands);
10625       DONE;
10626     }
10627 }")
10628
10629 (define_insn "*divdf3_media"
10630   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10632                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10633   "TARGET_SHMEDIA_FPU"
10634   "fdiv.d       %1, %2, %0"
10635   [(set_attr "type" "dfdiv_media")])
10636
10637 (define_insn "divdf3_i"
10638   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10639         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10640                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10641    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10642   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10643   "fdiv %2,%0"
10644   [(set_attr "type" "dfdiv")
10645    (set_attr "fp_mode" "double")])
10646
10647 (define_insn "floatdidf2"
10648   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10649         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10650   "TARGET_SHMEDIA_FPU"
10651   "float.qd     %1, %0"
10652   [(set_attr "type" "dfpconv_media")])
10653
10654 (define_expand "floatsidf2"
10655   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10656         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10657   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10658   "
10659 {
10660   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10661     {
10662       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10663                                       get_fpscr_rtx ()));
10664       DONE;
10665     }
10666 }")
10667
10668 (define_insn "*floatsidf2_media"
10669   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10670         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10671   "TARGET_SHMEDIA_FPU"
10672   "float.ld     %1, %0"
10673   [(set_attr "type" "dfpconv_media")])
10674
10675 (define_insn "floatsidf2_i"
10676   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10677         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10678    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10679   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10680   "float        %1,%0"
10681   [(set_attr "type" "dfp_conv")
10682    (set_attr "fp_mode" "double")])
10683
10684 (define_insn "fix_truncdfdi2"
10685   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10686         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10687   "TARGET_SHMEDIA_FPU"
10688   "ftrc.dq      %1, %0"
10689   [(set_attr "type" "dfpconv_media")])
10690
10691 (define_expand "fix_truncdfsi2"
10692   [(set (match_operand:SI 0 "fpul_operand" "")
10693         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10694   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10695   "
10696 {
10697   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10698     {
10699       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10700                                           get_fpscr_rtx ()));
10701       DONE;
10702     }
10703 }")
10704
10705 (define_insn "*fix_truncdfsi2_media"
10706   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10707         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10708   "TARGET_SHMEDIA_FPU"
10709   "ftrc.dl      %1, %0"
10710   [(set_attr "type" "dfpconv_media")])
10711
10712 (define_insn "fix_truncdfsi2_i"
10713   [(set (match_operand:SI 0 "fpul_operand" "=y")
10714         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10715    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10716   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10717   "ftrc %1,%0"
10718   [(set_attr "type" "dfp_conv")
10719    (set_attr "dfp_comp" "no")
10720    (set_attr "fp_mode" "double")])
10721
10722 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10723 ;; fix_truncdfsi2_i.
10724 ;; (define_insn "fix_truncdfsi2_i4"
10725 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10726 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10727 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10728 ;;    (clobber (reg:SI FPUL_REG))]
10729 ;;   "TARGET_SH4"
10730 ;;   "#"
10731 ;;   [(set_attr "length" "4")
10732 ;;    (set_attr "fp_mode" "double")])
10733 ;;
10734 ;; (define_split
10735 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10736 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10737 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10738 ;;    (clobber (reg:SI FPUL_REG))]
10739 ;;   "TARGET_SH4"
10740 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10741 ;;            (use (match_dup 2))])
10742 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10743
10744 (define_insn "cmpgtdf_t"
10745   [(set (reg:SI T_REG)
10746         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10747                (match_operand:DF 1 "arith_reg_operand" "f")))
10748    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10749   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10750   "fcmp/gt      %1,%0"
10751   [(set_attr "type" "dfp_cmp")
10752    (set_attr "fp_mode" "double")])
10753
10754 (define_insn "cmpeqdf_t"
10755   [(set (reg:SI T_REG)
10756         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10757                (match_operand:DF 1 "arith_reg_operand" "f")))
10758    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10759   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10760   "fcmp/eq      %1,%0"
10761   [(set_attr "type" "dfp_cmp")
10762    (set_attr "fp_mode" "double")])
10763
10764 (define_insn "*ieee_ccmpeqdf_t"
10765   [(set (reg:SI T_REG)
10766         (ior:SI (reg:SI T_REG)
10767                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10768                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10769    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10770   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10771   "* return output_ieee_ccmpeq (insn, operands);"
10772   [(set_attr "length" "4")
10773    (set_attr "fp_mode" "double")])
10774
10775 (define_insn "cmpeqdf_media"
10776   [(set (match_operand:DI 0 "register_operand" "=r")
10777         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10778                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10779   "TARGET_SHMEDIA_FPU"
10780   "fcmpeq.d     %1,%2,%0"
10781   [(set_attr "type" "fcmp_media")])
10782
10783 (define_insn "cmpsieqdf_media"
10784   [(set (match_operand:SI 0 "register_operand" "=r")
10785         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10786                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10787   "TARGET_SHMEDIA_FPU"
10788   "fcmpeq.d     %1,%2,%0"
10789   [(set_attr "type" "fcmp_media")])
10790
10791 (define_insn "cmpgtdf_media"
10792   [(set (match_operand:DI 0 "register_operand" "=r")
10793         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10794                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10795   "TARGET_SHMEDIA_FPU"
10796   "fcmpgt.d     %1,%2,%0"
10797   [(set_attr "type" "fcmp_media")])
10798
10799 (define_insn "cmpgedf_media"
10800   [(set (match_operand:DI 0 "register_operand" "=r")
10801         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10802                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10803   "TARGET_SHMEDIA_FPU"
10804   "fcmpge.d     %1,%2,%0"
10805   [(set_attr "type" "fcmp_media")])
10806
10807 (define_insn "cmpundf_media"
10808   [(set (match_operand:DI 0 "register_operand" "=r")
10809         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10810                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10811   "TARGET_SHMEDIA_FPU"
10812   "fcmpun.d     %1,%2,%0"
10813   [(set_attr "type" "fcmp_media")])
10814
10815 (define_expand "cmpdf"
10816   [(set (reg:SI T_REG)
10817         (compare (match_operand:DF 0 "arith_operand" "")
10818                  (match_operand:DF 1 "arith_operand" "")))]
10819   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10820   "
10821 {
10822   sh_compare_op0 = operands[0];
10823   sh_compare_op1 = operands[1];
10824   DONE;
10825 }")
10826
10827 (define_expand "negdf2"
10828   [(set (match_operand:DF 0 "arith_reg_operand" "")
10829         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10830   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10831   "
10832 {
10833   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10834     {
10835       expand_df_unop (&gen_negdf2_i, operands);
10836       DONE;
10837     }
10838 }")
10839
10840 (define_insn "*negdf2_media"
10841   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10843   "TARGET_SHMEDIA_FPU"
10844   "fneg.d       %1, %0"
10845   [(set_attr "type" "fmove_media")])
10846
10847 (define_insn "negdf2_i"
10848   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10849         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10850    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10851   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10852   "fneg %0"
10853   [(set_attr "type" "fmove")
10854    (set_attr "fp_mode" "double")])
10855
10856 (define_expand "sqrtdf2"
10857   [(set (match_operand:DF 0 "arith_reg_operand" "")
10858         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10860   "
10861 {
10862   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10863     {
10864       expand_df_unop (&gen_sqrtdf2_i, operands);
10865       DONE;
10866     }
10867 }")
10868
10869 (define_insn "*sqrtdf2_media"
10870   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10871         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872   "TARGET_SHMEDIA_FPU"
10873   "fsqrt.d      %1, %0"
10874   [(set_attr "type" "dfdiv_media")])
10875
10876 (define_insn "sqrtdf2_i"
10877   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10878         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10879    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881   "fsqrt        %0"
10882   [(set_attr "type" "dfdiv")
10883    (set_attr "fp_mode" "double")])
10884
10885 (define_expand "absdf2"
10886   [(set (match_operand:DF 0 "arith_reg_operand" "")
10887         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10888   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10889   "
10890 {
10891   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10892     {
10893       expand_df_unop (&gen_absdf2_i, operands);
10894       DONE;
10895     }
10896 }")
10897
10898 (define_insn "*absdf2_media"
10899   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10900         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10901   "TARGET_SHMEDIA_FPU"
10902   "fabs.d       %1, %0"
10903   [(set_attr "type" "fmove_media")])
10904
10905 (define_insn "absdf2_i"
10906   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10907         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10908    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10909   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10910   "fabs %0"
10911   [(set_attr "type" "fmove")
10912    (set_attr "fp_mode" "double")])
10913
10914 (define_expand "extendsfdf2"
10915   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10916         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10917   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10918   "
10919 {
10920   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10921     {
10922       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10923                                         get_fpscr_rtx ()));
10924       DONE;
10925     }
10926 }")
10927
10928 (define_insn "*extendsfdf2_media"
10929   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10930         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10931   "TARGET_SHMEDIA_FPU"
10932   "fcnv.sd      %1, %0"
10933   [(set_attr "type" "dfpconv_media")])
10934
10935 (define_insn "extendsfdf2_i4"
10936   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10937         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10938    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10939   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10940   "fcnvsd  %1,%0"
10941   [(set_attr "type" "fp")
10942    (set_attr "fp_mode" "double")])
10943
10944 (define_expand "truncdfsf2"
10945   [(set (match_operand:SF 0 "fpul_operand" "")
10946         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10947   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10948   "
10949 {
10950   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10951     {
10952       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10953                                        get_fpscr_rtx ()));
10954       DONE;
10955     }
10956 }")
10957
10958 (define_insn "*truncdfsf2_media"
10959   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10960         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10961   "TARGET_SHMEDIA_FPU"
10962   "fcnv.ds      %1, %0"
10963   [(set_attr "type" "dfpconv_media")])
10964
10965 (define_insn "truncdfsf2_i4"
10966   [(set (match_operand:SF 0 "fpul_operand" "=y")
10967         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10968    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10969   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10970   "fcnvds  %1,%0"
10971   [(set_attr "type" "fp")
10972    (set_attr "fp_mode" "double")])
10973 \f
10974 ;; Bit field extract patterns.  These give better code for packed bitfields,
10975 ;; because they allow auto-increment addresses to be generated.
10976
10977 (define_expand "insv"
10978   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10979                          (match_operand:SI 1 "immediate_operand" "")
10980                          (match_operand:SI 2 "immediate_operand" ""))
10981         (match_operand:SI 3 "general_operand" ""))]
10982   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10983   "
10984 {
10985   rtx addr_target, orig_address, shift_reg, qi_val;
10986   HOST_WIDE_INT bitsize, size, v = 0;
10987   rtx x = operands[3];
10988
10989   /* ??? expmed doesn't care for non-register predicates.  */
10990   if (! memory_operand (operands[0], VOIDmode)
10991       || ! immediate_operand (operands[1], VOIDmode)
10992       || ! immediate_operand (operands[2], VOIDmode)
10993       || ! general_operand (x, VOIDmode))
10994     FAIL;
10995   /* If this isn't a 16 / 24 / 32 bit field, or if
10996      it doesn't start on a byte boundary, then fail.  */
10997   bitsize = INTVAL (operands[1]);
10998   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10999       || (INTVAL (operands[2]) % 8) != 0)
11000     FAIL;
11001
11002   size = bitsize / 8;
11003   orig_address = XEXP (operands[0], 0);
11004   shift_reg = gen_reg_rtx (SImode);
11005   if (GET_CODE (x) == CONST_INT)
11006     {
11007       v = INTVAL (x);
11008       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11009     }
11010   else
11011     {
11012       emit_insn (gen_movsi (shift_reg, operands[3]));
11013       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11014     }
11015   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11016
11017   operands[0] = replace_equiv_address (operands[0], addr_target);
11018   emit_insn (gen_movqi (operands[0], qi_val));
11019
11020   while (size -= 1)
11021     {
11022       if (GET_CODE (x) == CONST_INT)
11023         qi_val
11024           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11025       else
11026         {
11027           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11028           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11029         }
11030       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11031       emit_insn (gen_movqi (operands[0], qi_val));
11032     }
11033
11034   DONE;
11035 }")
11036
11037 (define_insn "movua"
11038   [(set (match_operand:SI 0 "register_operand" "=z")
11039         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11040                          (const_int 32) (const_int 0)))]
11041   "TARGET_SH4A_ARCH"
11042   "movua.l      %1,%0"
11043   [(set_attr "type" "movua")])
11044
11045 ;; We shouldn't need this, but cse replaces increments with references
11046 ;; to other regs before flow has a chance to create post_inc
11047 ;; addressing modes, and only postreload's cse_move2add brings the
11048 ;; increments back to a usable form.
11049 (define_peephole2
11050   [(set (match_operand:SI 0 "register_operand" "")
11051         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11052                          (const_int 32) (const_int 0)))
11053    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11054   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11055   [(set (match_operand:SI 0 "register_operand" "")
11056         (sign_extract:SI (mem:SI (post_inc:SI
11057                                   (match_operand:SI 1 "register_operand" "")))
11058                          (const_int 32) (const_int 0)))]
11059   "")
11060
11061 (define_expand "extv"
11062   [(set (match_operand:SI 0 "register_operand" "")
11063         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11064                          (match_operand 2 "const_int_operand" "")
11065                          (match_operand 3 "const_int_operand" "")))]
11066   "TARGET_SH4A_ARCH"
11067 {
11068   if (TARGET_SH4A_ARCH
11069       && INTVAL (operands[2]) == 32
11070       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11071       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11072     {
11073       emit_insn (gen_movua (operands[0],
11074                             adjust_address (operands[1], SImode, 0)));
11075       DONE;
11076     }
11077
11078   FAIL;
11079 })
11080
11081 (define_expand "extzv"
11082   [(set (match_operand:SI 0 "register_operand" "")
11083         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11084                          (match_operand 2 "const_int_operand" "")
11085                          (match_operand 3 "const_int_operand" "")))]
11086   "TARGET_SH4A_ARCH"
11087 {
11088   if (TARGET_SH4A_ARCH
11089       && INTVAL (operands[2]) == 32
11090       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11091       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11092     {
11093       emit_insn (gen_movua (operands[0],
11094                             adjust_address (operands[1], SImode, 0)));
11095       DONE;
11096     }
11097
11098   FAIL;
11099 })
11100
11101 \f
11102 ;; -------------------------------------------------------------------------
11103 ;; Peepholes
11104 ;; -------------------------------------------------------------------------
11105
11106 ;; This matches cases where a stack pointer increment at the start of the
11107 ;; epilogue combines with a stack slot read loading the return value.
11108
11109 (define_peephole
11110   [(set (match_operand:SI 0 "arith_reg_operand" "")
11111         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11112    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11113   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11114   "mov.l        @%1+,%0")
11115
11116 ;; See the comment on the dt combiner pattern above.
11117
11118 (define_peephole
11119   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11120         (plus:SI (match_dup 0)
11121                  (const_int -1)))
11122    (set (reg:SI T_REG)
11123         (eq:SI (match_dup 0)
11124                (const_int 0)))]
11125   "TARGET_SH2"
11126   "dt   %0")
11127
11128 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11129 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11130 ;; reload when the constant is too large for a reg+offset address.
11131
11132 ;; ??? We would get much better code if this was done in reload.  This would
11133 ;; require modifying find_reloads_address to recognize that if the constant
11134 ;; is out-of-range for an immediate add, then we get better code by reloading
11135 ;; the constant into a register than by reloading the sum into a register,
11136 ;; since the former is one instruction shorter if the address does not need
11137 ;; to be offsettable.  Unfortunately this does not work, because there is
11138 ;; only one register, r0, that can be used as an index register.  This register
11139 ;; is also the function return value register.  So, if we try to force reload
11140 ;; to use double-reg addresses, then we end up with some instructions that
11141 ;; need to use r0 twice.  The only way to fix this is to change the calling
11142 ;; convention so that r0 is not used to return values.
11143
11144 (define_peephole
11145   [(set (match_operand:SI 0 "register_operand" "=r")
11146         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11147    (set (mem:SI (match_dup 0))
11148         (match_operand:SI 2 "general_movsrc_operand" ""))]
11149   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11150   "mov.l        %2,@(%0,%1)")
11151
11152 (define_peephole
11153   [(set (match_operand:SI 0 "register_operand" "=r")
11154         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11155    (set (match_operand:SI 2 "general_movdst_operand" "")
11156         (mem:SI (match_dup 0)))]
11157   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11158   "mov.l        @(%0,%1),%2")
11159
11160 (define_peephole
11161   [(set (match_operand:SI 0 "register_operand" "=r")
11162         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11163    (set (mem:HI (match_dup 0))
11164         (match_operand:HI 2 "general_movsrc_operand" ""))]
11165   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11166   "mov.w        %2,@(%0,%1)")
11167
11168 (define_peephole
11169   [(set (match_operand:SI 0 "register_operand" "=r")
11170         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11171    (set (match_operand:HI 2 "general_movdst_operand" "")
11172         (mem:HI (match_dup 0)))]
11173   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11174   "mov.w        @(%0,%1),%2")
11175
11176 (define_peephole
11177   [(set (match_operand:SI 0 "register_operand" "=r")
11178         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11179    (set (mem:QI (match_dup 0))
11180         (match_operand:QI 2 "general_movsrc_operand" ""))]
11181   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11182   "mov.b        %2,@(%0,%1)")
11183
11184 (define_peephole
11185   [(set (match_operand:SI 0 "register_operand" "=r")
11186         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11187    (set (match_operand:QI 2 "general_movdst_operand" "")
11188         (mem:QI (match_dup 0)))]
11189   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11190   "mov.b        @(%0,%1),%2")
11191
11192 (define_peephole
11193   [(set (match_operand:SI 0 "register_operand" "=r")
11194         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11195    (set (mem:SF (match_dup 0))
11196         (match_operand:SF 2 "general_movsrc_operand" ""))]
11197   "TARGET_SH1 && REGNO (operands[0]) == 0
11198    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11199        || (GET_CODE (operands[2]) == SUBREG
11200            && REGNO (SUBREG_REG (operands[2])) < 16))
11201    && reg_unused_after (operands[0], insn)"
11202   "mov.l        %2,@(%0,%1)")
11203
11204 (define_peephole
11205   [(set (match_operand:SI 0 "register_operand" "=r")
11206         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11207    (set (match_operand:SF 2 "general_movdst_operand" "")
11208
11209         (mem:SF (match_dup 0)))]
11210   "TARGET_SH1 && REGNO (operands[0]) == 0
11211    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11212        || (GET_CODE (operands[2]) == SUBREG
11213            && REGNO (SUBREG_REG (operands[2])) < 16))
11214    && reg_unused_after (operands[0], insn)"
11215   "mov.l        @(%0,%1),%2")
11216
11217 (define_peephole
11218   [(set (match_operand:SI 0 "register_operand" "=r")
11219         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11220    (set (mem:SF (match_dup 0))
11221         (match_operand:SF 2 "general_movsrc_operand" ""))]
11222   "TARGET_SH2E && REGNO (operands[0]) == 0
11223    && ((GET_CODE (operands[2]) == REG
11224         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11225        || (GET_CODE (operands[2]) == SUBREG
11226            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11227    && reg_unused_after (operands[0], insn)"
11228   "fmov{.s|}    %2,@(%0,%1)")
11229
11230 (define_peephole
11231   [(set (match_operand:SI 0 "register_operand" "=r")
11232         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11233    (set (match_operand:SF 2 "general_movdst_operand" "")
11234
11235         (mem:SF (match_dup 0)))]
11236   "TARGET_SH2E && REGNO (operands[0]) == 0
11237    && ((GET_CODE (operands[2]) == REG
11238         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11239        || (GET_CODE (operands[2]) == SUBREG
11240            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11241    && reg_unused_after (operands[0], insn)"
11242   "fmov{.s|}    @(%0,%1),%2")
11243
11244 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11245 (define_insn "sp_switch_1"
11246   [(const_int 1)]
11247   "TARGET_SH1"
11248   "*
11249 {
11250   rtx xoperands[1];
11251
11252   xoperands[0] = sp_switch;
11253   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11254   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11255   return \"mov r0,r15\";
11256 }"
11257   [(set_attr "length" "10")])
11258
11259 ;; Switch back to the original stack for interrupt functions with the
11260 ;; sp_switch attribute.  */
11261 (define_insn "sp_switch_2"
11262   [(const_int 2)]
11263   "TARGET_SH1"
11264   "mov.l @r15+,r15\;mov.l @r15+,r0"
11265   [(set_attr "length" "4")])
11266
11267 ;; Integer vector moves
11268
11269 (define_expand "movv8qi"
11270   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11271         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11272   "TARGET_SHMEDIA"
11273   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11274
11275 (define_insn "movv8qi_i"
11276   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11277         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11278   "TARGET_SHMEDIA
11279    && (register_operand (operands[0], V8QImode)
11280        || sh_register_operand (operands[1], V8QImode))"
11281   "@
11282         add     %1, r63, %0
11283         movi    %1, %0
11284         #
11285         ld%M1.q %m1, %0
11286         st%M0.q %m0, %N1"
11287   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11288    (set_attr "length" "4,4,16,4,4")])
11289
11290 (define_split
11291   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11292         (subreg:V8QI (const_int 0) 0))]
11293   "TARGET_SHMEDIA"
11294   [(set (match_dup 0)
11295         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11296                             (const_int 0) (const_int 0) (const_int 0)
11297                             (const_int 0) (const_int 0)]))])
11298
11299 (define_split
11300   [(set (match_operand 0 "arith_reg_dest" "")
11301         (match_operand 1 "sh_rep_vec" ""))]
11302   "TARGET_SHMEDIA && reload_completed
11303    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11304    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11305    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11306    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11307        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11308    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11309        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11310   [(set (match_dup 0) (match_dup 1))
11311    (match_dup 2)]
11312   "
11313 {
11314   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11315   rtx elt1 = XVECEXP (operands[1], 0, 1);
11316
11317   if (unit_size > 2)
11318     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11319   else
11320     {
11321       if (unit_size < 2)
11322         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11323       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11324     }
11325   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11326   operands[1] = XVECEXP (operands[1], 0, 0);
11327   if (unit_size < 2)
11328     {
11329       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11330         operands[1]
11331           = GEN_INT (TARGET_LITTLE_ENDIAN
11332                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11333                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11334       else
11335         {
11336           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11337           operands[1]
11338             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11339         }
11340     }
11341 }")
11342
11343 (define_split
11344   [(set (match_operand 0 "arith_reg_dest" "")
11345         (match_operand 1 "sh_const_vec" ""))]
11346   "TARGET_SHMEDIA && reload_completed
11347    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11348    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11349   [(set (match_dup 0) (match_dup 1))]
11350   "
11351 {
11352   rtx v = operands[1];
11353   enum machine_mode new_mode
11354     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11355
11356   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11357   operands[1]
11358     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11359 }")
11360
11361 (define_expand "movv2hi"
11362   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11363         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11364   "TARGET_SHMEDIA"
11365   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11366
11367 (define_insn "movv2hi_i"
11368   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11369         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11370   "TARGET_SHMEDIA
11371    && (register_operand (operands[0], V2HImode)
11372        || sh_register_operand (operands[1], V2HImode))"
11373   "@
11374         add.l   %1, r63, %0
11375         movi    %1, %0
11376         #
11377         ld%M1.l %m1, %0
11378         st%M0.l %m0, %N1"
11379   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11380    (set_attr "length" "4,4,16,4,4")
11381    (set (attr "highpart")
11382         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11383                (const_string "user")]
11384               (const_string "ignore")))])
11385
11386 (define_expand "movv4hi"
11387   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11388         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11389   "TARGET_SHMEDIA"
11390   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11391
11392 (define_insn "movv4hi_i"
11393   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11394         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11395   "TARGET_SHMEDIA
11396    && (register_operand (operands[0], V4HImode)
11397        || sh_register_operand (operands[1], V4HImode))"
11398   "@
11399         add     %1, r63, %0
11400         movi    %1, %0
11401         #
11402         ld%M1.q %m1, %0
11403         st%M0.q %m0, %N1"
11404   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11405    (set_attr "length" "4,4,16,4,4")
11406    (set_attr "highpart" "depend")])
11407
11408 (define_expand "movv2si"
11409   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11410         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11411   "TARGET_SHMEDIA"
11412   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11413
11414 (define_insn "movv2si_i"
11415   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11416         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11417   "TARGET_SHMEDIA
11418    && (register_operand (operands[0], V2SImode)
11419        || sh_register_operand (operands[1], V2SImode))"
11420   "@
11421         add     %1, r63, %0
11422         #
11423         #
11424         ld%M1.q %m1, %0
11425         st%M0.q %m0, %N1"
11426   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11427    (set_attr "length" "4,4,16,4,4")
11428    (set_attr "highpart" "depend")])
11429
11430 ;; Multimedia Intrinsics
11431
11432 (define_insn "absv2si2"
11433   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11434         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11435   "TARGET_SHMEDIA"
11436   "mabs.l       %1, %0"
11437   [(set_attr "type" "mcmp_media")
11438    (set_attr "highpart" "depend")])
11439
11440 (define_insn "absv4hi2"
11441   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11442         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11443   "TARGET_SHMEDIA"
11444   "mabs.w       %1, %0"
11445   [(set_attr "type" "mcmp_media")
11446    (set_attr "highpart" "depend")])
11447
11448 (define_insn "addv2si3"
11449   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11450         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11451                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11452   "TARGET_SHMEDIA"
11453   "madd.l       %1, %2, %0"
11454   [(set_attr "type" "arith_media")
11455    (set_attr "highpart" "depend")])
11456
11457 (define_insn "addv4hi3"
11458   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11459         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11460                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11461   "TARGET_SHMEDIA"
11462   "madd.w       %1, %2, %0"
11463   [(set_attr "type" "arith_media")
11464    (set_attr "highpart" "depend")])
11465
11466 (define_insn_and_split "addv2hi3"
11467   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11468         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11469                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11470   "TARGET_SHMEDIA"
11471   "#"
11472   "TARGET_SHMEDIA"
11473   [(const_int 0)]
11474   "
11475 {
11476   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11477   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11478   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11479   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11480   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11481
11482   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11483   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11484   DONE;
11485 }"
11486   [(set_attr "highpart" "must_split")])
11487
11488 (define_insn "ssaddv2si3"
11489   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11490         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11491                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11492   "TARGET_SHMEDIA"
11493   "madds.l      %1, %2, %0"
11494   [(set_attr "type" "mcmp_media")
11495    (set_attr "highpart" "depend")])
11496
11497 (define_insn "usaddv8qi3"
11498   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11499         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11500                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11501   "TARGET_SHMEDIA"
11502   "madds.ub     %1, %2, %0"
11503   [(set_attr "type" "mcmp_media")
11504    (set_attr "highpart" "depend")])
11505
11506 (define_insn "ssaddv4hi3"
11507   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11508         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11509                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11510   "TARGET_SHMEDIA"
11511   "madds.w      %1, %2, %0"
11512   [(set_attr "type" "mcmp_media")
11513    (set_attr "highpart" "depend")])
11514
11515 (define_insn "negcmpeqv8qi"
11516   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11517         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11518                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11519   "TARGET_SHMEDIA"
11520   "mcmpeq.b     %N1, %N2, %0"
11521   [(set_attr "type" "mcmp_media")
11522    (set_attr "highpart" "depend")])
11523
11524 (define_insn "negcmpeqv2si"
11525   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11526         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11527                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11528   "TARGET_SHMEDIA"
11529   "mcmpeq.l     %N1, %N2, %0"
11530   [(set_attr "type" "mcmp_media")
11531    (set_attr "highpart" "depend")])
11532
11533 (define_insn "negcmpeqv4hi"
11534   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11535         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11536                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11537   "TARGET_SHMEDIA"
11538   "mcmpeq.w     %N1, %N2, %0"
11539   [(set_attr "type" "mcmp_media")
11540    (set_attr "highpart" "depend")])
11541
11542 (define_insn "negcmpgtuv8qi"
11543   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11544         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11545                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11546   "TARGET_SHMEDIA"
11547   "mcmpgt.ub    %N1, %N2, %0"
11548   [(set_attr "type" "mcmp_media")
11549    (set_attr "highpart" "depend")])
11550
11551 (define_insn "negcmpgtv2si"
11552   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11553         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11554                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11555   "TARGET_SHMEDIA"
11556   "mcmpgt.l     %N1, %N2, %0"
11557   [(set_attr "type" "mcmp_media")
11558    (set_attr "highpart" "depend")])
11559
11560 (define_insn "negcmpgtv4hi"
11561   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11562         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11563                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11564   "TARGET_SHMEDIA"
11565   "mcmpgt.w     %N1, %N2, %0"
11566   [(set_attr "type" "mcmp_media")
11567    (set_attr "highpart" "depend")])
11568
11569 (define_insn "mcmv"
11570   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11571         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11572                         (match_operand:DI 2 "arith_reg_operand" "r"))
11573                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11574                         (not:DI (match_dup 2)))))]
11575   "TARGET_SHMEDIA"
11576   "mcmv %N1, %2, %0"
11577   [(set_attr "type" "arith_media")
11578    (set_attr "highpart" "depend")])
11579
11580 (define_insn "mcnvs_lw"
11581   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11582         (vec_concat:V4HI
11583          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11584          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11585   "TARGET_SHMEDIA"
11586   "mcnvs.lw     %N1, %N2, %0"
11587   [(set_attr "type" "mcmp_media")])
11588
11589 (define_insn "mcnvs_wb"
11590   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11591         (vec_concat:V8QI
11592          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11593          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11594   "TARGET_SHMEDIA"
11595   "mcnvs.wb     %N1, %N2, %0"
11596   [(set_attr "type" "mcmp_media")])
11597
11598 (define_insn "mcnvs_wub"
11599   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11600         (vec_concat:V8QI
11601          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11602          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11603   "TARGET_SHMEDIA"
11604   "mcnvs.wub    %N1, %N2, %0"
11605   [(set_attr "type" "mcmp_media")])
11606
11607 (define_insn "mextr_rl"
11608   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11609         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11610                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11611                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11612                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11613   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11614   "*
11615 {
11616   static char templ[21];
11617
11618   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11619            (int) INTVAL (operands[3]) >> 3);
11620   return templ;
11621 }"
11622   [(set_attr "type" "arith_media")])
11623
11624 (define_insn "*mextr_lr"
11625   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11626         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11627                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11628                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11629                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11630   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11631   "*
11632 {
11633   static char templ[21];
11634
11635   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11636            (int) INTVAL (operands[4]) >> 3);
11637   return templ;
11638 }"
11639   [(set_attr "type" "arith_media")])
11640
11641 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11642 ; vector then varies depending on endianness.
11643 (define_expand "mextr1"
11644   [(match_operand:DI 0 "arith_reg_dest" "")
11645    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11646    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11647   "TARGET_SHMEDIA"
11648   "
11649 {
11650   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11651                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11652   DONE;
11653 }")
11654
11655 (define_expand "mextr2"
11656   [(match_operand:DI 0 "arith_reg_dest" "")
11657    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11658    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11659   "TARGET_SHMEDIA"
11660   "
11661 {
11662   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11663                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11664   DONE;
11665 }")
11666
11667 (define_expand "mextr3"
11668   [(match_operand:DI 0 "arith_reg_dest" "")
11669    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11670    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11671   "TARGET_SHMEDIA"
11672   "
11673 {
11674   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11675                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11676   DONE;
11677 }")
11678
11679 (define_expand "mextr4"
11680   [(match_operand:DI 0 "arith_reg_dest" "")
11681    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11682    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11683   "TARGET_SHMEDIA"
11684   "
11685 {
11686   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11687                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11688   DONE;
11689 }")
11690
11691 (define_expand "mextr5"
11692   [(match_operand:DI 0 "arith_reg_dest" "")
11693    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11694    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11695   "TARGET_SHMEDIA"
11696   "
11697 {
11698   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11699                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11700   DONE;
11701 }")
11702
11703 (define_expand "mextr6"
11704   [(match_operand:DI 0 "arith_reg_dest" "")
11705    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11706    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11707   "TARGET_SHMEDIA"
11708   "
11709 {
11710   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11711                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11712   DONE;
11713 }")
11714
11715 (define_expand "mextr7"
11716   [(match_operand:DI 0 "arith_reg_dest" "")
11717    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11719   "TARGET_SHMEDIA"
11720   "
11721 {
11722   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11723                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11724   DONE;
11725 }")
11726
11727 (define_expand "mmacfx_wl"
11728   [(match_operand:V2SI 0 "arith_reg_dest" "")
11729    (match_operand:V2HI 1 "extend_reg_operand" "")
11730    (match_operand:V2HI 2 "extend_reg_operand" "")
11731    (match_operand:V2SI 3 "arith_reg_operand" "")]
11732   "TARGET_SHMEDIA"
11733   "
11734 {
11735   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11736                               operands[1], operands[2]));
11737   DONE;
11738 }")
11739
11740 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11741 ;; is depend
11742 (define_insn "mmacfx_wl_i"
11743   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11744         (ss_plus:V2SI
11745          (match_operand:V2SI 1 "arith_reg_operand" "0")
11746          (ss_truncate:V2SI
11747           (ashift:V2DI
11748            (sign_extend:V2DI
11749             (mult:V2SI
11750              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11751              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11752            (const_int 1)))))]
11753   "TARGET_SHMEDIA"
11754   "mmacfx.wl    %2, %3, %0"
11755   [(set_attr "type" "mac_media")
11756    (set_attr "highpart" "depend")])
11757
11758 (define_expand "mmacnfx_wl"
11759   [(match_operand:V2SI 0 "arith_reg_dest" "")
11760    (match_operand:V2HI 1 "extend_reg_operand" "")
11761    (match_operand:V2HI 2 "extend_reg_operand" "")
11762    (match_operand:V2SI 3 "arith_reg_operand" "")]
11763   "TARGET_SHMEDIA"
11764   "
11765 {
11766   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11767                                operands[1], operands[2]));
11768   DONE;
11769 }")
11770
11771 (define_insn "mmacnfx_wl_i"
11772   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11773         (ss_minus:V2SI
11774          (match_operand:V2SI 1 "arith_reg_operand" "0")
11775          (ss_truncate:V2SI
11776           (ashift:V2DI
11777            (sign_extend:V2DI
11778             (mult:V2SI
11779              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11780              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11781            (const_int 1)))))]
11782   "TARGET_SHMEDIA"
11783   "mmacnfx.wl   %2, %3, %0"
11784   [(set_attr "type" "mac_media")
11785    (set_attr "highpart" "depend")])
11786
11787 (define_insn "mulv2si3"
11788   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11789         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11790                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11791   "TARGET_SHMEDIA"
11792   "mmul.l       %1, %2, %0"
11793   [(set_attr "type" "d2mpy_media")
11794    (set_attr "highpart" "depend")])
11795
11796 (define_insn "mulv4hi3"
11797   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11798         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11799                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11800   "TARGET_SHMEDIA"
11801   "mmul.w       %1, %2, %0"
11802   [(set_attr "type" "dmpy_media")
11803    (set_attr "highpart" "depend")])
11804
11805 (define_insn "mmulfx_l"
11806   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11807         (ss_truncate:V2SI
11808          (ashiftrt:V2DI
11809           (mult:V2DI
11810            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11811            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11812           (const_int 31))))]
11813   "TARGET_SHMEDIA"
11814   "mmulfx.l     %1, %2, %0"
11815   [(set_attr "type" "d2mpy_media")
11816    (set_attr "highpart" "depend")])
11817
11818 (define_insn "mmulfx_w"
11819   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11820         (ss_truncate:V4HI
11821          (ashiftrt:V4SI
11822           (mult:V4SI
11823            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11824            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11825           (const_int 15))))]
11826   "TARGET_SHMEDIA"
11827   "mmulfx.w     %1, %2, %0"
11828   [(set_attr "type" "dmpy_media")
11829    (set_attr "highpart" "depend")])
11830
11831 (define_insn "mmulfxrp_w"
11832   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11833         (ss_truncate:V4HI
11834          (ashiftrt:V4SI
11835           (plus:V4SI
11836            (mult:V4SI
11837             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11838             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11839            (const_int 16384))
11840           (const_int 15))))]
11841   "TARGET_SHMEDIA"
11842   "mmulfxrp.w   %1, %2, %0"
11843   [(set_attr "type" "dmpy_media")
11844    (set_attr "highpart" "depend")])
11845
11846
11847 (define_expand "mmulhi_wl"
11848   [(match_operand:V2SI 0 "arith_reg_dest" "")
11849    (match_operand:V4HI 1 "arith_reg_operand" "")
11850    (match_operand:V4HI 2 "arith_reg_operand" "")]
11851   "TARGET_SHMEDIA"
11852   "
11853 {
11854   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11855              (operands[0], operands[1], operands[2]));
11856   DONE;
11857 }")
11858
11859 (define_expand "mmullo_wl"
11860   [(match_operand:V2SI 0 "arith_reg_dest" "")
11861    (match_operand:V4HI 1 "arith_reg_operand" "")
11862    (match_operand:V4HI 2 "arith_reg_operand" "")]
11863   "TARGET_SHMEDIA"
11864   "
11865 {
11866   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11867              (operands[0], operands[1], operands[2]));
11868   DONE;
11869 }")
11870
11871 (define_insn "mmul23_wl"
11872   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11873         (vec_select:V2SI
11874          (mult:V4SI
11875           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11876           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11877          (parallel [(const_int 2) (const_int 3)])))]
11878   "TARGET_SHMEDIA"
11879   "* return (TARGET_LITTLE_ENDIAN
11880              ? \"mmulhi.wl      %1, %2, %0\"
11881              : \"mmullo.wl      %1, %2, %0\");"
11882   [(set_attr "type" "dmpy_media")
11883    (set (attr "highpart")
11884         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11885          (const_string "user")))])
11886
11887 (define_insn "mmul01_wl"
11888   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11889         (vec_select:V2SI
11890          (mult:V4SI
11891           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11892           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11893          (parallel [(const_int 0) (const_int 1)])))]
11894   "TARGET_SHMEDIA"
11895   "* return (TARGET_LITTLE_ENDIAN
11896              ? \"mmullo.wl      %1, %2, %0\"
11897              : \"mmulhi.wl      %1, %2, %0\");"
11898   [(set_attr "type" "dmpy_media")
11899    (set (attr "highpart")
11900         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11901          (const_string "user")))])
11902
11903
11904 (define_expand "mmulsum_wq"
11905   [(match_operand:DI 0 "arith_reg_dest" "")
11906    (match_operand:V4HI 1 "arith_reg_operand" "")
11907    (match_operand:V4HI 2 "arith_reg_operand" "")
11908    (match_operand:DI 3 "arith_reg_operand" "")]
11909   "TARGET_SHMEDIA"
11910   "
11911 {
11912   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11913                                operands[1], operands[2]));
11914   DONE;
11915 }")
11916
11917 (define_insn "mmulsum_wq_i"
11918   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11919         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11920          (plus:DI
11921           (plus:DI
11922            (vec_select:DI
11923             (mult:V4DI
11924              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11925              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11926             (parallel [(const_int 0)]))
11927            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11928                                      (sign_extend:V4DI (match_dup 3)))
11929                           (parallel [(const_int 1)])))
11930           (plus:DI
11931            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11932                                      (sign_extend:V4DI (match_dup 3)))
11933                           (parallel [(const_int 2)]))
11934            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11935                                      (sign_extend:V4DI (match_dup 3)))
11936                           (parallel [(const_int 3)]))))))]
11937   "TARGET_SHMEDIA"
11938   "mmulsum.wq   %2, %3, %0"
11939   [(set_attr "type" "mac_media")])
11940
11941 (define_expand "mperm_w"
11942   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11943    (match_operand:V4HI 1 "arith_reg_operand" "r")
11944    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11945   "TARGET_SHMEDIA"
11946   "
11947 {
11948   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11949              (operands[0], operands[1], operands[2]));
11950   DONE;
11951 }")
11952
11953 ; This use of vec_select isn't exactly correct according to rtl.texi
11954 ; (because not constant), but it seems a straightforward extension.
11955 (define_insn "mperm_w_little"
11956   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11957         (vec_select:V4HI
11958          (match_operand:V4HI 1 "arith_reg_operand" "r")
11959          (parallel
11960           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11961                             (const_int 2) (const_int 0))
11962            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11963            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11964            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11965   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11966   "mperm.w      %1, %N2, %0"
11967   [(set_attr "type" "arith_media")])
11968
11969 (define_insn "mperm_w_big"
11970   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11971         (vec_select:V4HI
11972          (match_operand:V4HI 1 "arith_reg_operand" "r")
11973          (parallel
11974           [(zero_extract:QI (not:QI (match_operand:QI 2
11975                                      "extend_reg_or_0_operand" "rZ"))
11976                             (const_int 2) (const_int 0))
11977            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11978            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11979            (zero_extract:QI (not:QI (match_dup 2))
11980                             (const_int 2) (const_int 6))])))]
11981   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11982   "mperm.w      %1, %N2, %0"
11983   [(set_attr "type" "arith_media")])
11984
11985 (define_insn "mperm_w0"
11986   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11987         (vec_duplicate:V4HI (truncate:HI (match_operand 1
11988                                           "trunc_hi_operand" "r"))))]
11989   "TARGET_SHMEDIA"
11990   "mperm.w      %1, r63, %0"
11991   [(set_attr "type" "arith_media")
11992    (set_attr "highpart" "ignore")])
11993
11994 (define_expand "msad_ubq"
11995   [(match_operand:DI 0 "arith_reg_dest" "")
11996    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
11997    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
11998    (match_operand:DI 3 "arith_reg_operand" "")]
11999   "TARGET_SHMEDIA"
12000   "
12001 {
12002   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12003                              operands[1], operands[2]));
12004   DONE;
12005 }")
12006
12007 (define_insn "msad_ubq_i"
12008   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12009         (plus:DI
12010          (plus:DI
12011           (plus:DI
12012            (plus:DI
12013             (match_operand:DI 1 "arith_reg_operand" "0")
12014             (abs:DI (vec_select:DI
12015                      (minus:V8DI
12016                       (zero_extend:V8DI
12017                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12018                       (zero_extend:V8DI
12019                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12020                      (parallel [(const_int 0)]))))
12021            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12022                                               (zero_extend:V8DI (match_dup 3)))
12023                                   (parallel [(const_int 1)]))))
12024           (plus:DI
12025            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12026                                               (zero_extend:V8DI (match_dup 3)))
12027                                   (parallel [(const_int 2)])))
12028            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12029                                               (zero_extend:V8DI (match_dup 3)))
12030                                   (parallel [(const_int 3)])))))
12031          (plus:DI
12032           (plus:DI
12033            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12034                                               (zero_extend:V8DI (match_dup 3)))
12035                                   (parallel [(const_int 4)])))
12036            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12037                                               (zero_extend:V8DI (match_dup 3)))
12038                                   (parallel [(const_int 5)]))))
12039           (plus:DI
12040            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12041                                               (zero_extend:V8DI (match_dup 3)))
12042                                   (parallel [(const_int 6)])))
12043            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12044                                               (zero_extend:V8DI (match_dup 3)))
12045                                   (parallel [(const_int 7)])))))))]
12046   "TARGET_SHMEDIA"
12047   "msad.ubq     %N2, %N3, %0"
12048   [(set_attr "type" "mac_media")])
12049
12050 (define_insn "mshalds_l"
12051   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12052         (ss_truncate:V2SI
12053          (ashift:V2DI
12054           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12055           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12056                   (const_int 31)))))]
12057   "TARGET_SHMEDIA"
12058   "mshalds.l    %1, %2, %0"
12059   [(set_attr "type" "mcmp_media")
12060    (set_attr "highpart" "depend")])
12061
12062 (define_insn "mshalds_w"
12063   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12064         (ss_truncate:V4HI
12065          (ashift:V4SI
12066           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12067           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12068                   (const_int 15)))))]
12069   "TARGET_SHMEDIA"
12070   "mshalds.w    %1, %2, %0"
12071   [(set_attr "type" "mcmp_media")
12072    (set_attr "highpart" "depend")])
12073
12074 (define_insn "ashrv2si3"
12075   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12076         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12077                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12078   "TARGET_SHMEDIA"
12079   "mshard.l     %1, %2, %0"
12080   [(set_attr "type" "arith_media")
12081    (set_attr "highpart" "depend")])
12082
12083 (define_insn "ashrv4hi3"
12084   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12085         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12086                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12087   "TARGET_SHMEDIA"
12088   "mshard.w     %1, %2, %0"
12089   [(set_attr "type" "arith_media")
12090    (set_attr "highpart" "depend")])
12091
12092 (define_insn "mshards_q"
12093   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12094         (ss_truncate:HI
12095          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12096                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12097   "TARGET_SHMEDIA"
12098   "mshards.q    %1, %N2, %0"
12099   [(set_attr "type" "mcmp_media")])
12100
12101 (define_expand "mshfhi_b"
12102   [(match_operand:V8QI 0 "arith_reg_dest" "")
12103    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12104    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12105   "TARGET_SHMEDIA"
12106   "
12107 {
12108   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12109              (operands[0], operands[1], operands[2]));
12110   DONE;
12111 }")
12112
12113 (define_expand "mshflo_b"
12114   [(match_operand:V8QI 0 "arith_reg_dest" "")
12115    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12116    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12117   "TARGET_SHMEDIA"
12118   "
12119 {
12120   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12121              (operands[0], operands[1], operands[2]));
12122   DONE;
12123 }")
12124
12125 (define_insn "mshf4_b"
12126   [(set
12127     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12128     (vec_select:V8QI
12129      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12130                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12131      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12132                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12133   "TARGET_SHMEDIA"
12134   "* return (TARGET_LITTLE_ENDIAN
12135              ? \"mshfhi.b       %N1, %N2, %0\"
12136              : \"mshflo.b       %N1, %N2, %0\");"
12137   [(set_attr "type" "arith_media")
12138    (set (attr "highpart")
12139         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12140          (const_string "user")))])
12141
12142 (define_insn "mshf0_b"
12143   [(set
12144     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12145     (vec_select:V8QI
12146      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12147                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12148      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12149                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12150   "TARGET_SHMEDIA"
12151   "* return (TARGET_LITTLE_ENDIAN
12152              ? \"mshflo.b       %N1, %N2, %0\"
12153              : \"mshfhi.b       %N1, %N2, %0\");"
12154   [(set_attr "type" "arith_media")
12155    (set (attr "highpart")
12156         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12157          (const_string "user")))])
12158
12159 (define_expand "mshfhi_l"
12160   [(match_operand:V2SI 0 "arith_reg_dest" "")
12161    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12162    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12163   "TARGET_SHMEDIA"
12164   "
12165 {
12166   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12167              (operands[0], operands[1], operands[2]));
12168   DONE;
12169 }")
12170
12171 (define_expand "mshflo_l"
12172   [(match_operand:V2SI 0 "arith_reg_dest" "")
12173    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12174    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12175   "TARGET_SHMEDIA"
12176   "
12177 {
12178   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12179              (operands[0], operands[1], operands[2]));
12180   DONE;
12181 }")
12182
12183 (define_insn "mshf4_l"
12184   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12185         (vec_select:V2SI
12186          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12187                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12188          (parallel [(const_int 1) (const_int 3)])))]
12189   "TARGET_SHMEDIA"
12190   "* return (TARGET_LITTLE_ENDIAN
12191              ? \"mshfhi.l       %N1, %N2, %0\"
12192              : \"mshflo.l       %N1, %N2, %0\");"
12193   [(set_attr "type" "arith_media")
12194    (set (attr "highpart")
12195         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12196          (const_string "user")))])
12197
12198 (define_insn "mshf0_l"
12199   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12200         (vec_select:V2SI
12201          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12202                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12203          (parallel [(const_int 0) (const_int 2)])))]
12204   "TARGET_SHMEDIA"
12205   "* return (TARGET_LITTLE_ENDIAN
12206              ? \"mshflo.l       %N1, %N2, %0\"
12207              : \"mshfhi.l       %N1, %N2, %0\");"
12208   [(set_attr "type" "arith_media")
12209    (set (attr "highpart")
12210         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12211          (const_string "user")))])
12212
12213 (define_expand "mshfhi_w"
12214   [(match_operand:V4HI 0 "arith_reg_dest" "")
12215    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12216    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12217   "TARGET_SHMEDIA"
12218   "
12219 {
12220   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12221              (operands[0], operands[1], operands[2]));
12222   DONE;
12223 }")
12224
12225 (define_expand "mshflo_w"
12226   [(match_operand:V4HI 0 "arith_reg_dest" "")
12227    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12228    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12229   "TARGET_SHMEDIA"
12230   "
12231 {
12232   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12233              (operands[0], operands[1], operands[2]));
12234   DONE;
12235 }")
12236
12237 (define_insn "mshf4_w"
12238   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12239         (vec_select:V4HI
12240          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12241                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12242          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12243   "TARGET_SHMEDIA"
12244   "* return (TARGET_LITTLE_ENDIAN
12245              ? \"mshfhi.w       %N1, %N2, %0\"
12246              : \"mshflo.w       %N1, %N2, %0\");"
12247   [(set_attr "type" "arith_media")
12248    (set (attr "highpart")
12249         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12250          (const_string "user")))])
12251
12252 (define_insn "mshf0_w"
12253   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12254         (vec_select:V4HI
12255          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12256                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12257          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12258   "TARGET_SHMEDIA"
12259   "* return (TARGET_LITTLE_ENDIAN
12260              ? \"mshflo.w       %N1, %N2, %0\"
12261              : \"mshfhi.w       %N1, %N2, %0\");"
12262   [(set_attr "type" "arith_media")
12263    (set (attr "highpart")
12264         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12265          (const_string "user")))])
12266
12267 (define_insn "mshflo_w_x"
12268   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12269         (vec_select:V4HI
12270          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12271                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12272          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12273   "TARGET_SHMEDIA"
12274   "mshflo.w     %N1, %N2, %0"
12275   [(set_attr "type" "arith_media")
12276    (set_attr "highpart" "ignore")])
12277
12278 /* These are useful to expand ANDs and as combiner patterns.  */
12279 (define_insn_and_split "mshfhi_l_di"
12280   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12281         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12282                              (const_int 32))
12283                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12284                         (const_int -4294967296))))]
12285   "TARGET_SHMEDIA"
12286   "@
12287         mshfhi.l        %N1, %N2, %0
12288         #"
12289   "TARGET_SHMEDIA && reload_completed
12290    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12291   [(set (match_dup 3) (match_dup 4))
12292    (set (match_dup 5) (match_dup 6))]
12293   "
12294 {
12295   operands[3] = gen_lowpart (SImode, operands[0]);
12296   operands[4] = gen_highpart (SImode, operands[1]);
12297   operands[5] = gen_highpart (SImode, operands[0]);
12298   operands[6] = gen_highpart (SImode, operands[2]);
12299 }"
12300   [(set_attr "type" "arith_media")])
12301
12302 (define_insn "*mshfhi_l_di_rev"
12303   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12304         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12305                         (const_int -4294967296))
12306                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12307                              (const_int 32))))]
12308   "TARGET_SHMEDIA"
12309   "mshfhi.l     %N2, %N1, %0"
12310   [(set_attr "type" "arith_media")])
12311
12312 (define_split
12313   [(set (match_operand:DI 0 "arith_reg_dest" "")
12314         (ior:DI (zero_extend:DI (match_operand:SI 1
12315                                               "extend_reg_or_0_operand" ""))
12316                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12317                         (const_int -4294967296))))
12318    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12319   "TARGET_SHMEDIA"
12320   [(const_int 0)]
12321   "
12322 {
12323   emit_insn (gen_ashldi3_media (operands[3],
12324                                 simplify_gen_subreg (DImode, operands[1],
12325                                                      SImode, 0),
12326                                 GEN_INT (32)));
12327   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12328   DONE;
12329 }")
12330
12331 (define_insn "mshflo_l_di"
12332   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12333         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12334                         (const_int 4294967295))
12335                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12336                            (const_int 32))))]
12337
12338   "TARGET_SHMEDIA"
12339   "mshflo.l     %N1, %N2, %0"
12340   [(set_attr "type" "arith_media")
12341    (set_attr "highpart" "ignore")])
12342
12343 (define_insn "*mshflo_l_di_rev"
12344   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12345         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12346                            (const_int 32))
12347                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12348                         (const_int 4294967295))))]
12349
12350   "TARGET_SHMEDIA"
12351   "mshflo.l     %N2, %N1, %0"
12352   [(set_attr "type" "arith_media")
12353    (set_attr "highpart" "ignore")])
12354
12355 ;; Combiner pattern for trampoline initialization.
12356 (define_insn_and_split "*double_shori"
12357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12358         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12359                            (const_int 32))
12360                 (match_operand:DI 2 "const_int_operand" "n")))]
12361   "TARGET_SHMEDIA
12362    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12363   "#"
12364   "rtx_equal_p (operands[0], operands[1])"
12365   [(const_int 0)]
12366   "
12367 {
12368   HOST_WIDE_INT v = INTVAL (operands[2]);
12369
12370   emit_insn (gen_shori_media (operands[0], operands[0],
12371              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12372   emit_insn (gen_shori_media (operands[0], operands[0],
12373                               gen_int_mode (v, HImode)));
12374   DONE;
12375 }"
12376   [(set_attr "highpart" "ignore")])
12377
12378
12379 (define_insn "*mshflo_l_di_x"
12380   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12381         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12382                                  "rZ"))
12383                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12384                            (const_int 32))))]
12385
12386   "TARGET_SHMEDIA"
12387   "mshflo.l     %N1, %N2, %0"
12388   [(set_attr "type" "arith_media")
12389    (set_attr "highpart" "ignore")])
12390
12391 (define_insn_and_split "concat_v2sf"
12392   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12393 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12394         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12395                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12396
12397   "TARGET_SHMEDIA"
12398   "@
12399         mshflo.l        %N1, %N2, %0
12400         #
12401         #"
12402   "TARGET_SHMEDIA && reload_completed
12403    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12404   [(set (match_dup 3) (match_dup 1))
12405    (set (match_dup 4) (match_dup 2))]
12406   "
12407 {
12408   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12409   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12410 }"
12411   [(set_attr "type" "arith_media")
12412    (set_attr "highpart" "ignore")])
12413
12414 (define_insn "*mshflo_l_di_x_rev"
12415   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12416         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12417                            (const_int 32))
12418                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12419
12420   "TARGET_SHMEDIA"
12421   "mshflo.l     %N2, %N1, %0"
12422   [(set_attr "type" "arith_media")
12423    (set_attr "highpart" "ignore")])
12424
12425 (define_insn "ashlv2si3"
12426   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12427         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12428                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12429   "TARGET_SHMEDIA"
12430   "mshlld.l     %1, %2, %0"
12431   [(set_attr "type" "arith_media")
12432    (set_attr "highpart" "depend")])
12433
12434 (define_split
12435   [(set (match_operand 0 "any_register_operand" "")
12436         (match_operator 3 "shift_operator"
12437           [(match_operand 1 "any_register_operand" "")
12438            (match_operand 2 "shift_count_reg_operand" "")]))]
12439   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12440   [(set (match_dup 0) (match_dup 3))]
12441   "
12442 {
12443   rtx count = operands[2];
12444   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12445
12446   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12447          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12448          || GET_CODE (count) == TRUNCATE)
12449     count = XEXP (count, 0);
12450   inner_mode = GET_MODE (count);
12451   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12452                                subreg_lowpart_offset (outer_mode, inner_mode));
12453   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12454                                 operands[1], count);
12455 }")
12456
12457 (define_insn "ashlv4hi3"
12458   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12459         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12460                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12461   "TARGET_SHMEDIA"
12462   "mshlld.w     %1, %2, %0"
12463   [(set_attr "type" "arith_media")
12464    (set_attr "highpart" "depend")])
12465
12466 (define_insn "lshrv2si3"
12467   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12468         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12469                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12470   "TARGET_SHMEDIA"
12471   "mshlrd.l     %1, %2, %0"
12472   [(set_attr "type" "arith_media")
12473    (set_attr "highpart" "depend")])
12474
12475 (define_insn "lshrv4hi3"
12476   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12477         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12478                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12479   "TARGET_SHMEDIA"
12480   "mshlrd.w     %1, %2, %0"
12481   [(set_attr "type" "arith_media")
12482    (set_attr "highpart" "depend")])
12483
12484 (define_insn "subv2si3"
12485   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12486         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12487                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12488   "TARGET_SHMEDIA"
12489   "msub.l       %N1, %2, %0"
12490   [(set_attr "type" "arith_media")
12491    (set_attr "highpart" "depend")])
12492
12493 (define_insn "subv4hi3"
12494   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12495         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12496                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12497   "TARGET_SHMEDIA"
12498   "msub.w       %N1, %2, %0"
12499   [(set_attr "type" "arith_media")
12500    (set_attr "highpart" "depend")])
12501
12502 (define_insn_and_split "subv2hi3"
12503   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12504         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12505                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12506   "TARGET_SHMEDIA"
12507   "#"
12508   "TARGET_SHMEDIA"
12509   [(const_int 0)]
12510   "
12511 {
12512   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12513   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12514   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12515   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12516   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12517
12518   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12519   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12520   DONE;
12521 }"
12522   [(set_attr "highpart" "must_split")])
12523
12524 (define_insn "sssubv2si3"
12525   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12526         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12527                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12528   "TARGET_SHMEDIA"
12529   "msubs.l      %N1, %2, %0"
12530   [(set_attr "type" "mcmp_media")
12531    (set_attr "highpart" "depend")])
12532
12533 (define_insn "ussubv8qi3"
12534   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12535         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12536                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12537   "TARGET_SHMEDIA"
12538   "msubs.ub     %N1, %2, %0"
12539   [(set_attr "type" "mcmp_media")
12540    (set_attr "highpart" "depend")])
12541
12542 (define_insn "sssubv4hi3"
12543   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12544         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12545                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12546   "TARGET_SHMEDIA"
12547   "msubs.w      %N1, %2, %0"
12548   [(set_attr "type" "mcmp_media")
12549    (set_attr "highpart" "depend")])
12550
12551 ;; Floating Point Intrinsics
12552
12553 (define_insn "fcosa_s"
12554   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12555         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12556                    UNSPEC_FCOSA))]
12557   "TARGET_SHMEDIA"
12558   "fcosa.s      %1, %0"
12559   [(set_attr "type" "atrans_media")])
12560
12561 (define_insn "fsina_s"
12562   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12563         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12564                    UNSPEC_FSINA))]
12565   "TARGET_SHMEDIA"
12566   "fsina.s      %1, %0"
12567   [(set_attr "type" "atrans_media")])
12568
12569 (define_insn "fipr"
12570   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12571         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12572                                                     "fp_arith_reg_operand" "f")
12573                                                    (match_operand:V4SF 2
12574                                                     "fp_arith_reg_operand" "f"))
12575                                          (parallel [(const_int 0)]))
12576                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12577                                          (parallel [(const_int 1)])))
12578                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12579                                          (parallel [(const_int 2)]))
12580                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12581                                          (parallel [(const_int 3)])))))]
12582   "TARGET_SHMEDIA"
12583   "fipr.s       %1, %2, %0"
12584   [(set_attr "type" "fparith_media")])
12585
12586 (define_insn "fsrra_s"
12587   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12588         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12589                    UNSPEC_FSRRA))]
12590   "TARGET_SHMEDIA"
12591   "fsrra.s      %1, %0"
12592   [(set_attr "type" "atrans_media")])
12593
12594 (define_insn "ftrv"
12595   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12596         (plus:V4SF
12597          (plus:V4SF
12598           (mult:V4SF
12599            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12600                             (parallel [(const_int 0) (const_int 5)
12601                                        (const_int 10) (const_int 15)]))
12602            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12603           (mult:V4SF
12604            (vec_select:V4SF (match_dup 1)
12605                             (parallel [(const_int 4) (const_int 9)
12606                                        (const_int 14) (const_int 3)]))
12607            (vec_select:V4SF (match_dup 2)
12608                             (parallel [(const_int 1) (const_int 2)
12609                                        (const_int 3) (const_int 0)]))))
12610          (plus:V4SF
12611           (mult:V4SF
12612            (vec_select:V4SF (match_dup 1)
12613                             (parallel [(const_int 8) (const_int 13)
12614                                        (const_int 2) (const_int 7)]))
12615            (vec_select:V4SF (match_dup 2)
12616                             (parallel [(const_int 2) (const_int 3)
12617                                        (const_int 0) (const_int 1)])))
12618           (mult:V4SF
12619            (vec_select:V4SF (match_dup 1)
12620                             (parallel [(const_int 12) (const_int 1)
12621                                        (const_int 6) (const_int 11)]))
12622            (vec_select:V4SF (match_dup 2)
12623                             (parallel [(const_int 3) (const_int 0)
12624                                        (const_int 1) (const_int 2)]))))))]
12625   "TARGET_SHMEDIA"
12626   "ftrv.s %1, %2, %0"
12627   [(set_attr "type" "fparith_media")])
12628
12629 (define_insn "ldhi_l"
12630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12631         (zero_extract:SI
12632          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12633                                   (const_int 3))
12634                           (const_int -3)))
12635          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12636          (const_int 0)))]
12637   "TARGET_SHMEDIA32"
12638   "ldhi.l       %U1, %0"
12639   [(set_attr "type" "load_media")])
12640
12641 (define_insn "ldhi_q"
12642   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12643         (zero_extract:DI
12644          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12645                                   (const_int 7))
12646                           (const_int -7)))
12647          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12648          (const_int 0)))]
12649   "TARGET_SHMEDIA32"
12650   "ldhi.q       %U1, %0"
12651   [(set_attr "type" "load_media")])
12652
12653 (define_insn_and_split "*ldhi_q_comb0"
12654   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12655         (zero_extract:DI
12656          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12657                                             "register_operand" "r")
12658                                            (match_operand:SI 2
12659                                             "ua_offset" "I06"))
12660                                   (const_int 7))
12661                           (const_int -7)))
12662          (plus:SI (and:SI (match_dup 1) (const_int 7))
12663                   (const_int 1))
12664          (const_int 0)))]
12665   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12666   "#"
12667   ""
12668   [(pc)]
12669   "emit_insn (gen_ldhi_q (operands[0],
12670                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12671    DONE;")
12672
12673
12674 (define_insn_and_split "*ldhi_q_comb1"
12675   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12676         (zero_extract:DI
12677          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12678                                             "register_operand" "r")
12679                                            (match_operand:SI 2
12680                                             "ua_offset" "I06"))
12681                                   (const_int 7))
12682                           (const_int -7)))
12683          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12684                                                    "ua_offset" "I06"))
12685                           (const_int 7))
12686                   (const_int 1))
12687          (const_int 0)))]
12688   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12689    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12690   "#"
12691   ""
12692   [(pc)]
12693   "emit_insn (gen_ldhi_q (operands[0],
12694                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12695    DONE;")
12696
12697
12698 (define_insn "ldlo_l"
12699   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12700         (zero_extract:SI
12701          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12702                          (const_int -4)))
12703          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12704          (and:SI (match_dup 1) (const_int 3))))]
12705   "TARGET_SHMEDIA32"
12706   "ldlo.l       %U1, %0"
12707   [(set_attr "type" "load_media")])
12708
12709 (define_insn "ldlo_q"
12710   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12711         (zero_extract:DI
12712          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12713                          (const_int -8)))
12714          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12715          (and:SI (match_dup 1) (const_int 7))))]
12716   "TARGET_SHMEDIA32"
12717   "ldlo.q       %U1, %0"
12718   [(set_attr "type" "load_media")])
12719
12720 (define_insn_and_split "*ldlo_q_comb0"
12721   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12722         (zero_extract:DI
12723          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12724                                   (match_operand:SI 2 "ua_offset" "I06"))
12725                          (const_int -8)))
12726          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12727          (and:SI (match_dup 1) (const_int 7))))]
12728   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12729   "#"
12730   ""
12731   [(pc)]
12732   "emit_insn (gen_ldlo_q (operands[0],
12733                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12734    DONE;")
12735
12736 (define_insn_and_split "*ldlo_q_comb1"
12737   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12738         (zero_extract:DI
12739          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12740                                   (match_operand:SI 2 "ua_offset" "I06"))
12741                          (const_int -8)))
12742          (minus:SI (const_int 8)
12743                    (and:SI (plus:SI (match_dup 1)
12744                                     (match_operand:SI 3 "ua_offset" "I06"))
12745                            (const_int 7)))
12746          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12747   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12748    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12749   "#"
12750   ""
12751   [(pc)]
12752   "emit_insn (gen_ldlo_q (operands[0],
12753                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12754    DONE;")
12755
12756 (define_insn "sthi_l"
12757   [(set (zero_extract:SI
12758          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12759                                   (const_int 3))
12760                           (const_int -3)))
12761          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12762          (const_int 0))
12763         (match_operand:SI 1 "arith_reg_operand" "r"))]
12764   "TARGET_SHMEDIA32"
12765   "sthi.l       %U0, %1"
12766   [(set_attr "type" "ustore_media")])
12767
12768 ;; All unaligned stores are considered to be 'narrow' because they typically
12769 ;; operate on less that a quadword, and when they operate on a full quadword,
12770 ;; the vanilla store high / store low sequence will cause a stall if not
12771 ;; scheduled apart.
12772 (define_insn "sthi_q"
12773   [(set (zero_extract:DI
12774          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12775                                   (const_int 7))
12776                           (const_int -7)))
12777          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12778          (const_int 0))
12779         (match_operand:DI 1 "arith_reg_operand" "r"))]
12780   "TARGET_SHMEDIA32"
12781   "sthi.q       %U0, %1"
12782   [(set_attr "type" "ustore_media")])
12783
12784 (define_insn_and_split "*sthi_q_comb0"
12785   [(set (zero_extract:DI
12786          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12787                                             "register_operand" "r")
12788                                            (match_operand:SI 1 "ua_offset"
12789                                             "I06"))
12790                                   (const_int 7))
12791                           (const_int -7)))
12792          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12793          (const_int 0))
12794         (match_operand:DI 2 "arith_reg_operand" "r"))]
12795   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12796   "#"
12797   ""
12798   [(pc)]
12799   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12800                           operands[2]));
12801    DONE;")
12802
12803 (define_insn_and_split "*sthi_q_comb1"
12804   [(set (zero_extract:DI
12805          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12806                                             "register_operand" "r")
12807                                            (match_operand:SI 1 "ua_offset"
12808                                             "I06"))
12809                                   (const_int 7))
12810                           (const_int -7)))
12811          (plus:SI (and:SI (plus:SI (match_dup 0)
12812                                    (match_operand:SI 2 "ua_offset" "I06"))
12813                           (const_int 7))
12814                   (const_int 1))
12815          (const_int 0))
12816         (match_operand:DI 3 "arith_reg_operand" "r"))]
12817   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12818    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12819   "#"
12820   ""
12821   [(pc)]
12822   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12823                           operands[3]));
12824    DONE;")
12825
12826 ;; This is highpart user because the address is used as full 64 bit.
12827 (define_insn "stlo_l"
12828   [(set (zero_extract:SI
12829          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12830                          (const_int -4)))
12831          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12832          (and:SI (match_dup 0) (const_int 3)))
12833         (match_operand:SI 1 "arith_reg_operand" "r"))]
12834   "TARGET_SHMEDIA32"
12835   "stlo.l       %U0, %1"
12836   [(set_attr "type" "ustore_media")])
12837
12838 (define_insn "stlo_q"
12839   [(set (zero_extract:DI
12840          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12841                          (const_int -8)))
12842          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12843          (and:SI (match_dup 0) (const_int 7)))
12844         (match_operand:DI 1 "arith_reg_operand" "r"))]
12845   "TARGET_SHMEDIA32"
12846   "stlo.q       %U0, %1"
12847   [(set_attr "type" "ustore_media")])
12848
12849 (define_insn_and_split "*stlo_q_comb0"
12850   [(set (zero_extract:DI
12851          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12852                                   (match_operand:SI 1 "ua_offset" "I06"))
12853                          (const_int -8)))
12854          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12855          (and:SI (match_dup 0) (const_int 7)))
12856         (match_operand:DI 2 "arith_reg_operand" "r"))]
12857   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12858   "#"
12859   ""
12860   [(pc)]
12861   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12862                           operands[2]));
12863    DONE;")
12864
12865 (define_insn_and_split "*stlo_q_comb1"
12866   [(set (zero_extract:DI
12867          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12868                                   (match_operand:SI 1 "ua_offset" "I06"))
12869                          (const_int -8)))
12870          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12871                                                   (match_operand:SI 2
12872                                                    "ua_offset" "I06"))
12873                                          (const_int 7)))
12874          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12875         (match_operand:DI 3 "arith_reg_operand" "r"))]
12876   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12877   "#"
12878   ""
12879   [(pc)]
12880   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12881                           operands[3]));
12882    DONE;")
12883
12884 (define_insn "ldhi_l64"
12885   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12886         (zero_extract:SI
12887          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12888                                   (const_int 3))
12889                           (const_int -3)))
12890          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12891          (const_int 0)))]
12892   "TARGET_SHMEDIA64"
12893   "ldhi.l       %U1, %0"
12894   [(set_attr "type" "load_media")])
12895
12896 (define_insn "ldhi_q64"
12897   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12898         (zero_extract:DI
12899          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12900                                   (const_int 7))
12901                           (const_int -7)))
12902          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12903          (const_int 0)))]
12904   "TARGET_SHMEDIA64"
12905   "ldhi.q       %U1, %0"
12906   [(set_attr "type" "load_media")])
12907
12908 (define_insn "ldlo_l64"
12909   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12910         (zero_extract:SI
12911          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12912                          (const_int -4)))
12913          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12914          (and:DI (match_dup 1) (const_int 3))))]
12915   "TARGET_SHMEDIA64"
12916   "ldlo.l       %U1, %0"
12917   [(set_attr "type" "load_media")])
12918
12919 (define_insn "ldlo_q64"
12920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12921         (zero_extract:DI
12922          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12923                          (const_int -8)))
12924          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12925          (and:DI (match_dup 1) (const_int 7))))]
12926   "TARGET_SHMEDIA64"
12927   "ldlo.q       %U1, %0"
12928   [(set_attr "type" "load_media")])
12929
12930 (define_insn "sthi_l64"
12931   [(set (zero_extract:SI
12932          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12933                                   (const_int 3))
12934                           (const_int -3)))
12935          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12936          (const_int 0))
12937         (match_operand:SI 1 "arith_reg_operand" "r"))]
12938   "TARGET_SHMEDIA64"
12939   "sthi.l       %U0, %1"
12940   [(set_attr "type" "ustore_media")])
12941
12942 (define_insn "sthi_q64"
12943   [(set (zero_extract:DI
12944          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12945                                   (const_int 7))
12946                           (const_int -7)))
12947          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12948          (const_int 0))
12949         (match_operand:DI 1 "arith_reg_operand" "r"))]
12950   "TARGET_SHMEDIA64"
12951   "sthi.q       %U0, %1"
12952   [(set_attr "type" "ustore_media")])
12953
12954 (define_insn "stlo_l64"
12955   [(set (zero_extract:SI
12956          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12957                          (const_int -4)))
12958          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12959          (and:DI (match_dup 0) (const_int 3)))
12960         (match_operand:SI 1 "arith_reg_operand" "r"))]
12961   "TARGET_SHMEDIA64"
12962   "stlo.l       %U0, %1"
12963   [(set_attr "type" "ustore_media")])
12964
12965 (define_insn "stlo_q64"
12966   [(set (zero_extract:DI
12967          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12968                          (const_int -8)))
12969          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12970          (and:DI (match_dup 0) (const_int 7)))
12971         (match_operand:DI 1 "arith_reg_operand" "r"))]
12972   "TARGET_SHMEDIA64"
12973   "stlo.q       %U0, %1"
12974   [(set_attr "type" "ustore_media")])
12975
12976 (define_insn "nsb"
12977   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12978         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12979                    UNSPEC_NSB))]
12980   "TARGET_SHMEDIA"
12981   "nsb  %1, %0"
12982   [(set_attr "type" "arith_media")])
12983
12984 (define_insn "nsbsi"
12985   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12986         (zero_extend:SI
12987          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12988                     UNSPEC_NSB)))]
12989   "TARGET_SHMEDIA"
12990   "nsb  %1, %0"
12991   [(set_attr "type" "arith_media")])
12992
12993 (define_insn "nsbdi"
12994   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12995         (zero_extend:DI
12996          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12997                     UNSPEC_NSB)))]
12998   "TARGET_SHMEDIA"
12999   "nsb  %1, %0"
13000   [(set_attr "type" "arith_media")])
13001
13002 (define_expand "ffsdi2"
13003   [(set (match_operand:DI 0 "arith_reg_dest" "")
13004         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13005   "TARGET_SHMEDIA"
13006   "
13007 {
13008   rtx scratch = gen_reg_rtx (DImode);
13009   rtx last;
13010
13011   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13012   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13013   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13014   emit_insn (gen_nsbdi (scratch, scratch));
13015   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13016   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13017   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13018   REG_NOTES (last)
13019     = gen_rtx_EXPR_LIST (REG_EQUAL,
13020                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13021   DONE;
13022 }")
13023
13024 (define_expand "ffssi2"
13025   [(set (match_operand:SI 0 "arith_reg_dest" "")
13026         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13027   "TARGET_SHMEDIA"
13028   "
13029 {
13030   rtx scratch = gen_reg_rtx (SImode);
13031   rtx discratch = gen_reg_rtx (DImode);
13032   rtx last;
13033
13034   emit_insn (gen_adddi3 (discratch,
13035                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13036                          constm1_rtx));
13037   emit_insn (gen_andcdi3 (discratch,
13038                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13039                           discratch));
13040   emit_insn (gen_nsbsi (scratch, discratch));
13041   last = emit_insn (gen_subsi3 (operands[0],
13042                                 force_reg (SImode, GEN_INT (63)), scratch));
13043   REG_NOTES (last)
13044     = gen_rtx_EXPR_LIST (REG_EQUAL,
13045                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13046   DONE;
13047 }")
13048
13049 (define_insn "byterev"
13050   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13051         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13052                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13053                                     (const_int 4) (const_int 3) (const_int 2)
13054                                     (const_int 1) (const_int 0)])))]
13055   "TARGET_SHMEDIA"
13056   "byterev      %1, %0"
13057   [(set_attr "type" "arith_media")])
13058
13059 (define_insn "*prefetch_media"
13060   [(prefetch (match_operand:QI 0 "address_operand" "p")
13061              (match_operand:SI 1 "const_int_operand" "n")
13062              (match_operand:SI 2 "const_int_operand" "n"))]
13063   "TARGET_SHMEDIA"
13064   "*
13065 {
13066   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13067   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13068   return \"\";
13069 }"
13070   [(set_attr "type" "other")])
13071
13072 (define_insn "*prefetch_i4"
13073   [(prefetch (match_operand:SI 0 "register_operand" "r")
13074              (match_operand:SI 1 "const_int_operand" "n")
13075              (match_operand:SI 2 "const_int_operand" "n"))]
13076   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13077   "*
13078 {
13079   return \"pref @%0\";
13080 }"
13081   [(set_attr "type" "other")])
13082
13083 (define_expand "prefetch"
13084   [(prefetch (match_operand 0 "address_operand" "p")
13085              (match_operand:SI 1 "const_int_operand" "n")
13086              (match_operand:SI 2 "const_int_operand" "n"))]
13087   "TARGET_HARD_SH4 || TARGET_SH5"
13088   "
13089 {
13090   if (GET_MODE (operands[0]) != Pmode
13091       || GET_CODE (operands[1]) != CONST_INT
13092       || GET_CODE (operands[2]) != CONST_INT)
13093     FAIL;
13094   if (! TARGET_SHMEDIA)
13095     operands[0] = force_reg (Pmode, operands[0]);
13096 }")
13097
13098 (define_insn "alloco_i"
13099   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13100         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13101   "TARGET_SHMEDIA32"
13102   "*
13103 {
13104   rtx xops[2];
13105
13106   if (GET_CODE (operands[0]) == PLUS)
13107     {
13108       xops[0] = XEXP (operands[0], 0);
13109       xops[1] = XEXP (operands[0], 1);
13110     }
13111   else
13112     {
13113       xops[0] = operands[0];
13114       xops[1] = const0_rtx;
13115     }
13116   output_asm_insn (\"alloco   %0, %1\", xops);
13117   return \"\";
13118 }"
13119   [(set_attr "type" "other")])
13120
13121 (define_split
13122   [(set (match_operand 0 "any_register_operand" "")
13123         (match_operand 1 "" ""))]
13124   "TARGET_SHMEDIA && reload_completed"
13125   [(set (match_dup 0) (match_dup 1))]
13126   "
13127 {
13128   int n_changes = 0;
13129
13130   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13131   if (!n_changes)
13132     FAIL;
13133 }")