OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_CHKADD        38)
154   (UNSPEC_SP_SET        40)
155   (UNSPEC_SP_TEST       41)
156   (UNSPEC_MOVUA         42)
157
158   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160   (UNSPEC_EXTRACT_S16   43)
161   (UNSPEC_EXTRACT_U16   44)
162
163   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164   (UNSPEC_SYMOFF        45)
165
166   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167   (UNSPEC_PCREL_SYMOFF  46)
168
169   ;; These are used with unspec_volatile.
170   (UNSPECV_BLOCKAGE     0)
171   (UNSPECV_ALIGN        1)
172   (UNSPECV_CONST2       2)
173   (UNSPECV_CONST4       4)
174   (UNSPECV_CONST8       6)
175   (UNSPECV_WINDOW_END   10)
176   (UNSPECV_CONST_END    11)
177   (UNSPECV_EH_RETURN    12)
178 ])
179
180 ;; -------------------------------------------------------------------------
181 ;; Attributes
182 ;; -------------------------------------------------------------------------
183
184 ;; Target CPU.
185
186 (define_attr "cpu"
187  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188   (const (symbol_ref "sh_cpu_attr")))
189
190 (define_attr "endian" "big,little"
191  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192                       (const_string "little") (const_string "big"))))
193
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197                          (const_string "yes") (const_string "no"))))
198
199 (define_attr "fmovd" "yes,no"
200   (const (if_then_else (symbol_ref "TARGET_FMOVD")
201                        (const_string "yes") (const_string "no"))))
202 ;; pipeline model
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
204   (const
205    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207          (const_string "sh1"))))
208
209 ;; cbranch      conditional branch instructions
210 ;; jump         unconditional jumps
211 ;; arith        ordinary arithmetic
212 ;; arith3       a compound insn that behaves similarly to a sequence of
213 ;;              three insns of type arith
214 ;; arith3b      like above, but might end with a redirected branch
215 ;; load         from memory
216 ;; load_si      Likewise, SImode variant for general register.
217 ;; fload        Likewise, but load to fp register.
218 ;; store        to memory
219 ;; fstore       floating point register to memory
220 ;; move         general purpose register to register
221 ;; movi8        8-bit immediate to general purpose register
222 ;; mt_group     other sh4 mt instructions
223 ;; fmove        register to register, floating point
224 ;; smpy         word precision integer multiply
225 ;; dmpy         longword or doublelongword precision integer multiply
226 ;; return       rts
227 ;; pload        load of pr reg, which can't be put into delay slot of rts
228 ;; prset        copy register to pr reg, ditto
229 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
230 ;; prget        copy pr to register, ditto
231 ;; pcload       pc relative load of constant value
232 ;; pcfload      Likewise, but load to fp register.
233 ;; pcload_si    Likewise, SImode variant for general register.
234 ;; rte          return from exception
235 ;; sfunc        special function call with known used registers
236 ;; call         function call
237 ;; fp           floating point
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv         floating point divide (or square root)
240 ;; gp_fpul      move from general purpose register to fpul
241 ;; fpul_gp      move from fpul to general purpose register
242 ;; mac_gp       move from mac[lh] to general purpose register
243 ;; gp_mac       move from general purpose register to mac[lh]
244 ;; mac_mem      move from mac[lh] to memory
245 ;; mem_mac      move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s       fix_truncsfsi2_i4
248 ;; dfdiv        double precision floating point divide (or square root)
249 ;; cwb          ic_invalidate_line_i
250 ;; movua        SH4a unaligned load
251 ;; fsrra        square root reciprocal approximate
252 ;; fsca         sine and cosine approximate
253 ;; tls_load     load TLS related address
254 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media    SHmedia compare instructions
257 ;; dfdiv_media  SHmedia double precision divide and square root
258 ;; dfmul_media  SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media   SHmedia longword multiply
262 ;; fcmp_media   SHmedia floating point compare instructions
263 ;; fdiv_media   SHmedia single precision divide and square root
264 ;; fload_media  SHmedia floating point register load instructions
265 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media  SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media   SHmedia unconditional branch instructions
272 ;; load_media   SHmedia general register load instructions
273 ;; pt_media     SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media  SHmedia ptabs instruction
275 ;; store_media  SHmedia general register store instructions
276 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media    SHmedia mac-style fixed point operations
278 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil          no-op move, will be deleted.
282
283 (define_attr "type"
284  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
285   (const_string "other"))
286
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
289 ;;
290 ;; mt_group      SH4 "mt" group instructions.
291 ;;
292 ;; ex_group      SH4 "ex" group instructions.
293 ;;
294 ;; ls_group      SH4 "ls" group instructions.
295 ;;
296
297 (define_attr "insn_class"
298   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302          (eq_attr "type" "cbranch,jump") (const_string "br_group")
303          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304            (const_string "fe_group")
305          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306         (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
310
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
312
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
314
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
318 ;; state.
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long.  Something in the
325 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
328 ; 2 bytes.
329
330 ;; The maximum range used for SImode constant pool entries is 1018.  A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table.  That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
342 ;;
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
345
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347 ;; inside an le.
348 (define_attr "short_cbranch_p" "no,yes"
349   (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
350          (const_string "no")
351          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352          (const_string "yes")
353          (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356          (const_string "yes")
357          ] (const_string "no")))
358
359 (define_attr "med_branch_p" "no,yes"
360   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361               (const_int 1988))
362          (const_string "yes")
363          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366               (const_int 8186))
367          (const_string "yes")
368          ] (const_string "no")))
369
370 (define_attr "med_cbranch_p" "no,yes"
371   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372               (const_int 1986))
373          (const_string "yes")
374          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377                (const_int 8184))
378          (const_string "yes")
379          ] (const_string "no")))
380
381 (define_attr "braf_branch_p" "no,yes"
382   (cond [(match_test "! TARGET_SH2")
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385               (const_int 20660))
386          (const_string "yes")
387          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390               (const_int 65530))
391          (const_string "yes")
392          ] (const_string "no")))
393
394 (define_attr "braf_cbranch_p" "no,yes"
395   (cond [(match_test "! TARGET_SH2")
396          (const_string "no")
397          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398               (const_int 20658))
399          (const_string "yes")
400          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401          (const_string "no")
402          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403               (const_int 65528))
404          (const_string "yes")
405          ] (const_string "no")))
406
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
413
414 ; All other instructions are two bytes long by default.
415
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419   (cond [(eq_attr "type" "cbranch")
420          (cond [(eq_attr "short_cbranch_p" "yes")
421                 (const_int 2)
422                 (eq_attr "med_cbranch_p" "yes")
423                 (const_int 6)
424                 (eq_attr "braf_cbranch_p" "yes")
425                 (const_int 12)
426 ;; ??? using pc is not computed transitively.
427                 (ne (match_dup 0) (match_dup 0))
428                 (const_int 14)
429                 (match_test "flag_pic")
430                 (const_int 24)
431                 ] (const_int 16))
432          (eq_attr "type" "jump")
433          (cond [(eq_attr "med_branch_p" "yes")
434                 (const_int 2)
435                 (and (match_test "prev_nonnote_insn (insn)")
436                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")                              (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")                             (symbol_ref "code_for_indirect_jump_scratch"))))
438                 (cond [(eq_attr "braf_branch_p" "yes")
439                        (const_int 6)
440                        (not (match_test "flag_pic"))
441                        (const_int 10)
442                        (match_test "TARGET_SH2")
443                        (const_int 10)] (const_int 18))
444                 (eq_attr "braf_branch_p" "yes")
445                 (const_int 10)
446 ;; ??? using pc is not computed transitively.
447                 (ne (match_dup 0) (match_dup 0))
448                 (const_int 12)
449                 (match_test "flag_pic")
450                 (const_int 22)
451                 ] (const_int 14))
452          (eq_attr "type" "pt_media")
453          (if_then_else (match_test "TARGET_SHMEDIA64")
454                        (const_int 20) (const_int 12))
455          (and (eq_attr "type" "jump_media")
456               (match_test "TARGET_SH5_CUT2_WORKAROUND"))
457          (const_int 8)
458          ] (if_then_else (match_test "TARGET_SHMEDIA")
459                          (const_int 4)
460                          (const_int 2))))
461
462 ;; DFA descriptions for the pipelines
463
464 (include "sh1.md")
465 (include "shmedia.md")
466 (include "sh4.md")
467
468 (include "predicates.md")
469 (include "constraints.md")
470
471 ;; Definitions for filling delay slots
472
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
474
475 (define_attr "banked" "yes,no" 
476         (cond [(match_test "sh_loads_bankedreg_p (insn)")
477                (const_string "yes")]
478               (const_string "no")))
479
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482         (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
483                (const_string "no")]
484               (const_string "yes")))
485
486 (define_attr "interrupt_function" "no,yes"
487   (const (symbol_ref "current_function_interrupt")))
488
489 (define_attr "in_delay_slot" "yes,no"
490   (cond [(eq_attr "type" "cbranch") (const_string "no")
491          (eq_attr "type" "pcload,pcload_si") (const_string "no")
492          (eq_attr "needs_delay_slot" "yes") (const_string "no")
493          (eq_attr "length" "2") (const_string "yes")
494          ] (const_string "no")))
495
496 (define_attr "cond_delay_slot" "yes,no"
497   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498          ] (const_string "no")))
499
500 (define_attr "is_sfunc" ""
501   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
502
503 (define_attr "is_mac_media" ""
504   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
505
506 (define_attr "branch_zero" "yes,no"
507   (cond [(eq_attr "type" "!cbranch") (const_string "no")
508          (ne (symbol_ref "(next_active_insn (insn)\
509                            == (prev_active_insn\
510                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511                           && get_attr_length (next_active_insn (insn)) == 2")
512              (const_int 0))
513          (const_string "yes")]
514         (const_string "no")))
515
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520         (const_string "no")))
521
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527          (const_string "yes")]
528         (const_string "no")))
529
530 (define_attr "any_int_load" "yes,no"
531   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532          (const_string "yes")]
533         (const_string "no")))
534
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536   (const_string "user"))
537
538 (define_delay
539   (eq_attr "needs_delay_slot" "yes")
540   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
541
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
546
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
549
550 (define_delay
551   (eq_attr "type" "return")
552   [(and (eq_attr "in_delay_slot" "yes")
553         (ior (and (eq_attr "interrupt_function" "no")
554                   (eq_attr "type" "!pload,prset"))
555              (and (eq_attr "interrupt_function" "yes")
556                   (ior
557                    (not (match_test "TARGET_SH3"))
558                    (eq_attr "hit_stack" "no")
559                    (eq_attr "banked" "no"))))) (nil) (nil)])
560
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
563
564 (define_delay
565   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566   [(and (eq_attr "in_delay_slot" "yes")
567         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
568
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
571
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
575
576 (define_delay
577   (and (eq_attr "type" "cbranch")
578        (match_test "TARGET_SH2"))
579   ;; SH2e has a hardware bug that pretty much prohibits the use of
580   ;; annuled delay slots.
581   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
583 \f
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
587
588 (define_insn ""
589   [(set (reg:SI T_REG)
590         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
591                        (match_operand:SI 1 "logical_operand" "K08,r"))
592                (const_int 0)))]
593   "TARGET_SH1"
594   "tst  %1,%0"
595   [(set_attr "type" "mt_group")])
596
597 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
598 ;; That would still allow reload to create cmpi instructions, but would
599 ;; perhaps allow forcing the constant into a register when that is better.
600 ;; Probably should use r0 for mem/imm compares, but force constant into a
601 ;; register for pseudo/imm compares.
602
603 (define_insn "cmpeqsi_t"
604   [(set (reg:SI T_REG)
605         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
606                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
607   "TARGET_SH1"
608   "@
609         tst     %0,%0
610         cmp/eq  %1,%0
611         cmp/eq  %1,%0"
612    [(set_attr "type" "mt_group")])
613
614 (define_insn "cmpgtsi_t"
615   [(set (reg:SI T_REG)
616         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
617                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
618   "TARGET_SH1"
619   "@
620         cmp/gt  %1,%0
621         cmp/pl  %0"
622    [(set_attr "type" "mt_group")])
623
624 (define_insn "cmpgesi_t"
625   [(set (reg:SI T_REG)
626         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
627                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
628   "TARGET_SH1"
629   "@
630         cmp/ge  %1,%0
631         cmp/pz  %0"
632    [(set_attr "type" "mt_group")])
633
634 ;; -------------------------------------------------------------------------
635 ;; SImode compare and branch
636 ;; -------------------------------------------------------------------------
637
638 (define_expand "cbranchsi4"
639   [(set (pc)
640         (if_then_else (match_operator 0 "comparison_operator"
641                         [(match_operand:SI 1 "arith_operand" "")
642                          (match_operand:SI 2 "arith_operand" "")])
643                       (label_ref (match_operand 3 "" ""))
644                       (pc)))
645    (clobber (reg:SI T_REG))]
646   ""
647   "if (TARGET_SHMEDIA)
648       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
649                                              operands[2], operands[3]));
650    else if (TARGET_CBRANCHDI4)
651      expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
652    else
653      sh_emit_compare_and_branch (operands, SImode);
654    DONE;")
655
656 ;; -------------------------------------------------------------------------
657 ;; SImode unsigned integer comparisons
658 ;; -------------------------------------------------------------------------
659
660 (define_insn_and_split "cmpgeusi_t"
661   [(set (reg:SI T_REG)
662         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
664   "TARGET_SH1"
665   "cmp/hs       %1,%0"
666   "&& operands[1] == CONST0_RTX (SImode)"
667   [(pc)]
668   "
669 {
670   emit_insn (gen_sett ());
671   DONE;
672 }"
673    [(set_attr "type" "mt_group")])
674
675 (define_insn "cmpgtusi_t"
676   [(set (reg:SI T_REG)
677         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
678                 (match_operand:SI 1 "arith_reg_operand" "r")))]
679   "TARGET_SH1"
680   "cmp/hi       %1,%0"
681    [(set_attr "type" "mt_group")])
682
683 \f
684 ;; -------------------------------------------------------------------------
685 ;; DImode compare and branch
686 ;; -------------------------------------------------------------------------
687
688
689 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
690 ;; Therefore, we aim to have a set of three branches that go straight to the
691 ;; destination, i.e. only one of them is taken at any one time.
692 ;; This mechanism should also be slightly better for the sh4-200.
693
694 (define_expand "cbranchdi4"
695   [(set (pc)
696         (if_then_else (match_operator 0 "comparison_operator"
697                         [(match_operand:DI 1 "arith_operand" "")
698                          (match_operand:DI 2 "arith_operand" "")])
699                       (label_ref (match_operand 3 "" ""))
700                       (pc)))
701    (clobber (match_dup 4))
702    (clobber (reg:SI T_REG))]
703   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
704   "
705 {
706   enum rtx_code comparison;
707
708   if (TARGET_SHMEDIA)
709     {
710       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
711                                              operands[2], operands[3]));
712       DONE;
713     }
714
715   else if (!TARGET_CBRANCHDI4)
716     {
717       sh_emit_compare_and_branch (operands, DImode);
718       DONE;
719     }
720
721   else
722     {
723       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
724         DONE;
725
726       comparison = prepare_cbranch_operands (operands, DImode,
727                                              LAST_AND_UNUSED_RTX_CODE);
728       if (comparison != GET_CODE (operands[0]))
729         operands[0]
730           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
731        operands[4] = gen_rtx_SCRATCH (SImode);
732     }
733 }")
734
735 (define_insn_and_split "cbranchdi4_i"
736   [(set (pc)
737         (if_then_else (match_operator 0 "comparison_operator"
738                         [(match_operand:DI 1 "arith_operand" "r,r")
739                          (match_operand:DI 2 "arith_operand" "rN,I08")])
740                       (label_ref (match_operand 3 "" ""))
741                       (pc)))
742    (clobber (match_scratch:SI 4 "=X,&r"))
743    (clobber (reg:SI T_REG))]
744   "TARGET_CBRANCHDI4"
745   "#"
746   "&& reload_completed"
747   [(pc)]
748   "
749 {
750   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
751     FAIL;
752   DONE;
753 }")
754
755 ;; -------------------------------------------------------------------------
756 ;; DImode signed integer comparisons
757 ;; -------------------------------------------------------------------------
758
759 (define_insn ""
760   [(set (reg:SI T_REG)
761         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
762                        (match_operand:DI 1 "arith_operand" "r"))
763                (const_int 0)))]
764   "TARGET_SH1"
765   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
766                                  insn, operands);"
767   [(set_attr "length" "6")
768    (set_attr "type" "arith3b")])
769
770 (define_insn "cmpeqdi_t"
771   [(set (reg:SI T_REG)
772         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
774   "TARGET_SH1"
775   "@
776         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
777         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
778   [(set_attr "length" "6")
779    (set_attr "type" "arith3b")])
780
781 (define_split
782   [(set (reg:SI T_REG)
783         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
784                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
785 ;; If we applied this split when not optimizing, it would only be
786 ;; applied during the machine-dependent reorg, when no new basic blocks
787 ;; may be created.
788   "TARGET_SH1 && reload_completed && optimize"
789   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
790    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
791                            (label_ref (match_dup 6))
792                            (pc)))
793    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
794    (match_dup 6)]
795   "
796 {
797   operands[2]
798     = gen_rtx_REG (SImode,
799                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
800   operands[3]
801     = (operands[1] == const0_rtx
802        ? const0_rtx
803        : gen_rtx_REG (SImode,
804                       true_regnum (operands[1])
805                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
806   operands[4] = gen_lowpart (SImode, operands[0]);
807   operands[5] = gen_lowpart (SImode, operands[1]);
808   operands[6] = gen_label_rtx ();
809 }")
810
811 (define_insn "cmpgtdi_t"
812   [(set (reg:SI T_REG)
813         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
814                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
815   "TARGET_SH2"
816   "@
817         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
818         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
819   [(set_attr "length" "8")
820    (set_attr "type" "arith3")])
821
822 (define_insn "cmpgedi_t"
823   [(set (reg:SI T_REG)
824         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
825                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
826   "TARGET_SH2"
827   "@
828         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
829         cmp/pz\\t%S0"
830   [(set_attr "length" "8,2")
831    (set_attr "type" "arith3,mt_group")])
832 \f
833 ;; -------------------------------------------------------------------------
834 ;; DImode unsigned integer comparisons
835 ;; -------------------------------------------------------------------------
836
837 (define_insn "cmpgeudi_t"
838   [(set (reg:SI T_REG)
839         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
840                 (match_operand:DI 1 "arith_reg_operand" "r")))]
841   "TARGET_SH2"
842   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
843   [(set_attr "length" "8")
844    (set_attr "type" "arith3")])
845
846 (define_insn "cmpgtudi_t"
847   [(set (reg:SI T_REG)
848         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
849                 (match_operand:DI 1 "arith_reg_operand" "r")))]
850   "TARGET_SH2"
851   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
852   [(set_attr "length" "8")
853    (set_attr "type" "arith3")])
854
855 (define_insn "cmpeqsi_media"
856   [(set (match_operand:SI 0 "register_operand" "=r")
857         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
858                (match_operand:SI 2 "cmp_operand" "Nr")))]
859   "TARGET_SHMEDIA"
860   "cmpeq        %1, %N2, %0"
861   [(set_attr "type" "cmp_media")])
862
863 (define_insn "cmpeqdi_media"
864   [(set (match_operand:SI 0 "register_operand" "=r")
865         (eq:SI (match_operand:DI 1 "register_operand" "%r")
866                (match_operand:DI 2 "cmp_operand" "Nr")))]
867   "TARGET_SHMEDIA"
868   "cmpeq        %1, %N2, %0"
869   [(set_attr "type" "cmp_media")])
870
871 (define_insn "cmpgtsi_media"
872   [(set (match_operand:SI 0 "register_operand" "=r")
873         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
874                (match_operand:SI 2 "cmp_operand" "rN")))]
875   "TARGET_SHMEDIA"
876   "cmpgt        %N1, %N2, %0"
877   [(set_attr "type" "cmp_media")])
878
879 (define_insn "cmpgtdi_media"
880   [(set (match_operand:SI 0 "register_operand" "=r")
881         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
882                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
883   "TARGET_SHMEDIA"
884   "cmpgt        %N1, %N2, %0"
885   [(set_attr "type" "cmp_media")])
886
887 (define_insn "cmpgtusi_media"
888   [(set (match_operand:SI 0 "register_operand" "=r")
889         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
890                 (match_operand:SI 2 "cmp_operand" "rN")))]
891   "TARGET_SHMEDIA"
892   "cmpgtu       %N1, %N2, %0"
893   [(set_attr "type" "cmp_media")])
894
895 (define_insn "cmpgtudi_media"
896   [(set (match_operand:SI 0 "register_operand" "=r")
897         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
898                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
899   "TARGET_SHMEDIA"
900   "cmpgtu       %N1, %N2, %0"
901   [(set_attr "type" "cmp_media")])
902
903 ; These two patterns are for combine.
904 (define_insn "*cmpne0sisi_media"
905   [(set (match_operand:SI 0 "register_operand" "=r")
906         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
907   "TARGET_SHMEDIA"
908   "cmpgtu       %1,r63,%0"
909   [(set_attr "type" "cmp_media")])
910
911 ;; -------------------------------------------------------------------------
912 ;; Conditional move instructions
913 ;; -------------------------------------------------------------------------
914
915 ;; The insn names may seem reversed, but note that cmveq performs the move
916 ;; if op1 == 0, and cmvne does it if op1 != 0.
917
918 (define_insn "movdicc_false"
919   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
920         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
921                              (const_int 0))
922          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
923          (match_operand:DI 3 "arith_reg_operand" "0")))]
924   "TARGET_SHMEDIA"
925   "cmveq        %1, %N2, %0"
926   [(set_attr "type" "arith_media")])
927
928 (define_insn "movdicc_true"
929   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
930         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
931                              (const_int 0))
932          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
933          (match_operand:DI 3 "arith_reg_operand" "0")))]
934   "TARGET_SHMEDIA"
935   "cmvne        %1, %N2, %0"
936   [(set_attr "type" "arith_media")])
937
938 (define_peephole2
939   [(set (match_operand:DI 0 "arith_reg_dest" "")
940         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
941                            [(match_operand:DI 1 "arith_reg_operand" "")
942                             (const_int 0)])
943          (match_operand:DI 2 "arith_reg_dest" "")
944          (match_dup 0)))
945    (set (match_dup 2) (match_dup 0))]
946   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
947   [(set (match_dup 2)
948         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
949   "
950 {
951   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
952                                 VOIDmode, operands[1], CONST0_RTX (DImode));
953 }")
954
955 (define_peephole2
956   [(set (match_operand:DI 0 "general_movdst_operand" "")
957         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
958    (set (match_operand:DI 2 "arith_reg_dest" "")
959         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
960                            [(match_operand:DI 3 "arith_reg_operand" "")
961                             (const_int 0)])
962          (match_dup 0)
963          (match_dup 2)))]
964   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
965   [(set (match_dup 2)
966         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
967   "")
968
969 (define_expand "movdicc"
970   [(set (match_operand:DI 0 "register_operand" "")
971         (if_then_else:DI (match_operand 1 "comparison_operator" "")
972                          (match_operand:DI 2 "register_operand" "")
973                          (match_operand:DI 3 "register_operand" "")))]
974   "TARGET_SHMEDIA"
975   "
976 {
977   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
978       && GET_MODE (XEXP (operands[1], 0)) == DImode
979       && XEXP (operands[1], 1) == const0_rtx)
980     ;
981   else
982     {
983       if (!can_create_pseudo_p ())
984         FAIL;
985
986       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
987                                               GET_CODE (operands[1]),
988                                               XEXP (operands[1], 0),
989                                               XEXP (operands[1], 1));
990       if (!operands[1])
991         FAIL;
992     }
993 }")
994
995 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
996 ;; SImode to DImode.
997 (define_insn "movsicc_false"
998   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
999         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1000                           (const_int 0))
1001          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1002          (match_operand:SI 3 "arith_reg_operand" "0")))]
1003   "TARGET_SHMEDIA"
1004   "cmveq        %1, %N2, %0"
1005   [(set_attr "type" "arith_media")])
1006
1007 (define_insn "movsicc_true"
1008   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1009         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1010                           (const_int 0))
1011          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1012          (match_operand:SI 3 "arith_reg_operand" "0")))]
1013   "TARGET_SHMEDIA"
1014   "cmvne        %1, %N2, %0"
1015   [(set_attr "type" "arith_media")])
1016
1017 (define_peephole2
1018   [(set (match_operand:SI 0 "arith_reg_dest" "")
1019         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1020                            [(match_operand:SI 1 "arith_reg_operand" "")
1021                             (const_int 0)])
1022          (match_operand:SI 2 "arith_reg_dest" "")
1023          (match_dup 0)))
1024    (set (match_dup 2) (match_dup 0))]
1025   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1026   [(set (match_dup 2)
1027         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1028   "
1029 {
1030   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1031                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1032 }")
1033
1034 (define_peephole2
1035   [(set (match_operand:SI 0 "general_movdst_operand" "")
1036         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1037    (set (match_operand:SI 2 "arith_reg_dest" "")
1038         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1039                            [(match_operand:SI 3 "arith_reg_operand" "")
1040                             (const_int 0)])
1041          (match_dup 0)
1042          (match_dup 2)))]
1043   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1044    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1045   [(set (match_dup 2)
1046         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1047   "
1048 {
1049   replace_rtx (operands[4], operands[0], operands[1]);
1050 }")
1051
1052 (define_peephole2
1053   [(set (match_operand 0 "any_register_operand" "")
1054         (match_operand 1 "any_register_operand" ""))
1055    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1056    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1057   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1058     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1059    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1060    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1061    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1062    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1063    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1064    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1065    && (REGNO_REG_CLASS (REGNO (operands[0]))
1066        == REGNO_REG_CLASS (REGNO (operands[2])))
1067    && (REGNO_REG_CLASS (REGNO (operands[1]))
1068        == REGNO_REG_CLASS (REGNO (operands[0])))"
1069   [(set (match_dup 0) (match_dup 3))
1070    (set (match_dup 4) (match_dup 5))]
1071   "
1072 {
1073   rtx set1, set2, insn2;
1074   rtx replacements[4];
1075
1076   /* We want to replace occurrences of operands[0] with operands[1] and
1077      operands[2] with operands[0] in operands[4]/operands[5].
1078      Doing just two replace_rtx calls naively would result in the second
1079      replacement undoing all that the first did if operands[1] and operands[2]
1080      are identical, so we must do this simultaneously.  */
1081   replacements[0] = operands[0];
1082   replacements[1] = operands[1];
1083   replacements[2] = operands[2];
1084   replacements[3] = operands[0];
1085   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1086       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1087       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1088     FAIL;
1089
1090   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1091   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1092   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1093   /* The operands array is aliased to recog_data.operand, which gets
1094      clobbered by extract_insn, so finish with it now.  */
1095   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1096   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1097   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1098      always uses emit_insn.  */
1099   /* Check that we don't violate matching constraints or earlyclobbers.  */
1100   extract_insn (emit_insn (set1));
1101   if (! constrain_operands (1))
1102     goto failure;
1103   insn2 = emit (set2);
1104   if (GET_CODE (insn2) == BARRIER)
1105     goto failure;
1106   extract_insn (insn2);
1107   if (! constrain_operands (1))
1108     {
1109       rtx tmp;
1110     failure:
1111       tmp = replacements[0];
1112       replacements[0] = replacements[1];
1113       replacements[1] = tmp;
1114       tmp = replacements[2];
1115       replacements[2] = replacements[3];
1116       replacements[3] = tmp;
1117       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1118       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1119       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1120       FAIL;
1121     }
1122   DONE;
1123 }")
1124
1125 ;; The register allocator is rather clumsy in handling multi-way conditional
1126 ;; moves, so allow the combiner to make them, and we split them up after
1127 ;; reload.  */
1128 (define_insn_and_split "*movsicc_umin"
1129   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1130         (umin:SI (if_then_else:SI
1131                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1132                        (const_int 0))
1133                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1134                    (match_operand:SI 3 "register_operand" "0"))
1135                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1136    (clobber (match_scratch:SI 5 "=&r"))]
1137   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1138   "#"
1139   "TARGET_SHMEDIA && reload_completed"
1140   [(pc)]
1141   "
1142 {
1143   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1144                                 operands[3]));
1145   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1146   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1147                                 operands[0]));
1148   DONE;
1149 }")
1150
1151 (define_insn "*movsicc_t_false"
1152   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1153         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1154                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1155                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1156   "TARGET_PRETEND_CMOVE
1157    && (arith_reg_operand (operands[1], SImode)
1158        || (immediate_operand (operands[1], SImode)
1159            && satisfies_constraint_I08 (operands[1])))"
1160   "bt 0f\;mov %1,%0\\n0:"
1161   [(set_attr "type" "mt_group,arith") ;; poor approximation
1162    (set_attr "length" "4")])
1163
1164 (define_insn "*movsicc_t_true"
1165   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1166         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1167                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1168                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1169   "TARGET_PRETEND_CMOVE
1170    && (arith_reg_operand (operands[1], SImode)
1171        || (immediate_operand (operands[1], SImode)
1172            && satisfies_constraint_I08 (operands[1])))"
1173   "bf 0f\;mov %1,%0\\n0:"
1174   [(set_attr "type" "mt_group,arith") ;; poor approximation
1175    (set_attr "length" "4")])
1176
1177 (define_expand "movsicc"
1178   [(set (match_operand:SI 0 "arith_reg_dest" "")
1179         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1180                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1181                          (match_operand:SI 3 "arith_reg_operand" "")))]
1182   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1183   "
1184 {
1185   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1186       && GET_MODE (XEXP (operands[1], 0)) == SImode
1187       && (TARGET_SHMEDIA
1188           || (REG_P (XEXP (operands[1], 0))
1189               && REGNO (XEXP (operands[1], 0)) == T_REG))
1190       && XEXP (operands[1], 1) == const0_rtx)
1191     ;
1192
1193   else if (TARGET_PRETEND_CMOVE)
1194     {
1195       enum rtx_code code = GET_CODE (operands[1]);
1196       enum rtx_code new_code = code;
1197       rtx op0 = XEXP (operands[1], 0);
1198       rtx op1 = XEXP (operands[1], 1);
1199
1200       if (! currently_expanding_to_rtl)
1201         FAIL;
1202       switch (code)
1203         {
1204         case LT: case LE: case LEU: case LTU:
1205           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1206             break;
1207         case NE:
1208           new_code = reverse_condition (code);
1209           break;
1210         case EQ: case GT: case GE: case GEU: case GTU:
1211           break;
1212         default:
1213           FAIL;
1214         }
1215       sh_emit_scc_to_t (new_code, op0, op1);
1216       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1217                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1218     }
1219   else
1220     {
1221       if (!can_create_pseudo_p ())
1222         FAIL;
1223
1224       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1225                                               GET_CODE (operands[1]),
1226                                               XEXP (operands[1], 0),
1227                                               XEXP (operands[1], 1));
1228       if (!operands[1])
1229         FAIL;
1230     }
1231 }")
1232
1233 (define_expand "movqicc"
1234   [(set (match_operand:QI 0 "register_operand" "")
1235         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1236                          (match_operand:QI 2 "register_operand" "")
1237                          (match_operand:QI 3 "register_operand" "")))]
1238   "TARGET_SHMEDIA"
1239   "
1240 {
1241   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1242   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1243   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1244   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1245   DONE;
1246 }")
1247 \f
1248 ;; -------------------------------------------------------------------------
1249 ;; Addition instructions
1250 ;; -------------------------------------------------------------------------
1251
1252 (define_expand "adddi3"
1253   [(set (match_operand:DI 0 "arith_reg_operand" "")
1254         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1255                  (match_operand:DI 2 "arith_operand" "")))]
1256   ""
1257   "
1258 {
1259   if (TARGET_SH1)
1260     {
1261       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1262         FAIL;
1263       operands[2] = force_reg (DImode, operands[2]);
1264       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1265       DONE;
1266     }
1267 }")
1268
1269 (define_insn "*adddi3_media"
1270   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1271         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1272                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1273   "TARGET_SHMEDIA"
1274   "@
1275         add     %1, %2, %0
1276         addi    %1, %2, %0"
1277   [(set_attr "type" "arith_media")])
1278
1279 (define_insn "*adddisi3_media"
1280   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1281         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1282                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1283   "TARGET_SHMEDIA"
1284   "@
1285         add.l   %1, %2, %0
1286         addi.l  %1, %2, %0"
1287   [(set_attr "type" "arith_media")
1288    (set_attr "highpart" "ignore")])
1289
1290 (define_insn "adddi3z_media"
1291   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1292         (zero_extend:DI
1293          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1294                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1295   "TARGET_SHMEDIA"
1296   "addz.l       %1, %N2, %0"
1297   [(set_attr "type" "arith_media")
1298    (set_attr "highpart" "ignore")])
1299
1300 (define_insn "adddi3_compact"
1301   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1302         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1303                  (match_operand:DI 2 "arith_reg_operand" "r")))
1304    (clobber (reg:SI T_REG))]
1305   "TARGET_SH1"
1306   "#"
1307   [(set_attr "length" "6")])
1308
1309 (define_split
1310   [(set (match_operand:DI 0 "arith_reg_dest" "")
1311         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1312                  (match_operand:DI 2 "arith_reg_operand" "")))
1313    (clobber (reg:SI T_REG))]
1314   "TARGET_SH1 && reload_completed"
1315   [(const_int 0)]
1316   "
1317 {
1318   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1319   high0 = gen_rtx_REG (SImode,
1320                        true_regnum (operands[0])
1321                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1322   high2 = gen_rtx_REG (SImode,
1323                        true_regnum (operands[2])
1324                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325   emit_insn (gen_clrt ());
1326   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1327   emit_insn (gen_addc1 (high0, high0, high2));
1328   DONE;
1329 }")
1330
1331 (define_insn "addc"
1332   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1333         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1334                           (match_operand:SI 2 "arith_reg_operand" "r"))
1335                  (reg:SI T_REG)))
1336    (set (reg:SI T_REG)
1337         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1338   "TARGET_SH1"
1339   "addc %2,%0"
1340   [(set_attr "type" "arith")])
1341
1342 (define_insn "addc1"
1343   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1344         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1345                           (match_operand:SI 2 "arith_reg_operand" "r"))
1346                  (reg:SI T_REG)))
1347    (clobber (reg:SI T_REG))]
1348   "TARGET_SH1"
1349   "addc %2,%0"
1350   [(set_attr "type" "arith")])
1351
1352 (define_expand "addsi3"
1353   [(set (match_operand:SI 0 "arith_reg_operand" "")
1354         (plus:SI (match_operand:SI 1 "arith_operand" "")
1355                  (match_operand:SI 2 "arith_operand" "")))]
1356   ""
1357   "
1358 {
1359   if (TARGET_SHMEDIA)
1360     operands[1] = force_reg (SImode, operands[1]);
1361 }")
1362
1363 (define_insn "addsi3_media"
1364   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1365         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1366                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1367   "TARGET_SHMEDIA"
1368   "@
1369         add.l   %1, %2, %0
1370         addi.l  %1, %2, %0"
1371   [(set_attr "type" "arith_media")
1372    (set_attr "highpart" "ignore")])
1373
1374 (define_insn "addsidi3_media"
1375   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1376         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1377                                   "%r,r")
1378                                  (match_operand:SI 2 "arith_operand"
1379                                   "r,I10"))))]
1380   "TARGET_SHMEDIA"
1381   "@
1382         add.l   %1, %2, %0
1383         addi.l  %1, %2, %0"
1384   [(set_attr "type" "arith_media")
1385    (set_attr "highpart" "ignore")])
1386
1387 (define_insn "*addsi3_compact"
1388   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1389         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1390                  (match_operand:SI 2 "arith_operand" "rI08")))]
1391   "TARGET_SH1"
1392   "add  %2,%0"
1393   [(set_attr "type" "arith")])
1394
1395 ;; -------------------------------------------------------------------------
1396 ;; Subtraction instructions
1397 ;; -------------------------------------------------------------------------
1398
1399 (define_expand "subdi3"
1400   [(set (match_operand:DI 0 "arith_reg_operand" "")
1401         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1402                   (match_operand:DI 2 "arith_reg_operand" "")))]
1403   ""
1404   "
1405 {
1406   if (TARGET_SH1)
1407     {
1408       operands[1] = force_reg (DImode, operands[1]);
1409       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1410       DONE;
1411     }
1412 }")
1413
1414 (define_insn "*subdi3_media"
1415   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1416         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1417                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1418   "TARGET_SHMEDIA"
1419   "sub  %N1, %2, %0"
1420   [(set_attr "type" "arith_media")])
1421   
1422 (define_insn "subdisi3_media"
1423   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1424         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1425                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1426   "TARGET_SHMEDIA"
1427   "sub.l        %N1, %2, %0"
1428   [(set_attr "type" "arith_media")
1429    (set_attr "highpart" "ignore")])
1430
1431 (define_insn "subdi3_compact"
1432   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1433         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1434                  (match_operand:DI 2 "arith_reg_operand" "r")))
1435    (clobber (reg:SI T_REG))]
1436   "TARGET_SH1"
1437   "#"
1438   [(set_attr "length" "6")])
1439
1440 (define_split
1441   [(set (match_operand:DI 0 "arith_reg_dest" "")
1442         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1443                   (match_operand:DI 2 "arith_reg_operand" "")))
1444    (clobber (reg:SI T_REG))]
1445   "TARGET_SH1 && reload_completed"
1446   [(const_int 0)]
1447   "
1448 {
1449   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1450   high0 = gen_rtx_REG (SImode,
1451                        true_regnum (operands[0])
1452                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1453   high2 = gen_rtx_REG (SImode,
1454                        true_regnum (operands[2])
1455                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456   emit_insn (gen_clrt ());
1457   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1458   emit_insn (gen_subc1 (high0, high0, high2));
1459   DONE;
1460 }")
1461
1462 (define_insn "subc"
1463   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1464         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1465                             (match_operand:SI 2 "arith_reg_operand" "r"))
1466                   (reg:SI T_REG)))
1467    (set (reg:SI T_REG)
1468         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1469                           (reg:SI T_REG))
1470                 (match_dup 1)))]
1471   "TARGET_SH1"
1472   "subc %2,%0"
1473   [(set_attr "type" "arith")])
1474
1475 (define_insn "subc1"
1476   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1477         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1478                             (match_operand:SI 2 "arith_reg_operand" "r"))
1479                   (reg:SI T_REG)))
1480    (clobber (reg:SI T_REG))]
1481   "TARGET_SH1"
1482   "subc %2,%0"
1483   [(set_attr "type" "arith")])
1484
1485 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1486 ;; pattern for this case.  This helps multimedia applications that compute
1487 ;; the sum of absolute differences.
1488 (define_insn "mov_neg_si_t"
1489   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1490   "TARGET_SH1"
1491   "subc %0,%0"
1492   [(set_attr "type" "arith")])
1493
1494 (define_insn "*subsi3_internal"
1495   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1496         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1497                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1498   "TARGET_SH1"
1499   "sub  %2,%0"
1500   [(set_attr "type" "arith")])
1501
1502 (define_insn_and_split "*subsi3_media"
1503   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1504         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1505                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1506   "TARGET_SHMEDIA
1507    && (operands[1] != constm1_rtx
1508        || (GET_CODE (operands[2]) != TRUNCATE
1509            && GET_CODE (operands[2]) != SUBREG))"
1510   "sub.l        %N1, %2, %0"
1511   "operands[1] == constm1_rtx"
1512   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1513   ""
1514   [(set_attr "type" "arith_media")
1515    (set_attr "highpart" "ignore")])
1516
1517 (define_split
1518   [(set (match_operand:SI 0 "arith_reg_dest" "")
1519         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1520                                                        "general_extend_operand"
1521                                                        "") 0)) 0)))]
1522   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1523   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1524    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1525   "")
1526
1527 (define_split
1528   [(set (match_operand:SI 0 "arith_reg_dest" "")
1529         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1530                                                        "general_extend_operand"
1531                                                        "") 0)) 3)))]
1532   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1533   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1534    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1535   "")
1536 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1537 ;; will sometimes save one instruction.  Otherwise we might get
1538 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1539 ;; are the same.
1540
1541 (define_expand "subsi3"
1542   [(set (match_operand:SI 0 "arith_reg_operand" "")
1543         (minus:SI (match_operand:SI 1 "arith_operand" "")
1544                   (match_operand:SI 2 "arith_reg_operand" "")))]
1545   ""
1546   "
1547 {
1548   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1549     {
1550       emit_insn (gen_negsi2 (operands[0], operands[2]));
1551       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1552       DONE;
1553     }
1554   if (TARGET_SHMEDIA)
1555     {
1556       if (!can_create_pseudo_p ()
1557           && ! arith_reg_or_0_operand (operands[1], SImode))
1558         FAIL;
1559       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1560         operands[1] = force_reg (SImode, operands[1]);
1561     }
1562 }")
1563 \f
1564 ;; -------------------------------------------------------------------------
1565 ;; Division instructions
1566 ;; -------------------------------------------------------------------------
1567
1568 ;; We take advantage of the library routines which don't clobber as many
1569 ;; registers as a normal function call would.
1570
1571 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1572 ;; also has an effect on the register that holds the address of the sfunc.
1573 ;; To make this work, we have an extra dummy insn that shows the use
1574 ;; of this register for reorg.
1575
1576 (define_insn "use_sfunc_addr"
1577   [(set (reg:SI PR_REG)
1578         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1579   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1580   ""
1581   [(set_attr "length" "0")])
1582
1583 (define_insn "udivsi3_sh2a"
1584   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1585         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1586                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1587   "TARGET_SH2A"
1588   "divu %2,%1"
1589   [(set_attr "type" "arith")
1590    (set_attr "in_delay_slot" "no")])
1591
1592 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1593 ;; hard register 0.  If we used hard register 0, then the next instruction
1594 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1595 ;; gets allocated to a stack slot that needs its address reloaded, then
1596 ;; there is nothing to prevent reload from using r0 to reload the address.
1597 ;; This reload would clobber the value in r0 we are trying to store.
1598 ;; If we let reload allocate r0, then this problem can never happen.
1599
1600 (define_insn "udivsi3_i1"
1601   [(set (match_operand:SI 0 "register_operand" "=z")
1602         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1603    (clobber (reg:SI T_REG))
1604    (clobber (reg:SI PR_REG))
1605    (clobber (reg:SI R4_REG))
1606    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1607   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1608   "jsr  @%1%#"
1609   [(set_attr "type" "sfunc")
1610    (set_attr "needs_delay_slot" "yes")])
1611
1612 ; Since shmedia-nofpu code could be linked against shcompact code, and
1613 ; the udivsi3 libcall has the same name, we must consider all registers
1614 ; clobbered that are in the union of the registers clobbered by the
1615 ; shmedia and the shcompact implementation.  Note, if the shcompact
1616 ; implementation actually used shcompact code, we'd need to clobber
1617 ; also r23 and fr23.
1618 (define_insn "udivsi3_i1_media"
1619   [(set (match_operand:SI 0 "register_operand" "=z")
1620         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1621    (clobber (reg:SI T_MEDIA_REG))
1622    (clobber (reg:SI PR_MEDIA_REG))
1623    (clobber (reg:SI R20_REG))
1624    (clobber (reg:SI R21_REG))
1625    (clobber (reg:SI R22_REG))
1626    (clobber (reg:DI TR0_REG))
1627    (clobber (reg:DI TR1_REG))
1628    (clobber (reg:DI TR2_REG))
1629    (use (match_operand 1 "target_reg_operand" "b"))]
1630   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1631   "blink        %1, r18"
1632   [(set_attr "type" "sfunc")
1633    (set_attr "needs_delay_slot" "yes")])
1634
1635 (define_expand "udivsi3_i4_media"
1636   [(set (match_dup 3)
1637         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1638    (set (match_dup 4)
1639         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1640    (set (match_dup 5) (float:DF (match_dup 3)))
1641    (set (match_dup 6) (float:DF (match_dup 4)))
1642    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1643    (set (match_dup 8) (fix:DI (match_dup 7)))
1644    (set (match_operand:SI 0 "register_operand" "")
1645         (truncate:SI (match_dup 8)))]
1646   "TARGET_SHMEDIA_FPU"
1647   "
1648 {
1649   operands[3] = gen_reg_rtx (DImode);
1650   operands[4] = gen_reg_rtx (DImode);
1651   operands[5] = gen_reg_rtx (DFmode);
1652   operands[6] = gen_reg_rtx (DFmode);
1653   operands[7] = gen_reg_rtx (DFmode);
1654   operands[8] = gen_reg_rtx (DImode);
1655 }")
1656
1657 (define_insn "udivsi3_i4"
1658   [(set (match_operand:SI 0 "register_operand" "=y")
1659         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1660    (clobber (reg:SI T_REG))
1661    (clobber (reg:SI PR_REG))
1662    (clobber (reg:DF DR0_REG))
1663    (clobber (reg:DF DR2_REG))
1664    (clobber (reg:DF DR4_REG))
1665    (clobber (reg:SI R0_REG))
1666    (clobber (reg:SI R1_REG))
1667    (clobber (reg:SI R4_REG))
1668    (clobber (reg:SI R5_REG))
1669    (use (reg:PSI FPSCR_REG))
1670    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1671   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1672   "jsr  @%1%#"
1673   [(set_attr "type" "sfunc")
1674    (set_attr "fp_mode" "double")
1675    (set_attr "needs_delay_slot" "yes")])
1676
1677 (define_insn "udivsi3_i4_single"
1678   [(set (match_operand:SI 0 "register_operand" "=y")
1679         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1680    (clobber (reg:SI T_REG))
1681    (clobber (reg:SI PR_REG))
1682    (clobber (reg:DF DR0_REG))
1683    (clobber (reg:DF DR2_REG))
1684    (clobber (reg:DF DR4_REG))
1685    (clobber (reg:SI R0_REG))
1686    (clobber (reg:SI R1_REG))
1687    (clobber (reg:SI R4_REG))
1688    (clobber (reg:SI R5_REG))
1689    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1690   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1691   "jsr  @%1%#"
1692   [(set_attr "type" "sfunc")
1693    (set_attr "needs_delay_slot" "yes")])
1694
1695 (define_insn "udivsi3_i4_int"
1696   [(set (match_operand:SI 0 "register_operand" "=z")
1697         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1698    (clobber (reg:SI T_REG))
1699    (clobber (reg:SI R1_REG))
1700    (clobber (reg:SI PR_REG))
1701    (clobber (reg:SI MACH_REG))
1702    (clobber (reg:SI MACL_REG))
1703    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1704   "TARGET_SH1"
1705   "jsr  @%1%#"
1706   [(set_attr "type" "sfunc")
1707    (set_attr "needs_delay_slot" "yes")])
1708
1709
1710 (define_expand "udivsi3"
1711   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1712    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1713    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1714    (parallel [(set (match_operand:SI 0 "register_operand" "")
1715                    (udiv:SI (reg:SI R4_REG)
1716                             (reg:SI R5_REG)))
1717               (clobber (reg:SI T_REG))
1718               (clobber (reg:SI PR_REG))
1719               (clobber (reg:SI R4_REG))
1720               (use (match_dup 3))])]
1721   ""
1722   "
1723 {
1724   rtx last;
1725
1726   operands[3] = gen_reg_rtx (Pmode);
1727   /* Emit the move of the address to a pseudo outside of the libcall.  */
1728   if (TARGET_DIVIDE_CALL_TABLE)
1729     {
1730       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1731          that causes problems when the divide code is supposed to come from a
1732          separate library.  Division by zero is undefined, so dividing 1 can be
1733          implemented by comparing with the divisor.  */
1734       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1735         {
1736           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1737           emit_insn (gen_cstoresi4 (operands[0], test,
1738                                     operands[1], operands[2]));
1739           DONE;
1740         }
1741       else if (operands[2] == const0_rtx)
1742         {
1743           emit_move_insn (operands[0], operands[2]);
1744           DONE;
1745         }
1746       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1747       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1748     }
1749   else if (TARGET_DIVIDE_CALL_FP)
1750     {
1751       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1752       if (TARGET_FPU_SINGLE)
1753         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1754       else
1755         last = gen_udivsi3_i4 (operands[0], operands[3]);
1756     }
1757   else if (TARGET_SHMEDIA_FPU)
1758     {
1759       operands[1] = force_reg (SImode, operands[1]);
1760       operands[2] = force_reg (SImode, operands[2]);
1761       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1762       DONE;
1763     }
1764   else if (TARGET_SH2A)
1765     {
1766       operands[1] = force_reg (SImode, operands[1]);
1767       operands[2] = force_reg (SImode, operands[2]);
1768       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1769       DONE;
1770     }
1771   else if (TARGET_SH5)
1772     {
1773       function_symbol (operands[3],
1774                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1775                        SFUNC_STATIC);
1776
1777       if (TARGET_SHMEDIA)
1778         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1779       else if (TARGET_FPU_ANY)
1780         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1781       else
1782         last = gen_udivsi3_i1 (operands[0], operands[3]);
1783     }
1784   else
1785     {
1786       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1787       last = gen_udivsi3_i1 (operands[0], operands[3]);
1788     }
1789   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1790   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1791   emit_insn (last);
1792   DONE;
1793 }")
1794
1795 (define_insn "divsi3_sh2a"
1796   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1797         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1798                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1799   "TARGET_SH2A"
1800   "divs %2,%1"
1801   [(set_attr "type" "arith")
1802    (set_attr "in_delay_slot" "no")])
1803
1804 (define_insn "divsi3_i1"
1805   [(set (match_operand:SI 0 "register_operand" "=z")
1806         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1807    (clobber (reg:SI T_REG))
1808    (clobber (reg:SI PR_REG))
1809    (clobber (reg:SI R1_REG))
1810    (clobber (reg:SI R2_REG))
1811    (clobber (reg:SI R3_REG))
1812    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1813   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1814   "jsr  @%1%#"
1815   [(set_attr "type" "sfunc")
1816    (set_attr "needs_delay_slot" "yes")])
1817
1818 (define_insn "divsi3_i1_media"
1819   [(set (match_operand:SI 0 "register_operand" "=z")
1820         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1821    (clobber (reg:SI T_MEDIA_REG))
1822    (clobber (reg:SI PR_MEDIA_REG))
1823    (clobber (reg:SI R1_REG))
1824    (clobber (reg:SI R20_REG))
1825    (clobber (reg:SI R21_REG))
1826    (clobber (reg:SI TR0_REG))
1827    (use (match_operand 1 "target_reg_operand" "b"))]
1828   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1829   "blink        %1, r18"
1830   [(set_attr "type" "sfunc")])
1831
1832 (define_insn "divsi3_media_2"
1833   [(set (match_operand:SI 0 "register_operand" "=z")
1834         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1835    (clobber (reg:SI T_MEDIA_REG))
1836    (clobber (reg:SI PR_MEDIA_REG))
1837    (clobber (reg:SI R1_REG))
1838    (clobber (reg:SI R21_REG))
1839    (clobber (reg:SI TR0_REG))
1840    (use (reg:SI R20_REG))
1841    (use (match_operand 1 "target_reg_operand" "b"))]
1842   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1843   "blink        %1, r18"
1844   [(set_attr "type" "sfunc")])
1845
1846 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1847 ;; hard reg clobbers and data dependencies that we need when we want
1848 ;; to rematerialize the division into a call.
1849 (define_insn_and_split "divsi_inv_call"
1850   [(set (match_operand:SI 0 "register_operand" "=r")
1851         (div:SI (match_operand:SI 1 "register_operand" "r")
1852                 (match_operand:SI 2 "register_operand" "r")))
1853    (clobber (reg:SI R4_REG))
1854    (clobber (reg:SI R5_REG))
1855    (clobber (reg:SI T_MEDIA_REG))
1856    (clobber (reg:SI PR_MEDIA_REG))
1857    (clobber (reg:SI R1_REG))
1858    (clobber (reg:SI R21_REG))
1859    (clobber (reg:SI TR0_REG))
1860    (clobber (reg:SI R20_REG))
1861    (use (match_operand:SI 3 "register_operand" "r"))]
1862   "TARGET_SHMEDIA"
1863   "#"
1864   "&& (high_life_started || reload_completed)"
1865   [(set (match_dup 0) (match_dup 3))]
1866   ""
1867   [(set_attr "highpart" "must_split")])
1868
1869 ;; This is the combiner pattern for -mdiv=inv:call .
1870 (define_insn_and_split "*divsi_inv_call_combine"
1871   [(set (match_operand:SI 0 "register_operand" "=z")
1872         (div:SI (match_operand:SI 1 "register_operand" "r")
1873                 (match_operand:SI 2 "register_operand" "r")))
1874    (clobber (reg:SI R4_REG))
1875    (clobber (reg:SI R5_REG))
1876    (clobber (reg:SI T_MEDIA_REG))
1877    (clobber (reg:SI PR_MEDIA_REG))
1878    (clobber (reg:SI R1_REG))
1879    (clobber (reg:SI R21_REG))
1880    (clobber (reg:SI TR0_REG))
1881    (clobber (reg:SI R20_REG))
1882    (use (unspec:SI [(match_dup 1)
1883                     (match_operand:SI 3 "" "")
1884                     (unspec:SI [(match_operand:SI 4 "" "")
1885                                 (match_dup 3)
1886                                 (match_operand:DI 5 "" "")]
1887                      UNSPEC_DIV_INV_M2)
1888                     (match_operand:DI 6 "" "")
1889                     (const_int 0)
1890                     (const_int 0)]
1891          UNSPEC_DIV_INV_M3))]
1892   "TARGET_SHMEDIA"
1893   "#"
1894   "&& (high_life_started || reload_completed)"
1895   [(pc)]
1896   "
1897 {
1898   const char *name = sh_divsi3_libfunc;
1899   enum sh_function_kind kind = SFUNC_GOT;
1900   rtx sym;
1901
1902   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1903   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1904   while (TARGET_DIVIDE_INV_CALL2)
1905     {
1906       rtx x = operands[3];
1907
1908       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1909         break;
1910       x = XVECEXP (x, 0, 0);
1911       name = \"__sdivsi3_2\";
1912       kind = SFUNC_STATIC;
1913       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1914       break;
1915     }
1916   sym = function_symbol (NULL, name, kind);
1917   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1918   DONE;
1919 }"
1920   [(set_attr "highpart" "must_split")])
1921
1922 (define_expand "divsi3_i4_media"
1923   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1924    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1925    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1926    (set (match_operand:SI 0 "register_operand" "=r")
1927         (fix:SI (match_dup 5)))]
1928   "TARGET_SHMEDIA_FPU"
1929   "
1930 {
1931   operands[3] = gen_reg_rtx (DFmode);
1932   operands[4] = gen_reg_rtx (DFmode);
1933   operands[5] = gen_reg_rtx (DFmode);
1934 }")
1935
1936 (define_insn "divsi3_i4"
1937   [(set (match_operand:SI 0 "register_operand" "=y")
1938         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1939    (clobber (reg:SI PR_REG))
1940    (clobber (reg:DF DR0_REG))
1941    (clobber (reg:DF DR2_REG))
1942    (use (reg:PSI FPSCR_REG))
1943    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1944   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1945   "jsr  @%1%#"
1946   [(set_attr "type" "sfunc")
1947    (set_attr "fp_mode" "double")
1948    (set_attr "needs_delay_slot" "yes")])
1949
1950 (define_insn "divsi3_i4_single"
1951   [(set (match_operand:SI 0 "register_operand" "=y")
1952         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1953    (clobber (reg:SI PR_REG))
1954    (clobber (reg:DF DR0_REG))
1955    (clobber (reg:DF DR2_REG))
1956    (clobber (reg:SI R2_REG))
1957    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1958   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1959   "jsr  @%1%#"
1960   [(set_attr "type" "sfunc")
1961    (set_attr "needs_delay_slot" "yes")])
1962
1963 (define_insn "divsi3_i4_int"
1964   [(set (match_operand:SI 0 "register_operand" "=z")
1965         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1966    (clobber (reg:SI T_REG))
1967    (clobber (reg:SI PR_REG))
1968    (clobber (reg:SI R1_REG))
1969    (clobber (reg:SI MACH_REG))
1970    (clobber (reg:SI MACL_REG))
1971    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1972   "TARGET_SH1"
1973   "jsr  @%1%#"
1974   [(set_attr "type" "sfunc")
1975    (set_attr "needs_delay_slot" "yes")])
1976
1977 (define_expand "divsi3"
1978   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1979    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1980    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1981    (parallel [(set (match_operand:SI 0 "register_operand" "")
1982                    (div:SI (reg:SI R4_REG)
1983                            (reg:SI R5_REG)))
1984               (clobber (reg:SI T_REG))
1985               (clobber (reg:SI PR_REG))
1986               (clobber (reg:SI R1_REG))
1987               (clobber (reg:SI R2_REG))
1988               (clobber (reg:SI R3_REG))
1989               (use (match_dup 3))])]
1990   ""
1991   "
1992 {
1993   rtx last;
1994
1995   operands[3] = gen_reg_rtx (Pmode);
1996   /* Emit the move of the address to a pseudo outside of the libcall.  */
1997   if (TARGET_DIVIDE_CALL_TABLE)
1998     {
1999       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2000       last = gen_divsi3_i4_int (operands[0], operands[3]);
2001     }
2002   else if (TARGET_DIVIDE_CALL_FP)
2003     {
2004       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2005       if (TARGET_FPU_SINGLE)
2006         last = gen_divsi3_i4_single (operands[0], operands[3]);
2007       else
2008         last = gen_divsi3_i4 (operands[0], operands[3]);
2009     }
2010   else if (TARGET_SH2A)
2011     {
2012       operands[1] = force_reg (SImode, operands[1]);
2013       operands[2] = force_reg (SImode, operands[2]);
2014       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2015       DONE;
2016     }
2017   else if (TARGET_DIVIDE_INV)
2018     {
2019       rtx dividend = operands[1];
2020       rtx divisor = operands[2];
2021       rtx tab_base;
2022       rtx nsb_res = gen_reg_rtx (DImode);
2023       rtx norm64 = gen_reg_rtx (DImode);
2024       rtx tab_ix = gen_reg_rtx (DImode);
2025       rtx norm32 = gen_reg_rtx (SImode);
2026       rtx i92 = force_reg (DImode, GEN_INT (92));
2027       rtx scratch0a = gen_reg_rtx (DImode);
2028       rtx scratch0b = gen_reg_rtx (DImode);
2029       rtx inv0 = gen_reg_rtx (SImode);
2030       rtx scratch1a = gen_reg_rtx (DImode);
2031       rtx scratch1b = gen_reg_rtx (DImode);
2032       rtx shift = gen_reg_rtx (DImode);
2033       rtx i2p27, i43;
2034       rtx inv1 = gen_reg_rtx (SImode);
2035       rtx scratch2a = gen_reg_rtx (DImode);
2036       rtx scratch2b = gen_reg_rtx (SImode);
2037       rtx inv2 = gen_reg_rtx (SImode);
2038       rtx scratch3a = gen_reg_rtx (DImode);
2039       rtx scratch3b = gen_reg_rtx (DImode);
2040       rtx scratch3c = gen_reg_rtx (DImode);
2041       rtx scratch3d = gen_reg_rtx (SImode);
2042       rtx scratch3e = gen_reg_rtx (DImode);
2043       rtx result = gen_reg_rtx (SImode);
2044
2045       if (! arith_reg_or_0_operand (dividend, SImode))
2046         dividend = force_reg (SImode, dividend);
2047       if (! arith_reg_operand (divisor, SImode))
2048         divisor = force_reg (SImode, divisor);
2049       if (flag_pic && Pmode != DImode)
2050         {
2051           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2052           tab_base = gen_datalabel_ref (tab_base);
2053           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2054         }
2055       else
2056         {
2057           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2058           tab_base = gen_datalabel_ref (tab_base);
2059           tab_base = force_reg (DImode, tab_base);
2060         }
2061       if (TARGET_DIVIDE_INV20U)
2062         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2063       else
2064         i2p27 = GEN_INT (0);
2065       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2066         i43 = force_reg (DImode, GEN_INT (43));
2067       else
2068         i43 = GEN_INT (0);
2069       emit_insn (gen_nsbdi (nsb_res,
2070                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2071       emit_insn (gen_ashldi3_media (norm64,
2072                                     gen_rtx_SUBREG (DImode, divisor, 0),
2073                                     nsb_res));
2074       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2075       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2076       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2077                                    inv0, scratch0a, scratch0b,
2078                                    scratch1a, scratch1b));
2079       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2080       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2081                                    scratch2a));
2082       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2083                                    i2p27, i43,
2084                                    scratch3a, scratch3b, scratch3c,
2085                                    scratch2a, scratch2b, scratch3d, scratch3e));
2086       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2087         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2088       else if (TARGET_DIVIDE_INV_FP)
2089         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2090                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2091                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2092                                      gen_reg_rtx (DFmode)));
2093       else
2094         emit_move_insn (operands[0], result);
2095       DONE;
2096     }
2097   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2098     {
2099       operands[1] = force_reg (SImode, operands[1]);
2100       operands[2] = force_reg (SImode, operands[2]);
2101       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2102       DONE;
2103     }
2104   else if (TARGET_SH5)
2105     {
2106       if (TARGET_DIVIDE_CALL2)
2107         {
2108           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2109           tab_base = gen_datalabel_ref (tab_base);
2110           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2111         }
2112       if (TARGET_FPU_ANY && TARGET_SH1)
2113         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2114       else if (TARGET_DIVIDE_CALL2)
2115         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2116       else
2117         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2118
2119       if (TARGET_SHMEDIA)
2120         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2121                 (operands[0], operands[3]));
2122       else if (TARGET_FPU_ANY)
2123         last = gen_divsi3_i4_single (operands[0], operands[3]);
2124       else
2125         last = gen_divsi3_i1 (operands[0], operands[3]);
2126     }
2127   else
2128     {
2129       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2130       last = gen_divsi3_i1 (operands[0], operands[3]);
2131     }
2132   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2133   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2134   emit_insn (last);
2135   DONE;
2136 }")
2137
2138 ;; operands: scratch, tab_base, tab_ix
2139 ;; These are unspecs because we could generate an indexed addressing mode
2140 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2141 ;; confuse reload.  See PR27117.
2142
2143 (define_insn "divsi_inv_qitable"
2144   [(set (match_operand:DI 0 "register_operand" "=r")
2145         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2146                                     (match_operand:DI 2 "register_operand" "r")]
2147                          UNSPEC_DIV_INV_TABLE)))]
2148   "TARGET_SHMEDIA"
2149   "@
2150         ldx.ub  %1, %2, %0"
2151   [(set_attr "type" "load_media")
2152    (set_attr "highpart" "user")])
2153
2154 ;; operands: scratch, tab_base, tab_ix
2155 (define_insn "divsi_inv_hitable"
2156   [(set (match_operand:DI 0 "register_operand" "=r")
2157         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2158                                     (match_operand:DI 2 "register_operand" "r")]
2159                          UNSPEC_DIV_INV_TABLE)))]
2160   "TARGET_SHMEDIA"
2161   "@
2162         ldx.w   %1, %2, %0"
2163   [(set_attr "type" "load_media")
2164    (set_attr "highpart" "user")])
2165
2166 ;; operands: inv0, tab_base, tab_ix, norm32
2167 ;; scratch equiv in sdivsi3_2: r19, r21
2168 (define_expand "divsi_inv_m0"
2169   [(set (match_operand:SI 0 "register_operand" "=r")
2170         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2171                     (match_operand:DI 2 "register_operand" "r")
2172                     (match_operand:SI 3 "register_operand" "r")]
2173          UNSPEC_DIV_INV_M0))
2174    (clobber (match_operand:DI 4 "register_operand" "=r"))
2175    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2176   "TARGET_SHMEDIA"
2177   "
2178 {
2179 /*
2180 tab_base: r20
2181 tab_ix: r21
2182 norm32: r25
2183  ldx.ub r20, r21, r19 // u0.8
2184  shlli r21, 1, r21
2185  muls.l r25, r19, r19 // s2.38
2186  ldx.w r20, r21, r21  // s2.14
2187  shari r19, 24, r19   // truncate to s2.14
2188  sub r21, r19, r19    // some 11 bit inverse in s1.14
2189 */
2190
2191   rtx inv0 = operands[0];
2192   rtx tab_base = operands[1];
2193   rtx tab_ix = operands[2];
2194   rtx norm32 = operands[3];
2195   rtx scratch0 = operands[4];
2196   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2197   rtx scratch1 = operands[5];
2198
2199   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2200   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2201   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2202   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2203   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2204   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2205   DONE;
2206 }")
2207
2208 ;; operands: inv1, tab_base, tab_ix, norm32
2209 (define_insn_and_split "divsi_inv_m1"
2210   [(set (match_operand:SI 0 "register_operand" "=r")
2211         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2212                     (match_operand:DI 2 "register_operand" "r")
2213                     (match_operand:SI 3 "register_operand" "r")]
2214          UNSPEC_DIV_INV_M1))
2215    (clobber (match_operand:SI 4 "register_operand" "=r"))
2216    (clobber (match_operand:DI 5 "register_operand" "=r"))
2217    (clobber (match_operand:DI 6 "register_operand" "=r"))
2218    (clobber (match_operand:DI 7 "register_operand" "=r"))
2219    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2220   "TARGET_SHMEDIA"
2221   "#"
2222   "&& !can_create_pseudo_p ()"
2223   [(pc)]
2224   "
2225 {
2226 /* inv0: r19
2227  muls.l r19, r19, r18 // u0.28
2228  muls.l r25, r18, r18 // s2.58
2229  shlli r19, 45, r0    // multiply by two and convert to s2.58
2230  sub r0, r18, r18
2231  shari r18, 28, r18   // some 18 bit inverse in s1.30
2232 */
2233
2234   rtx inv1 = operands[0];
2235   rtx tab_base = operands[1];
2236   rtx tab_ix = operands[2];
2237   rtx norm32 = operands[3];
2238   rtx inv0 = operands[4];
2239   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2240   rtx scratch0a = operands[5];
2241   rtx scratch0b = operands[6];
2242   rtx scratch0 = operands[7];
2243   rtx scratch1 = operands[8];
2244   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2245
2246   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2247                                scratch0a, scratch0b));
2248   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2249   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2250   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2251   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2252   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2253   DONE;
2254 }")
2255
2256 ;; operands: inv2, norm32, inv1, i92
2257 (define_insn_and_split "divsi_inv_m2"
2258   [(set (match_operand:SI 0 "register_operand" "=r")
2259         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2260                     (match_operand:SI 2 "register_operand" "r")
2261                     (match_operand:DI 3 "register_operand" "r")]
2262          UNSPEC_DIV_INV_M2))
2263    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2264   "TARGET_SHMEDIA"
2265   "#"
2266   "&& !can_create_pseudo_p ()"
2267   [(pc)]
2268   "
2269 {
2270 /*
2271  muls.l r18, r25, r0  // s2.60
2272  shari r0, 16, r0     // s-16.44
2273   sub
2274  muls.l r0, r18, r19  // s-16.74
2275  shari r19, 30, r19   // s-16.44
2276 */
2277   rtx inv2 = operands[0];
2278   rtx norm32 = operands[1];
2279   rtx inv1 = operands[2];
2280   rtx i92 = operands[3];
2281   rtx scratch0 = operands[4];
2282   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2283
2284   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2285   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2286   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2287   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2288   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2289   DONE;
2290 }")
2291
2292 (define_insn_and_split "divsi_inv_m3"
2293   [(set (match_operand:SI 0 "register_operand" "=r")
2294         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2295                     (match_operand:SI 2 "register_operand" "r")
2296                     (match_operand:SI 3 "register_operand" "r")
2297                     (match_operand:DI 4 "register_operand" "r")
2298                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2299                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2300          UNSPEC_DIV_INV_M3))
2301    (clobber (match_operand:DI 7 "register_operand" "=r"))
2302    (clobber (match_operand:DI 8 "register_operand" "=r"))
2303    (clobber (match_operand:DI 9 "register_operand" "=r"))
2304    (clobber (match_operand:DI 10 "register_operand" "=r"))
2305    (clobber (match_operand:SI 11 "register_operand" "=r"))
2306    (clobber (match_operand:SI 12 "register_operand" "=r"))
2307    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2308   "TARGET_SHMEDIA"
2309   "#"
2310   "&& !can_create_pseudo_p ()"
2311   [(pc)]
2312   "
2313 {
2314 /*
2315   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2316   r0: scratch0  r19: scratch1 r21: scratch2
2317
2318   muls.l r18, r4, r25 // s32.30
2319  muls.l r19, r4, r19  // s15.30
2320  shari r25, 63, r21
2321   shari r19, 14, r19  // s18.-14
2322  sub r25, r19, r0
2323  shard r0, r1, r0
2324  sub r0, r21, r0
2325 */
2326
2327   rtx result = operands[0];
2328   rtx dividend = operands[1];
2329   rtx inv1 = operands[2];
2330   rtx inv2 = operands[3];
2331   rtx shift = operands[4];
2332   rtx scratch0 = operands[7];
2333   rtx scratch1 = operands[8];
2334   rtx scratch2 = operands[9];
2335
2336   if (satisfies_constraint_N (dividend))
2337     {
2338       emit_move_insn (result, dividend);
2339       DONE;
2340     }
2341
2342   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2343   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2344   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2345   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2346   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2347   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2348   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2349   DONE;
2350 }")
2351
2352 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2353 ;; inv1: tab_base, tab_ix, norm32
2354 ;; inv2: norm32, inv1, i92
2355 (define_insn_and_split "divsi_inv_m1_3"
2356   [(set (match_operand:SI 0 "register_operand" "=r")
2357         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2358                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2359                                 (match_operand:DI 3 "register_operand" "r")
2360                                 (match_operand:SI 4 "register_operand" "r")]
2361                      UNSPEC_DIV_INV_M1)
2362                     (unspec:SI [(match_dup 4)
2363                                 (unspec:SI [(match_dup 2)
2364                                             (match_dup 3)
2365                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2366                                 (match_operand:SI 5 "" "")]
2367                      UNSPEC_DIV_INV_M2)
2368                     (match_operand:DI 6 "register_operand" "r")
2369                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2370                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2371          UNSPEC_DIV_INV_M3))
2372    (clobber (match_operand:DI 9 "register_operand" "=r"))
2373    (clobber (match_operand:DI 10 "register_operand" "=r"))
2374    (clobber (match_operand:DI 11 "register_operand" "=r"))
2375    (clobber (match_operand:DI 12 "register_operand" "=r"))
2376    (clobber (match_operand:SI 13 "register_operand" "=r"))
2377    (clobber (match_operand:SI 14 "register_operand" "=r"))
2378    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2379   "TARGET_SHMEDIA
2380    && (TARGET_DIVIDE_INV_MINLAT
2381        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2382   "#"
2383   "&& !can_create_pseudo_p ()"
2384   [(pc)]
2385   "
2386 {
2387   rtx result = operands[0];
2388   rtx dividend = operands[1];
2389   rtx tab_base = operands[2];
2390   rtx tab_ix = operands[3];
2391   rtx norm32 = operands[4];
2392   /* rtx i92 = operands[5]; */
2393   rtx shift = operands[6];
2394   rtx i2p27 = operands[7];
2395   rtx i43 = operands[8];
2396   rtx scratch0 = operands[9];
2397   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2398   rtx scratch1 = operands[10];
2399   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2400   rtx scratch2 = operands[11];
2401   rtx scratch3 = operands[12];
2402   rtx scratch4 = operands[13];
2403   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2404   rtx scratch5 = operands[14];
2405   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2406   rtx scratch6 = operands[15];
2407
2408   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2409                                scratch0, scratch1));
2410   /* inv0 == scratch4 */
2411   if (! TARGET_DIVIDE_INV20U)
2412     {
2413       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2414       i2p27 = scratch0;
2415       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2416     }
2417   else
2418     {
2419       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2420       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2421     }
2422   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2423   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2424   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2425   /* inv1 == scratch4 */
2426
2427   if (TARGET_DIVIDE_INV_MINLAT)
2428     {
2429       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2430       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2431       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2432       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2433       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2434       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2435       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2436       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2437       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2438       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2439       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2440     }
2441   else
2442     {
2443       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2444       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2445       emit_insn (gen_nsbdi (scratch6,
2446                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2447       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2448       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2449       emit_insn (gen_divsi_inv20 (scratch2,
2450                                   norm32, scratch4, dividend,
2451                                   scratch6, scratch3, i43,
2452                                   /* scratch0 may be shared with i2p27.  */
2453                                   scratch0, scratch1, scratch5,
2454                                   label, label, i2p27));
2455     }
2456   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2457   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2458   DONE;
2459 }")
2460
2461 (define_insn "divsi_inv20"
2462   [(set (match_operand:DI 0 "register_operand" "=&r")
2463         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2464                     (match_operand:SI 2 "register_operand" "r")
2465                     (match_operand:SI 3 "register_operand" "r")
2466                     (match_operand:DI 4 "register_operand" "r")
2467                     (match_operand:DI 5 "register_operand" "r")
2468                     (match_operand:DI 6 "register_operand" "r")
2469                     (match_operand:DI 12 "register_operand" "r")
2470                     (match_operand 10 "target_operand" "b")
2471                     (match_operand 11 "immediate_operand" "i")]
2472          UNSPEC_DIV_INV20))
2473    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2474    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2475    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2476   "TARGET_SHMEDIA
2477    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2478   "*
2479 {
2480 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2481              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2482              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2483              %10 label (tr), %11 label (imm)
2484
2485  muls.l inv1, norm32, scratch0  // s2.60
2486   muls.l inv1, dividend, result // s32.30
2487   xor i2p27, result_sign, round_scratch
2488  bge/u dividend_nsb, i43, tr.. (label)
2489  shari scratch0, 16, scratch0   // s-16.44
2490  muls.l sratch0_si, inv1, scratch0 // s-16.74
2491   sub result, round_scratch, result
2492   shari dividend, 14, scratch1   // s19.-14
2493  shari scratch0, 30, scratch0   // s-16.44
2494  muls.l scratch0, scratch1, round_scratch // s15.30
2495 label:
2496  sub result, round_scratch, result */
2497
2498   int likely = TARGET_DIVIDE_INV20L;
2499
2500   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2501   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2502   output_asm_insn (likely
2503                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2504                    : \"bge/u\t%4, %6, %10\", operands);
2505   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2506   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2507   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2508   return (likely
2509           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2510           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2511 }")
2512
2513 (define_insn_and_split "divsi_inv_fp"
2514   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2515         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2516                 (match_operand:SI 2 "register_operand" "rf")))
2517    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2518    (clobber (match_operand:SI 4 "register_operand" "=r"))
2519    (clobber (match_operand:SI 5 "register_operand" "=r"))
2520    (clobber (match_operand:DF 6 "register_operand" "=r"))
2521    (clobber (match_operand:DF 7 "register_operand" "=r"))
2522    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2523   "TARGET_SHMEDIA_FPU"
2524   "#"
2525   "&& (high_life_started || reload_completed)"
2526   [(set (match_dup 0) (match_dup 3))]
2527   ""
2528   [(set_attr "highpart" "must_split")])
2529
2530 ;; If a matching group of divide-by-inverse instructions is in the same
2531 ;; basic block after gcse & loop optimizations, we want to transform them
2532 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2533 (define_insn_and_split "*divsi_inv_fp_combine"
2534   [(set (match_operand:SI 0 "register_operand" "=f")
2535         (div:SI (match_operand:SI 1 "register_operand" "f")
2536                 (match_operand:SI 2 "register_operand" "f")))
2537    (use (unspec:SI [(match_dup 1)
2538                     (match_operand:SI 3 "" "")
2539                     (unspec:SI [(match_operand:SI 4 "" "")
2540                                 (match_dup 3)
2541                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2542                     (match_operand:DI 6 "" "")
2543                     (const_int 0)
2544                     (const_int 0)] UNSPEC_DIV_INV_M3))
2545    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2546    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2547    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2548    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2549    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2550   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2551   "#"
2552   "&& 1"
2553   [(set (match_dup 9) (float:DF (match_dup 1)))
2554    (set (match_dup 10) (float:DF (match_dup 2)))
2555    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2556    (set (match_dup 8)
2557         (fix:SI (match_dup 11)))
2558    (set (match_dup 0) (match_dup 8))]
2559   "
2560 {
2561   if (! fp_arith_reg_operand (operands[1], SImode))
2562     {
2563       emit_move_insn (operands[7], operands[1]);
2564       operands[1] = operands[7];
2565     }
2566   if (! fp_arith_reg_operand (operands[2], SImode))
2567     {
2568       emit_move_insn (operands[8], operands[2]);
2569       operands[2] = operands[8];
2570     }
2571 }"
2572   [(set_attr "highpart" "must_split")])
2573 \f
2574 ;; -------------------------------------------------------------------------
2575 ;; Multiplication instructions
2576 ;; -------------------------------------------------------------------------
2577
2578 (define_insn "umulhisi3_i"
2579   [(set (reg:SI MACL_REG)
2580         (mult:SI (zero_extend:SI
2581                   (match_operand:HI 0 "arith_reg_operand" "r"))
2582                  (zero_extend:SI
2583                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2584   "TARGET_SH1"
2585   "mulu.w       %1,%0"
2586   [(set_attr "type" "smpy")])
2587
2588 (define_insn "mulhisi3_i"
2589   [(set (reg:SI MACL_REG)
2590         (mult:SI (sign_extend:SI
2591                   (match_operand:HI 0 "arith_reg_operand" "r"))
2592                  (sign_extend:SI
2593                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2594   "TARGET_SH1"
2595   "muls.w       %1,%0"
2596   [(set_attr "type" "smpy")])
2597
2598 (define_expand "mulhisi3"
2599   [(set (reg:SI MACL_REG)
2600         (mult:SI (sign_extend:SI
2601                   (match_operand:HI 1 "arith_reg_operand" ""))
2602                  (sign_extend:SI
2603                   (match_operand:HI 2 "arith_reg_operand" ""))))
2604    (set (match_operand:SI 0 "arith_reg_operand" "")
2605         (reg:SI MACL_REG))]
2606   "TARGET_SH1"
2607   "
2608 {
2609   rtx insn, macl;
2610
2611   macl = gen_rtx_REG (SImode, MACL_REG);
2612   start_sequence ();
2613   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2614   insn = get_insns ();  
2615   end_sequence ();
2616   /* expand_binop can't find a suitable code in umul_widen_optab to
2617      make a REG_EQUAL note from, so make one here.
2618      See also smulsi3_highpart.
2619      ??? Alternatively, we could put this at the calling site of expand_binop,
2620      i.e. expand_expr.  */
2621   /* Use emit_libcall_block for loop invariant code motion and to make
2622      a REG_EQUAL note.  */
2623   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2624
2625   DONE;
2626 }")
2627
2628 (define_expand "umulhisi3"
2629   [(set (reg:SI MACL_REG)
2630         (mult:SI (zero_extend:SI
2631                   (match_operand:HI 1 "arith_reg_operand" ""))
2632                  (zero_extend:SI
2633                   (match_operand:HI 2 "arith_reg_operand" ""))))
2634    (set (match_operand:SI 0 "arith_reg_operand" "")
2635         (reg:SI MACL_REG))]
2636   "TARGET_SH1"
2637   "
2638 {
2639   rtx insn, macl;
2640
2641   macl = gen_rtx_REG (SImode, MACL_REG);
2642   start_sequence ();
2643   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2644   insn = get_insns ();  
2645   end_sequence ();
2646   /* expand_binop can't find a suitable code in umul_widen_optab to
2647      make a REG_EQUAL note from, so make one here.
2648      See also smulsi3_highpart.
2649      ??? Alternatively, we could put this at the calling site of expand_binop,
2650      i.e. expand_expr.  */
2651   /* Use emit_libcall_block for loop invariant code motion and to make
2652      a REG_EQUAL note.  */
2653   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2654
2655   DONE;
2656 }")
2657
2658 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2659 ;; a call to a routine which clobbers known registers.
2660
2661 (define_insn ""
2662   [(set (match_operand:SI 1 "register_operand" "=z")
2663         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2664    (clobber (reg:SI MACL_REG))
2665    (clobber (reg:SI T_REG))
2666    (clobber (reg:SI PR_REG))
2667    (clobber (reg:SI R3_REG))
2668    (clobber (reg:SI R2_REG))
2669    (clobber (reg:SI R1_REG))
2670    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2671   "TARGET_SH1"
2672   "jsr  @%0%#"
2673   [(set_attr "type" "sfunc")
2674    (set_attr "needs_delay_slot" "yes")])
2675
2676 (define_expand "mulsi3_call"
2677   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2678    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2679    (parallel[(set (match_operand:SI 0 "register_operand" "")
2680                   (mult:SI (reg:SI R4_REG)
2681                            (reg:SI R5_REG)))
2682              (clobber (reg:SI MACL_REG))
2683              (clobber (reg:SI T_REG))
2684              (clobber (reg:SI PR_REG))
2685              (clobber (reg:SI R3_REG))
2686              (clobber (reg:SI R2_REG))
2687              (clobber (reg:SI R1_REG))
2688              (use (match_operand:SI 3 "register_operand" ""))])]
2689   "TARGET_SH1"
2690   "")
2691
2692 (define_insn "mul_r"
2693   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2694         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2695                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2696   "TARGET_SH2A"
2697   "mulr %2,%0"
2698   [(set_attr "type" "dmpy")])
2699
2700 (define_insn "mul_l"
2701   [(set (reg:SI MACL_REG)
2702         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2703                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2704   "TARGET_SH2"
2705   "mul.l        %1,%0"
2706   [(set_attr "type" "dmpy")])
2707
2708 (define_expand "mulsi3"
2709   [(set (reg:SI MACL_REG)
2710         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2711                   (match_operand:SI 2 "arith_reg_operand" "")))
2712    (set (match_operand:SI 0 "arith_reg_operand" "")
2713         (reg:SI MACL_REG))]
2714   "TARGET_SH1"
2715   "
2716 {
2717   if (!TARGET_SH2)
2718     {
2719       /* The address must be set outside the libcall,
2720          since it goes into a pseudo.  */
2721       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2722       rtx addr = force_reg (SImode, sym);
2723       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2724                                    operands[2], addr);
2725       emit_insn (insns);
2726     }
2727   else
2728     {
2729       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2730
2731       emit_insn (gen_mul_l (operands[1], operands[2]));
2732       /* consec_sets_giv can only recognize the first insn that sets a
2733          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2734          note.  */
2735       emit_insn (gen_movsi_i ((operands[0]), macl));
2736     }
2737   DONE;
2738 }")
2739
2740 (define_insn "mulsidi3_i"
2741   [(set (reg:SI MACH_REG)
2742         (truncate:SI
2743          (lshiftrt:DI
2744           (mult:DI
2745            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2746            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2747           (const_int 32))))
2748    (set (reg:SI MACL_REG)
2749         (mult:SI (match_dup 0)
2750                  (match_dup 1)))]
2751   "TARGET_SH2"
2752   "dmuls.l      %1,%0"
2753   [(set_attr "type" "dmpy")])
2754
2755 (define_expand "mulsidi3"
2756   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2757         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2758                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2759   "TARGET_SH2 || TARGET_SHMEDIA"
2760   "
2761 {
2762   if (TARGET_SH2)
2763     {
2764        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2765                                         operands[2]));
2766        DONE;
2767     }
2768 }")
2769
2770 (define_insn "mulsidi3_media"
2771   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2772         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2773                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2774   "TARGET_SHMEDIA"
2775   "muls.l       %1, %2, %0"
2776   [(set_attr "type" "dmpy_media")
2777    (set_attr "highpart" "ignore")])
2778
2779 (define_insn "mulsidi3_compact"
2780   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2781         (mult:DI
2782          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2783          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2784    (clobber (reg:SI MACH_REG))
2785    (clobber (reg:SI MACL_REG))]
2786   "TARGET_SH2"
2787   "#")
2788
2789 (define_split
2790   [(set (match_operand:DI 0 "arith_reg_dest" "")
2791         (mult:DI
2792          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2793          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2794    (clobber (reg:SI MACH_REG))
2795    (clobber (reg:SI MACL_REG))]
2796   "TARGET_SH2"
2797   [(const_int 0)]
2798   "
2799 {
2800   rtx low_dst = gen_lowpart (SImode, operands[0]);
2801   rtx high_dst = gen_highpart (SImode, operands[0]);
2802
2803   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2804
2805   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2806   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2807   /* We need something to tag the possible REG_EQUAL notes on to.  */
2808   emit_move_insn (operands[0], operands[0]);
2809   DONE;
2810 }")
2811
2812 (define_insn "umulsidi3_i"
2813   [(set (reg:SI MACH_REG)
2814         (truncate:SI
2815          (lshiftrt:DI
2816           (mult:DI
2817            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2818            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2819           (const_int 32))))
2820    (set (reg:SI MACL_REG)
2821         (mult:SI (match_dup 0)
2822                  (match_dup 1)))]
2823   "TARGET_SH2"
2824   "dmulu.l      %1,%0"
2825   [(set_attr "type" "dmpy")])
2826
2827 (define_expand "umulsidi3"
2828   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2829         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2830                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2831   "TARGET_SH2 || TARGET_SHMEDIA"
2832   "
2833 {
2834   if (TARGET_SH2)
2835     {
2836        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2837                                          operands[2]));
2838        DONE;
2839     }
2840 }")
2841
2842 (define_insn "umulsidi3_media"
2843   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2844         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2845                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2846   "TARGET_SHMEDIA"
2847   "mulu.l       %1, %2, %0"
2848   [(set_attr "type" "dmpy_media")
2849    (set_attr "highpart" "ignore")])
2850
2851 (define_insn "umulsidi3_compact"
2852   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2853         (mult:DI
2854          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2855          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2856    (clobber (reg:SI MACH_REG))
2857    (clobber (reg:SI MACL_REG))]
2858   "TARGET_SH2"
2859   "#")
2860
2861 (define_split
2862   [(set (match_operand:DI 0 "arith_reg_dest" "")
2863         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2864                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2865    (clobber (reg:SI MACH_REG))
2866    (clobber (reg:SI MACL_REG))]
2867   "TARGET_SH2"
2868   [(const_int 0)]
2869   "
2870 {
2871   rtx low_dst = gen_lowpart (SImode, operands[0]);
2872   rtx high_dst = gen_highpart (SImode, operands[0]);
2873
2874   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2875
2876   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2877   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2878   /* We need something to tag the possible REG_EQUAL notes on to.  */
2879   emit_move_insn (operands[0], operands[0]);
2880   DONE;
2881 }")
2882
2883 (define_insn "smulsi3_highpart_i"
2884   [(set (reg:SI MACH_REG)
2885         (truncate:SI
2886          (lshiftrt:DI
2887           (mult:DI
2888            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2889            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2890           (const_int 32))))
2891    (clobber (reg:SI MACL_REG))]
2892   "TARGET_SH2"
2893   "dmuls.l      %1,%0"
2894   [(set_attr "type" "dmpy")])
2895
2896 (define_expand "smulsi3_highpart"
2897   [(parallel
2898     [(set (reg:SI MACH_REG)
2899           (truncate:SI
2900            (lshiftrt:DI
2901             (mult:DI
2902              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2903              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2904             (const_int 32))))
2905     (clobber (reg:SI MACL_REG))])
2906    (set (match_operand:SI 0 "arith_reg_operand" "")
2907         (reg:SI MACH_REG))]
2908   "TARGET_SH2"
2909   "
2910 {
2911   rtx insn, mach;
2912
2913   mach = gen_rtx_REG (SImode, MACH_REG);
2914   start_sequence ();
2915   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2916   insn = get_insns ();  
2917   end_sequence ();
2918   /* expand_binop can't find a suitable code in mul_highpart_optab to
2919      make a REG_EQUAL note from, so make one here.
2920      See also {,u}mulhisi.
2921      ??? Alternatively, we could put this at the calling site of expand_binop,
2922      i.e. expand_mult_highpart.  */
2923   /* Use emit_libcall_block for loop invariant code motion and to make
2924      a REG_EQUAL note.  */
2925   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2926
2927   DONE;
2928 }")
2929
2930 (define_insn "umulsi3_highpart_i"
2931   [(set (reg:SI MACH_REG)
2932         (truncate:SI
2933          (lshiftrt:DI
2934           (mult:DI
2935            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2936            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2937           (const_int 32))))
2938    (clobber (reg:SI MACL_REG))]
2939   "TARGET_SH2"
2940   "dmulu.l      %1,%0"
2941   [(set_attr "type" "dmpy")])
2942
2943 (define_expand "umulsi3_highpart"
2944   [(parallel
2945     [(set (reg:SI MACH_REG)
2946           (truncate:SI
2947            (lshiftrt:DI
2948             (mult:DI
2949              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2950              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2951             (const_int 32))))
2952     (clobber (reg:SI MACL_REG))])
2953    (set (match_operand:SI 0 "arith_reg_operand" "")
2954         (reg:SI MACH_REG))]
2955   "TARGET_SH2"
2956   "
2957 {
2958   rtx insn, mach;
2959
2960   mach = gen_rtx_REG (SImode, MACH_REG);
2961   start_sequence ();
2962   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2963   insn = get_insns ();  
2964   end_sequence ();
2965   /* Use emit_libcall_block for loop invariant code motion and to make
2966      a REG_EQUAL note.  */
2967   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2968
2969   DONE;
2970 }")
2971
2972 (define_insn_and_split "muldi3"
2973   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2974         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2975                  (match_operand:DI 2 "arith_reg_operand" "r")))
2976    (clobber (match_scratch:DI 3 "=&r"))
2977    (clobber (match_scratch:DI 4 "=r"))]
2978   "TARGET_SHMEDIA"
2979   "#"
2980   "reload_completed"
2981   [(const_int 0)]
2982   "
2983 {
2984   rtx op3_v2si, op2_v2si;
2985
2986   op3_v2si = operands[3];
2987   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2988     {
2989       op3_v2si = XEXP (op3_v2si, 0);
2990       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2991     }
2992   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2993   op2_v2si = operands[2];
2994   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2995     {
2996       op2_v2si = XEXP (op2_v2si, 0);
2997       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2998     }
2999   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3000   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3001   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3002   emit_insn (gen_umulsidi3_media (operands[4],
3003                                  sh_gen_truncate (SImode, operands[1], 0),
3004                                  sh_gen_truncate (SImode, operands[2], 0)));
3005   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3006   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3007   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3008   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3009   DONE;
3010 }")
3011
3012 \f
3013 ;; -------------------------------------------------------------------------
3014 ;; Logical operations
3015 ;; -------------------------------------------------------------------------
3016
3017 (define_insn "*andsi3_compact"
3018   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3019         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3020                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3021   "TARGET_SH1"
3022   "and  %2,%0"
3023   [(set_attr "type" "arith")])
3024
3025 (define_insn "*andsi3_media"
3026   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3027         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3028                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3029   "TARGET_SHMEDIA"
3030   "@
3031         and     %1, %2, %0
3032         andi    %1, %2, %0"
3033   [(set_attr "type" "arith_media")])
3034
3035 (define_insn "*andsi3_bclr"
3036   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3037         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3038                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3039   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3040   "bclr\\t%W2,%0"
3041   [(set_attr "type" "arith")])
3042
3043 ;; If the constant is 255, then emit an extu.b instruction instead of an
3044 ;; and, since that will give better code.
3045
3046 (define_expand "andsi3"
3047   [(set (match_operand:SI 0 "arith_reg_operand" "")
3048         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3049                 (match_operand:SI 2 "logical_operand" "")))]
3050   ""
3051   "
3052 {
3053   if (TARGET_SH1
3054       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3055     {
3056       emit_insn (gen_zero_extendqisi2 (operands[0],
3057                                        gen_lowpart (QImode, operands[1])));
3058       DONE;
3059     }
3060 }")
3061
3062 (define_insn_and_split "anddi3"
3063   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3064         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3065                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3066   "TARGET_SHMEDIA"
3067   "@
3068         and     %1, %2, %0
3069         andi    %1, %2, %0
3070         #"
3071   "reload_completed
3072    && ! logical_operand (operands[2], DImode)"
3073   [(const_int 0)]
3074   "
3075 {
3076   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3077     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3078   else
3079     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3080   DONE;
3081 }"
3082   [(set_attr "type" "arith_media")])
3083
3084 (define_insn "andcsi3"
3085   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3086         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3087                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3088   "TARGET_SHMEDIA"
3089   "andc %1,%2,%0"
3090   [(set_attr "type" "arith_media")])
3091
3092 (define_insn "andcdi3"
3093   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3094         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3095                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3096   "TARGET_SHMEDIA"
3097   "andc %1,%2,%0"
3098   [(set_attr "type" "arith_media")])
3099
3100 (define_expand "iorsi3"
3101   [(set (match_operand:SI 0 "arith_reg_operand" "")
3102         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3103                 (match_operand:SI 2 "logical_operand" "")))]
3104   ""
3105   "")
3106
3107 (define_insn "*iorsi3_compact"
3108   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3109         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3110                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3111   "TARGET_SH1
3112    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3113   "or   %2,%0"
3114   [(set_attr "type" "arith")])
3115
3116 (define_insn "*iorsi3_media"
3117   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3118         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3119                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3120   "TARGET_SHMEDIA"
3121   "@
3122         or      %1, %2, %0
3123         ori     %1, %2, %0"
3124   [(set_attr "type" "arith_media")])
3125
3126 (define_insn "*iorsi3_bset"
3127   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3128         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3129         (match_operand:SI 2 "const_int_operand" "Pso")))]
3130   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3131   "bset\\t%V2,%0"
3132   [(set_attr "type" "arith")])
3133
3134 (define_insn "iordi3"
3135   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3136         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3137                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3138   "TARGET_SHMEDIA"
3139   "@
3140         or      %1, %2, %0
3141         ori     %1, %2, %0"
3142   [(set_attr "type" "arith_media")])
3143
3144 (define_insn_and_split "*logical_sidi3"
3145   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3146         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3147                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3148                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3149   "TARGET_SHMEDIA"
3150   "#"
3151   "&& reload_completed"
3152   [(set (match_dup 0) (match_dup 3))]
3153   "
3154 {
3155   operands[3]
3156     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3157                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3158                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3159 }")
3160
3161 (define_insn_and_split "*logical_sidisi3"
3162   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3163         (truncate:SI (sign_extend:DI
3164                         (match_operator:SI 3 "logical_operator"
3165                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3166                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3167   "TARGET_SHMEDIA"
3168   "#"
3169   "&& 1"
3170   [(set (match_dup 0) (match_dup 3))])
3171
3172 (define_insn_and_split "*logical_sidi3_2"
3173   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3174         (sign_extend:DI (truncate:SI (sign_extend:DI
3175                         (match_operator:SI 3 "logical_operator"
3176                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3177                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3178   "TARGET_SHMEDIA"
3179   "#"
3180   "&& 1"
3181   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3182
3183 (define_expand "xorsi3"
3184   [(set (match_operand:SI 0 "arith_reg_operand" "")
3185         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3186                 (match_operand:SI 2 "xor_operand" "")))]
3187   ""
3188   "")
3189
3190 (define_insn "*xorsi3_compact"
3191   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3192         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3193                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3194   "TARGET_SH1"
3195   "xor  %2,%0"
3196   [(set_attr "type" "arith")])
3197
3198 (define_insn "*xorsi3_media"
3199   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3200         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3201                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3202   "TARGET_SHMEDIA"
3203   "@
3204         xor     %1, %2, %0
3205         xori    %1, %2, %0"
3206   [(set_attr "type" "arith_media")])
3207
3208 ;; Store the complements of the T bit in a register.
3209 (define_insn "xorsi3_movrt"
3210   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3211         (xor:SI (reg:SI T_REG)
3212                 (const_int 1)))]
3213   "TARGET_SH2A"
3214   "movrt\\t%0"
3215   [(set_attr "type" "arith")])
3216
3217 (define_insn "xordi3"
3218   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3219         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3220                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3221   "TARGET_SHMEDIA"
3222   "@
3223         xor     %1, %2, %0
3224         xori    %1, %2, %0"
3225   [(set_attr "type" "arith_media")])
3226
3227 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3228 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3229 (define_split
3230   [(set (match_operand:DI 0 "arith_reg_dest" "")
3231         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3232                           [(match_operand 1 "any_register_operand" "")
3233                            (match_operand 2 "any_register_operand" "")])))]
3234   "TARGET_SHMEDIA"
3235   [(set (match_dup 5) (match_dup 4))
3236    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3237 "
3238 {
3239   enum machine_mode inmode = GET_MODE (operands[1]);
3240   int offset = 0;
3241
3242   if (GET_CODE (operands[0]) == SUBREG)
3243     {
3244       offset = SUBREG_BYTE (operands[0]);
3245       operands[0] = SUBREG_REG (operands[0]);
3246     }
3247   gcc_assert (REG_P (operands[0]));
3248   if (! TARGET_LITTLE_ENDIAN)
3249     offset += 8 - GET_MODE_SIZE (inmode);
3250   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3251 }")
3252 \f
3253 ;; -------------------------------------------------------------------------
3254 ;; Shifts and rotates
3255 ;; -------------------------------------------------------------------------
3256
3257 (define_expand "rotldi3"
3258   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3259         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3260                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3261   "TARGET_SHMEDIA"
3262   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3263
3264 (define_insn "rotldi3_mextr"
3265   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3266         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3267                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3268   "TARGET_SHMEDIA"
3269   "*
3270 {
3271   static char templ[16];
3272
3273   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3274            8 - (int) (INTVAL (operands[2]) >> 3));
3275   return templ;
3276 }"
3277   [(set_attr "type" "arith_media")])
3278
3279 (define_expand "rotrdi3"
3280   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3281         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3282                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3283   "TARGET_SHMEDIA"
3284   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3285
3286 (define_insn "rotrdi3_mextr"
3287   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3288         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3289                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3290   "TARGET_SHMEDIA"
3291   "*
3292 {
3293   static char templ[16];
3294
3295   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3296   return templ;
3297 }"
3298   [(set_attr "type" "arith_media")])
3299
3300 (define_split
3301   [(set (match_operand:DI 0 "arith_reg_dest" "")
3302         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3303                                          "ua_address_operand" "")))
3304                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3305                            (const_int 8))))
3306    (clobber (match_operand:DI 3 "register_operand" ""))]
3307   "TARGET_SHMEDIA"
3308   [(match_dup 4) (match_dup 5)]
3309   "
3310 {
3311   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3312                  (operands[3], operands[1]));
3313   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3314                               GEN_INT (56), GEN_INT (8));
3315 }")
3316
3317 (define_insn "rotlsi3_1"
3318   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3319         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3320                    (const_int 1)))
3321    (set (reg:SI T_REG)
3322         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3323   "TARGET_SH1"
3324   "rotl %0"
3325   [(set_attr "type" "arith")])
3326
3327 (define_insn "rotlsi3_31"
3328   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3329         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3330                    (const_int 31)))
3331    (clobber (reg:SI T_REG))]
3332   "TARGET_SH1"
3333   "rotr %0"
3334   [(set_attr "type" "arith")])
3335
3336 (define_insn "rotlsi3_16"
3337   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3338         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3339                    (const_int 16)))]
3340   "TARGET_SH1"
3341   "swap.w       %1,%0"
3342   [(set_attr "type" "arith")])
3343
3344 (define_expand "rotlsi3"
3345   [(set (match_operand:SI 0 "arith_reg_dest" "")
3346         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3347                    (match_operand:SI 2 "immediate_operand" "")))]
3348   "TARGET_SH1"
3349   "
3350 {
3351   static const char rot_tab[] = {
3352     000, 000, 000, 000, 000, 000, 010, 001,
3353     001, 001, 011, 013, 003, 003, 003, 003,
3354     003, 003, 003, 003, 003, 013, 012, 002,
3355     002, 002, 010, 000, 000, 000, 000, 000,
3356   };
3357
3358   int count, choice;
3359
3360   if (!CONST_INT_P (operands[2]))
3361     FAIL;
3362   count = INTVAL (operands[2]);
3363   choice = rot_tab[count];
3364   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3365     FAIL;
3366   choice &= 7;
3367   switch (choice)
3368     {
3369     case 0:
3370       emit_move_insn (operands[0], operands[1]);
3371       count -= (count & 16) * 2;
3372       break;
3373     case 3:
3374      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3375      count -= 16;
3376      break;
3377     case 1:
3378     case 2:
3379       {
3380         rtx parts[2];
3381         parts[0] = gen_reg_rtx (SImode);
3382         parts[1] = gen_reg_rtx (SImode);
3383         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3384         emit_move_insn (parts[choice-1], operands[1]);
3385         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3386         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3387         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3388         count = (count & ~16) - 8;
3389       }
3390     }
3391
3392   for (; count > 0; count--)
3393     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3394   for (; count < 0; count++)
3395     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3396
3397   DONE;
3398 }")
3399
3400 (define_insn "*rotlhi3_8"
3401   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3402         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3403                    (const_int 8)))]
3404   "TARGET_SH1"
3405   "swap.b       %1,%0"
3406   [(set_attr "type" "arith")])
3407
3408 (define_expand "rotlhi3"
3409   [(set (match_operand:HI 0 "arith_reg_operand" "")
3410         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3411                    (match_operand:HI 2 "immediate_operand" "")))]
3412   "TARGET_SH1"
3413   "
3414 {
3415   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3416     FAIL;
3417 }")
3418
3419 ;;
3420 ;; shift left
3421
3422 (define_insn "ashlsi3_sh2a"
3423   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3424         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3425                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3426   "TARGET_SH2A"
3427   "shad %2,%0"
3428   [(set_attr "type" "arith")
3429    (set_attr "length" "4")])
3430
3431 ;; This pattern is used by init_expmed for computing the costs of shift
3432 ;; insns.
3433
3434 (define_insn_and_split "ashlsi3_std"
3435   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3436         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3437                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3438    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3439   "TARGET_SH3
3440    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3441   "@
3442    shld %2,%0
3443    add  %0,%0
3444    shll%O2      %0
3445    #"
3446   "TARGET_SH3
3447    && reload_completed
3448    && CONST_INT_P (operands[2])
3449    && ! satisfies_constraint_P27 (operands[2])"
3450   [(set (match_dup 3) (match_dup 2))
3451    (parallel
3452     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3453      (clobber (match_dup 4))])]
3454   "operands[4] = gen_rtx_SCRATCH (SImode);"
3455   [(set_attr "length" "*,*,*,4")
3456    (set_attr "type" "dyn_shift,arith,arith,arith")])
3457
3458 (define_insn "ashlhi3_k"
3459   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3460         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3461                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3462   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3463   "@
3464         add     %0,%0
3465         shll%O2 %0"
3466   [(set_attr "type" "arith")])
3467
3468 (define_insn "ashlsi3_n"
3469   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3471                    (match_operand:SI 2 "const_int_operand" "n")))
3472    (clobber (reg:SI T_REG))]
3473   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3474   "#"
3475   [(set (attr "length")
3476         (cond [(match_test "shift_insns_rtx (insn)")
3477                (const_string "2")
3478                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3479                (const_string "4")
3480                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3481                (const_string "6")]
3482               (const_string "8")))
3483    (set_attr "type" "arith")])
3484
3485 (define_split
3486   [(set (match_operand:SI 0 "arith_reg_dest" "")
3487         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3488                    (match_operand:SI 2 "const_int_operand" "")))
3489    (clobber (reg:SI T_REG))]
3490   "TARGET_SH1 && reload_completed"
3491   [(use (reg:SI R0_REG))]
3492   "
3493 {
3494   gen_shifty_op (ASHIFT, operands);
3495   DONE;
3496 }")
3497
3498 (define_insn "ashlsi3_media"
3499   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3500         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3501                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3502   "TARGET_SHMEDIA"
3503   "@
3504         shlld.l %1, %2, %0
3505         shlli.l %1, %2, %0"
3506   [(set_attr "type" "arith_media")
3507    (set_attr "highpart" "ignore")])
3508
3509 (define_expand "ashlsi3"
3510   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3511                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3512                               (match_operand:SI 2 "nonmemory_operand" "")))
3513               (clobber (reg:SI T_REG))])]
3514   ""
3515   "
3516 {
3517   if (TARGET_SHMEDIA)
3518     {
3519       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3520       DONE;
3521     }
3522   if (CONST_INT_P (operands[2])
3523       && sh_dynamicalize_shift_p (operands[2]))
3524     operands[2] = force_reg (SImode, operands[2]);
3525   if (TARGET_SH3)
3526     {
3527       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3528       DONE;
3529     }
3530   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3531     FAIL;
3532 }")
3533
3534 (define_insn "*ashlhi3_n"
3535   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3536         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3537                    (match_operand:HI 2 "const_int_operand" "n")))
3538    (clobber (reg:SI T_REG))]
3539   "TARGET_SH1"
3540   "#"
3541   [(set (attr "length")
3542         (cond [(match_test "shift_insns_rtx (insn)")
3543                (const_string "2")
3544                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3545                (const_string "4")]
3546               (const_string "6")))
3547    (set_attr "type" "arith")])
3548
3549 (define_expand "ashlhi3"
3550   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3551                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3552                               (match_operand:SI 2 "nonmemory_operand" "")))
3553               (clobber (reg:SI T_REG))])]
3554   "TARGET_SH1"
3555   "
3556 {
3557   if (!CONST_INT_P (operands[2]))
3558     FAIL;
3559   /* It may be possible to call gen_ashlhi3 directly with more generic
3560      operands.  Make sure operands[1] is a HImode register here.  */
3561   if (!arith_reg_operand (operands[1], HImode))
3562     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3563 }")
3564
3565 (define_split
3566   [(set (match_operand:HI 0 "arith_reg_dest" "")
3567         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3568                    (match_operand:HI 2 "const_int_operand" "")))
3569    (clobber (reg:SI T_REG))]
3570   "TARGET_SH1 && reload_completed"
3571   [(use (reg:SI R0_REG))]
3572   "
3573 {
3574   gen_shifty_hi_op (ASHIFT, operands);
3575   DONE;
3576 }")
3577
3578 ;
3579 ; arithmetic shift right
3580 ;
3581
3582 (define_insn "ashrsi3_sh2a"
3583   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3584         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3585                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3586   "TARGET_SH2A"
3587   "shad %2,%0"
3588   [(set_attr "type" "dyn_shift")
3589    (set_attr "length" "4")])
3590
3591 (define_insn "ashrsi3_k"
3592   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3593         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3594                      (match_operand:SI 2 "const_int_operand" "M")))
3595    (clobber (reg:SI T_REG))]
3596   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3597   "shar %0"
3598   [(set_attr "type" "arith")])
3599
3600 ;; We can't do HImode right shifts correctly unless we start out with an
3601 ;; explicit zero / sign extension; doing that would result in worse overall
3602 ;; code, so just let the machine independent code widen the mode.
3603 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3604
3605
3606 ;; ??? This should be a define expand.
3607
3608 (define_insn "ashrsi2_16"
3609   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3610         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3611                      (const_int 16)))]
3612   "TARGET_SH1"
3613   "#"
3614   [(set_attr "length" "4")])
3615
3616 (define_split
3617   [(set (match_operand:SI 0 "arith_reg_dest" "")
3618         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3619                      (const_int 16)))]
3620   "TARGET_SH1"
3621   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3622    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3623   "operands[2] = gen_lowpart (HImode, operands[0]);")
3624
3625 ;; ??? This should be a define expand.
3626
3627 (define_insn "ashrsi2_31"
3628   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3629         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3630                      (const_int 31)))
3631    (clobber (reg:SI T_REG))]
3632   "TARGET_SH1"
3633   "#"
3634   [(set_attr "length" "4")])
3635
3636 (define_split
3637   [(set (match_operand:SI 0 "arith_reg_dest" "")
3638         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3639                      (const_int 31)))
3640    (clobber (reg:SI T_REG))]
3641   "TARGET_SH1"
3642   [(const_int 0)]
3643   "
3644 {
3645   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3646   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3647   DONE;
3648 }")
3649
3650 (define_peephole2
3651   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3652    (set (reg:SI T_REG)
3653         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3654   "TARGET_SH1
3655    && peep2_reg_dead_p (2, operands[0])
3656    && peep2_reg_dead_p (2, operands[1])"
3657   [(const_int 0)]
3658   "
3659 {
3660   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3661   DONE;
3662 }")
3663
3664 (define_insn "ashlsi_c"
3665   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3666         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3667    (set (reg:SI T_REG)
3668         (lt:SI (match_dup 1) (const_int 0)))]
3669   "TARGET_SH1"
3670   "shll %0"
3671   [(set_attr "type" "arith")])
3672
3673 (define_insn "*ashlsi_c_void"
3674   [(set (reg:SI T_REG)
3675         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3676    (clobber (match_scratch:SI 1 "=0"))]
3677   "TARGET_SH1 && cse_not_expected"
3678   "shll %0"
3679   [(set_attr "type" "arith")])
3680
3681 (define_insn "ashrsi3_d"
3682   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685   "TARGET_SH3"
3686   "shad %2,%0"
3687   [(set_attr "type" "dyn_shift")])
3688
3689 (define_insn "ashrsi3_n"
3690   [(set (reg:SI R4_REG)
3691         (ashiftrt:SI (reg:SI R4_REG)
3692                      (match_operand:SI 0 "const_int_operand" "i")))
3693    (clobber (reg:SI T_REG))
3694    (clobber (reg:SI PR_REG))
3695    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3696   "TARGET_SH1"
3697   "jsr  @%1%#"
3698   [(set_attr "type" "sfunc")
3699    (set_attr "needs_delay_slot" "yes")])
3700
3701 (define_insn "ashrsi3_media"
3702   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3703         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3704                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3705   "TARGET_SHMEDIA"
3706   "@
3707         shard.l %1, %2, %0
3708         shari.l %1, %2, %0"
3709   [(set_attr "type" "arith_media")
3710    (set_attr "highpart" "ignore")])
3711
3712 (define_expand "ashrsi3"
3713   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3714                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3715                                 (match_operand:SI 2 "nonmemory_operand" "")))
3716               (clobber (reg:SI T_REG))])]
3717   ""
3718   "
3719 {
3720   if (TARGET_SHMEDIA)
3721     {
3722       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3723       DONE;
3724     }
3725   if (expand_ashiftrt (operands))
3726     DONE;
3727   else
3728     FAIL;
3729 }")
3730
3731 ;; logical shift right
3732
3733 (define_insn "lshrsi3_sh2a"
3734   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3736                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3737   "TARGET_SH2A"
3738   "shld %2,%0"
3739   [(set_attr "type" "dyn_shift")
3740    (set_attr "length" "4")])
3741
3742 (define_insn "lshrsi3_d"
3743   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3744         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3745                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3746   "TARGET_SH3"
3747   "shld %2,%0"
3748   [(set_attr "type" "dyn_shift")])
3749
3750 ;;  Only the single bit shift clobbers the T bit.
3751
3752 (define_insn "lshrsi3_m"
3753   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3754         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3755                      (match_operand:SI 2 "const_int_operand" "M")))
3756    (clobber (reg:SI T_REG))]
3757   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3758   "shlr %0"
3759   [(set_attr "type" "arith")])
3760
3761 (define_insn "lshrsi3_k"
3762   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3763         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3764                      (match_operand:SI 2 "const_int_operand" "P27")))]
3765   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3766    && ! satisfies_constraint_M (operands[2])"
3767   "shlr%O2      %0"
3768   [(set_attr "type" "arith")])
3769
3770 (define_insn "lshrsi3_n"
3771   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3773                      (match_operand:SI 2 "const_int_operand" "n")))
3774    (clobber (reg:SI T_REG))]
3775   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3776   "#"
3777   [(set (attr "length")
3778         (cond [(match_test "shift_insns_rtx (insn)")
3779                (const_string "2")
3780                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3781                (const_string "4")
3782                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3783                (const_string "6")]
3784               (const_string "8")))
3785    (set_attr "type" "arith")])
3786
3787 (define_split
3788   [(set (match_operand:SI 0 "arith_reg_dest" "")
3789         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3790                      (match_operand:SI 2 "const_int_operand" "")))
3791    (clobber (reg:SI T_REG))]
3792   "TARGET_SH1 && reload_completed"
3793   [(use (reg:SI R0_REG))]
3794   "
3795 {
3796   gen_shifty_op (LSHIFTRT, operands);
3797   DONE;
3798 }")
3799
3800 (define_insn "lshrsi3_media"
3801   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3802         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3803                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3804   "TARGET_SHMEDIA"
3805   "@
3806         shlrd.l %1, %2, %0
3807         shlri.l %1, %2, %0"
3808   [(set_attr "type" "arith_media")
3809    (set_attr "highpart" "ignore")])
3810
3811 (define_expand "lshrsi3"
3812   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3813                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3814                                 (match_operand:SI 2 "nonmemory_operand" "")))
3815               (clobber (reg:SI T_REG))])]
3816   ""
3817   "
3818 {
3819   if (TARGET_SHMEDIA)
3820     {
3821       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3822       DONE;
3823     }
3824   if (CONST_INT_P (operands[2])
3825       && sh_dynamicalize_shift_p (operands[2]))
3826     operands[2] = force_reg (SImode, operands[2]);
3827   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3828     {
3829       rtx count = copy_to_mode_reg (SImode, operands[2]);
3830       emit_insn (gen_negsi2 (count, count));
3831       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3832       DONE;
3833     }
3834   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3835     FAIL;
3836 }")
3837
3838 ;; ??? This should be a define expand.
3839
3840 (define_insn "ashldi3_k"
3841   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3842         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3843                    (const_int 1)))
3844    (clobber (reg:SI T_REG))]
3845   "TARGET_SH1"
3846   "shll %R0\;rotcl      %S0"
3847   [(set_attr "length" "4")
3848    (set_attr "type" "arith")])
3849
3850 ;; Expander for DImode shift left with SImode operations.
3851
3852 (define_expand "ashldi3_std"
3853   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3854         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3855                    (match_operand:DI 2 "const_int_operand" "n")))]
3856   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3857   "
3858 {
3859   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3860   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3861   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3862   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3863   rtx dst = gen_reg_rtx (DImode);
3864   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3865   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3866   rtx tmp0, tmp1;
3867
3868   tmp0 = gen_reg_rtx (SImode);
3869   tmp1 = gen_reg_rtx (SImode);
3870   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3871   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3872   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3873   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3874   emit_move_insn (operands[0], dst);
3875   DONE;
3876 }")
3877
3878 (define_insn "ashldi3_media"
3879   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3880         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3881                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3882   "TARGET_SHMEDIA"
3883   "@
3884         shlld   %1, %2, %0
3885         shlli   %1, %2, %0"
3886   [(set_attr "type" "arith_media")])
3887
3888 (define_insn "*ashldisi3_media"
3889   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3890         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3891                    (match_operand:DI 2 "const_int_operand" "n")))]
3892   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3893   "shlli.l      %1, %2, %0"
3894   [(set_attr "type" "arith_media")
3895    (set_attr "highpart" "ignore")])
3896
3897 (define_expand "ashldi3"
3898   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3899                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3900                               (match_operand:DI 2 "immediate_operand" "")))
3901               (clobber (reg:SI T_REG))])]
3902   ""
3903   "
3904 {
3905   if (TARGET_SHMEDIA)
3906     {
3907       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3908       DONE;
3909     }
3910   if (CONST_INT_P (operands[2])
3911       && INTVAL (operands[2]) == 1)
3912     {
3913       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3914       DONE;
3915     }
3916   else if (CONST_INT_P (operands[2])
3917       && INTVAL (operands[2]) < 32)
3918     {
3919       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3920       DONE;
3921     }
3922   else
3923     FAIL;
3924 }")
3925
3926 ;; ??? This should be a define expand.
3927
3928 (define_insn "lshrdi3_k"
3929   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3930         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3931                      (const_int 1)))
3932    (clobber (reg:SI T_REG))]
3933   "TARGET_SH1"
3934   "shlr %S0\;rotcr      %R0"
3935   [(set_attr "length" "4")
3936    (set_attr "type" "arith")])
3937
3938 (define_insn "lshrdi3_media"
3939   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3940         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3941                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3942   "TARGET_SHMEDIA
3943    && (arith_reg_dest (operands[0], DImode)
3944        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3945   "@
3946         shlrd   %1, %2, %0
3947         shlri   %1, %2, %0"
3948   [(set_attr "type" "arith_media")])
3949
3950 (define_insn "*lshrdisi3_media"
3951   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3952         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3953                      (match_operand:DI 2 "const_int_operand" "n")))]
3954   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3955   "shlri.l      %1, %2, %0"
3956   [(set_attr "type" "arith_media")
3957    (set_attr "highpart" "ignore")])
3958
3959 (define_expand "lshrdi3"
3960   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3961                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3962                                (match_operand:DI 2 "immediate_operand" "")))
3963              (clobber (reg:SI T_REG))])]
3964   ""
3965   "
3966 {
3967   if (TARGET_SHMEDIA)
3968     {
3969       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3970       DONE;
3971     }
3972   if (!CONST_INT_P (operands[2])
3973       || INTVAL (operands[2]) != 1)
3974     FAIL;
3975 }")
3976
3977 ;; ??? This should be a define expand.
3978
3979 (define_insn "ashrdi3_k"
3980   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3981         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3982                      (const_int 1)))
3983    (clobber (reg:SI T_REG))]
3984   "TARGET_SH1"
3985   "shar %S0\;rotcr      %R0"
3986   [(set_attr "length" "4")
3987    (set_attr "type" "arith")])
3988
3989 (define_insn "ashrdi3_media"
3990   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3991         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3992                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3993   "TARGET_SHMEDIA
3994    && (arith_reg_dest (operands[0], DImode)
3995        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
3996   "@
3997         shard   %1, %2, %0
3998         shari   %1, %2, %0"
3999   [(set_attr "type" "arith_media")])
4000
4001 (define_insn "*ashrdisi3_media"
4002   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4003         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004                      (match_operand:DI 2 "const_int_operand" "n")))]
4005   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4006   "shari.l      %1, %2, %0"
4007   [(set_attr "type" "arith_media")
4008    (set_attr "highpart" "ignore")])
4009
4010 (define_insn "ashrdisi3_media_high"
4011   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4012         (truncate:SI
4013            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4014                         (match_operand:DI 2 "const_int_operand" "n"))))]
4015   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4016   "shari        %1, %2, %0"
4017   [(set_attr "type" "arith_media")])
4018
4019 (define_insn "ashrdisi3_media_opaque"
4020   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4021         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4022                     (match_operand:DI 2 "const_int_operand" "n")]
4023          UNSPEC_ASHIFTRT))]
4024   "TARGET_SHMEDIA"
4025   "shari        %1, %2, %0"
4026   [(set_attr "type" "arith_media")])
4027
4028 (define_expand "ashrdi3"
4029   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4030                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4031                                 (match_operand:DI 2 "immediate_operand" "")))
4032               (clobber (reg:SI T_REG))])]
4033   ""
4034   "
4035 {
4036   if (TARGET_SHMEDIA)
4037     {
4038       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4039       DONE;
4040     }
4041   if (!CONST_INT_P (operands[2])
4042       || INTVAL (operands[2]) != 1)
4043     FAIL;
4044 }")
4045
4046 ;; combined left/right shift
4047
4048 (define_split
4049   [(set (match_operand:SI 0 "register_operand" "")
4050         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4051                            (match_operand:SI 2 "const_int_operand" ""))
4052                 (match_operand:SI 3 "const_int_operand" "")))]
4053   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4054   [(use (reg:SI R0_REG))]
4055   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4056    DONE;")
4057
4058 (define_split
4059   [(set (match_operand:SI 0 "register_operand" "")
4060         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4061                            (match_operand:SI 2 "const_int_operand" ""))
4062                 (match_operand:SI 3 "const_int_operand" "")))
4063    (clobber (reg:SI T_REG))]
4064   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4065   [(use (reg:SI R0_REG))]
4066   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4067    DONE;")
4068
4069 (define_insn ""
4070   [(set (match_operand:SI 0 "register_operand" "=r")
4071         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4072                            (match_operand:SI 2 "const_int_operand" "n"))
4073                 (match_operand:SI 3 "const_int_operand" "n")))
4074    (clobber (reg:SI T_REG))]
4075   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4076  "#"
4077   [(set (attr "length")
4078         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4079                (const_string "4")
4080                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4081                (const_string "6")
4082                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4083                (const_string "8")
4084                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4085                (const_string "10")
4086                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4087                (const_string "12")
4088                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4089                (const_string "14")
4090                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4091                (const_string "16")]
4092               (const_string "18")))
4093    (set_attr "type" "arith")])
4094
4095 (define_insn ""
4096   [(set (match_operand:SI 0 "register_operand" "=z")
4097         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4098                            (match_operand:SI 2 "const_int_operand" "n"))
4099                 (match_operand:SI 3 "const_int_operand" "n")))
4100    (clobber (reg:SI T_REG))]
4101   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4102  "#"
4103   [(set (attr "length")
4104         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4105                (const_string "4")
4106                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4107                (const_string "6")
4108                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4109                (const_string "8")]
4110               (const_string "10")))
4111    (set_attr "type" "arith")])
4112
4113 ;; shift left / and combination with a scratch register: The combine pass
4114 ;; does not accept the individual instructions, even though they are
4115 ;; cheap.  But it needs a precise description so that it is usable after
4116 ;; reload.
4117 (define_insn "and_shl_scratch"
4118   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4119         (lshiftrt:SI
4120          (ashift:SI
4121           (and:SI
4122            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4123                         (match_operand:SI 2 "const_int_operand" "N,n"))
4124            (match_operand:SI 3 "" "0,r"))
4125           (match_operand:SI 4 "const_int_operand" "n,n"))
4126          (match_operand:SI 5 "const_int_operand" "n,n")))
4127    (clobber (reg:SI T_REG))]
4128   "TARGET_SH1"
4129   "#"
4130   [(set (attr "length")
4131         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4132                (const_string "4")
4133                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4134                (const_string "6")
4135                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4136                (const_string "8")
4137                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4138                (const_string "10")]
4139               (const_string "12")))
4140    (set_attr "type" "arith")])
4141
4142 (define_split
4143   [(set (match_operand:SI 0 "register_operand" "")
4144         (lshiftrt:SI
4145          (ashift:SI
4146           (and:SI
4147            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4148                         (match_operand:SI 2 "const_int_operand" ""))
4149            (match_operand:SI 3 "register_operand" ""))
4150           (match_operand:SI 4 "const_int_operand" ""))
4151          (match_operand:SI 5 "const_int_operand" "")))
4152    (clobber (reg:SI T_REG))]
4153   "TARGET_SH1"
4154   [(use (reg:SI R0_REG))]
4155   "
4156 {
4157   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4158
4159   if (INTVAL (operands[2]))
4160     {
4161       gen_shifty_op (LSHIFTRT, operands);
4162     }
4163   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4164   operands[2] = operands[4];
4165   gen_shifty_op (ASHIFT, operands);
4166   if (INTVAL (operands[5]))
4167     {
4168       operands[2] = operands[5];
4169       gen_shifty_op (LSHIFTRT, operands);
4170     }
4171   DONE;
4172 }")
4173
4174 ;; signed left/right shift combination.
4175 (define_split
4176   [(set (match_operand:SI 0 "register_operand" "")
4177         (sign_extract:SI
4178          (ashift:SI (match_operand:SI 1 "register_operand" "")
4179                     (match_operand:SI 2 "const_int_operand" ""))
4180          (match_operand:SI 3 "const_int_operand" "")
4181          (const_int 0)))
4182    (clobber (reg:SI T_REG))]
4183   "TARGET_SH1"
4184   [(use (reg:SI R0_REG))]
4185   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4186    DONE;")
4187
4188 (define_insn "shl_sext_ext"
4189   [(set (match_operand:SI 0 "register_operand" "=r")
4190         (sign_extract:SI
4191          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4192                     (match_operand:SI 2 "const_int_operand" "n"))
4193          (match_operand:SI 3 "const_int_operand" "n")
4194          (const_int 0)))
4195    (clobber (reg:SI T_REG))]
4196   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4197   "#"
4198   [(set (attr "length")
4199         (cond [(match_test "shl_sext_length (insn)")
4200                (const_string "2")
4201                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4202                (const_string "4")
4203                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4204                (const_string "6")
4205                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4206                (const_string "8")
4207                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4208                (const_string "10")
4209                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4210                (const_string "12")
4211                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4212                (const_string "14")
4213                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4214                (const_string "16")]
4215               (const_string "18")))
4216     (set_attr "type" "arith")])
4217
4218 (define_insn "shl_sext_sub"
4219   [(set (match_operand:SI 0 "register_operand" "=z")
4220         (sign_extract:SI
4221          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4222                     (match_operand:SI 2 "const_int_operand" "n"))
4223          (match_operand:SI 3 "const_int_operand" "n")
4224          (const_int 0)))
4225    (clobber (reg:SI T_REG))]
4226   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4227   "#"
4228   [(set (attr "length")
4229         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4230                (const_string "6")
4231                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4232                (const_string "8")
4233                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4234                (const_string "10")
4235                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4236                (const_string "12")]
4237               (const_string "14")))
4238     (set_attr "type" "arith")])
4239
4240 ;; These patterns are found in expansions of DImode shifts by 16, and
4241 ;; allow the xtrct instruction to be generated from C source.
4242
4243 (define_insn "xtrct_left"
4244   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4245         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4246                            (const_int 16))
4247                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4248                              (const_int 16))))]
4249   "TARGET_SH1"
4250   "xtrct        %1,%0"
4251   [(set_attr "type" "arith")])
4252
4253 (define_insn "xtrct_right"
4254   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4255         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4256                              (const_int 16))
4257                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4258                            (const_int 16))))]
4259   "TARGET_SH1"
4260   "xtrct        %2,%0"
4261   [(set_attr "type" "arith")])
4262
4263 ;; -------------------------------------------------------------------------
4264 ;; Unary arithmetic
4265 ;; -------------------------------------------------------------------------
4266
4267 (define_insn "negc"
4268   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4269         (neg:SI (plus:SI (reg:SI T_REG)
4270                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4271    (set (reg:SI T_REG)
4272         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4273                (const_int 0)))]
4274   "TARGET_SH1"
4275   "negc %1,%0"
4276   [(set_attr "type" "arith")])
4277
4278 (define_insn "*negdi_media"
4279   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4280         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4281   "TARGET_SHMEDIA"
4282   "sub  r63, %1, %0"
4283   [(set_attr "type" "arith_media")])
4284
4285 (define_expand "negdi2"
4286   [(set (match_operand:DI 0 "arith_reg_operand" "")
4287         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4288   ""
4289   "
4290 {
4291   if (TARGET_SH1)
4292     {
4293       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4294       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4295
4296       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4297       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4298
4299       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4300       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4301
4302       emit_insn (gen_clrt ());
4303       emit_insn (gen_negc (low_dst, low_src));
4304       emit_insn (gen_negc (high_dst, high_src));
4305       DONE;
4306     }
4307 }")
4308
4309 (define_insn "negsi2"
4310   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4311         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4312   "TARGET_SH1"
4313   "neg  %1,%0"
4314   [(set_attr "type" "arith")])
4315
4316 (define_insn "one_cmplsi2"
4317   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4318         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4319   "TARGET_SH1"
4320   "not  %1,%0"
4321   [(set_attr "type" "arith")])
4322
4323 (define_expand "one_cmpldi2"
4324   [(set (match_operand:DI 0 "arith_reg_dest" "")
4325         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4326                 (const_int -1)))]
4327   "TARGET_SHMEDIA" "")
4328
4329 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4330    This can be used as some kind of conditional execution, which is useful
4331    for abs.  */
4332 (define_split
4333   [(set (match_operand:SI 0 "arith_reg_dest" "")
4334         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4335                          (match_operand:SI 1 "arith_reg_operand" ""))
4336                  (reg:SI T_REG)))]
4337   "TARGET_HARD_SH4"
4338   [(const_int 0)]
4339   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4340    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4341    DONE;")
4342
4343 (define_insn "cneg"
4344   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4345         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4346                       (match_operand:SI 1 "arith_reg_operand" "0")
4347                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4348   "TARGET_HARD_SH4"
4349   "bf 0f\;neg %2,%0\\n0:"
4350   [(set_attr "type" "arith") ;; poor approximation
4351    (set_attr "length" "4")])
4352
4353 \f
4354 ;; -------------------------------------------------------------------------
4355 ;; Zero extension instructions
4356 ;; -------------------------------------------------------------------------
4357
4358 (define_insn "zero_extendsidi2"
4359   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4360         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4361   "TARGET_SHMEDIA"
4362   "addz.l       %1, r63, %0"
4363   [(set_attr "type" "arith_media")
4364    (set_attr "highpart" "extend")])
4365
4366 (define_insn "zero_extendhidi2"
4367   [(set (match_operand:DI 0 "register_operand" "=r,r")
4368         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4369   "TARGET_SHMEDIA"
4370   "@
4371         #
4372         ld%M1.uw        %m1, %0"
4373   [(set_attr "type" "*,load_media")
4374    (set (attr "highpart")
4375         (cond [(match_test "sh_contains_memref_p (insn)")
4376                (const_string "user")]
4377               (const_string "ignore")))])
4378
4379 (define_split
4380   [(set (match_operand:DI 0 "register_operand" "")
4381         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4382   "TARGET_SHMEDIA && reload_completed"
4383   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4384    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4385   "
4386 {
4387   if (GET_CODE (operands[1]) == TRUNCATE)
4388     operands[1] = XEXP (operands[1], 0);
4389 }")
4390
4391 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4392 ;; reload the entire truncate expression.
4393 (define_insn_and_split "*loaddi_trunc"
4394   [(set (match_operand 0 "any_register_operand" "=r")
4395         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4396   "TARGET_SHMEDIA && reload_completed"
4397   "#"
4398   "TARGET_SHMEDIA && reload_completed"
4399   [(set (match_dup 0) (match_dup 1))]
4400   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4401
4402 (define_insn "zero_extendqidi2"
4403   [(set (match_operand:DI 0 "register_operand" "=r,r")
4404         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4405   "TARGET_SHMEDIA"
4406   "@
4407         andi    %1, 255, %0
4408         ld%M1.ub        %m1, %0"
4409   [(set_attr "type" "arith_media,load_media")
4410    (set (attr "highpart")
4411         (cond [(match_test "sh_contains_memref_p (insn)")
4412                (const_string "user")]
4413               (const_string "ignore")))])
4414
4415 (define_expand "zero_extendhisi2"
4416   [(set (match_operand:SI 0 "arith_reg_operand" "")
4417         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4418   ""
4419   "
4420 {
4421   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4422     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4423 }")
4424
4425 (define_insn "*zero_extendhisi2_compact"
4426   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4427         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4428   "TARGET_SH1"
4429   "extu.w       %1,%0"
4430   [(set_attr "type" "arith")])
4431
4432 (define_insn "*zero_extendhisi2_media"
4433   [(set (match_operand:SI 0 "register_operand" "=r,r")
4434         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4435   "TARGET_SHMEDIA"
4436   "@
4437         #
4438         ld%M1.uw        %m1, %0"
4439   [(set_attr "type" "arith_media,load_media")
4440    (set (attr "highpart")
4441         (cond [(match_test "sh_contains_memref_p (insn)")
4442                (const_string "user")]
4443               (const_string "ignore")))])
4444
4445 (define_split
4446   [(set (match_operand:SI 0 "register_operand" "")
4447         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4448   "TARGET_SHMEDIA && reload_completed"
4449   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4450    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4451   "
4452 {
4453   rtx op1 = operands[1];
4454
4455   if (GET_CODE (op1) == TRUNCATE)
4456     op1 = XEXP (op1, 0);
4457   operands[2]
4458     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4459                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4460 }")
4461
4462 (define_expand "zero_extendqisi2"
4463   [(set (match_operand:SI 0 "arith_reg_operand" "")
4464         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4465   ""
4466   "
4467 {
4468   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4469     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4470 }")
4471
4472 (define_insn "*zero_extendqisi2_compact"
4473   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4474         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4475   "TARGET_SH1"
4476   "extu.b       %1,%0"
4477   [(set_attr "type" "arith")])
4478
4479 (define_insn "*zero_extendqisi2_media"
4480   [(set (match_operand:SI 0 "register_operand" "=r,r")
4481         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4482   "TARGET_SHMEDIA"
4483   "@
4484         andi    %1, 255, %0
4485         ld%M1.ub        %m1, %0"
4486   [(set_attr "type" "arith_media,load_media")
4487    (set (attr "highpart")
4488         (cond [(match_test "sh_contains_memref_p (insn)")
4489                (const_string "user")]
4490               (const_string "ignore")))])
4491
4492 (define_insn "zero_extendqihi2"
4493   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4494         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4495   "TARGET_SH1"
4496   "extu.b       %1,%0"
4497   [(set_attr "type" "arith")])
4498
4499 ;; -------------------------------------------------------------------------
4500 ;; Sign extension instructions
4501 ;; -------------------------------------------------------------------------
4502
4503 ;; ??? This should be a define expand.
4504 ;; ??? Or perhaps it should be dropped?
4505
4506 ;; convert_move generates good code for SH[1-4].
4507 (define_insn "extendsidi2"
4508   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4509         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4510   "TARGET_SHMEDIA"
4511   "@
4512         add.l   %1, r63, %0
4513         ld%M1.l %m1, %0
4514         fmov.sl %1, %0"
4515   [(set_attr "type" "arith_media,load_media,fpconv_media")
4516    (set (attr "highpart")
4517         (cond [(match_test "sh_contains_memref_p (insn)")
4518                (const_string "user")]
4519               (const_string "extend")))])
4520
4521 (define_insn "extendhidi2"
4522   [(set (match_operand:DI 0 "register_operand" "=r,r")
4523         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4524   "TARGET_SHMEDIA"
4525   "@
4526         #
4527         ld%M1.w %m1, %0"
4528   [(set_attr "type" "*,load_media")
4529    (set (attr "highpart")
4530         (cond [(match_test "sh_contains_memref_p (insn)")
4531                (const_string "user")]
4532               (const_string "ignore")))])
4533
4534 (define_split
4535   [(set (match_operand:DI 0 "register_operand" "")
4536         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4537   "TARGET_SHMEDIA && reload_completed"
4538   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4539    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4540   "
4541 {
4542   if (GET_CODE (operands[1]) == TRUNCATE)
4543     operands[1] = XEXP (operands[1], 0);
4544 }")
4545
4546 (define_insn "extendqidi2"
4547   [(set (match_operand:DI 0 "register_operand" "=r,r")
4548         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4549   "TARGET_SHMEDIA"
4550   "@
4551         #
4552         ld%M1.b %m1, %0"
4553   [(set_attr "type" "*,load_media")
4554    (set (attr "highpart")
4555         (cond [(match_test "sh_contains_memref_p (insn)")
4556                (const_string "user")]
4557               (const_string "ignore")))])
4558
4559 (define_split
4560   [(set (match_operand:DI 0 "register_operand" "")
4561         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4562   "TARGET_SHMEDIA && reload_completed"
4563   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4564    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4565   "
4566 {
4567   if (GET_CODE (operands[1]) == TRUNCATE)
4568     operands[1] = XEXP (operands[1], 0);
4569 }")
4570
4571 (define_expand "extendhisi2"
4572   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4573         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4574   ""
4575   "")
4576
4577 (define_insn "*extendhisi2_compact"
4578   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4579         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4580   "TARGET_SH1"
4581   "@
4582         exts.w  %1,%0
4583         mov.w   %1,%0"
4584   [(set_attr "type" "arith,load")])
4585
4586 (define_insn "*extendhisi2_media"
4587   [(set (match_operand:SI 0 "register_operand" "=r,r")
4588         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4589   "TARGET_SHMEDIA"
4590   "@
4591         #
4592         ld%M1.w %m1, %0"
4593   [(set_attr "type" "arith_media,load_media")
4594    (set (attr "highpart")
4595         (cond [(match_test "sh_contains_memref_p (insn)")
4596                (const_string "user")]
4597               (const_string "ignore")))])
4598
4599 (define_split
4600   [(set (match_operand:SI 0 "register_operand" "")
4601         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4602   "TARGET_SHMEDIA && reload_completed"
4603   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4604    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4605   "
4606 {
4607   rtx op1 = operands[1];
4608   if (GET_CODE (op1) == TRUNCATE)
4609     op1 = XEXP (op1, 0);
4610   operands[2]
4611     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4612                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4613 }")
4614
4615 (define_expand "extendqisi2"
4616   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4617         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4618   ""
4619   "")
4620
4621 (define_insn "*extendqisi2_compact"
4622   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4623         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4624   "TARGET_SH1"
4625   "@
4626         exts.b  %1,%0
4627         mov.b   %1,%0"
4628   [(set_attr "type" "arith,load")
4629    (set_attr_alternative "length"
4630      [(const_int 2)
4631        (if_then_else
4632         (match_test "TARGET_SH2A")
4633         (const_int 4) (const_int 2))])])
4634
4635 (define_insn "*extendqisi2_media"
4636   [(set (match_operand:SI 0 "register_operand" "=r,r")
4637         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4638   "TARGET_SHMEDIA"
4639   "@
4640         #
4641         ld%M1.b %m1, %0"
4642   [(set_attr "type" "arith_media,load_media")
4643    (set (attr "highpart")
4644         (cond [(match_test "sh_contains_memref_p (insn)")
4645                (const_string "user")]
4646               (const_string "ignore")))])
4647
4648 (define_split
4649   [(set (match_operand:SI 0 "register_operand" "")
4650         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4651   "TARGET_SHMEDIA && reload_completed"
4652   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4653    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4654    "
4655 {
4656   rtx op1 = operands[1];
4657   if (GET_CODE (op1) == TRUNCATE)
4658     op1 = XEXP (op1, 0);
4659   operands[2]
4660     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4661                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4662 }")
4663
4664 (define_insn "extendqihi2"
4665   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4666         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4667   "TARGET_SH1"
4668   "@
4669         exts.b  %1,%0
4670         mov.b   %1,%0"
4671   [(set_attr "type" "arith,load")
4672    (set_attr_alternative "length"
4673      [(const_int 2)
4674        (if_then_else
4675         (match_test "TARGET_SH2A")
4676         (const_int 4) (const_int 2))])])
4677
4678 /* It would seem useful to combine the truncXi patterns into the movXi
4679    patterns, but unary operators are ignored when matching constraints,
4680    so we need separate patterns.  */
4681 (define_insn "truncdisi2"
4682   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4683         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4684   "TARGET_SHMEDIA"
4685   "@
4686         add.l   %1, r63, %0
4687         st%M0.l %m0, %1
4688         fst%M0.s        %m0, %T1
4689         fmov.ls %1, %0
4690         fmov.sl %T1, %0
4691         fmov.s  %T1, %0"
4692   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4693    (set (attr "highpart")
4694         (cond [(match_test "sh_contains_memref_p (insn)")
4695                (const_string "user")]
4696               (const_string "extend")))])
4697
4698 (define_insn "truncdihi2"
4699   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4700         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4701   "TARGET_SHMEDIA"
4702   "@
4703         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4704         st%M0.w %m0, %1"
4705   [(set_attr "type"   "arith_media,store_media")
4706    (set_attr "length" "8,4")
4707    (set (attr "highpart")
4708         (cond [(match_test "sh_contains_memref_p (insn)")
4709                (const_string "user")]
4710               (const_string "extend")))])
4711
4712 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4713 ; Because we use zero extension, we can't provide signed QImode compares
4714 ; using a simple compare or conditional branch insn.
4715 (define_insn "truncdiqi2"
4716   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4717         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4718   "TARGET_SHMEDIA"
4719   "@
4720         andi    %1, 255, %0
4721         st%M0.b %m0, %1"
4722   [(set_attr "type"   "arith_media,store")
4723    (set (attr "highpart")
4724         (cond [(match_test "sh_contains_memref_p (insn)")
4725                (const_string "user")]
4726               (const_string "extend")))])
4727 ;; -------------------------------------------------------------------------
4728 ;; Move instructions
4729 ;; -------------------------------------------------------------------------
4730
4731 ;; define push and pop so it is easy for sh.c
4732 ;; We can't use push and pop on SHcompact because the stack must always
4733 ;; be 8-byte aligned.
4734
4735 (define_expand "push"
4736   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4737         (match_operand:SI 0 "register_operand" "r,l,x"))]
4738   "TARGET_SH1 && ! TARGET_SH5"
4739   "")
4740
4741 (define_expand "pop"
4742   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4743         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4744   "TARGET_SH1 && ! TARGET_SH5"
4745   "")
4746
4747 (define_expand "push_e"
4748   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4749                    (match_operand:SF 0 "" ""))
4750               (use (reg:PSI FPSCR_REG))
4751               (clobber (scratch:SI))])]
4752   "TARGET_SH1 && ! TARGET_SH5"
4753   "")
4754
4755 (define_insn "push_fpul"
4756   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4757   "TARGET_SH2E && ! TARGET_SH5"
4758   "sts.l        fpul,@-r15"
4759   [(set_attr "type" "fstore")
4760    (set_attr "late_fp_use" "yes")
4761    (set_attr "hit_stack" "yes")])
4762
4763 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4764 ;; so use that.
4765 (define_expand "push_4"
4766   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4767                    (match_operand:DF 0 "" ""))
4768               (use (reg:PSI FPSCR_REG))
4769               (clobber (scratch:SI))])]
4770   "TARGET_SH1 && ! TARGET_SH5"
4771   "")
4772
4773 (define_expand "pop_e"
4774   [(parallel [(set (match_operand:SF 0 "" "")
4775               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4776               (use (reg:PSI FPSCR_REG))
4777               (clobber (scratch:SI))])]
4778   "TARGET_SH1 && ! TARGET_SH5"
4779   "")
4780
4781 (define_insn "pop_fpul"
4782   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4783   "TARGET_SH2E && ! TARGET_SH5"
4784   "lds.l        @r15+,fpul"
4785   [(set_attr "type" "load")
4786    (set_attr "hit_stack" "yes")])
4787
4788 (define_expand "pop_4"
4789   [(parallel [(set (match_operand:DF 0 "" "")
4790                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4791               (use (reg:PSI FPSCR_REG))
4792               (clobber (scratch:SI))])]
4793   "TARGET_SH1 && ! TARGET_SH5"
4794   "")
4795
4796 (define_expand "push_fpscr"
4797   [(const_int 0)]
4798   "TARGET_SH2E"
4799   "
4800 {
4801   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4802                                                  gen_rtx_PRE_DEC (Pmode,
4803                                                           stack_pointer_rtx)),
4804                                         get_fpscr_rtx ()));
4805   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4806   DONE;
4807 }")
4808
4809 (define_expand "pop_fpscr"
4810   [(const_int 0)]
4811   "TARGET_SH2E"
4812   "
4813 {
4814   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4815                                         gen_frame_mem (PSImode,
4816                                                  gen_rtx_POST_INC (Pmode,
4817                                                           stack_pointer_rtx))));
4818   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4819   DONE;
4820 }")
4821
4822 ;; These two patterns can happen as the result of optimization, when
4823 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4824 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4825
4826 (define_insn "clrt"
4827   [(set (reg:SI T_REG) (const_int 0))]
4828   "TARGET_SH1"
4829   "clrt")
4830
4831 (define_insn "sett"
4832   [(set (reg:SI T_REG) (const_int 1))]
4833   "TARGET_SH1"
4834   "sett")
4835
4836 ;; Define additional pop for SH1 and SH2 so it does not get 
4837 ;; placed in the delay slot.
4838 (define_insn "*movsi_pop"
4839   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
4840         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
4841   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
4842    && ! TARGET_SH3"
4843   "@
4844    mov.l   %1,%0
4845    lds.l   %1,%0
4846    lds.l   %1,%0"
4847   [(set_attr "type" "load_si,mem_mac,pload")
4848    (set_attr "length" "2,2,2")
4849    (set_attr "in_delay_slot" "no,no,no")])
4850
4851 ;; t/r must come after r/r, lest reload will try to reload stuff like
4852 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4853 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4854 (define_insn "movsi_i"
4855   [(set (match_operand:SI 0 "general_movdst_operand"
4856             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4857         (match_operand:SI 1 "general_movsrc_operand"
4858          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4859   "TARGET_SH1
4860    && ! TARGET_SH2E
4861    && ! TARGET_SH2A
4862    && (register_operand (operands[0], SImode)
4863        || register_operand (operands[1], SImode))"
4864   "@
4865         mov.l   %1,%0
4866         mov     %1,%0
4867         mov     %1,%0
4868         cmp/pl  %1
4869         mov.l   %1,%0
4870         sts     %1,%0
4871         sts     %1,%0
4872         movt    %0
4873         mov.l   %1,%0
4874         sts.l   %1,%0
4875         sts.l   %1,%0
4876         lds     %1,%0
4877         lds     %1,%0
4878         lds.l   %1,%0
4879         lds.l   %1,%0
4880         fake    %1,%0"
4881   [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4882    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4883
4884 ;; t/r must come after r/r, lest reload will try to reload stuff like
4885 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4886 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4887 ;; will require a reload.
4888 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4889 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4890 (define_insn "movsi_ie"
4891   [(set (match_operand:SI 0 "general_movdst_operand"
4892             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4893         (match_operand:SI 1 "general_movsrc_operand"
4894          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4895   "(TARGET_SH2E || TARGET_SH2A)
4896    && (register_operand (operands[0], SImode)
4897        || register_operand (operands[1], SImode))"
4898   "@
4899         mov.l   %1,%0
4900         mov     %1,%0
4901         mov     %1,%0
4902         movi20  %1,%0
4903         movi20s %1,%0
4904         cmp/pl  %1
4905         mov.l   %1,%0
4906         sts     %1,%0
4907         sts     %1,%0
4908         movt    %0
4909         mov.l   %1,%0
4910         sts.l   %1,%0
4911         sts.l   %1,%0
4912         lds     %1,%0
4913         lds     %1,%0
4914         lds.l   %1,%0
4915         lds.l   %1,%0
4916         lds.l   %1,%0
4917         sts.l   %1,%0
4918         fake    %1,%0
4919         lds     %1,%0
4920         sts     %1,%0
4921         fsts    fpul,%0
4922         flds    %1,fpul
4923         fmov    %1,%0
4924         ! move optimized away"
4925   [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4926    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4927    (set_attr_alternative "length"
4928      [(const_int 2)
4929       (const_int 2)
4930       (const_int 2)
4931       (const_int 4)
4932       (const_int 4)
4933       (const_int 2)
4934       (if_then_else
4935         (match_test "TARGET_SH2A")
4936         (const_int 4) (const_int 2))
4937       (const_int 2)
4938       (const_int 2)
4939       (const_int 2)
4940       (if_then_else
4941         (match_test "TARGET_SH2A")
4942         (const_int 4) (const_int 2))
4943       (const_int 2)
4944       (const_int 2)
4945       (const_int 2)
4946       (const_int 2)
4947       (const_int 2)
4948       (const_int 2)
4949       (const_int 2)
4950       (const_int 2)
4951       (const_int 2)
4952       (const_int 2)
4953       (const_int 2)
4954       (const_int 2)
4955       (const_int 2)
4956       (const_int 2)
4957       (const_int 0)])])
4958
4959 (define_insn "movsi_i_lowpart"
4960   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4961         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4962    "TARGET_SH1
4963     && (register_operand (operands[0], SImode)
4964         || register_operand (operands[1], SImode))"
4965   "@
4966         mov.l   %1,%0
4967         mov     %1,%0
4968         mov     %1,%0
4969         mov.l   %1,%0
4970         sts     %1,%0
4971         sts     %1,%0
4972         movt    %0
4973         mov.l   %1,%0
4974         fake    %1,%0"
4975   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4976
4977 (define_insn_and_split "load_ra"
4978   [(set (match_operand:SI 0 "general_movdst_operand" "")
4979         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4980   "TARGET_SH1"
4981   "#"
4982   "&& ! currently_expanding_to_rtl"
4983   [(set (match_dup 0) (match_dup 1))]
4984   "
4985 {
4986   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4987     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4988 }")
4989
4990 ;; The '?'s in the following constraints may not reflect the time taken
4991 ;; to perform the move. They are there to discourage the use of floating-
4992 ;; point registers for storing integer values.
4993 (define_insn "*movsi_media"
4994   [(set (match_operand:SI 0 "general_movdst_operand"
4995                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4996         (match_operand:SI 1 "general_movsrc_operand"
4997          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4998   "TARGET_SHMEDIA_FPU
4999    && (register_operand (operands[0], SImode)
5000        || sh_register_operand (operands[1], SImode)
5001        || GET_CODE (operands[1]) == TRUNCATE)"
5002   "@
5003         add.l   %1, r63, %0
5004         movi    %1, %0
5005         #
5006         ld%M1.l %m1, %0
5007         st%M0.l %m0, %N1
5008         fld%M1.s        %m1, %0
5009         fst%M0.s        %m0, %1
5010         fmov.ls %N1, %0
5011         fmov.sl %1, %0
5012         fmov.s  %1, %0
5013         ptabs   %1, %0
5014         gettr   %1, %0
5015         pt      %1, %0"
5016   [(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")
5017    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5018    (set (attr "highpart")
5019         (cond [(match_test "sh_contains_memref_p (insn)")
5020                (const_string "user")]
5021               (const_string "ignore")))])
5022
5023 (define_insn "*movsi_media_nofpu"
5024   [(set (match_operand:SI 0 "general_movdst_operand"
5025                 "=r,r,r,r,m,*b,r,*b")
5026         (match_operand:SI 1 "general_movsrc_operand"
5027          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5028   "TARGET_SHMEDIA
5029    && (register_operand (operands[0], SImode)
5030        || sh_register_operand (operands[1], SImode)
5031        || GET_CODE (operands[1]) == TRUNCATE)"
5032   "@
5033         add.l   %1, r63, %0
5034         movi    %1, %0
5035         #
5036         ld%M1.l %m1, %0
5037         st%M0.l %m0, %N1
5038         ptabs   %1, %0
5039         gettr   %1, %0
5040         pt      %1, %0"
5041   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5042    (set_attr "length" "4,4,8,4,4,4,4,12")
5043    (set (attr "highpart")
5044         (cond [(match_test "sh_contains_memref_p (insn)")
5045                (const_string "user")]
5046               (const_string "ignore")))])
5047
5048 (define_expand "movsi_const"
5049   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5050         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5051                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5052    (set (match_dup 0)
5053         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5054                 (const:SI (unspec:SI [(match_dup 1)
5055                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5056   "TARGET_SHMEDIA && reload_completed
5057    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5058   "
5059 {
5060   if (GET_CODE (operands[1]) == LABEL_REF
5061       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5062     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5063   else if (GOTOFF_P (operands[1]))
5064     {
5065       rtx unspec = XEXP (operands[1], 0);
5066
5067       if (! UNSPEC_GOTOFF_P (unspec))
5068         {
5069           unspec = XEXP (unspec, 0);
5070           if (! UNSPEC_GOTOFF_P (unspec))
5071             abort ();
5072         }
5073       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5074           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5075         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5076     }
5077 }")
5078
5079 (define_expand "movsi_const_16bit"
5080   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5081         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5082                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5083   "TARGET_SHMEDIA && flag_pic && reload_completed
5084    && GET_CODE (operands[1]) == SYMBOL_REF"
5085   "")
5086
5087 (define_split
5088   [(set (match_operand:SI 0 "arith_reg_dest" "")
5089         (match_operand:SI 1 "immediate_operand" ""))]
5090   "TARGET_SHMEDIA && reload_completed
5091    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5092   [(const_int 0)]
5093   "
5094 {
5095   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5096
5097   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5098
5099   DONE;
5100 }")
5101
5102 (define_split
5103   [(set (match_operand:SI 0 "register_operand" "")
5104         (match_operand:SI 1 "immediate_operand" ""))]
5105   "TARGET_SHMEDIA && reload_completed
5106    && ((CONST_INT_P (operands[1])
5107         && ! satisfies_constraint_I16 (operands[1]))
5108        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5109   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5110
5111 (define_expand "movsi"
5112   [(set (match_operand:SI 0 "general_movdst_operand" "")
5113         (match_operand:SI 1 "general_movsrc_operand" ""))]
5114   ""
5115   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5116
5117 (define_expand "ic_invalidate_line"
5118   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5119                                 (match_dup 1)] UNSPEC_ICACHE)
5120               (clobber (scratch:SI))])]
5121   "TARGET_HARD_SH4 || TARGET_SH5"
5122   "
5123 {
5124   if (TARGET_SHMEDIA)
5125     {
5126       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5127       DONE;
5128     }
5129   else if (TARGET_SHCOMPACT)
5130     {
5131       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5132       operands[1] = force_reg (Pmode, operands[1]);
5133       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5134       DONE;
5135     }
5136   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5137     {
5138       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5139       DONE;
5140     }
5141   operands[0] = force_reg (Pmode, operands[0]);
5142   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5143                                                                Pmode)));
5144 }")
5145
5146 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5147 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5148 ;; the requirement *1*00 for associative address writes.  The alignment of
5149 ;; %0 implies that its least significant bit is cleared,
5150 ;; thus we clear the V bit of a matching entry if there is one.
5151 (define_insn "ic_invalidate_line_i"
5152   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5153                      (match_operand:SI 1 "register_operand" "r")]
5154                      UNSPEC_ICACHE)
5155    (clobber (match_scratch:SI 2 "=&r"))]
5156   "TARGET_HARD_SH4"
5157   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5158   [(set_attr "length" "8")
5159    (set_attr "type" "cwb")])
5160
5161 (define_insn "ic_invalidate_line_sh4a"
5162   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5163                     UNSPEC_ICACHE)]
5164   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5165   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5166   [(set_attr "length" "16")
5167    (set_attr "type" "cwb")])
5168
5169 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5170 ;; an add in the code that calculates the address.
5171 (define_insn "ic_invalidate_line_media"
5172   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5173                     UNSPEC_ICACHE)]
5174   "TARGET_SHMEDIA"
5175   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5176   [(set_attr "length" "16")
5177    (set_attr "type" "invalidate_line_media")])
5178
5179 (define_insn "ic_invalidate_line_compact"
5180   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5181                      (match_operand:SI 1 "register_operand" "r")]
5182                     UNSPEC_ICACHE)
5183    (clobber (reg:SI PR_REG))]
5184   "TARGET_SHCOMPACT"
5185   "jsr @%1%#"
5186   [(set_attr "type" "sfunc")
5187    (set_attr "needs_delay_slot" "yes")])
5188
5189 (define_expand "initialize_trampoline"
5190   [(match_operand:SI 0 "" "")
5191    (match_operand:SI 1 "" "")
5192    (match_operand:SI 2 "" "")]
5193   "TARGET_SHCOMPACT"
5194   "
5195 {
5196   rtx sfun, tramp;
5197
5198   tramp = force_reg (Pmode, operands[0]);
5199   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5200                                             SFUNC_STATIC));
5201   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5202   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5203
5204   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5205   DONE;
5206 }")
5207
5208 (define_insn "initialize_trampoline_compact"
5209   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5210                      (match_operand:SI 1 "register_operand" "r")
5211                      (reg:SI R2_REG) (reg:SI R3_REG)]
5212                     UNSPEC_INIT_TRAMP)
5213
5214    (clobber (reg:SI PR_REG))]
5215   "TARGET_SHCOMPACT"
5216   "jsr @%1%#"
5217   [(set_attr "type" "sfunc")
5218    (set_attr "needs_delay_slot" "yes")])
5219
5220 (define_insn "movqi_i"
5221   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5222         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5223   "TARGET_SH1
5224    && (arith_reg_operand (operands[0], QImode)
5225        || arith_reg_operand (operands[1], QImode))"
5226   "@
5227         mov     %1,%0
5228         mov     %1,%0
5229         mov.b   %1,%0
5230         mov.b   %1,%0
5231         movt    %0
5232         sts     %1,%0
5233         lds     %1,%0"
5234  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5235   (set_attr_alternative "length"
5236      [(const_int 2)
5237       (const_int 2)
5238       (if_then_else
5239         (match_test "TARGET_SH2A")
5240         (const_int 4) (const_int 2))
5241       (if_then_else
5242         (match_test "TARGET_SH2A")
5243         (const_int 4) (const_int 2))
5244       (const_int 2)
5245       (const_int 2)
5246       (const_int 2)])])
5247
5248 (define_insn "*movqi_media"
5249   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5250         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5251   "TARGET_SHMEDIA
5252    && (arith_reg_operand (operands[0], QImode)
5253        || extend_reg_or_0_operand (operands[1], QImode))"
5254   "@
5255         add.l   %1, r63, %0
5256         movi    %1, %0
5257         ld%M1.ub        %m1, %0
5258         st%M0.b %m0, %N1"
5259   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5260    (set (attr "highpart")
5261         (cond [(match_test "sh_contains_memref_p (insn)")
5262                (const_string "user")]
5263               (const_string "ignore")))])
5264
5265 (define_expand "movqi"
5266   [(set (match_operand:QI 0 "general_operand" "")
5267         (match_operand:QI 1 "general_operand"  ""))]
5268   ""
5269   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5270
5271 (define_expand "reload_inqi"
5272   [(set (match_operand:SI 2 "" "=&r")
5273         (match_operand:QI 1 "inqhi_operand" ""))
5274    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5275         (truncate:QI (match_dup 3)))]
5276   "TARGET_SHMEDIA"
5277   "
5278 {
5279   rtx inner = XEXP (operands[1], 0);
5280   int regno = REGNO (inner);
5281
5282   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5283   operands[1] = gen_rtx_REG (SImode, regno);
5284   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5285 }")
5286
5287 /* When storing r0, we have to avoid reg+reg addressing.  */
5288 (define_insn "movhi_i"
5289   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5290         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5291   "TARGET_SH1
5292    && (arith_reg_operand (operands[0], HImode)
5293        || arith_reg_operand (operands[1], HImode))
5294    && (!MEM_P (operands[0])
5295        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5296        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5297        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5298   "@
5299         mov.w   %1,%0
5300         mov     %1,%0
5301         mov.w   %1,%0
5302         movt    %0
5303         mov.w   %1,%0
5304         sts     %1,%0
5305         lds     %1,%0
5306         fake    %1,%0"
5307   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5308
5309 (define_insn "*movhi_media"
5310   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5311         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5312   "TARGET_SHMEDIA
5313    && (arith_reg_operand (operands[0], HImode)
5314        || arith_reg_or_0_operand (operands[1], HImode))"
5315   "@
5316         add.l   %1, r63, %0
5317         movi    %1, %0
5318         #
5319         ld%M1.w %m1, %0
5320         st%M0.w %m0, %N1"
5321   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5322    (set (attr "highpart")
5323         (cond [(match_test "sh_contains_memref_p (insn)")
5324                (const_string "user")]
5325               (const_string "ignore")))])
5326
5327 (define_split
5328   [(set (match_operand:HI 0 "register_operand" "")
5329         (match_operand:HI 1 "immediate_operand" ""))]
5330   "TARGET_SHMEDIA && reload_completed
5331    && ! satisfies_constraint_I16 (operands[1])"
5332   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5333
5334 (define_expand "movhi"
5335   [(set (match_operand:HI 0 "general_movdst_operand" "")
5336         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5337   ""
5338   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5339
5340 (define_expand "reload_inhi"
5341   [(set (match_operand:SI 2 "" "=&r")
5342         (match_operand:HI 1 "inqhi_operand" ""))
5343    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5344         (truncate:HI (match_dup 3)))]
5345   "TARGET_SHMEDIA"
5346   "
5347 {
5348   rtx inner = XEXP (operands[1], 0);
5349   int regno = REGNO (inner);
5350
5351   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5352   operands[1] = gen_rtx_REG (SImode, regno);
5353   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5354 }")
5355
5356 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5357 ;; compiled with -m2 -ml -O3 -funroll-loops
5358 (define_insn "*movdi_i"
5359   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5360         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5361   "TARGET_SH1
5362    && (arith_reg_operand (operands[0], DImode)
5363        || arith_reg_operand (operands[1], DImode))"
5364   "* return output_movedouble (insn, operands, DImode);"
5365   [(set_attr "length" "4")
5366    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5367
5368 ;; If the output is a register and the input is memory or a register, we have
5369 ;; to be careful and see which word needs to be loaded first.
5370
5371 (define_split
5372   [(set (match_operand:DI 0 "general_movdst_operand" "")
5373         (match_operand:DI 1 "general_movsrc_operand" ""))]
5374   "TARGET_SH1 && reload_completed"
5375   [(set (match_dup 2) (match_dup 3))
5376    (set (match_dup 4) (match_dup 5))]
5377   "
5378 {
5379   int regno;
5380
5381   if ((MEM_P (operands[0])
5382        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5383       || (MEM_P (operands[1])
5384           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5385     FAIL;
5386
5387   switch (GET_CODE (operands[0]))
5388     {
5389     case REG:
5390       regno = REGNO (operands[0]);
5391       break;
5392     case SUBREG:
5393       regno = subreg_regno (operands[0]);
5394       break;
5395     case MEM:
5396       regno = -1;
5397       break;
5398     default:
5399       gcc_unreachable ();
5400     }
5401
5402   if (regno == -1
5403       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5404     {
5405       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5406       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5407       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5408       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5409     }
5410   else
5411     {
5412       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5413       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5414       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5415       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5416     }
5417
5418   if (operands[2] == 0 || operands[3] == 0
5419       || operands[4] == 0 || operands[5] == 0)
5420     FAIL;
5421 }")
5422
5423 ;; The '?'s in the following constraints may not reflect the time taken
5424 ;; to perform the move. They are there to discourage the use of floating-
5425 ;; point registers for storing integer values.
5426 (define_insn "*movdi_media"
5427   [(set (match_operand:DI 0 "general_movdst_operand"
5428                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5429         (match_operand:DI 1 "general_movsrc_operand"
5430          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5431   "TARGET_SHMEDIA_FPU
5432    && (register_operand (operands[0], DImode)
5433        || sh_register_operand (operands[1], DImode))"
5434   "@
5435         add     %1, r63, %0
5436         movi    %1, %0
5437         #
5438         ld%M1.q %m1, %0
5439         st%M0.q %m0, %N1
5440         fld%M1.d        %m1, %0
5441         fst%M0.d        %m0, %1
5442         fmov.qd %N1, %0
5443         fmov.dq %1, %0
5444         fmov.d  %1, %0
5445         ptabs   %1, %0
5446         gettr   %1, %0
5447         pt      %1, %0"
5448   [(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")
5449    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5450
5451 (define_insn "*movdi_media_nofpu"
5452   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5453         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5454   "TARGET_SHMEDIA
5455    && (register_operand (operands[0], DImode)
5456        || sh_register_operand (operands[1], DImode))"
5457   "@
5458         add     %1, r63, %0
5459         movi    %1, %0
5460         #
5461         ld%M1.q %m1, %0
5462         st%M0.q %m0, %N1
5463         ptabs   %1, %0
5464         gettr   %1, %0
5465         pt      %1, %0"
5466   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5467    (set_attr "length" "4,4,16,4,4,4,4,*")])
5468
5469 (define_insn "*movdi_media_I16"
5470   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5471         (match_operand:DI 1 "const_int_operand" "I16"))]
5472   "TARGET_SHMEDIA && reload_completed"
5473   "movi %1, %0"
5474   [(set_attr "type" "arith_media")
5475    (set_attr "length" "4")])
5476
5477 (define_split
5478   [(set (match_operand:DI 0 "arith_reg_dest" "")
5479         (match_operand:DI 1 "immediate_operand" ""))]
5480   "TARGET_SHMEDIA && reload_completed
5481    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5482   [(set (match_dup 0) (match_dup 1))]
5483   "
5484 {
5485   rtx insn;
5486
5487   if (TARGET_SHMEDIA64)
5488     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5489   else
5490     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5491
5492   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5493
5494   DONE;
5495 }")
5496
5497 (define_expand "movdi_const"
5498   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5499         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5500                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5501    (set (match_dup 0)
5502         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5503                 (const:DI (unspec:DI [(match_dup 1)
5504                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5505    (set (match_dup 0)
5506         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5507                 (const:DI (unspec:DI [(match_dup 1)
5508                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5509    (set (match_dup 0)
5510         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5511                 (const:DI (unspec:DI [(match_dup 1)
5512                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5513   "TARGET_SHMEDIA64 && reload_completed
5514    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5515   "
5516 {
5517   sh_mark_label (operands[1], 4);
5518 }")
5519
5520 (define_expand "movdi_const_32bit"
5521   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5522         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5523                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5524    (set (match_dup 0)
5525         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5526                 (const:DI (unspec:DI [(match_dup 1)
5527                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5528   "TARGET_SHMEDIA32 && reload_completed
5529    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5530   "
5531 {
5532   sh_mark_label (operands[1], 2);
5533 }")
5534
5535 (define_expand "movdi_const_16bit"
5536   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5537         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5538                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5539   "TARGET_SHMEDIA && flag_pic && reload_completed
5540    && GET_CODE (operands[1]) == SYMBOL_REF"
5541   "")
5542
5543 (define_split
5544   [(set (match_operand:DI 0 "ext_dest_operand" "")
5545         (match_operand:DI 1 "immediate_operand" ""))]
5546   "TARGET_SHMEDIA && reload_completed
5547    && CONST_INT_P (operands[1])
5548    && ! satisfies_constraint_I16 (operands[1])"
5549   [(set (match_dup 0) (match_dup 2))
5550    (match_dup 1)]
5551   "
5552 {
5553   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5554   unsigned HOST_WIDE_INT low = val;
5555   unsigned HOST_WIDE_INT high = val;
5556   unsigned HOST_WIDE_INT sign;
5557   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5558
5559   /* Zero-extend the 16 least-significant bits.  */
5560   low &= 0xffff;
5561
5562   /* Arithmetic shift right the word by 16 bits.  */
5563   high >>= 16;
5564   if (GET_CODE (operands[0]) == SUBREG
5565       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5566     {
5567       high &= 0xffff;
5568       high ^= 0x8000;
5569       high -= 0x8000;
5570     }
5571   else
5572     {
5573       sign = 1;
5574       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5575       high ^= sign;
5576       high -= sign;
5577     }
5578   do
5579     {
5580       /* If we can't generate the constant with a two-insn movi / shori
5581          sequence, try some other strategies.  */
5582       if (! CONST_OK_FOR_I16 (high))
5583         {
5584           /* Try constant load / left shift.  We know VAL != 0.  */
5585           val2 = val ^ (val-1);
5586           if (val2 > 0x1ffff)
5587             {
5588               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5589
5590               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5591                   || (! CONST_OK_FOR_I16 (high >> 16)
5592                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5593                 {
5594                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5595                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5596                                                    GEN_INT (trailing_zeroes));
5597                   break;
5598                 }
5599             }
5600           /* Try constant load / right shift.  */
5601           val2 = (val >> 15) + 1;
5602           if (val2 == (val2 & -val2))
5603             {
5604               int shift = 49 - exact_log2 (val2);
5605
5606               val2 = trunc_int_for_mode (val << shift, DImode);
5607               if (CONST_OK_FOR_I16 (val2))
5608                 {
5609                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5610                                                    GEN_INT (shift));
5611                   break;
5612                 }
5613             }
5614           /* Try mperm.w .  */
5615           val2 = val & 0xffff;
5616           if ((val >> 16 & 0xffff) == val2
5617               && (val >> 32 & 0xffff) == val2
5618               && (val >> 48 & 0xffff) == val2)
5619             {
5620               val2 = (HOST_WIDE_INT) val >> 48;
5621               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5622               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5623               break;
5624             }
5625           /* Try movi / mshflo.l  */
5626           val2 = (HOST_WIDE_INT) val >> 32;
5627           if (val2 == ((unsigned HOST_WIDE_INT)
5628                         trunc_int_for_mode (val, SImode)))
5629             {
5630               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5631                                              operands[0]);
5632               break;
5633             }
5634           /* Try movi / mshflo.l w/ r63.  */
5635           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5636           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5637             {
5638               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5639                                              const0_rtx);
5640               break;
5641             }
5642         }
5643       val2 = high;
5644       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5645     }
5646   while (0);
5647   operands[2] = GEN_INT (val2);
5648 }")
5649
5650 (define_split
5651   [(set (match_operand:DI 0 "ext_dest_operand" "")
5652         (match_operand:DI 1 "immediate_operand" ""))]
5653   "TARGET_SHMEDIA && reload_completed
5654    && GET_CODE (operands[1]) == CONST_DOUBLE"
5655   [(set (match_dup 0) (match_dup 2))
5656   (set (match_dup 0)
5657        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5658   "
5659 {
5660   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5661   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5662   unsigned HOST_WIDE_INT val = low;
5663   unsigned HOST_WIDE_INT sign;
5664
5665   /* Zero-extend the 16 least-significant bits.  */
5666   val &= 0xffff;
5667   operands[1] = GEN_INT (val);
5668
5669   /* Arithmetic shift right the double-word by 16 bits.  */
5670   low >>= 16;
5671   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5672   high >>= 16;
5673   sign = 1;
5674   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5675   high ^= sign;
5676   high -= sign;
5677
5678   /* This will only be true if high is a sign-extension of low, i.e.,
5679      it must be either 0 or (unsigned)-1, and be zero iff the
5680      most-significant bit of low is set.  */
5681   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5682     operands[2] = GEN_INT (low);
5683   else
5684     operands[2] = immed_double_const (low, high, DImode);
5685 }")
5686
5687 (define_insn "shori_media"
5688   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5689         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5690                            (const_int 16))
5691                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5692   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5693   "@
5694         shori   %u2, %0
5695         #"
5696   [(set_attr "type" "arith_media,*")])
5697
5698 (define_insn "*shori_media_si"
5699   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5700         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5701                            (const_int 16))
5702                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5703   "TARGET_SHMEDIA"
5704   "shori        %u2, %0")
5705
5706 (define_expand "movdi"
5707   [(set (match_operand:DI 0 "general_movdst_operand" "")
5708         (match_operand:DI 1 "general_movsrc_operand" ""))]
5709   ""
5710   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5711
5712 (define_insn "movdf_media"
5713   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5714         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5715   "TARGET_SHMEDIA_FPU
5716    && (register_operand (operands[0], DFmode)
5717        || sh_register_operand (operands[1], DFmode))"
5718   "@
5719         fmov.d  %1, %0
5720         fmov.qd %N1, %0
5721         fmov.dq %1, %0
5722         add     %1, r63, %0
5723         #
5724         fld%M1.d        %m1, %0
5725         fst%M0.d        %m0, %1
5726         ld%M1.q %m1, %0
5727         st%M0.q %m0, %N1"
5728   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5729
5730 (define_insn "movdf_media_nofpu"
5731   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5732         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5733   "TARGET_SHMEDIA
5734    && (register_operand (operands[0], DFmode)
5735        || sh_register_operand (operands[1], DFmode))"
5736   "@
5737         add     %1, r63, %0
5738         #
5739         ld%M1.q %m1, %0
5740         st%M0.q %m0, %N1"
5741   [(set_attr "type" "arith_media,*,load_media,store_media")])
5742
5743 (define_split
5744   [(set (match_operand:DF 0 "arith_reg_dest" "")
5745         (match_operand:DF 1 "immediate_operand" ""))]
5746   "TARGET_SHMEDIA && reload_completed"
5747   [(set (match_dup 3) (match_dup 2))]
5748   "
5749 {
5750   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5751   long values[2];
5752   REAL_VALUE_TYPE value;
5753
5754   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5755   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5756
5757   if (HOST_BITS_PER_WIDE_INT >= 64)
5758     operands[2] = immed_double_const ((unsigned long) values[endian]
5759                                       | ((HOST_WIDE_INT) values[1 - endian]
5760                                          << 32), 0, DImode);
5761   else
5762     {
5763       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5764       operands[2] = immed_double_const (values[endian], values[1 - endian],
5765                                         DImode);
5766     }
5767
5768   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5769 }")
5770
5771 ;; ??? This should be a define expand.
5772
5773 (define_insn "movdf_k"
5774   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5775         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5776   "TARGET_SH1
5777    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5778        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5779        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5780        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5781    && (arith_reg_operand (operands[0], DFmode)
5782        || arith_reg_operand (operands[1], DFmode))"
5783   "* return output_movedouble (insn, operands, DFmode);"
5784   [(set_attr "length" "4")
5785    (set_attr "type" "move,pcload,load,store")])
5786
5787 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5788 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5789 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5790 ;; the d/m/c/X alternative, which is split later into single-precision
5791 ;; instructions.  And when not optimizing, no splits are done before fixing
5792 ;; up pcloads, so we need usable length information for that.
5793 (define_insn "movdf_i4"
5794   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5795         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5796    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5797    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5798   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5799    && (arith_reg_operand (operands[0], DFmode)
5800        || arith_reg_operand (operands[1], DFmode))"
5801   {
5802     switch (which_alternative)
5803     {
5804     case 0:
5805       if (TARGET_FMOVD)
5806         return "fmov    %1,%0";
5807       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5808         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5809       else
5810         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5811     case 3:
5812     case 4:
5813       return "fmov.d    %1,%0";
5814     default:
5815       return "#";
5816     }
5817   }
5818   [(set_attr_alternative "length"
5819      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5820       (const_int 4)
5821       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5822       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5823       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5824       (const_int 4)
5825       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5826       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5827       ;; increment or decrement r15 explicitly.
5828       (if_then_else
5829        (match_test "TARGET_SHCOMPACT")
5830        (const_int 10) (const_int 8))
5831       (if_then_else
5832        (match_test "TARGET_SHCOMPACT")
5833        (const_int 10) (const_int 8))])
5834    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5835    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5836    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5837                                            (const_string "double")
5838                                            (const_string "none")))])
5839
5840 ;; Moving DFmode between fp/general registers through memory
5841 ;; (the top of the stack) is faster than moving through fpul even for
5842 ;; little endian.  Because the type of an instruction is important for its
5843 ;; scheduling,  it is beneficial to split these operations, rather than
5844 ;; emitting them in one single chunk, even if this will expose a stack
5845 ;; use that will prevent scheduling of other stack accesses beyond this
5846 ;; instruction.
5847 (define_split
5848   [(set (match_operand:DF 0 "register_operand" "")
5849         (match_operand:DF 1 "register_operand" ""))
5850    (use (match_operand:PSI 2 "fpscr_operand" ""))
5851    (clobber (match_scratch:SI 3 "=X"))]
5852   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5853    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5854   [(const_int 0)]
5855   "
5856 {
5857   rtx insn, tos;
5858
5859   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5860     {
5861       emit_move_insn (stack_pointer_rtx,
5862                       plus_constant (stack_pointer_rtx, -8));
5863       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5864     }
5865   else
5866     tos = gen_tmp_stack_mem (DFmode,
5867                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5868   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5869   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5870     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5871   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5872     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5873   else
5874     tos = gen_tmp_stack_mem (DFmode,
5875                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5876   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5877   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5878     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5879   else
5880     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5881   DONE;
5882 }")
5883
5884 ;; local-alloc sometimes allocates scratch registers even when not required,
5885 ;; so we must be prepared to handle these.
5886
5887 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5888 (define_split
5889   [(set (match_operand:DF 0 "general_movdst_operand" "")
5890         (match_operand:DF 1 "general_movsrc_operand"  ""))
5891    (use (match_operand:PSI 2 "fpscr_operand" ""))
5892    (clobber (match_scratch:SI 3 ""))]
5893   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5894    && reload_completed
5895    && true_regnum (operands[0]) < 16
5896    && true_regnum (operands[1]) < 16"
5897   [(set (match_dup 0) (match_dup 1))]
5898   "
5899 {
5900   /* If this was a reg <-> mem operation with base + index reg addressing,
5901      we have to handle this in a special way.  */
5902   rtx mem = operands[0];
5903   int store_p = 1;
5904   if (! memory_operand (mem, DFmode))
5905     {
5906       mem = operands[1];
5907       store_p = 0;
5908     }
5909   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5910     mem = SUBREG_REG (mem);
5911   if (MEM_P (mem))
5912     {
5913       rtx addr = XEXP (mem, 0);
5914       if (GET_CODE (addr) == PLUS
5915           && REG_P (XEXP (addr, 0))
5916           && REG_P (XEXP (addr, 1)))
5917         {
5918           int offset;
5919           rtx reg0 = gen_rtx_REG (Pmode, 0);
5920           rtx regop = operands[store_p], word0 ,word1;
5921
5922           if (GET_CODE (regop) == SUBREG)
5923             alter_subreg (&regop);
5924           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5925             offset = 2;
5926           else
5927             offset = 4;
5928           mem = copy_rtx (mem);
5929           PUT_MODE (mem, SImode);
5930           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5931           alter_subreg (&word0);
5932           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5933           alter_subreg (&word1);
5934           if (store_p || ! refers_to_regno_p (REGNO (word0),
5935                                               REGNO (word0) + 1, addr, 0))
5936             {
5937               emit_insn (store_p
5938                          ? gen_movsi_ie (mem, word0)
5939                          : gen_movsi_ie (word0, mem));
5940               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5941               mem = copy_rtx (mem);
5942               emit_insn (store_p
5943                          ? gen_movsi_ie (mem, word1)
5944                          : gen_movsi_ie (word1, mem));
5945               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5946             }
5947           else
5948             {
5949               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5950               emit_insn (gen_movsi_ie (word1, mem));
5951               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5952               mem = copy_rtx (mem);
5953               emit_insn (gen_movsi_ie (word0, mem));
5954             }
5955           DONE;
5956         }
5957     }
5958 }")
5959
5960 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5961 (define_split
5962   [(set (match_operand:DF 0 "register_operand" "")
5963         (match_operand:DF 1 "memory_operand"  ""))
5964    (use (match_operand:PSI 2 "fpscr_operand" ""))
5965    (clobber (reg:SI R0_REG))]
5966   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5967   [(parallel [(set (match_dup 0) (match_dup 1))
5968               (use (match_dup 2))
5969               (clobber (scratch:SI))])]
5970   "")
5971
5972 (define_expand "reload_indf__frn"
5973   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5974                    (match_operand:DF 1 "immediate_operand" "FQ"))
5975               (use (reg:PSI FPSCR_REG))
5976               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5977   "TARGET_SH1"
5978   "")
5979
5980 (define_expand "reload_outdf__RnFRm"
5981   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5982                    (match_operand:DF 1 "register_operand" "af,r"))
5983               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5984   "TARGET_SH1"
5985   "")
5986
5987 ;; Simplify no-op moves.
5988 (define_split
5989   [(set (match_operand:SF 0 "register_operand" "")
5990         (match_operand:SF 1 "register_operand" ""))
5991    (use (match_operand:PSI 2 "fpscr_operand" ""))
5992    (clobber (match_scratch:SI 3 ""))]
5993   "TARGET_SH2E && reload_completed
5994    && true_regnum (operands[0]) == true_regnum (operands[1])"
5995   [(set (match_dup 0) (match_dup 0))]
5996   "")
5997
5998 ;; fmovd substitute post-reload splits
5999 (define_split
6000   [(set (match_operand:DF 0 "register_operand" "")
6001         (match_operand:DF 1 "register_operand" ""))
6002    (use (match_operand:PSI 2 "fpscr_operand" ""))
6003    (clobber (match_scratch:SI 3 ""))]
6004   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6005    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6006    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6007   [(const_int 0)]
6008   "
6009 {
6010   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6011   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6012                            gen_rtx_REG (SFmode, src), operands[2]));
6013   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6014                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6015   DONE;
6016 }")
6017
6018 (define_split
6019   [(set (match_operand:DF 0 "register_operand" "")
6020         (mem:DF (match_operand:SI 1 "register_operand" "")))
6021    (use (match_operand:PSI 2 "fpscr_operand" ""))
6022    (clobber (match_scratch:SI 3 ""))]
6023   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6024    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6025    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6026   [(const_int 0)]
6027   "
6028 {
6029   int regno = true_regnum (operands[0]);
6030   rtx insn;
6031   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6032   rtx mem2
6033     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6034   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6035                                            regno + !! TARGET_LITTLE_ENDIAN),
6036                                   mem2, operands[2]));
6037   add_reg_note (insn, REG_INC, operands[1]);
6038   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6039                                                regno + ! TARGET_LITTLE_ENDIAN),
6040                                   change_address (mem, SFmode, NULL_RTX),
6041                                   operands[2]));
6042   DONE;
6043 }")
6044
6045 (define_split
6046   [(set (match_operand:DF 0 "register_operand" "")
6047         (match_operand:DF 1 "memory_operand" ""))
6048    (use (match_operand:PSI 2 "fpscr_operand" ""))
6049    (clobber (match_scratch:SI 3 ""))]
6050   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6051    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6052   [(const_int 0)]
6053 {
6054   int regno = true_regnum (operands[0]);
6055   rtx addr, insn;
6056   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6057   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6058   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6059
6060   operands[1] = copy_rtx (mem2);
6061   addr = XEXP (mem2, 0);
6062
6063   switch (GET_CODE (addr))
6064     {
6065     case REG:
6066       /* This is complicated.  If the register is an arithmetic register
6067          we can just fall through to the REG+DISP case below.  Otherwise
6068          we have to use a combination of POST_INC and REG addressing...  */
6069       if (! arith_reg_operand (operands[1], SFmode))
6070         {
6071           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6072           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6073           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6074           
6075           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6076
6077           /* If we have modified the stack pointer, the value that we have
6078              read with post-increment might be modified by an interrupt,
6079              so write it back.  */
6080           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6081             emit_insn (gen_push_e (reg0));
6082           else
6083             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6084           break;
6085         }
6086       /* Fall through.  */
6087          
6088     case PLUS:
6089       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6090       operands[1] = copy_rtx (operands[1]);
6091       XEXP (operands[1], 0) = plus_constant (addr, 4);
6092       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6093       break;
6094       
6095     case POST_INC:
6096       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6097       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6098     
6099       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6100       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6101       break;
6102
6103     default:
6104       debug_rtx (addr);
6105       gcc_unreachable ();
6106     }
6107
6108   DONE;
6109 })
6110
6111 (define_split
6112   [(set (match_operand:DF 0 "memory_operand" "")
6113         (match_operand:DF 1 "register_operand" ""))
6114    (use (match_operand:PSI 2 "fpscr_operand" ""))
6115    (clobber (match_scratch:SI 3 ""))]
6116   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6117    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6118   [(const_int 0)]
6119 {
6120   int regno = true_regnum (operands[1]);
6121   rtx insn, addr;
6122   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6123   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6124
6125   operands[0] = copy_rtx (operands[0]);
6126   PUT_MODE (operands[0], SFmode);
6127   addr = XEXP (operands[0], 0);
6128
6129   switch (GET_CODE (addr))
6130     {
6131     case REG:
6132       /* This is complicated.  If the register is an arithmetic register
6133          we can just fall through to the REG+DISP case below.  Otherwise
6134          we have to use a combination of REG and PRE_DEC addressing...  */
6135       if (! arith_reg_operand (operands[0], SFmode))
6136         {
6137           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6138           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6139
6140           operands[0] = copy_rtx (operands[0]);
6141           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6142           
6143           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6144           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6145           break;
6146         }
6147       /* Fall through.  */
6148       
6149     case PLUS:
6150       /* Since REG+DISP addressing has already been decided upon by gcc
6151          we can rely upon it having chosen an arithmetic register as the
6152          register component of the address.  Just emit the lower numbered
6153          register first, to the lower address, then the higher numbered
6154          register to the higher address.  */
6155       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6156
6157       operands[0] = copy_rtx (operands[0]);
6158       XEXP (operands[0], 0) = plus_constant (addr, 4);
6159
6160       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6161       break;
6162       
6163     case PRE_DEC:
6164       /* This is easy.  Output the word to go to the higher address
6165          first (ie the word in the higher numbered register) then the
6166          word to go to the lower address.  */
6167
6168       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6169       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6170
6171       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6172       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6173       break;
6174       
6175     default:
6176       /* FAIL; */
6177       debug_rtx (addr);
6178       gcc_unreachable ();
6179     }
6180
6181   DONE;
6182 })
6183
6184 ;; If the output is a register and the input is memory or a register, we have
6185 ;; to be careful and see which word needs to be loaded first.
6186
6187 (define_split
6188   [(set (match_operand:DF 0 "general_movdst_operand" "")
6189         (match_operand:DF 1 "general_movsrc_operand" ""))]
6190   "TARGET_SH1 && reload_completed"
6191   [(set (match_dup 2) (match_dup 3))
6192    (set (match_dup 4) (match_dup 5))]
6193   "
6194 {
6195   int regno;
6196
6197   if ((MEM_P (operands[0])
6198        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6199       || (MEM_P (operands[1])
6200           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6201     FAIL;
6202
6203   switch (GET_CODE (operands[0]))
6204     {
6205     case REG:
6206       regno = REGNO (operands[0]);
6207       break;
6208     case SUBREG:
6209       regno = subreg_regno (operands[0]);
6210       break;
6211     case MEM:
6212       regno = -1;
6213       break;
6214     default:
6215       gcc_unreachable ();
6216     }
6217
6218   if (regno == -1
6219       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6220     {
6221       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6222       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6223       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6224       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6225     }
6226   else
6227     {
6228       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6229       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6230       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6231       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6232     }
6233
6234   if (operands[2] == 0 || operands[3] == 0
6235       || operands[4] == 0 || operands[5] == 0)
6236     FAIL;
6237 }")
6238
6239 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6240 ;; used only once, let combine add in the index again.
6241
6242 (define_split
6243   [(set (match_operand:SI 0 "register_operand" "")
6244         (match_operand:SI 1 "" ""))
6245    (clobber (match_operand 2 "register_operand" ""))]
6246   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6247    && ALLOW_INDEXED_ADDRESS"
6248   [(use (reg:SI R0_REG))]
6249   "
6250 {
6251   rtx addr, reg, const_int;
6252
6253   if (!MEM_P (operands[1]))
6254     FAIL;
6255   addr = XEXP (operands[1], 0);
6256   if (GET_CODE (addr) != PLUS)
6257     FAIL;
6258   reg = XEXP (addr, 0);
6259   const_int = XEXP (addr, 1);
6260   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6261          && CONST_INT_P (const_int)))
6262     FAIL;
6263   emit_move_insn (operands[2], const_int);
6264   emit_move_insn (operands[0],
6265                   change_address (operands[1], VOIDmode,
6266                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6267   DONE;
6268 }")
6269
6270 (define_split
6271   [(set (match_operand:SI 1 "" "")
6272         (match_operand:SI 0 "register_operand" ""))
6273    (clobber (match_operand 2 "register_operand" ""))]
6274   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6275    && ALLOW_INDEXED_ADDRESS"
6276   [(use (reg:SI R0_REG))]
6277   "
6278 {
6279   rtx addr, reg, const_int;
6280
6281   if (!MEM_P (operands[1]))
6282     FAIL;
6283   addr = XEXP (operands[1], 0);
6284   if (GET_CODE (addr) != PLUS)
6285     FAIL;
6286   reg = XEXP (addr, 0);
6287   const_int = XEXP (addr, 1);
6288   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6289          && CONST_INT_P (const_int)))
6290     FAIL;
6291   emit_move_insn (operands[2], const_int);
6292   emit_move_insn (change_address (operands[1], VOIDmode,
6293                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6294                   operands[0]);
6295   DONE;
6296 }")
6297
6298 (define_expand "movdf"
6299   [(set (match_operand:DF 0 "general_movdst_operand" "")
6300         (match_operand:DF 1 "general_movsrc_operand" ""))]
6301   ""
6302   "
6303 {
6304   if (prepare_move_operands (operands, DFmode)) DONE;
6305   if (TARGET_SHMEDIA)
6306     {
6307       if (TARGET_SHMEDIA_FPU)
6308         emit_insn (gen_movdf_media (operands[0], operands[1]));
6309       else
6310         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6311       DONE;
6312     }
6313   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6314     {
6315       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6316       DONE;
6317     }
6318 }")
6319
6320 ;;This is incompatible with the way gcc uses subregs.
6321 ;;(define_insn "movv2sf_i"
6322 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6323 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6324 ;;  "TARGET_SHMEDIA_FPU
6325 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6326 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6327 ;;  "@
6328 ;;      #
6329 ;;      fld%M1.p        %m1, %0
6330 ;;      fst%M0.p        %m0, %1"
6331 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6332
6333 (define_insn_and_split "movv2sf_i"
6334   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6335         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6336   "TARGET_SHMEDIA_FPU"
6337   "#"
6338   "TARGET_SHMEDIA_FPU && reload_completed"
6339   [(set (match_dup 0) (match_dup 1))]
6340   "
6341 {
6342   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6343   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6344 }")
6345
6346 (define_expand "movv2sf"
6347   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6348         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6349   "TARGET_SHMEDIA_FPU"
6350   "
6351 {
6352   if (prepare_move_operands (operands, V2SFmode))
6353     DONE;
6354 }")
6355
6356 (define_expand "addv2sf3"
6357   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6358    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6359    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6360   "TARGET_SHMEDIA_FPU"
6361   "
6362 {
6363   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6364   DONE;
6365 }")
6366
6367 (define_expand "subv2sf3"
6368   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6369    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6370    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6371   "TARGET_SHMEDIA_FPU"
6372   "
6373 {
6374   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6375   DONE;
6376 }")
6377
6378 (define_expand "mulv2sf3"
6379   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6380    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6381    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6382   "TARGET_SHMEDIA_FPU"
6383   "
6384 {
6385   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6386   DONE;
6387 }")
6388
6389 (define_expand "divv2sf3"
6390   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6391    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6392    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6393   "TARGET_SHMEDIA_FPU"
6394   "
6395 {
6396   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6397   DONE;
6398 }")
6399
6400 (define_insn_and_split "*movv4sf_i"
6401   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6402         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6403   "TARGET_SHMEDIA_FPU"
6404   "#"
6405   "&& reload_completed"
6406   [(const_int 0)]
6407   "
6408 {
6409   int i;
6410
6411   for (i = 0; i < 4/2; i++)
6412     {
6413       rtx x, y;
6414
6415       if (MEM_P (operands[0]))
6416         x = adjust_address (operands[0], V2SFmode,
6417                             i * GET_MODE_SIZE (V2SFmode));
6418       else
6419         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6420
6421       if (MEM_P (operands[1]))
6422         y = adjust_address (operands[1], V2SFmode,
6423                             i * GET_MODE_SIZE (V2SFmode));
6424       else
6425         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6426
6427       emit_insn (gen_movv2sf_i (x, y));
6428     }
6429
6430   DONE;
6431 }"
6432   [(set_attr "length" "8")])
6433
6434 (define_expand "movv4sf"
6435   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6436         (match_operand:V4SF 1 "general_operand" ""))]
6437   "TARGET_SHMEDIA_FPU"
6438   "
6439 {
6440   if (prepare_move_operands (operands, V4SFmode))
6441     DONE;
6442 }")
6443
6444 (define_insn_and_split "*movv16sf_i"
6445   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6446         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6447   "TARGET_SHMEDIA_FPU"
6448   "#"
6449   "&& reload_completed"
6450   [(const_int 0)]
6451   "
6452 {
6453   int i;
6454
6455   for (i = 0; i < 16/2; i++)
6456     {
6457       rtx x,y;
6458
6459       if (MEM_P (operands[0]))
6460         x = adjust_address (operands[0], V2SFmode,
6461                             i * GET_MODE_SIZE (V2SFmode));
6462       else
6463         {
6464           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6465           alter_subreg (&x);
6466         }
6467
6468       if (MEM_P (operands[1]))
6469         y = adjust_address (operands[1], V2SFmode,
6470                             i * GET_MODE_SIZE (V2SFmode));
6471       else
6472         {
6473           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6474           alter_subreg (&y);
6475         }
6476
6477       emit_insn (gen_movv2sf_i (x, y));
6478     }
6479
6480   DONE;
6481 }"
6482   [(set_attr "length" "32")])
6483
6484 (define_expand "movv16sf"
6485   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6486         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6487   "TARGET_SHMEDIA_FPU"
6488   "
6489 {
6490   if (prepare_move_operands (operands, V16SFmode))
6491     DONE;
6492 }")
6493
6494 (define_insn "movsf_media"
6495   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6496         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6497   "TARGET_SHMEDIA_FPU
6498    && (register_operand (operands[0], SFmode)
6499        || sh_register_operand (operands[1], SFmode))"
6500   "@
6501         fmov.s  %1, %0
6502         fmov.ls %N1, %0
6503         fmov.sl %1, %0
6504         add.l   %1, r63, %0
6505         #
6506         fld%M1.s        %m1, %0
6507         fst%M0.s        %m0, %1
6508         ld%M1.l %m1, %0
6509         st%M0.l %m0, %N1"
6510   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6511    (set (attr "highpart")
6512         (cond [(match_test "sh_contains_memref_p (insn)")
6513                (const_string "user")]
6514               (const_string "ignore")))])
6515
6516 (define_insn "movsf_media_nofpu"
6517   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6518         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6519   "TARGET_SHMEDIA
6520    && (register_operand (operands[0], SFmode)
6521        || sh_register_operand (operands[1], SFmode))"
6522   "@
6523         add.l   %1, r63, %0
6524         #
6525         ld%M1.l %m1, %0
6526         st%M0.l %m0, %N1"
6527   [(set_attr "type" "arith_media,*,load_media,store_media")
6528    (set (attr "highpart")
6529         (cond [(match_test "sh_contains_memref_p (insn)")
6530                (const_string "user")]
6531               (const_string "ignore")))])
6532
6533 (define_split
6534   [(set (match_operand:SF 0 "arith_reg_dest" "")
6535         (match_operand:SF 1 "immediate_operand" ""))]
6536   "TARGET_SHMEDIA && reload_completed
6537    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6538   [(set (match_dup 3) (match_dup 2))]
6539   "
6540 {
6541   long values;
6542   REAL_VALUE_TYPE value;
6543
6544   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6545   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6546   operands[2] = GEN_INT (values);
6547
6548   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6549 }")
6550
6551 (define_insn "movsf_i"
6552   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6553         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6554   "TARGET_SH1
6555    && (! TARGET_SH2E
6556        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6557        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6558        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6559    && (arith_reg_operand (operands[0], SFmode)
6560        || arith_reg_operand (operands[1], SFmode))"
6561   "@
6562         mov     %1,%0
6563         mov     #0,%0
6564         mov.l   %1,%0
6565         mov.l   %1,%0
6566         mov.l   %1,%0
6567         lds     %1,%0
6568         sts     %1,%0"
6569   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6570
6571 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6572 ;; update_flow_info would not know where to put REG_EQUAL notes
6573 ;; when the destination changes mode.
6574 (define_insn "movsf_ie"
6575   [(set (match_operand:SF 0 "general_movdst_operand"
6576          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6577         (match_operand:SF 1 "general_movsrc_operand"
6578           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6579    (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"))
6580    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6581
6582   "TARGET_SH2E
6583    && (arith_reg_operand (operands[0], SFmode)
6584        || arith_reg_operand (operands[1], SFmode)
6585        || arith_reg_operand (operands[3], SImode)
6586        || (fpul_operand (operands[0], SFmode)
6587            && memory_operand (operands[1], SFmode)
6588            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6589        || (fpul_operand (operands[1], SFmode)
6590            && memory_operand (operands[0], SFmode)
6591            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6592   "@
6593         fmov    %1,%0
6594         mov     %1,%0
6595         fldi0   %0
6596         fldi1   %0
6597         #
6598         fmov.s  %1,%0
6599         fmov.s  %1,%0
6600         mov.l   %1,%0
6601         mov.l   %1,%0
6602         mov.l   %1,%0
6603         fsts    fpul,%0
6604         flds    %1,fpul
6605         lds.l   %1,%0
6606         #
6607         sts     %1,%0
6608         lds     %1,%0
6609         sts.l   %1,%0
6610         lds.l   %1,%0
6611         ! move optimized away"
6612   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6613    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6614    (set_attr_alternative "length"
6615      [(const_int 2)
6616       (const_int 2)
6617       (const_int 2)
6618       (const_int 2)
6619       (const_int 4)
6620       (if_then_else
6621         (match_test "TARGET_SH2A")
6622         (const_int 4) (const_int 2))
6623       (if_then_else
6624         (match_test "TARGET_SH2A")
6625         (const_int 4) (const_int 2))
6626       (const_int 2)
6627       (if_then_else
6628         (match_test "TARGET_SH2A")
6629         (const_int 4) (const_int 2))
6630       (if_then_else
6631         (match_test "TARGET_SH2A")
6632         (const_int 4) (const_int 2))
6633       (const_int 2)
6634       (const_int 2)
6635       (const_int 2)
6636       (const_int 4)
6637       (const_int 2)
6638       (const_int 2)
6639       (const_int 2)
6640       (const_int 2)
6641       (const_int 0)])
6642    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6643                                            (const_string "single")
6644                                            (const_string "single")))])
6645
6646 (define_split
6647   [(set (match_operand:SF 0 "register_operand" "")
6648         (match_operand:SF 1 "register_operand" ""))
6649    (use (match_operand:PSI 2 "fpscr_operand" ""))
6650    (clobber (reg:SI FPUL_REG))]
6651   "TARGET_SH1"
6652   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6653               (use (match_dup 2))
6654               (clobber (scratch:SI))])
6655    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6656               (use (match_dup 2))
6657               (clobber (scratch:SI))])]
6658   "")
6659
6660 (define_expand "movsf"
6661   [(set (match_operand:SF 0 "general_movdst_operand" "")
6662         (match_operand:SF 1 "general_movsrc_operand" ""))]
6663   ""
6664   "
6665 {
6666   if (prepare_move_operands (operands, SFmode))
6667     DONE;
6668   if (TARGET_SHMEDIA)
6669     {
6670       if (TARGET_SHMEDIA_FPU)
6671         emit_insn (gen_movsf_media (operands[0], operands[1]));
6672       else
6673         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6674       DONE;
6675     }
6676   if (TARGET_SH2E)
6677     {
6678       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6679       DONE;
6680     }
6681 }")
6682
6683 (define_insn "mov_nop"
6684   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6685   "TARGET_SH2E"
6686   ""
6687   [(set_attr "length" "0")
6688    (set_attr "type" "nil")])
6689
6690 (define_expand "reload_insf__frn"
6691   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6692                    (match_operand:SF 1 "immediate_operand" "FQ"))
6693               (use (reg:PSI FPSCR_REG))
6694               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6695   "TARGET_SH1"
6696   "")
6697
6698 (define_expand "reload_insi__i_fpul"
6699   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6700                    (match_operand:SI 1 "immediate_operand" "i"))
6701               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6702   "TARGET_SH1"
6703   "")
6704
6705 (define_expand "ptabs"
6706   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6707   "TARGET_SHMEDIA"
6708   "
6709 {
6710   if (!TARGET_PT_FIXED)
6711     {
6712       rtx eq = operands[1];
6713
6714       /* ??? For canonical RTL we really should remove any CONST from EQ
6715          before wrapping it in the AND, and finally wrap the EQ into a
6716          const if is constant.  However, for reload we must expose the
6717          input register or symbolic constant, and we can't have
6718          different insn structures outside of the operands for different
6719          alternatives of the same pattern.  */
6720       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6721                        GEN_INT (3));
6722       operands[1]
6723         = (gen_rtx_IF_THEN_ELSE
6724             (PDImode,
6725              eq,
6726              gen_rtx_MEM (PDImode, operands[1]),
6727              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6728                             PDImode, operands[1])));
6729     }
6730 }")
6731
6732 ;; expanded by ptabs expander.
6733 (define_insn "*extendsipdi_media"
6734   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6735         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6736                                                           "r,Csy")
6737                                       (const_int 3))
6738                               (const_int 3))
6739                           (mem:PDI (match_dup 1))
6740                           (sign_extend:PDI (match_dup 1))))]
6741   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6742   "@
6743         ptabs   %1, %0
6744         pt      %1, %0"
6745   [(set_attr "type"   "ptabs_media,pt_media")
6746    (set_attr "length" "4,*")])
6747
6748 (define_insn "*truncdipdi_media"
6749   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6750         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6751                                                           "r,Csy")
6752                                       (const_int 3))
6753                               (const_int 3))
6754                           (mem:PDI (match_dup 1))
6755                           (truncate:PDI (match_dup 1))))]
6756   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6757   "@
6758         ptabs   %1, %0
6759         pt      %1, %0"
6760   [(set_attr "type"   "ptabs_media,pt_media")
6761    (set_attr "length" "4,*")])
6762
6763 (define_insn "*movsi_y"
6764   [(set (match_operand:SI 0 "register_operand" "=y,y")
6765         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6766    (clobber (match_scratch:SI 2 "=&z,r"))]
6767   "TARGET_SH2E
6768    && (reload_in_progress || reload_completed)"
6769   "#"
6770   [(set_attr "length" "4")
6771    (set_attr "type" "pcload,move")])
6772
6773 (define_split
6774   [(set (match_operand:SI 0 "register_operand" "")
6775         (match_operand:SI 1 "immediate_operand" ""))
6776    (clobber (match_operand:SI 2 "register_operand" ""))]
6777   "TARGET_SH1"
6778   [(set (match_dup 2) (match_dup 1))
6779    (set (match_dup 0) (match_dup 2))]
6780   "")
6781
6782 (define_split
6783   [(set (match_operand:SI 0 "register_operand" "")
6784         (match_operand:SI 1 "memory_operand" ""))
6785    (clobber (reg:SI R0_REG))]
6786   "TARGET_SH1"
6787   [(set (match_dup 0) (match_dup 1))]
6788   "")
6789 \f
6790 ;; ------------------------------------------------------------------------
6791 ;; Define the real conditional branch instructions.
6792 ;; ------------------------------------------------------------------------
6793
6794 (define_insn "branch_true"
6795   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6796                            (label_ref (match_operand 0 "" ""))
6797                            (pc)))]
6798   "TARGET_SH1"
6799   "* return output_branch (1, insn, operands);"
6800   [(set_attr "type" "cbranch")])
6801
6802 (define_insn "branch_false"
6803   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6804                            (label_ref (match_operand 0 "" ""))
6805                            (pc)))]
6806   "TARGET_SH1"
6807   "* return output_branch (0, insn, operands);"
6808   [(set_attr "type" "cbranch")])
6809
6810 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6811 ;; which destination is too far away.
6812 ;; The const_int_operand is distinct for each branch target; it avoids
6813 ;; unwanted matches with redundant_insn.
6814 (define_insn "block_branch_redirect"
6815   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6816   "TARGET_SH1"
6817   ""
6818   [(set_attr "length" "0")])
6819
6820 ;; This one has the additional purpose to record a possible scratch register
6821 ;; for the following branch.
6822 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6823 ;; because the insn then might be deemed dead and deleted.  And we can't
6824 ;; make the use in the jump insn explicit because that would disable
6825 ;; delay slot scheduling from the target.
6826 (define_insn "indirect_jump_scratch"
6827   [(set (match_operand:SI 0 "register_operand" "=r")
6828         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6829    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6830   "TARGET_SH1"
6831   ""
6832   [(set_attr "length" "0")])
6833
6834 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6835 ;; being pulled into the delay slot of a condbranch that has been made to
6836 ;; jump around the unconditional jump because it was out of range.
6837 (define_insn "stuff_delay_slot"
6838   [(set (pc)
6839         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6840                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6841   "TARGET_SH1"
6842   ""
6843   [(set_attr "length" "0")
6844    (set_attr "cond_delay_slot" "yes")])
6845 \f
6846 ;; Conditional branch insns
6847
6848 (define_expand "cbranchint4_media"
6849   [(set (pc)
6850         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6851                        [(match_operand 1 "" "")
6852                         (match_operand 2 "" "")])
6853                       (match_operand 3 "" "")
6854                       (pc)))]
6855   "TARGET_SHMEDIA"
6856   "
6857 {
6858   enum machine_mode mode = GET_MODE (operands[1]);
6859   if (mode == VOIDmode)
6860     mode = GET_MODE (operands[2]);
6861   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6862     {
6863       operands[1] = force_reg (mode, operands[1]);
6864       if (CONSTANT_P (operands[2])
6865           && (! satisfies_constraint_I06 (operands[2])))
6866         operands[2] = force_reg (mode, operands[2]);
6867     }
6868   else
6869     {
6870       if (operands[1] != const0_rtx)
6871         operands[1] = force_reg (mode, operands[1]);
6872       if (operands[2] != const0_rtx)
6873         operands[2] = force_reg (mode, operands[2]);
6874     }
6875   switch (GET_CODE (operands[0]))
6876     {
6877     case LEU:
6878     case LE:
6879     case LTU:
6880     case LT:
6881       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6882                                     VOIDmode, operands[2], operands[1]);
6883       operands[1] = XEXP (operands[0], 0);
6884       operands[2] = XEXP (operands[0], 1);
6885       break;
6886     default:
6887       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6888                                     VOIDmode, operands[1], operands[2]);
6889       break;
6890     }
6891   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6892 }")
6893
6894 (define_expand "cbranchfp4_media"
6895   [(set (pc)
6896         (if_then_else (match_operator 0 "sh_float_comparison_operator"
6897                        [(match_operand 1 "" "")
6898                         (match_operand 2 "" "")])
6899                       (match_operand 3 "" "")
6900                       (pc)))]
6901   "TARGET_SHMEDIA"
6902   "
6903 {
6904   rtx tmp = gen_reg_rtx (SImode);
6905   rtx cmp;
6906   if (GET_CODE (operands[0]) == NE)
6907     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6908   else
6909     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6910                           operands[1], operands[2]);
6911
6912   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6913
6914   if (GET_CODE (cmp) == GET_CODE (operands[0]))
6915     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6916   else
6917     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6918   operands[1] = tmp;
6919   operands[2] = const0_rtx;
6920   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6921 }")
6922
6923 (define_insn "*beq_media_i"
6924   [(set (pc)
6925         (if_then_else (match_operator 3 "equality_comparison_operator"
6926                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6927                          (match_operand:DI 2 "arith_operand" "r,I06")])
6928                       (match_operand 0 "target_operand" "b,b")
6929                       (pc)))]
6930   "TARGET_SHMEDIA"
6931   "@
6932         b%o3%'  %1, %2, %0%>
6933         b%o3i%' %1, %2, %0%>"
6934   [(set_attr "type" "cbranch_media")])
6935
6936 (define_insn "*beq_media_i32"
6937   [(set (pc)
6938         (if_then_else (match_operator 3 "equality_comparison_operator"
6939                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6940                          (match_operand:SI 2 "arith_operand" "r,I06")])
6941                       (match_operand 0 "target_operand" "b,b")
6942                       (pc)))]
6943   "TARGET_SHMEDIA"
6944   "@
6945         b%o3%'  %1, %2, %0%>
6946         b%o3i%' %1, %2, %0%>"
6947   [(set_attr "type" "cbranch_media")])
6948
6949 (define_insn "*bgt_media_i"
6950   [(set (pc)
6951         (if_then_else (match_operator 3 "greater_comparison_operator"
6952                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6953                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6954                       (match_operand 0 "target_operand" "b")
6955                       (pc)))]
6956   "TARGET_SHMEDIA"
6957   "b%o3%'       %N1, %N2, %0%>"
6958   [(set_attr "type" "cbranch_media")])
6959
6960 (define_insn "*bgt_media_i32"
6961   [(set (pc)
6962         (if_then_else (match_operator 3 "greater_comparison_operator"
6963                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6964                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6965                       (match_operand 0 "target_operand" "b")
6966                       (pc)))]
6967   "TARGET_SHMEDIA"
6968   "b%o3%'       %N1, %N2, %0%>"
6969   [(set_attr "type" "cbranch_media")])
6970
6971 ;; These are only needed to make invert_jump() happy - otherwise, jump
6972 ;; optimization will be silently disabled.
6973 (define_insn "*blt_media_i"
6974   [(set (pc)
6975         (if_then_else (match_operator 3 "less_comparison_operator"
6976                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6977                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6978                       (match_operand 0 "target_operand" "b")
6979                       (pc)))]
6980   "TARGET_SHMEDIA"
6981   "b%o3%'       %N2, %N1, %0%>"
6982   [(set_attr "type" "cbranch_media")])
6983
6984 (define_insn "*blt_media_i32"
6985   [(set (pc)
6986         (if_then_else (match_operator 3 "less_comparison_operator"
6987                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6988                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6989                       (match_operand 0 "target_operand" "b")
6990                       (pc)))]
6991   "TARGET_SHMEDIA"
6992   "b%o3%'       %N2, %N1, %0%>"
6993   [(set_attr "type" "cbranch_media")])
6994
6995 ;; combiner splitter for test-and-branch on single bit in register.  This
6996 ;; is endian dependent because the non-paradoxical subreg looks different
6997 ;; on big endian.
6998 (define_split
6999   [(set (pc)
7000         (if_then_else
7001           (match_operator 3 "equality_comparison_operator"
7002             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7003                                                       "extend_reg_operand" "")
7004                                                     0)
7005                                          (const_int 1)
7006                                          (match_operand 2
7007                                           "const_int_operand" "")) 0)
7008              (const_int 0)])
7009           (match_operand 0 "target_operand" "")
7010           (pc)))
7011    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7012   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7013   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7014    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7015
7016   "
7017 {
7018   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7019   operands[6] = (GET_CODE (operands[3]) == EQ
7020                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7021                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7022 }")
7023
7024 ; operand 0 is the loop count pseudo register
7025 ; operand 1 is the number of loop iterations or 0 if it is unknown
7026 ; operand 2 is the maximum number of loop iterations
7027 ; operand 3 is the number of levels of enclosed loops
7028 ; operand 4 is the label to jump to at the top of the loop
7029
7030 (define_expand "doloop_end"
7031   [(parallel [(set (pc) (if_then_else
7032                           (ne:SI (match_operand:SI 0 "" "")
7033                               (const_int 1))
7034                           (label_ref (match_operand 4 "" ""))
7035                           (pc)))
7036               (set (match_dup 0)
7037                    (plus:SI (match_dup 0) (const_int -1)))
7038               (clobber (reg:SI T_REG))])]
7039   "TARGET_SH2"
7040   "
7041 {
7042   if (GET_MODE (operands[0]) != SImode)
7043     FAIL;
7044 }
7045 ")
7046
7047 (define_insn_and_split "doloop_end_split"
7048   [(set (pc)
7049         (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7050                           (const_int 1))
7051                       (label_ref (match_operand 1 "" ""))
7052                       (pc)))
7053    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7054         (plus (match_dup 2) (const_int -1)))
7055    (clobber (reg:SI T_REG))]
7056   "TARGET_SH2"
7057   "#"
7058   ""
7059   [(parallel [(set (reg:SI T_REG)
7060                    (eq:SI (match_dup 2) (const_int 1)))
7061               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7062    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7063                            (label_ref (match_dup 1))
7064                            (pc)))]
7065 ""
7066    [(set_attr "type" "cbranch")])
7067
7068 \f
7069 ;; ------------------------------------------------------------------------
7070 ;; Jump and linkage insns
7071 ;; ------------------------------------------------------------------------
7072
7073 (define_insn "jump_compact"
7074   [(set (pc)
7075         (label_ref (match_operand 0 "" "")))]
7076   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7077   "*
7078 {
7079   /* The length is 16 if the delay slot is unfilled.  */
7080   if (get_attr_length(insn) > 4)
7081     return output_far_jump(insn, operands[0]);
7082   else
7083     return   \"bra      %l0%#\";
7084 }"
7085   [(set_attr "type" "jump")
7086    (set_attr "needs_delay_slot" "yes")])
7087
7088 ;; ??? It would be much saner to explicitly use the scratch register
7089 ;; in the jump insn, and have indirect_jump_scratch only set it,
7090 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7091 ;; from the target then, as it uses simplejump_p.
7092 ;;(define_insn "jump_compact_far"
7093 ;;  [(set (pc)
7094 ;;      (label_ref (match_operand 0 "" "")))
7095 ;;   (use (match_operand 1 "register_operand" "r")]
7096 ;;  "TARGET_SH1"
7097 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7098 ;;  [(set_attr "type" "jump")
7099 ;;   (set_attr "needs_delay_slot" "yes")])
7100
7101 (define_insn "jump_media"
7102   [(set (pc)
7103         (match_operand 0 "target_operand" "b"))]
7104   "TARGET_SHMEDIA"
7105   "blink        %0, r63%>"
7106   [(set_attr "type" "jump_media")])
7107
7108 (define_expand "jump"
7109   [(set (pc)
7110         (label_ref (match_operand 0 "" "")))]
7111   ""
7112   "
7113 {
7114   if (TARGET_SH1)
7115     emit_jump_insn (gen_jump_compact (operands[0]));
7116   else if (TARGET_SHMEDIA)
7117     {
7118       if (reload_in_progress || reload_completed)
7119         FAIL;
7120       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7121                                                          operands[0])));
7122     }
7123   DONE;
7124 }")
7125
7126 (define_insn "force_mode_for_call"
7127   [(use (reg:PSI FPSCR_REG))]
7128   "TARGET_SHCOMPACT"
7129   ""
7130   [(set_attr "length" "0")
7131    (set (attr "fp_mode")
7132         (if_then_else (eq_attr "fpu_single" "yes")
7133                       (const_string "single") (const_string "double")))])
7134
7135 (define_insn "calli"
7136   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7137          (match_operand 1 "" ""))
7138    (use (reg:PSI FPSCR_REG))
7139    (clobber (reg:SI PR_REG))]
7140   "TARGET_SH1"
7141   "*
7142    {
7143      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7144         return \"jsr/n\\t@%0\";
7145      else
7146         return \"jsr\\t@%0%#\";
7147    }"
7148
7149   [(set_attr "type" "call")
7150    (set (attr "fp_mode")
7151         (if_then_else (eq_attr "fpu_single" "yes")
7152                       (const_string "single") (const_string "double")))
7153    (set_attr "needs_delay_slot" "yes")
7154    (set_attr "fp_set" "unknown")])
7155
7156 ;; This is TBR relative jump instruction for SH2A architecture.
7157 ;; Its use is enabled assigning an attribute "function_vector"
7158 ;; and the vector number to a function during its declaration.
7159
7160 (define_insn "calli_tbr_rel"
7161   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7162          (match_operand 1 "" ""))
7163    (use (reg:PSI FPSCR_REG))
7164    (clobber (reg:SI PR_REG))]
7165   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7166   "*
7167 {
7168   unsigned HOST_WIDE_INT vect_num;
7169   vect_num = sh2a_get_function_vector_number (operands[0]);
7170   operands[2] = GEN_INT (vect_num * 4);
7171
7172   return \"jsr/n\\t@@(%O2,tbr)\";
7173 }"
7174   [(set_attr "type" "call")
7175    (set (attr "fp_mode")
7176         (if_then_else (eq_attr "fpu_single" "yes")
7177                       (const_string "single") (const_string "double")))
7178    (set_attr "needs_delay_slot" "no")
7179    (set_attr "fp_set" "unknown")])
7180
7181 ;; This is a pc-rel call, using bsrf, for use with PIC.
7182
7183 (define_insn "calli_pcrel"
7184   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7185          (match_operand 1 "" ""))
7186    (use (reg:PSI FPSCR_REG))
7187    (use (reg:SI PIC_REG))
7188    (use (match_operand 2 "" ""))
7189    (clobber (reg:SI PR_REG))]
7190   "TARGET_SH2"
7191   "bsrf %0\\n%O2:%#"
7192   [(set_attr "type" "call")
7193    (set (attr "fp_mode")
7194         (if_then_else (eq_attr "fpu_single" "yes")
7195                       (const_string "single") (const_string "double")))
7196    (set_attr "needs_delay_slot" "yes")
7197    (set_attr "fp_set" "unknown")])
7198
7199 (define_insn_and_split "call_pcrel"
7200   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7201          (match_operand 1 "" ""))
7202    (use (reg:PSI FPSCR_REG))
7203    (use (reg:SI PIC_REG))
7204    (clobber (reg:SI PR_REG))
7205    (clobber (match_scratch:SI 2 "=r"))]
7206   "TARGET_SH2"
7207   "#"
7208   "reload_completed"
7209   [(const_int 0)]
7210   "
7211 {
7212   rtx lab = PATTERN (gen_call_site ());
7213
7214   if (SYMBOL_REF_LOCAL_P (operands[0]))
7215     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7216   else
7217     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7218   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7219   DONE;
7220 }"
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 "call_compact"
7229   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7230          (match_operand 1 "" ""))
7231    (match_operand 2 "immediate_operand" "n")
7232    (use (reg:SI R0_REG))
7233    (use (reg:SI R1_REG))
7234    (use (reg:PSI FPSCR_REG))
7235    (clobber (reg:SI PR_REG))]
7236   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7237   "jsr  @%0%#"
7238   [(set_attr "type" "call")
7239    (set (attr "fp_mode")
7240         (if_then_else (eq_attr "fpu_single" "yes")
7241                       (const_string "single") (const_string "double")))
7242    (set_attr "needs_delay_slot" "yes")])
7243
7244 (define_insn "call_compact_rettramp"
7245   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7246          (match_operand 1 "" ""))
7247    (match_operand 2 "immediate_operand" "n")
7248    (use (reg:SI R0_REG))
7249    (use (reg:SI R1_REG))
7250    (use (reg:PSI FPSCR_REG))
7251    (clobber (reg:SI R10_REG))
7252    (clobber (reg:SI PR_REG))]
7253   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7254   "jsr  @%0%#"
7255   [(set_attr "type" "call")
7256    (set (attr "fp_mode")
7257         (if_then_else (eq_attr "fpu_single" "yes")
7258                       (const_string "single") (const_string "double")))
7259    (set_attr "needs_delay_slot" "yes")])
7260
7261 (define_insn "call_media"
7262   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7263          (match_operand 1 "" ""))
7264    (clobber (reg:DI PR_MEDIA_REG))]
7265   "TARGET_SHMEDIA"
7266   "blink        %0, r18"
7267   [(set_attr "type" "jump_media")])
7268
7269 (define_insn "call_valuei"
7270   [(set (match_operand 0 "" "=rf")
7271         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7272               (match_operand 2 "" "")))
7273    (use (reg:PSI FPSCR_REG))
7274    (clobber (reg:SI PR_REG))]
7275   "TARGET_SH1"
7276   "*
7277    {
7278      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7279         return \"jsr/n\\t@%1\";
7280      else
7281         return \"jsr\\t@%1%#\";
7282    }"
7283   [(set_attr "type" "call")
7284    (set (attr "fp_mode")
7285         (if_then_else (eq_attr "fpu_single" "yes")
7286                       (const_string "single") (const_string "double")))
7287    (set_attr "needs_delay_slot" "yes")
7288    (set_attr "fp_set" "unknown")])
7289
7290 ;; This is TBR relative jump instruction for SH2A architecture.
7291 ;; Its use is enabled assigning an attribute "function_vector"
7292 ;; and the vector number to a function during its declaration.
7293
7294 (define_insn "call_valuei_tbr_rel"
7295   [(set (match_operand 0 "" "=rf")
7296         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7297               (match_operand 2 "" "")))
7298    (use (reg:PSI FPSCR_REG))
7299    (clobber (reg:SI PR_REG))]
7300   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7301   "*
7302 {
7303   unsigned HOST_WIDE_INT vect_num;
7304   vect_num = sh2a_get_function_vector_number (operands[1]);
7305   operands[3] = GEN_INT (vect_num * 4);
7306
7307   return \"jsr/n\\t@@(%O3,tbr)\";
7308 }"
7309   [(set_attr "type" "call")
7310    (set (attr "fp_mode")
7311         (if_then_else (eq_attr "fpu_single" "yes")
7312                       (const_string "single") (const_string "double")))
7313    (set_attr "needs_delay_slot" "no")
7314    (set_attr "fp_set" "unknown")])
7315
7316 (define_insn "call_valuei_pcrel"
7317   [(set (match_operand 0 "" "=rf")
7318         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7319               (match_operand 2 "" "")))
7320    (use (reg:PSI FPSCR_REG))
7321    (use (reg:SI PIC_REG))
7322    (use (match_operand 3 "" ""))
7323    (clobber (reg:SI PR_REG))]
7324   "TARGET_SH2"
7325   "bsrf %1\\n%O3:%#"
7326   [(set_attr "type" "call")
7327    (set (attr "fp_mode")
7328         (if_then_else (eq_attr "fpu_single" "yes")
7329                       (const_string "single") (const_string "double")))
7330    (set_attr "needs_delay_slot" "yes")
7331    (set_attr "fp_set" "unknown")])
7332
7333 (define_insn_and_split "call_value_pcrel"
7334   [(set (match_operand 0 "" "=rf")
7335         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7336               (match_operand 2 "" "")))
7337    (use (reg:PSI FPSCR_REG))
7338    (use (reg:SI PIC_REG))
7339    (clobber (reg:SI PR_REG))
7340    (clobber (match_scratch:SI 3 "=r"))]
7341   "TARGET_SH2"
7342   "#"
7343   "reload_completed"
7344   [(const_int 0)]
7345   "
7346 {
7347   rtx lab = PATTERN (gen_call_site ());
7348
7349   if (SYMBOL_REF_LOCAL_P (operands[1]))
7350     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7351   else
7352     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7353   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7354                                          operands[2], copy_rtx (lab)));
7355   DONE;
7356 }"
7357   [(set_attr "type" "call")
7358    (set (attr "fp_mode")
7359         (if_then_else (eq_attr "fpu_single" "yes")
7360                       (const_string "single") (const_string "double")))
7361    (set_attr "needs_delay_slot" "yes")
7362    (set_attr "fp_set" "unknown")])
7363
7364 (define_insn "call_value_compact"
7365   [(set (match_operand 0 "" "=rf")
7366         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7367               (match_operand 2 "" "")))
7368    (match_operand 3 "immediate_operand" "n")
7369    (use (reg:SI R0_REG))
7370    (use (reg:SI R1_REG))
7371    (use (reg:PSI FPSCR_REG))
7372    (clobber (reg:SI PR_REG))]
7373   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7374   "jsr  @%1%#"
7375   [(set_attr "type" "call")
7376    (set (attr "fp_mode")
7377         (if_then_else (eq_attr "fpu_single" "yes")
7378                       (const_string "single") (const_string "double")))
7379    (set_attr "needs_delay_slot" "yes")])
7380
7381 (define_insn "call_value_compact_rettramp"
7382   [(set (match_operand 0 "" "=rf")
7383         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7384               (match_operand 2 "" "")))
7385    (match_operand 3 "immediate_operand" "n")
7386    (use (reg:SI R0_REG))
7387    (use (reg:SI R1_REG))
7388    (use (reg:PSI FPSCR_REG))
7389    (clobber (reg:SI R10_REG))
7390    (clobber (reg:SI PR_REG))]
7391   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7392   "jsr  @%1%#"
7393   [(set_attr "type" "call")
7394    (set (attr "fp_mode")
7395         (if_then_else (eq_attr "fpu_single" "yes")
7396                       (const_string "single") (const_string "double")))
7397    (set_attr "needs_delay_slot" "yes")])
7398
7399 (define_insn "call_value_media"
7400   [(set (match_operand 0 "" "=rf")
7401         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7402               (match_operand 2 "" "")))
7403    (clobber (reg:DI PR_MEDIA_REG))]
7404   "TARGET_SHMEDIA"
7405   "blink        %1, r18"
7406   [(set_attr "type" "jump_media")])
7407
7408 (define_expand "call"
7409   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7410                             (match_operand 1 "" ""))
7411               (match_operand 2 "" "")
7412               (use (reg:PSI FPSCR_REG))
7413               (clobber (reg:SI PR_REG))])]
7414   ""
7415   "
7416 {
7417   if (TARGET_SHMEDIA)
7418     {
7419       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7420       emit_call_insn (gen_call_media (operands[0], operands[1]));
7421       DONE;
7422     }
7423   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7424     {
7425       rtx cookie_rtx = operands[2];
7426       long cookie = INTVAL (cookie_rtx);
7427       rtx func = XEXP (operands[0], 0);
7428       rtx r0, r1;
7429
7430       if (flag_pic)
7431         {
7432           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7433             {
7434               rtx reg = gen_reg_rtx (Pmode);
7435
7436               emit_insn (gen_symGOTPLT2reg (reg, func));
7437               func = reg;
7438             }
7439           else
7440             func = legitimize_pic_address (func, Pmode, 0);
7441         }
7442
7443       r0 = gen_rtx_REG (SImode, R0_REG);
7444       r1 = gen_rtx_REG (SImode, R1_REG);
7445
7446       /* Since such a call function may use all call-clobbered
7447          registers, we force a mode switch earlier, so that we don't
7448          run out of registers when adjusting fpscr for the call.  */
7449       emit_insn (gen_force_mode_for_call ());
7450
7451       operands[0]
7452         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7453                            SFUNC_GOT);
7454       operands[0] = force_reg (SImode, operands[0]);
7455
7456       emit_move_insn (r0, func);
7457       emit_move_insn (r1, cookie_rtx);
7458
7459       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7460         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7461                                                    operands[2]));
7462       else
7463         emit_call_insn (gen_call_compact (operands[0], operands[1],
7464                                           operands[2]));
7465
7466       DONE;
7467     }
7468   else if (TARGET_SHCOMPACT && flag_pic
7469            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7470            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7471     {
7472       rtx reg = gen_reg_rtx (Pmode);
7473
7474       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7475       XEXP (operands[0], 0) = reg;
7476     }
7477   if (!flag_pic && TARGET_SH2A
7478       && MEM_P (operands[0])
7479       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7480     {
7481       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7482         {
7483           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7484                                              operands[1]));
7485           DONE;
7486         }
7487     }
7488   if (flag_pic && TARGET_SH2
7489       && MEM_P (operands[0])
7490       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7491     {
7492       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7493       DONE;
7494     }
7495   else
7496   {
7497     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7498     operands[1] = operands[2];
7499   }
7500
7501   emit_call_insn (gen_calli (operands[0], operands[1]));
7502   DONE;
7503 }")
7504
7505 (define_insn "call_pop_compact"
7506   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7507          (match_operand 1 "" ""))
7508    (match_operand 2 "immediate_operand" "n")
7509    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7510                                  (match_operand 3 "immediate_operand" "n")))
7511    (use (reg:SI R0_REG))
7512    (use (reg:SI R1_REG))
7513    (use (reg:PSI FPSCR_REG))
7514    (clobber (reg:SI PR_REG))]
7515   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7516   "jsr  @%0%#"
7517   [(set_attr "type" "call")
7518    (set (attr "fp_mode")
7519         (if_then_else (eq_attr "fpu_single" "yes")
7520                       (const_string "single") (const_string "double")))
7521    (set_attr "needs_delay_slot" "yes")])
7522
7523 (define_insn "call_pop_compact_rettramp"
7524   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7525          (match_operand 1 "" ""))
7526    (match_operand 2 "immediate_operand" "n")
7527    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7528                                  (match_operand 3 "immediate_operand" "n")))
7529    (use (reg:SI R0_REG))
7530    (use (reg:SI R1_REG))
7531    (use (reg:PSI FPSCR_REG))
7532    (clobber (reg:SI R10_REG))
7533    (clobber (reg:SI PR_REG))]
7534   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7535   "jsr  @%0%#"
7536   [(set_attr "type" "call")
7537    (set (attr "fp_mode")
7538         (if_then_else (eq_attr "fpu_single" "yes")
7539                       (const_string "single") (const_string "double")))
7540    (set_attr "needs_delay_slot" "yes")])
7541
7542 (define_expand "call_pop"
7543   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7544                     (match_operand 1 "" ""))
7545              (match_operand 2 "" "")
7546              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7547                                            (match_operand 3 "" "")))])]
7548   "TARGET_SHCOMPACT"
7549   "
7550 {
7551   rtx cookie_rtx;
7552   long cookie;
7553   rtx func;
7554   rtx r0, r1;
7555
7556   gcc_assert (operands[2] && INTVAL (operands[2]));
7557   cookie_rtx = operands[2];
7558   cookie = INTVAL (cookie_rtx);
7559   func = XEXP (operands[0], 0);
7560
7561   if (flag_pic)
7562     {
7563       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7564         {
7565           rtx reg = gen_reg_rtx (Pmode);
7566           emit_insn (gen_symGOTPLT2reg (reg, func));
7567           func = reg;
7568         }
7569       else
7570         func = legitimize_pic_address (func, Pmode, 0);
7571     }
7572
7573   r0 = gen_rtx_REG (SImode, R0_REG);
7574   r1 = gen_rtx_REG (SImode, R1_REG);
7575
7576   /* Since such a call function may use all call-clobbered
7577      registers, we force a mode switch earlier, so that we don't
7578      run out of registers when adjusting fpscr for the call.  */
7579   emit_insn (gen_force_mode_for_call ());
7580
7581   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7582                                  SFUNC_GOT);
7583   operands[0] = force_reg (SImode, operands[0]);
7584
7585   emit_move_insn (r0, func);
7586   emit_move_insn (r1, cookie_rtx);
7587
7588   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7589     emit_call_insn (gen_call_pop_compact_rettramp
7590                      (operands[0], operands[1], operands[2], operands[3]));
7591   else
7592     emit_call_insn (gen_call_pop_compact
7593                      (operands[0], operands[1], operands[2], operands[3]));
7594
7595   DONE;
7596 }")
7597
7598 (define_expand "call_value"
7599   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7600                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7601                                  (match_operand 2 "" "")))
7602               (match_operand 3 "" "")
7603               (use (reg:PSI FPSCR_REG))
7604               (clobber (reg:SI PR_REG))])]
7605   ""
7606   "
7607 {
7608   if (TARGET_SHMEDIA)
7609     {
7610       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7611       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7612                                             operands[2]));
7613       DONE;
7614     }
7615   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7616     {
7617       rtx cookie_rtx = operands[3];
7618       long cookie = INTVAL (cookie_rtx);
7619       rtx func = XEXP (operands[1], 0);
7620       rtx r0, r1;
7621
7622       if (flag_pic)
7623         {
7624           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7625             {
7626               rtx reg = gen_reg_rtx (Pmode);
7627
7628               emit_insn (gen_symGOTPLT2reg (reg, func));
7629               func = reg;
7630             }
7631           else
7632             func = legitimize_pic_address (func, Pmode, 0);
7633         }
7634
7635       r0 = gen_rtx_REG (SImode, R0_REG);
7636       r1 = gen_rtx_REG (SImode, R1_REG);
7637
7638       /* Since such a call function may use all call-clobbered
7639          registers, we force a mode switch earlier, so that we don't
7640          run out of registers when adjusting fpscr for the call.  */
7641       emit_insn (gen_force_mode_for_call ());
7642
7643       operands[1]
7644         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7645                            SFUNC_GOT);
7646       operands[1] = force_reg (SImode, operands[1]);
7647
7648       emit_move_insn (r0, func);
7649       emit_move_insn (r1, cookie_rtx);
7650
7651       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7652         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7653                                                          operands[1],
7654                                                          operands[2],
7655                                                          operands[3]));
7656       else
7657         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7658                                                 operands[2], operands[3]));
7659
7660       DONE;
7661     }
7662   else if (TARGET_SHCOMPACT && flag_pic
7663            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7664            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7665     {
7666       rtx reg = gen_reg_rtx (Pmode);
7667
7668       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7669       XEXP (operands[1], 0) = reg;
7670     }
7671   if (!flag_pic && TARGET_SH2A
7672       && MEM_P (operands[1])
7673       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7674     {
7675       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7676         {
7677           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7678                                  XEXP (operands[1], 0), operands[2]));
7679           DONE;
7680         }
7681     }
7682   if (flag_pic && TARGET_SH2
7683       && MEM_P (operands[1])
7684       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7685     {
7686       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7687                                             operands[2]));
7688       DONE;
7689     }
7690   else
7691     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7692
7693   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7694   DONE;
7695 }")
7696
7697 (define_insn "sibcalli"
7698   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7699          (match_operand 1 "" ""))
7700    (use (reg:PSI FPSCR_REG))
7701    (return)]
7702   "TARGET_SH1"
7703   "jmp  @%0%#"
7704   [(set_attr "needs_delay_slot" "yes")
7705    (set (attr "fp_mode")
7706         (if_then_else (eq_attr "fpu_single" "yes")
7707                       (const_string "single") (const_string "double")))
7708    (set_attr "type" "jump_ind")])
7709
7710 (define_insn "sibcalli_pcrel"
7711   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7712          (match_operand 1 "" ""))
7713    (use (match_operand 2 "" ""))
7714    (use (reg:PSI FPSCR_REG))
7715    (return)]
7716   "TARGET_SH2"
7717   "braf %0\\n%O2:%#"
7718   [(set_attr "needs_delay_slot" "yes")
7719    (set (attr "fp_mode")
7720         (if_then_else (eq_attr "fpu_single" "yes")
7721                       (const_string "single") (const_string "double")))
7722    (set_attr "type" "jump_ind")])
7723
7724 ;; This uses an unspec to describe that the symbol_ref is very close.
7725 (define_insn "sibcalli_thunk"
7726   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7727                              UNSPEC_THUNK))
7728          (match_operand 1 "" ""))
7729    (use (reg:PSI FPSCR_REG))
7730    (return)]
7731   "TARGET_SH1"
7732   "bra  %O0"
7733   [(set_attr "needs_delay_slot" "yes")
7734    (set (attr "fp_mode")
7735         (if_then_else (eq_attr "fpu_single" "yes")
7736                       (const_string "single") (const_string "double")))
7737    (set_attr "type" "jump")
7738    (set_attr "length" "2")])
7739
7740 (define_insn_and_split "sibcall_pcrel"
7741   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7742          (match_operand 1 "" ""))
7743    (use (reg:PSI FPSCR_REG))
7744    (clobber (match_scratch:SI 2 "=k"))
7745    (return)]
7746   "TARGET_SH2"
7747   "#"
7748   "reload_completed"
7749   [(const_int 0)]
7750   "
7751 {
7752   rtx lab = PATTERN (gen_call_site ());
7753   rtx call_insn;
7754
7755   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7756   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7757                                                   copy_rtx (lab)));
7758   SIBLING_CALL_P (call_insn) = 1;
7759   DONE;
7760 }"
7761   [(set_attr "needs_delay_slot" "yes")
7762    (set (attr "fp_mode")
7763         (if_then_else (eq_attr "fpu_single" "yes")
7764                       (const_string "single") (const_string "double")))
7765    (set_attr "type" "jump_ind")])
7766
7767 (define_insn "sibcall_compact"
7768   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7769          (match_operand 1 "" ""))
7770    (return)
7771    (use (match_operand:SI 2 "register_operand" "z,x"))
7772    (use (reg:SI R1_REG))
7773    (use (reg:PSI FPSCR_REG))
7774    ;; We want to make sure the `x' above will only match MACH_REG
7775    ;; because sibcall_epilogue may clobber MACL_REG.
7776    (clobber (reg:SI MACL_REG))]
7777   "TARGET_SHCOMPACT"
7778   "@
7779         jmp     @%0%#
7780         jmp     @%0\\n  sts     %2, r0"
7781   [(set_attr "needs_delay_slot" "yes,no")
7782    (set_attr "length" "2,4")
7783    (set (attr "fp_mode") (const_string "single"))
7784    (set_attr "type" "jump_ind")])
7785
7786 (define_insn "sibcall_media"
7787   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7788          (match_operand 1 "" ""))
7789    (use (reg:SI PR_MEDIA_REG))
7790    (return)]
7791   "TARGET_SHMEDIA"
7792   "blink        %0, r63"
7793   [(set_attr "type" "jump_media")])
7794
7795 (define_expand "sibcall"
7796   [(parallel
7797     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7798            (match_operand 1 "" ""))
7799      (match_operand 2 "" "")
7800      (use (reg:PSI FPSCR_REG))
7801      (return)])]
7802   ""
7803   "
7804 {
7805   if (TARGET_SHMEDIA)
7806     {
7807       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7808       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7809       DONE;
7810     }
7811   else if (TARGET_SHCOMPACT && operands[2]
7812            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7813     {
7814       rtx cookie_rtx = operands[2];
7815       long cookie = INTVAL (cookie_rtx);
7816       rtx func = XEXP (operands[0], 0);
7817       rtx mach, r1;
7818
7819       if (flag_pic)
7820         {
7821           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7822             {
7823               rtx reg = gen_reg_rtx (Pmode);
7824
7825               emit_insn (gen_symGOT2reg (reg, func));
7826               func = reg;
7827             }
7828           else
7829             func = legitimize_pic_address (func, Pmode, 0);
7830         }
7831
7832       /* FIXME: if we could tell whether all argument registers are
7833          already taken, we could decide whether to force the use of
7834          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7835          simple way to tell.  We could use the CALL_COOKIE, but we
7836          can't currently tell a register used for regular argument
7837          passing from one that is unused.  If we leave it up to reload
7838          to decide which register to use, it seems to always choose
7839          R0_REG, which leaves no available registers in SIBCALL_REGS
7840          to hold the address of the trampoline.  */
7841       mach = gen_rtx_REG (SImode, MACH_REG);
7842       r1 = gen_rtx_REG (SImode, R1_REG);
7843
7844       /* Since such a call function may use all call-clobbered
7845          registers, we force a mode switch earlier, so that we don't
7846          run out of registers when adjusting fpscr for the call.  */
7847       emit_insn (gen_force_mode_for_call ());
7848
7849       operands[0]
7850         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7851                            SFUNC_GOT);
7852       operands[0] = force_reg (SImode, operands[0]);
7853
7854       /* We don't need a return trampoline, since the callee will
7855          return directly to the upper caller.  */
7856       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7857         {
7858           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7859           cookie_rtx = GEN_INT (cookie);
7860         }
7861
7862       emit_move_insn (mach, func);
7863       emit_move_insn (r1, cookie_rtx);
7864
7865       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7866       DONE;
7867     }
7868   else if (TARGET_SHCOMPACT && flag_pic
7869            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7870            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7871     {
7872       rtx reg = gen_reg_rtx (Pmode);
7873
7874       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7875       XEXP (operands[0], 0) = reg;
7876     }
7877   if (flag_pic && TARGET_SH2
7878       && MEM_P (operands[0])
7879       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7880       /* The PLT needs the PIC register, but the epilogue would have
7881          to restore it, so we can only use PC-relative PIC calls for
7882          static functions.  */
7883       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7884     {
7885       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7886       DONE;
7887     }
7888   else
7889     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7890
7891   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7892   DONE;
7893 }")
7894
7895 (define_insn "sibcall_valuei"
7896   [(set (match_operand 0 "" "=rf")
7897         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7898               (match_operand 2 "" "")))
7899    (use (reg:PSI FPSCR_REG))
7900    (return)]
7901   "TARGET_SH1"
7902   "jmp  @%1%#"
7903   [(set_attr "needs_delay_slot" "yes")
7904    (set (attr "fp_mode")
7905         (if_then_else (eq_attr "fpu_single" "yes")
7906                       (const_string "single") (const_string "double")))
7907    (set_attr "type" "jump_ind")])
7908
7909 (define_insn "sibcall_valuei_pcrel"
7910   [(set (match_operand 0 "" "=rf")
7911         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7912               (match_operand 2 "" "")))
7913    (use (match_operand 3 "" ""))
7914    (use (reg:PSI FPSCR_REG))
7915    (return)]
7916   "TARGET_SH2"
7917   "braf %1\\n%O3:%#"
7918   [(set_attr "needs_delay_slot" "yes")
7919    (set (attr "fp_mode")
7920         (if_then_else (eq_attr "fpu_single" "yes")
7921                       (const_string "single") (const_string "double")))
7922    (set_attr "type" "jump_ind")])
7923
7924 (define_insn_and_split "sibcall_value_pcrel"
7925   [(set (match_operand 0 "" "=rf")
7926         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7927               (match_operand 2 "" "")))
7928    (use (reg:PSI FPSCR_REG))
7929    (clobber (match_scratch:SI 3 "=k"))
7930    (return)]
7931   "TARGET_SH2"
7932   "#"
7933   "reload_completed"
7934   [(const_int 0)]
7935   "
7936 {
7937   rtx lab = PATTERN (gen_call_site ());
7938   rtx call_insn;
7939
7940   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7941   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7942                                                         operands[3],
7943                                                         operands[2],
7944                                                         copy_rtx (lab)));
7945   SIBLING_CALL_P (call_insn) = 1;
7946   DONE;
7947 }"
7948   [(set_attr "needs_delay_slot" "yes")
7949    (set (attr "fp_mode")
7950         (if_then_else (eq_attr "fpu_single" "yes")
7951                       (const_string "single") (const_string "double")))
7952    (set_attr "type" "jump_ind")])
7953
7954 (define_insn "sibcall_value_compact"
7955   [(set (match_operand 0 "" "=rf,rf")
7956         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7957               (match_operand 2 "" "")))
7958    (return)
7959    (use (match_operand:SI 3 "register_operand" "z,x"))
7960    (use (reg:SI R1_REG))
7961    (use (reg:PSI FPSCR_REG))
7962    ;; We want to make sure the `x' above will only match MACH_REG
7963    ;; because sibcall_epilogue may clobber MACL_REG.
7964    (clobber (reg:SI MACL_REG))]
7965   "TARGET_SHCOMPACT"
7966   "@
7967         jmp     @%1%#
7968         jmp     @%1\\n  sts     %3, r0"
7969   [(set_attr "needs_delay_slot" "yes,no")
7970    (set_attr "length" "2,4")
7971    (set (attr "fp_mode") (const_string "single"))
7972    (set_attr "type" "jump_ind")])
7973
7974 (define_insn "sibcall_value_media"
7975   [(set (match_operand 0 "" "=rf")
7976         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7977               (match_operand 2 "" "")))
7978    (use (reg:SI PR_MEDIA_REG))
7979    (return)]
7980   "TARGET_SHMEDIA"
7981   "blink        %1, r63"
7982   [(set_attr "type" "jump_media")])
7983
7984 (define_expand "sibcall_value"
7985   [(parallel
7986     [(set (match_operand 0 "arith_reg_operand" "")
7987           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7988                 (match_operand 2 "" "")))
7989      (match_operand 3 "" "")
7990      (use (reg:PSI FPSCR_REG))
7991      (return)])]
7992   ""
7993   "
7994 {
7995   if (TARGET_SHMEDIA)
7996     {
7997       operands[1] = shmedia_prepare_call_address (operands[1], 1);
7998       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
7999                                                operands[2]));
8000       DONE;
8001     }
8002   else if (TARGET_SHCOMPACT && operands[3]
8003            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8004     {
8005       rtx cookie_rtx = operands[3];
8006       long cookie = INTVAL (cookie_rtx);
8007       rtx func = XEXP (operands[1], 0);
8008       rtx mach, r1;
8009
8010       if (flag_pic)
8011         {
8012           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8013             {
8014               rtx reg = gen_reg_rtx (Pmode);
8015
8016               emit_insn (gen_symGOT2reg (reg, func));
8017               func = reg;
8018             }
8019           else
8020             func = legitimize_pic_address (func, Pmode, 0);
8021         }
8022
8023       /* FIXME: if we could tell whether all argument registers are
8024          already taken, we could decide whether to force the use of
8025          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8026          simple way to tell.  We could use the CALL_COOKIE, but we
8027          can't currently tell a register used for regular argument
8028          passing from one that is unused.  If we leave it up to reload
8029          to decide which register to use, it seems to always choose
8030          R0_REG, which leaves no available registers in SIBCALL_REGS
8031          to hold the address of the trampoline.  */
8032       mach = gen_rtx_REG (SImode, MACH_REG);
8033       r1 = gen_rtx_REG (SImode, R1_REG);
8034
8035       /* Since such a call function may use all call-clobbered
8036          registers, we force a mode switch earlier, so that we don't
8037          run out of registers when adjusting fpscr for the call.  */
8038       emit_insn (gen_force_mode_for_call ());
8039
8040       operands[1]
8041         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8042                            SFUNC_GOT);
8043       operands[1] = force_reg (SImode, operands[1]);
8044
8045       /* We don't need a return trampoline, since the callee will
8046          return directly to the upper caller.  */
8047       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8048         {
8049           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8050           cookie_rtx = GEN_INT (cookie);
8051         }
8052
8053       emit_move_insn (mach, func);
8054       emit_move_insn (r1, cookie_rtx);
8055
8056       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8057                                                  operands[2], mach));
8058       DONE;
8059     }
8060   else if (TARGET_SHCOMPACT && flag_pic
8061            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8062            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8063     {
8064       rtx reg = gen_reg_rtx (Pmode);
8065
8066       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8067       XEXP (operands[1], 0) = reg;
8068     }
8069   if (flag_pic && TARGET_SH2
8070       && MEM_P (operands[1])
8071       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8072       /* The PLT needs the PIC register, but the epilogue would have
8073          to restore it, so we can only use PC-relative PIC calls for
8074          static functions.  */
8075       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8076     {
8077       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8078                                                XEXP (operands[1], 0),
8079                                                operands[2]));
8080       DONE;
8081     }
8082   else
8083     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8084
8085   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8086   DONE;
8087 }")
8088
8089 (define_insn "call_value_pop_compact"
8090   [(set (match_operand 0 "" "=rf")
8091         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8092               (match_operand 2 "" "")))
8093    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8094                                  (match_operand 4 "immediate_operand" "n")))
8095    (match_operand 3 "immediate_operand" "n")
8096    (use (reg:SI R0_REG))
8097    (use (reg:SI R1_REG))
8098    (use (reg:PSI FPSCR_REG))
8099    (clobber (reg:SI PR_REG))]
8100   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8101   "jsr  @%1%#"
8102   [(set_attr "type" "call")
8103    (set (attr "fp_mode")
8104         (if_then_else (eq_attr "fpu_single" "yes")
8105                       (const_string "single") (const_string "double")))
8106    (set_attr "needs_delay_slot" "yes")])
8107
8108 (define_insn "call_value_pop_compact_rettramp"
8109   [(set (match_operand 0 "" "=rf")
8110         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8111               (match_operand 2 "" "")))
8112    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8113                                  (match_operand 4 "immediate_operand" "n")))
8114    (match_operand 3 "immediate_operand" "n")
8115    (use (reg:SI R0_REG))
8116    (use (reg:SI R1_REG))
8117    (use (reg:PSI FPSCR_REG))
8118    (clobber (reg:SI R10_REG))
8119    (clobber (reg:SI PR_REG))]
8120   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8121   "jsr  @%1%#"
8122   [(set_attr "type" "call")
8123    (set (attr "fp_mode")
8124         (if_then_else (eq_attr "fpu_single" "yes")
8125                       (const_string "single") (const_string "double")))
8126    (set_attr "needs_delay_slot" "yes")])
8127
8128 (define_expand "call_value_pop"
8129   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8130                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8131                                  (match_operand 2 "" "")))
8132               (match_operand 3 "" "")
8133               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8134                                             (match_operand 4 "" "")))])]
8135   "TARGET_SHCOMPACT"
8136   "
8137 {
8138   rtx cookie_rtx;
8139   long cookie;
8140   rtx func;
8141   rtx r0, r1;
8142
8143   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8144   cookie_rtx = operands[3];
8145   cookie = INTVAL (cookie_rtx);
8146   func = XEXP (operands[1], 0);
8147
8148   if (flag_pic)
8149     {
8150       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8151         {
8152           rtx reg = gen_reg_rtx (Pmode);
8153
8154           emit_insn (gen_symGOTPLT2reg (reg, func));
8155           func = reg;
8156         }
8157       else
8158         func = legitimize_pic_address (func, Pmode, 0);
8159     }
8160
8161   r0 = gen_rtx_REG (SImode, R0_REG);
8162   r1 = gen_rtx_REG (SImode, R1_REG);
8163
8164   /* Since such a call function may use all call-clobbered
8165      registers, we force a mode switch earlier, so that we don't
8166      run out of registers when adjusting fpscr for the call.  */
8167   emit_insn (gen_force_mode_for_call ());
8168
8169   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8170                                  SFUNC_GOT);
8171   operands[1] = force_reg (SImode, operands[1]);
8172
8173   emit_move_insn (r0, func);
8174   emit_move_insn (r1, cookie_rtx);
8175
8176   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8177     emit_call_insn (gen_call_value_pop_compact_rettramp
8178                         (operands[0], operands[1], operands[2],
8179                          operands[3], operands[4]));
8180   else
8181     emit_call_insn (gen_call_value_pop_compact
8182                         (operands[0], operands[1], operands[2],
8183                          operands[3], operands[4]));
8184
8185   DONE;
8186 }")
8187
8188 (define_expand "sibcall_epilogue"
8189   [(return)]
8190   ""
8191   "
8192 {
8193   sh_expand_epilogue (1);
8194   if (TARGET_SHCOMPACT)
8195     {
8196       rtx insn, set;
8197
8198       /* If epilogue clobbers r0, preserve it in macl.  */
8199       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8200         if ((set = single_set (insn))
8201             && REG_P (SET_DEST (set))
8202             && REGNO (SET_DEST (set)) == R0_REG)
8203           {
8204             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8205             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8206
8207             /* We can't tell at this point whether the sibcall is a
8208                sibcall_compact and, if it is, whether it uses r0 or
8209                mach as operand 2, so let the instructions that
8210                preserve r0 be optimized away if r0 turns out to be
8211                dead.  */
8212             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8213             emit_move_insn (r0, tmp);
8214             break;
8215           }
8216     }
8217   DONE;
8218 }")
8219
8220 (define_insn "indirect_jump_compact"
8221   [(set (pc)
8222         (match_operand:SI 0 "arith_reg_operand" "r"))]
8223   "TARGET_SH1"
8224   "jmp  @%0%#"
8225   [(set_attr "needs_delay_slot" "yes")
8226    (set_attr "type" "jump_ind")])
8227
8228 (define_expand "indirect_jump"
8229   [(set (pc)
8230         (match_operand 0 "register_operand" ""))]
8231   ""
8232   "
8233 {
8234   if (GET_MODE (operands[0]) != Pmode)
8235     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8236 }")
8237
8238 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8239 ;; which can be present in structured code from indirect jumps which can not
8240 ;; be present in structured code.  This allows -fprofile-arcs to work.
8241
8242 ;; For SH1 processors.
8243 (define_insn "casesi_jump_1"
8244   [(set (pc)
8245         (match_operand:SI 0 "register_operand" "r"))
8246    (use (label_ref (match_operand 1 "" "")))]
8247   "TARGET_SH1"
8248   "jmp  @%0%#"
8249   [(set_attr "needs_delay_slot" "yes")
8250    (set_attr "type" "jump_ind")])
8251
8252 ;; For all later processors.
8253 (define_insn "casesi_jump_2"
8254   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8255                       (label_ref (match_operand 1 "" ""))))
8256    (use (label_ref (match_operand 2 "" "")))]
8257   "TARGET_SH2
8258    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8259   "braf %0%#"
8260   [(set_attr "needs_delay_slot" "yes")
8261    (set_attr "type" "jump_ind")])
8262
8263 (define_insn "casesi_jump_media"
8264   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8265    (use (label_ref (match_operand 1 "" "")))]
8266   "TARGET_SHMEDIA"
8267   "blink        %0, r63"
8268   [(set_attr "type" "jump_media")])
8269
8270 ;; Call subroutine returning any type.
8271 ;; ??? This probably doesn't work.
8272
8273 (define_expand "untyped_call"
8274   [(parallel [(call (match_operand 0 "" "")
8275                     (const_int 0))
8276               (match_operand 1 "" "")
8277               (match_operand 2 "" "")])]
8278   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8279   "
8280 {
8281   int i;
8282
8283   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8284
8285   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8286     {
8287       rtx set = XVECEXP (operands[2], 0, i);
8288       emit_move_insn (SET_DEST (set), SET_SRC (set));
8289     }
8290
8291   /* The optimizer does not know that the call sets the function value
8292      registers we stored in the result block.  We avoid problems by
8293      claiming that all hard registers are used and clobbered at this
8294      point.  */
8295   emit_insn (gen_blockage ());
8296
8297   DONE;
8298 }")
8299 \f
8300 ;; ------------------------------------------------------------------------
8301 ;; Misc insns
8302 ;; ------------------------------------------------------------------------
8303
8304 (define_insn "dect"
8305   [(set (reg:SI T_REG)
8306         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8307    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8308         (plus:SI (match_dup 1) (const_int -1)))]
8309   "TARGET_SH2"
8310   "dt   %0"
8311   [(set_attr "type" "arith")])
8312
8313 (define_insn "nop"
8314   [(const_int 0)]
8315   ""
8316   "nop")
8317
8318 ;; Load address of a label. This is only generated by the casesi expand,
8319 ;; and by machine_dependent_reorg (fixing up fp moves).
8320 ;; This must use unspec, because this only works for labels that are
8321 ;; within range,
8322
8323 (define_insn "mova"
8324   [(set (reg:SI R0_REG)
8325         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8326   "TARGET_SH1"
8327   "mova %O0,r0"
8328   [(set_attr "in_delay_slot" "no")
8329    (set_attr "type" "arith")])
8330
8331 ;; machine_dependent_reorg will make this a `mova'.
8332 (define_insn "mova_const"
8333   [(set (reg:SI R0_REG)
8334         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8335   "TARGET_SH1"
8336   "#"
8337   [(set_attr "in_delay_slot" "no")
8338    (set_attr "type" "arith")])
8339
8340 (define_expand "GOTaddr2picreg"
8341   [(set (reg:SI R0_REG)
8342         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8343                    UNSPEC_MOVA))
8344    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8345    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8346   "" "
8347 {
8348   if (TARGET_VXWORKS_RTP)
8349     {
8350       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8351       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8352       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8353       DONE;
8354     }
8355
8356   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8357   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8358
8359   if (TARGET_SHMEDIA)
8360     {
8361       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8362       rtx pic = operands[0];
8363       rtx lab = PATTERN (gen_call_site ());
8364       rtx insn, equiv;
8365
8366       equiv = operands[1];
8367       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8368                                     UNSPEC_PCREL_SYMOFF);
8369       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8370
8371       if (Pmode == SImode)
8372         {
8373           emit_insn (gen_movsi_const (pic, operands[1]));
8374           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8375         }
8376       else
8377         {
8378           emit_insn (gen_movdi_const (pic, operands[1]));
8379           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8380         }
8381
8382       insn = emit_move_insn (operands[0], tr);
8383
8384       set_unique_reg_note (insn, REG_EQUAL, equiv);
8385
8386       DONE;
8387     }
8388 }
8389 ")
8390
8391 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8392 ;; PIC register.
8393
8394 (define_expand "vxworks_picreg"
8395   [(set (reg:SI PIC_REG)
8396         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8397    (set (reg:SI R0_REG)
8398         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8399    (set (reg:SI PIC_REG)
8400         (mem:SI (reg:SI PIC_REG)))
8401    (set (reg:SI PIC_REG)
8402         (mem:SI (plus:SI (reg:SI PIC_REG)
8403                          (reg:SI R0_REG))))]
8404   "TARGET_VXWORKS_RTP")
8405
8406 (define_insn "*ptb"
8407   [(set (match_operand 0 "target_reg_operand" "=b")
8408         (const (unspec [(match_operand 1 "" "Csy")]
8409                              UNSPEC_DATALABEL)))]
8410   "TARGET_SHMEDIA && flag_pic
8411    && satisfies_constraint_Csy (operands[1])"
8412   "ptb/u        datalabel %1, %0"
8413   [(set_attr "type" "ptabs_media")
8414    (set_attr "length" "*")])
8415
8416 (define_insn "ptrel_si"
8417   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8418         (plus:SI (match_operand:SI 1 "register_operand" "r")
8419               (pc)))
8420    (match_operand:SI 2 "" "")]
8421   "TARGET_SHMEDIA"
8422   "%O2: ptrel/u %1, %0"
8423   [(set_attr "type" "ptabs_media")])
8424
8425 (define_insn "ptrel_di"
8426   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8427         (plus:DI (match_operand:DI 1 "register_operand" "r")
8428               (pc)))
8429    (match_operand:DI 2 "" "")]
8430   "TARGET_SHMEDIA"
8431   "%O2: ptrel/u %1, %0"
8432   [(set_attr "type" "ptabs_media")])
8433
8434 (define_expand "builtin_setjmp_receiver"
8435   [(match_operand 0 "" "")]
8436   "flag_pic"
8437   "
8438 {
8439   emit_insn (gen_GOTaddr2picreg ());
8440   DONE;
8441 }")
8442
8443 (define_expand "call_site"
8444   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8445   "TARGET_SH1"
8446   "
8447 {
8448   static HOST_WIDE_INT i = 0;
8449   operands[0] = GEN_INT (i);
8450   i++;
8451 }")
8452
8453 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8454 ;; in symGOT_load expand.
8455
8456 (define_insn_and_split "chk_guard_add"
8457   [(set (match_operand:SI 0 "register_operand" "=&r")
8458         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8459                     (reg:SI PIC_REG)]
8460                    UNSPEC_CHKADD))]
8461   "TARGET_SH1"
8462   "#"
8463   "TARGET_SH1 && reload_completed"
8464   [(set (match_dup 0) (reg:SI PIC_REG))
8465    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8466   ""
8467   [(set_attr "type" "arith")])
8468
8469 (define_expand "sym_label2reg"
8470   [(set (match_operand:SI 0 "" "")
8471         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8472                               (const (plus:SI (match_operand:SI 2 "" "")
8473                                               (const_int 2)))]
8474                              UNSPEC_SYMOFF)))]
8475   "TARGET_SH1" "")
8476
8477 (define_expand "symGOT_load"
8478   [(set (match_dup 2) (match_operand 1 "" ""))
8479    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8480    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8481   ""
8482   "
8483 {
8484   rtx mem;
8485
8486   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8487   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8488
8489   if (TARGET_SHMEDIA)
8490     {
8491       rtx reg = operands[2];
8492
8493       if (Pmode == DImode)
8494         {      
8495           if (flag_pic > 1)
8496             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8497           else
8498             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8499         }
8500       else
8501         {
8502           if (flag_pic > 1)
8503             emit_insn (gen_movsi_const (reg, operands[1]));
8504           else
8505             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8506         }
8507     }
8508   else
8509     emit_move_insn (operands[2], operands[1]);
8510
8511   /* When stack protector inserts codes after the result is set to
8512      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8513      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8514      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8515      matter because this is a rare situation.  */
8516   if (!TARGET_SHMEDIA
8517       && flag_stack_protect
8518       && GET_CODE (operands[1]) == CONST
8519       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8520       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8521       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8522                  \"__stack_chk_guard\") == 0)
8523     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8524   else
8525     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8526                                                gen_rtx_REG (Pmode, PIC_REG)));
8527
8528   /* N.B. This is not constant for a GOTPLT relocation.  */
8529   mem = gen_rtx_MEM (Pmode, operands[3]);
8530   MEM_NOTRAP_P (mem) = 1;
8531   /* ??? Should we have a special alias set for the GOT?  */
8532   emit_move_insn (operands[0], mem);
8533
8534   DONE;
8535 }")
8536
8537 (define_expand "sym2GOT"
8538   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8539   ""
8540   "")
8541
8542 (define_expand "symGOT2reg"
8543   [(match_operand 0 "" "") (match_operand 1 "" "")]
8544   ""
8545   "
8546 {
8547   rtx gotsym, insn;
8548
8549   gotsym = gen_sym2GOT (operands[1]);
8550   PUT_MODE (gotsym, Pmode);
8551   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8552
8553   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8554
8555   DONE;
8556 }")
8557
8558 (define_expand "symGOTPLT2reg"
8559   [(match_operand 0 "" "") (match_operand 1 "" "")]
8560   ""
8561   "
8562 {
8563   rtx pltsym = gen_rtx_CONST (Pmode,
8564                               gen_rtx_UNSPEC (Pmode,
8565                                               gen_rtvec (1, operands[1]),
8566                                               UNSPEC_GOTPLT));
8567   emit_insn (gen_symGOT_load (operands[0], pltsym));
8568   DONE;
8569 }")
8570
8571 (define_expand "sym2GOTOFF"
8572   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8573   ""
8574   "")
8575
8576 (define_expand "symGOTOFF2reg"
8577   [(match_operand 0 "" "") (match_operand 1 "" "")]
8578   ""
8579   "
8580 {
8581   rtx gotoffsym, insn;
8582   rtx t = (!can_create_pseudo_p ()
8583            ? operands[0]
8584            : gen_reg_rtx (GET_MODE (operands[0])));
8585
8586   gotoffsym = gen_sym2GOTOFF (operands[1]);
8587   PUT_MODE (gotoffsym, Pmode);
8588   emit_move_insn (t, gotoffsym);
8589   insn = emit_move_insn (operands[0],
8590                          gen_rtx_PLUS (Pmode, t,
8591                                        gen_rtx_REG (Pmode, PIC_REG)));
8592
8593   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8594
8595   DONE;
8596 }")
8597
8598 (define_expand "symPLT_label2reg"
8599   [(set (match_operand:SI 0 "" "")
8600         (const:SI
8601          (unspec:SI
8602           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8603            (const:SI (plus:SI (match_operand:SI 2 "" "")
8604                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8605    ;; Even though the PIC register is not really used by the call
8606    ;; sequence in which this is expanded, the PLT code assumes the PIC
8607    ;; register is set, so we must not skip its initialization.  Since
8608    ;; we only use this expand as part of calling sequences, and never
8609    ;; to take the address of a function, this is the best point to
8610    ;; insert the (use).  Using the PLT to take the address of a
8611    ;; function would be wrong, not only because the PLT entry could
8612    ;; then be called from a function that doesn't initialize the PIC
8613    ;; register to the proper GOT, but also because pointers to the
8614    ;; same function might not compare equal, should they be set by
8615    ;; different shared libraries.
8616    (use (reg:SI PIC_REG))]
8617   "TARGET_SH1"
8618   "")
8619
8620 (define_expand "sym2PIC"
8621   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8622   ""
8623   "")
8624
8625 ;; TLS code generation.
8626 ;; ??? this should be a define_insn_and_split
8627 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8628 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8629 ;; for details.
8630
8631 (define_insn "tls_global_dynamic"
8632   [(set (match_operand:SI 0 "register_operand" "=&z")
8633         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8634                                   UNSPEC_TLSGD))
8635               (const_int 0)))
8636    (use (reg:PSI FPSCR_REG))
8637    (use (reg:SI PIC_REG))
8638    (clobber (reg:SI PR_REG))
8639    (clobber (scratch:SI))]
8640   "TARGET_SH1"
8641   "*
8642 {
8643   return \"\\
8644 mov.l\\t1f,r4\\n\\
8645 \\tmova\\t2f,r0\\n\\
8646 \\tmov.l\\t2f,r1\\n\\
8647 \\tadd\\tr0,r1\\n\\
8648 \\tjsr\\t@r1\\n\\
8649 \\tadd\\tr12,r4\\n\\
8650 \\tbra\\t3f\\n\\
8651 \\tnop\\n\\
8652 \\t.align\\t2\\n\\
8653 1:\\t.long\\t%a1@TLSGD\\n\\
8654 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8655 3:\";
8656 }"
8657   [(set_attr "type" "tls_load")
8658    (set_attr "length" "26")])
8659
8660 (define_insn "tls_local_dynamic"
8661   [(set (match_operand:SI 0 "register_operand" "=&z")
8662         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8663                                   UNSPEC_TLSLDM))
8664               (const_int 0)))
8665    (use (reg:PSI FPSCR_REG))
8666    (use (reg:SI PIC_REG))
8667    (clobber (reg:SI PR_REG))
8668    (clobber (scratch:SI))]
8669   "TARGET_SH1"
8670   "*
8671 {
8672   return \"\\
8673 mov.l\\t1f,r4\\n\\
8674 \\tmova\\t2f,r0\\n\\
8675 \\tmov.l\\t2f,r1\\n\\
8676 \\tadd\\tr0,r1\\n\\
8677 \\tjsr\\t@r1\\n\\
8678 \\tadd\\tr12,r4\\n\\
8679 \\tbra\\t3f\\n\\
8680 \\tnop\\n\\
8681 \\t.align\\t2\\n\\
8682 1:\\t.long\\t%a1@TLSLDM\\n\\
8683 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8684 3:\";
8685 }"
8686   [(set_attr "type" "tls_load")
8687    (set_attr "length" "26")])
8688
8689 (define_expand "sym2DTPOFF"
8690   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8691   ""
8692   "")
8693
8694 (define_expand "symDTPOFF2reg"
8695   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8696   ""
8697   "
8698 {
8699   rtx dtpoffsym;
8700   rtx t = (!can_create_pseudo_p ()
8701            ? operands[0]
8702            : gen_reg_rtx (GET_MODE (operands[0])));
8703
8704   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8705   PUT_MODE (dtpoffsym, Pmode);
8706   emit_move_insn (t, dtpoffsym);
8707   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8708   DONE;
8709 }")
8710
8711 (define_expand "sym2GOTTPOFF"
8712   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8713   ""
8714   "")
8715
8716 (define_insn "tls_initial_exec"
8717   [(set (match_operand:SI 0 "register_operand" "=&r")
8718         (unspec:SI [(match_operand:SI 1 "" "")]
8719                     UNSPEC_TLSIE))
8720    (use (reg:SI GBR_REG))
8721    (use (reg:SI PIC_REG))
8722    (clobber (reg:SI R0_REG))]
8723   ""
8724   "*
8725 {
8726   return \"\\
8727 mov.l\\t1f,r0\\n\\
8728 \\tstc\\tgbr,%0\\n\\
8729 \\tmov.l\\t@(r0,r12),r0\\n\\
8730 \\tbra\\t2f\\n\\
8731 \\tadd\\tr0,%0\\n\\
8732 \\t.align\\t2\\n\\
8733 1:\\t.long\\t%a1\\n\\
8734 2:\";
8735 }"
8736   [(set_attr "type" "tls_load")
8737    (set_attr "length" "16")])
8738
8739 (define_expand "sym2TPOFF"
8740   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8741   ""
8742   "")
8743
8744 (define_expand "symTPOFF2reg"
8745   [(match_operand 0 "" "") (match_operand 1 "" "")]
8746   ""
8747   "
8748 {
8749   rtx tpoffsym;
8750
8751   tpoffsym = gen_sym2TPOFF (operands[1]);
8752   PUT_MODE (tpoffsym, Pmode);
8753   emit_move_insn (operands[0], tpoffsym);
8754   DONE;
8755 }")
8756
8757 (define_insn "load_gbr"
8758   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8759    (use (reg:SI GBR_REG))]
8760   ""
8761   "stc  gbr,%0"
8762   [(set_attr "type" "tls_load")])
8763
8764 ;; case instruction for switch statements.
8765
8766 ;; Operand 0 is index
8767 ;; operand 1 is the minimum bound
8768 ;; operand 2 is the maximum bound - minimum bound + 1
8769 ;; operand 3 is CODE_LABEL for the table;
8770 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8771
8772 (define_expand "casesi"
8773   [(match_operand:SI 0 "arith_reg_operand" "")
8774    (match_operand:SI 1 "arith_reg_operand" "")
8775    (match_operand:SI 2 "arith_reg_operand" "")
8776    (match_operand 3 "" "") (match_operand 4 "" "")]
8777   ""
8778   "
8779 {
8780   rtx reg = gen_reg_rtx (SImode);
8781   rtx reg2 = gen_reg_rtx (SImode);
8782   if (TARGET_SHMEDIA)
8783     {
8784       rtx reg = gen_reg_rtx (DImode);
8785       rtx reg2 = gen_reg_rtx (DImode);
8786       rtx reg3 = gen_reg_rtx (Pmode);
8787       rtx reg4 = gen_reg_rtx (Pmode);
8788       rtx reg5 = gen_reg_rtx (Pmode);
8789       rtx load, test;
8790
8791       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8792       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8793       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8794
8795       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8796       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8797       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8798       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8799       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8800       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8801       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8802                                                (Pmode, operands[3])));
8803       /* Messy: can we subreg to clean this up? */
8804       if (Pmode == DImode)
8805         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8806       else
8807         load = gen_casesi_load_media (reg4,
8808                                       gen_rtx_SUBREG (DImode, reg3, 0),
8809                                       reg2, operands[3]);
8810       PUT_MODE (SET_SRC (load), Pmode);
8811       emit_insn (load);
8812       /* ??? The following add could be eliminated if we used ptrel.  */
8813       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8814       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8815       emit_barrier ();
8816       DONE;
8817     }
8818   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8819   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8820   /* If optimizing, casesi_worker depends on the mode of the instruction
8821      before label it 'uses' - operands[3].  */
8822   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8823                            reg));
8824   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8825   if (TARGET_SH2)
8826     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8827   else
8828     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8829   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8830      operands[3], but to lab.  We will fix this up in
8831      machine_dependent_reorg.  */
8832   emit_barrier ();
8833   DONE;
8834 }")
8835
8836 (define_expand "casesi_0"
8837   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8838    (set (match_dup 4) (minus:SI (match_dup 4)
8839                                 (match_operand:SI 1 "arith_operand" "")))
8840    (set (reg:SI T_REG)
8841         (gtu:SI (match_dup 4)
8842                 (match_operand:SI 2 "arith_reg_operand" "")))
8843    (set (pc)
8844         (if_then_else (ne (reg:SI T_REG)
8845                           (const_int 0))
8846                       (label_ref (match_operand 3 "" ""))
8847                       (pc)))]
8848   "TARGET_SH1"
8849   "")
8850
8851 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8852 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8853 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8854
8855 (define_insn "casesi_worker_0"
8856   [(set (match_operand:SI 0 "register_operand" "=r,r")
8857         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8858                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8859    (clobber (match_scratch:SI 3 "=X,1"))
8860    (clobber (match_scratch:SI 4 "=&z,z"))]
8861   "TARGET_SH1"
8862   "#")
8863
8864 (define_split
8865   [(set (match_operand:SI 0 "register_operand" "")
8866         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8867                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8868    (clobber (match_scratch:SI 3 ""))
8869    (clobber (match_scratch:SI 4 ""))]
8870   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8871   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8872    (parallel [(set (match_dup 0)
8873               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8874                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8875               (clobber (match_dup 3))])
8876    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8877   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8878
8879 (define_split
8880   [(set (match_operand:SI 0 "register_operand" "")
8881         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8882                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8883    (clobber (match_scratch:SI 3 ""))
8884    (clobber (match_scratch:SI 4 ""))]
8885   "TARGET_SH2 && reload_completed"
8886   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8887    (parallel [(set (match_dup 0)
8888               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8889                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8890               (clobber (match_dup 3))])]
8891   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8892
8893 (define_insn "casesi_worker_1"
8894   [(set (match_operand:SI 0 "register_operand" "=r,r")
8895         (unspec:SI [(reg:SI R0_REG)
8896                     (match_operand:SI 1 "register_operand" "0,r")
8897                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8898    (clobber (match_scratch:SI 3 "=X,1"))]
8899   "TARGET_SH1"
8900   "*
8901 {
8902   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8903
8904   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8905
8906   switch (GET_MODE (diff_vec))
8907     {
8908     case SImode:
8909       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8910     case HImode:
8911       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8912     case QImode:
8913       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8914         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8915       return \"mov.b    @(r0,%1),%0\";
8916     default:
8917       gcc_unreachable ();
8918     }
8919 }"
8920   [(set_attr "length" "4")])
8921
8922 (define_insn "casesi_worker_2"
8923   [(set (match_operand:SI 0 "register_operand" "=r,r")
8924         (unspec:SI [(reg:SI R0_REG)
8925                     (match_operand:SI 1 "register_operand" "0,r")
8926                     (label_ref (match_operand 2 "" ""))
8927                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8928    (clobber (match_operand:SI 4 "" "=X,1"))]
8929   "TARGET_SH2 && reload_completed && flag_pic"
8930   "*
8931 {
8932   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8933   const char *load;
8934
8935   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8936
8937   switch (GET_MODE (diff_vec))
8938     {
8939     case SImode:
8940       output_asm_insn (\"shll2    %1\", operands);
8941       load = \"mov.l    @(r0,%1),%0\"; break;
8942     case HImode:
8943       output_asm_insn (\"add    %1,%1\", operands);
8944       load = \"mov.w    @(r0,%1),%0\"; break;
8945     case QImode:
8946       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8947         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8948       else
8949         load = \"mov.b  @(r0,%1),%0\";
8950       break;
8951     default:
8952       gcc_unreachable ();
8953     }
8954   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8955   return load;
8956 }"
8957   [(set_attr "length" "8")])
8958
8959 (define_insn "casesi_shift_media"
8960   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8961         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8962                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8963                     UNSPEC_CASESI)))]
8964   "TARGET_SHMEDIA"
8965   "*
8966 {
8967   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8968
8969   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8970
8971   switch (GET_MODE (diff_vec))
8972     {
8973     case SImode:
8974       return \"shlli    %1, 2, %0\";
8975     case HImode:
8976       return \"shlli    %1, 1, %0\";
8977     case QImode:
8978       if (rtx_equal_p (operands[0], operands[1]))
8979         return \"\";
8980       return \"add      %1, r63, %0\";
8981     default:
8982       gcc_unreachable ();
8983     }
8984 }"
8985   [(set_attr "type" "arith_media")])
8986
8987 (define_insn "casesi_load_media"
8988   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8989         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8990                          (match_operand:DI 2 "arith_reg_operand" "r")
8991                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8992   "TARGET_SHMEDIA"
8993   "*
8994 {
8995   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8996
8997   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8998
8999   switch (GET_MODE (diff_vec))
9000     {
9001     case SImode:
9002       return \"ldx.l    %1, %2, %0\";
9003     case HImode:
9004 #if 0
9005       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9006         return \"ldx.uw %1, %2, %0\";
9007 #endif
9008       return \"ldx.w    %1, %2, %0\";
9009     case QImode:
9010       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9011         return \"ldx.ub %1, %2, %0\";
9012       return \"ldx.b    %1, %2, %0\";
9013     default:
9014       gcc_unreachable ();
9015     }
9016 }"
9017   [(set_attr "type" "load_media")])
9018
9019 (define_expand "return"
9020   [(return)]
9021   "reload_completed && ! sh_need_epilogue ()"
9022   "
9023 {
9024   if (TARGET_SHMEDIA)
9025     {
9026       emit_jump_insn (gen_return_media ());
9027       DONE;
9028     }
9029
9030   if (TARGET_SHCOMPACT
9031       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9032     {
9033       emit_jump_insn (gen_shcompact_return_tramp ());
9034       DONE;
9035     }
9036 }")
9037
9038 (define_insn "*return_i"
9039   [(return)]
9040   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9041                     && (crtl->args.info.call_cookie
9042                         & CALL_COOKIE_RET_TRAMP (1)))
9043    && reload_completed
9044    && lookup_attribute (\"trap_exit\",
9045                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9046   "*
9047   {
9048     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9049                         && !current_function_interrupt)
9050        return \"rts/n\";
9051     else
9052        return \"%@      %#\";
9053   }"
9054   [(set_attr "type" "return")
9055    (set_attr "needs_delay_slot" "yes")])
9056
9057 ;; trapa has no delay slot.
9058 (define_insn "*return_trapa"
9059   [(return)]
9060   "TARGET_SH1 && !TARGET_SHCOMPACT
9061    && reload_completed"
9062   "%@"
9063   [(set_attr "type" "return")])
9064
9065 (define_expand "shcompact_return_tramp"
9066   [(return)]
9067   "TARGET_SHCOMPACT
9068    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9069   "
9070 {
9071   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9072
9073   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9074   emit_jump_insn (gen_shcompact_return_tramp_i ());
9075   DONE;
9076 }")
9077
9078 (define_insn "shcompact_return_tramp_i"
9079   [(parallel [(return) (use (reg:SI R0_REG))])]
9080   "TARGET_SHCOMPACT
9081    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9082   "jmp  @r0%#"
9083   [(set_attr "type" "jump_ind")
9084    (set_attr "needs_delay_slot" "yes")])
9085
9086 (define_insn "return_media_i"
9087   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9088   "TARGET_SHMEDIA && reload_completed"
9089   "blink        %0, r63"
9090   [(set_attr "type" "jump_media")])
9091
9092 (define_insn "return_media_rte"
9093   [(return)]
9094   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9095   "rte"
9096   [(set_attr "type" "jump_media")])
9097
9098 (define_expand "return_media"
9099   [(return)]
9100   "TARGET_SHMEDIA && reload_completed"
9101   "
9102 {
9103   int tr_regno = sh_media_register_for_return ();
9104   rtx tr;
9105
9106   if (current_function_interrupt)
9107     {
9108       emit_jump_insn (gen_return_media_rte ());
9109       DONE;
9110     }
9111   if (tr_regno < 0)
9112     {
9113       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9114
9115       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9116       tr_regno = TR0_REG;
9117       tr = gen_rtx_REG (Pmode, tr_regno);
9118       emit_move_insn (tr, r18);
9119     }
9120   else
9121     tr = gen_rtx_REG (Pmode, tr_regno);
9122
9123   emit_jump_insn (gen_return_media_i (tr));
9124   DONE;
9125 }")
9126
9127 (define_insn "shcompact_preserve_incoming_args"
9128   [(set (match_operand:SI 0 "register_operand" "+r")
9129         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9130   "TARGET_SHCOMPACT"
9131   ""
9132   [(set_attr "length" "0")])
9133
9134 (define_insn "shcompact_incoming_args"
9135   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9136    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9137    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9138    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9139    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9140    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9141    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9142    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9143    (set (mem:BLK (reg:SI MACL_REG))
9144         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9145    (use (reg:SI R0_REG))
9146    (clobber (reg:SI R0_REG))
9147    (clobber (reg:SI MACL_REG))
9148    (clobber (reg:SI MACH_REG))
9149    (clobber (reg:SI PR_REG))]
9150   "TARGET_SHCOMPACT"
9151   "jsr  @r0%#"
9152   [(set_attr "needs_delay_slot" "yes")])
9153
9154 (define_insn "shmedia_save_restore_regs_compact"
9155   [(set (reg:SI SP_REG)
9156         (plus:SI (reg:SI SP_REG)
9157                  (match_operand:SI 0 "immediate_operand" "i")))
9158    (use (reg:SI R0_REG))
9159    (clobber (reg:SI PR_REG))]
9160   "TARGET_SHCOMPACT
9161    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9162        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9163   "jsr @r0%#"
9164   [(set_attr "needs_delay_slot" "yes")])
9165
9166 (define_expand "prologue"
9167   [(const_int 0)]
9168   ""
9169   "sh_expand_prologue (); DONE;")
9170
9171 (define_expand "epilogue"
9172   [(return)]
9173   ""
9174   "
9175 {
9176   sh_expand_epilogue (0);
9177   emit_jump_insn (gen_return ());
9178   DONE;
9179 }")
9180
9181 (define_expand "eh_return"
9182   [(use (match_operand 0 "register_operand" ""))]
9183   ""
9184 {
9185   rtx ra = operands[0];
9186
9187   if (TARGET_SHMEDIA64)
9188     emit_insn (gen_eh_set_ra_di (ra));
9189   else
9190     emit_insn (gen_eh_set_ra_si (ra));
9191
9192   DONE;
9193 })
9194
9195 ;; Clobber the return address on the stack.  We can't expand this
9196 ;; until we know where it will be put in the stack frame.
9197
9198 (define_insn "eh_set_ra_si"
9199   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9200       UNSPECV_EH_RETURN)
9201    (clobber (match_scratch:SI 1 "=&r"))]
9202   "! TARGET_SHMEDIA64"
9203   "#")
9204
9205 (define_insn "eh_set_ra_di"
9206   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9207       UNSPECV_EH_RETURN)
9208    (clobber (match_scratch:DI 1 "=&r"))]
9209   "TARGET_SHMEDIA64"
9210   "#")
9211
9212 (define_split
9213   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9214       UNSPECV_EH_RETURN)
9215    (clobber (match_scratch 1 ""))]
9216   "reload_completed"
9217   [(const_int 0)]
9218   "
9219 {
9220   sh_set_return_address (operands[0], operands[1]);
9221   DONE;
9222 }")
9223
9224 (define_insn "blockage"
9225   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9226   ""
9227   ""
9228   [(set_attr "length" "0")])
9229 \f
9230 ;; Define movml instructions for SH2A target.  Currently they are
9231 ;; used to push and pop all banked registers only.
9232
9233 (define_insn "movml_push_banked"
9234   [(set (match_operand:SI 0 "register_operand" "=r")
9235           (plus (match_dup 0) (const_int -32)))
9236    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9237    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9238    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9239    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9240    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9241    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9242    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9243    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9244   "TARGET_SH2A && REGNO (operands[0]) == 15"
9245   "movml.l\tr7,@-r15"
9246   [(set_attr "in_delay_slot" "no")])
9247
9248 (define_insn "movml_pop_banked"
9249   [(set (match_operand:SI 0 "register_operand" "=r")
9250           (plus (match_dup 0) (const_int 32)))
9251    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9252    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9253    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9254    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9255    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9256    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9257    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9258    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9259   "TARGET_SH2A && REGNO (operands[0]) == 15"
9260   "movml.l\t@r15+,r7"
9261   [(set_attr "in_delay_slot" "no")])
9262 \f
9263 ;; ------------------------------------------------------------------------
9264 ;; Scc instructions
9265 ;; ------------------------------------------------------------------------
9266
9267 (define_insn "movt"
9268   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9269         (eq:SI (reg:SI T_REG) (const_int 1)))]
9270   "TARGET_SH1"
9271   "movt %0"
9272   [(set_attr "type" "arith")])
9273
9274 (define_expand "cstore4_media"
9275   [(set (match_operand:SI 0 "register_operand" "=r")
9276         (match_operator:SI 1 "sh_float_comparison_operator"
9277          [(match_operand 2 "logical_operand" "")
9278           (match_operand 3 "cmp_operand" "")]))]
9279   "TARGET_SHMEDIA"
9280   "
9281 {
9282   enum machine_mode mode = GET_MODE (operands[2]);
9283   enum rtx_code code = GET_CODE (operands[1]);
9284   bool invert, swap;
9285   if (mode == VOIDmode)
9286     mode = GET_MODE (operands[3]);
9287   if (operands[2] == const0_rtx)
9288     {
9289       if (code == EQ || code == NE)
9290         operands[2] = operands[3], operands[3] = const0_rtx;
9291     }
9292   else
9293     operands[2] = force_reg (mode, operands[2]);
9294   if (operands[3] != const0_rtx)
9295     operands[3] = force_reg (mode, operands[3]);
9296
9297   switch (code)
9298     {
9299     case GEU:
9300     case GE:
9301       swap = invert = !FLOAT_MODE_P (mode);
9302       break;
9303
9304     case LEU:
9305     case LE:
9306       swap = FLOAT_MODE_P (mode), invert = !swap;
9307       break;
9308
9309     case LTU:
9310     case LT:
9311       swap = true, invert = false;
9312       break;
9313
9314     case GTU:
9315     case GT:
9316     case EQ:
9317     case UNORDERED:
9318       swap = invert = false;
9319       break;
9320
9321     case NE:
9322       swap = invert = true;
9323       break;
9324
9325     default:
9326       gcc_unreachable ();
9327   }
9328
9329   if (swap)
9330     {
9331       rtx tem = operands[2];
9332       operands[2] = operands[3];
9333       operands[3] = tem;
9334       code = swap_condition (code);
9335     }
9336
9337   if (invert)
9338     {
9339       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9340       code = reverse_condition (code);
9341       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9342       emit_insn (gen_cstore4_media (tem, operands[1],
9343                                     operands[2], operands[3]));
9344       code = EQ;
9345       operands[2] = tem;
9346       operands[3] = const0_rtx;
9347     }
9348
9349   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9350 }")
9351
9352 (define_expand "cstoresi4"
9353   [(set (match_operand:SI 0 "register_operand" "=r")
9354         (match_operator:SI 1 "comparison_operator"
9355          [(match_operand:SI 2 "cmpsi_operand" "")
9356           (match_operand:SI 3 "arith_operand" "")]))]
9357   "TARGET_SH1 || TARGET_SHMEDIA"
9358   "if (TARGET_SHMEDIA)
9359     {
9360       emit_insn (gen_cstore4_media (operands[0], operands[1],
9361                                     operands[2], operands[3]));
9362       DONE;
9363     }
9364
9365    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9366        && sh_expand_t_scc (operands))
9367      DONE;
9368
9369    if (! currently_expanding_to_rtl)
9370      FAIL;
9371    
9372    sh_emit_compare_and_set (operands, SImode);
9373    DONE;
9374 ")
9375
9376 (define_expand "cstoredi4"
9377   [(set (match_operand:SI 0 "register_operand" "=r")
9378         (match_operator:SI 1 "comparison_operator"
9379          [(match_operand:DI 2 "arith_operand" "")
9380           (match_operand:DI 3 "arith_operand" "")]))]
9381   "TARGET_SH2 || TARGET_SHMEDIA"
9382   "if (TARGET_SHMEDIA)
9383     {
9384       emit_insn (gen_cstore4_media (operands[0], operands[1],
9385                                     operands[2], operands[3]));
9386       DONE;
9387     }
9388
9389    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9390        && sh_expand_t_scc (operands))
9391      DONE;
9392
9393    if (! currently_expanding_to_rtl)
9394      FAIL;
9395    
9396    sh_emit_compare_and_set (operands, DImode);
9397    DONE;
9398 ")
9399
9400
9401
9402 ;; sne moves the complement of the T reg to DEST like this:
9403 ;;      cmp/eq ...
9404 ;;      mov    #-1,temp
9405 ;;      negc   temp,dest
9406 ;;   This is better than xoring compare result with 1 because it does
9407 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9408 ;;   loop.
9409
9410 (define_expand "movnegt"
9411   [(set (match_dup 1) (const_int -1))
9412    (parallel [(set (match_operand:SI 0 "" "")
9413                    (neg:SI (plus:SI (reg:SI T_REG)
9414                                     (match_dup 1))))
9415               (set (reg:SI T_REG)
9416                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9417                           (const_int 0)))])]
9418   ""
9419   "
9420 {
9421   operands[1] = gen_reg_rtx (SImode);
9422 }")
9423
9424
9425 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9426 ;; This prevents a regression that occurred when we switched from xor to
9427 ;; mov/neg for sne.
9428
9429 (define_split
9430   [(set (match_operand:SI 0 "arith_reg_dest" "")
9431         (plus:SI (reg:SI T_REG)
9432                  (const_int -1)))]
9433   "TARGET_SH1"
9434   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9435    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9436   "")
9437
9438 (define_expand "cstoresf4"
9439   [(set (match_operand:SI 0 "register_operand" "=r")
9440         (match_operator:SI 1 "sh_float_comparison_operator"
9441          [(match_operand:SF 2 "arith_operand" "")
9442           (match_operand:SF 3 "arith_operand" "")]))]
9443   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9444   "if (TARGET_SHMEDIA)
9445      {
9446        emit_insn (gen_cstore4_media (operands[0], operands[1],
9447                                      operands[2], operands[3]));
9448        DONE;
9449      }
9450
9451    if (! currently_expanding_to_rtl)
9452      FAIL;
9453    
9454    sh_emit_compare_and_set (operands, SFmode);
9455    DONE;
9456 ")
9457
9458 (define_expand "cstoredf4"
9459   [(set (match_operand:SI 0 "register_operand" "=r")
9460         (match_operator:SI 1 "sh_float_comparison_operator"
9461          [(match_operand:DF 2 "arith_operand" "")
9462           (match_operand:DF 3 "arith_operand" "")]))]
9463   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9464   "if (TARGET_SHMEDIA)
9465      {
9466        emit_insn (gen_cstore4_media (operands[0], operands[1],
9467                                      operands[2], operands[3]));
9468        DONE;
9469      }
9470
9471     if (! currently_expanding_to_rtl)
9472       FAIL;
9473    
9474    sh_emit_compare_and_set (operands, DFmode);
9475    DONE;
9476 ")
9477
9478
9479 ;; -------------------------------------------------------------------------
9480 ;; Instructions to cope with inline literal tables
9481 ;; -------------------------------------------------------------------------
9482
9483 ; 2 byte integer in line
9484
9485 (define_insn "consttable_2"
9486  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9487                     (match_operand 1 "" "")]
9488                    UNSPECV_CONST2)]
9489  ""
9490  "*
9491 {
9492   if (operands[1] != const0_rtx)
9493     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9494   return \"\";
9495 }"
9496  [(set_attr "length" "2")
9497  (set_attr "in_delay_slot" "no")])
9498
9499 ; 4 byte integer in line
9500
9501 (define_insn "consttable_4"
9502  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9503                     (match_operand 1 "" "")]
9504                    UNSPECV_CONST4)]
9505  ""
9506  "*
9507 {
9508   if (operands[1] != const0_rtx)
9509     {
9510       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9511       mark_symbol_refs_as_used (operands[0]);
9512     }
9513   return \"\";
9514 }"
9515  [(set_attr "length" "4")
9516   (set_attr "in_delay_slot" "no")])
9517
9518 ; 8 byte integer in line
9519
9520 (define_insn "consttable_8"
9521  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9522                     (match_operand 1 "" "")]
9523                    UNSPECV_CONST8)]
9524  ""
9525  "*
9526 {
9527   if (operands[1] != const0_rtx)
9528     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9529   return \"\";
9530 }"
9531  [(set_attr "length" "8")
9532   (set_attr "in_delay_slot" "no")])
9533
9534 ; 4 byte floating point
9535
9536 (define_insn "consttable_sf"
9537  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9538                     (match_operand 1 "" "")]
9539                    UNSPECV_CONST4)]
9540  ""
9541  "*
9542 {
9543   if (operands[1] != const0_rtx)
9544     {
9545       REAL_VALUE_TYPE d;
9546       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9547       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9548     }
9549   return \"\";
9550 }"
9551  [(set_attr "length" "4")
9552   (set_attr "in_delay_slot" "no")])
9553
9554 ; 8 byte floating point
9555
9556 (define_insn "consttable_df"
9557  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9558                     (match_operand 1 "" "")]
9559                    UNSPECV_CONST8)]
9560  ""
9561  "*
9562 {
9563   if (operands[1] != const0_rtx)
9564     {
9565       REAL_VALUE_TYPE d;
9566       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9567       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9568     }
9569   return \"\";
9570 }"
9571  [(set_attr "length" "8")
9572   (set_attr "in_delay_slot" "no")])
9573
9574 ;; Alignment is needed for some constant tables; it may also be added for
9575 ;; Instructions at the start of loops, or after unconditional branches.
9576 ;; ??? We would get more accurate lengths if we did instruction
9577 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9578 ;; here is too conservative.
9579
9580 ; align to a two byte boundary
9581
9582 (define_expand "align_2"
9583  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9584  ""
9585  "")
9586
9587 ; align to a four byte boundary
9588 ;; align_4 and align_log are instructions for the starts of loops, or
9589 ;; after unconditional branches, which may take up extra room.
9590
9591 (define_expand "align_4"
9592  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9593  ""
9594  "")
9595
9596 ; align to a cache line boundary
9597
9598 (define_insn "align_log"
9599  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9600  ""
9601  ""
9602  [(set_attr "length" "0")
9603   (set_attr "in_delay_slot" "no")])
9604
9605 ; emitted at the end of the literal table, used to emit the
9606 ; 32bit branch labels if needed.
9607
9608 (define_insn "consttable_end"
9609   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9610   ""
9611   "* return output_jump_label_table ();"
9612   [(set_attr "in_delay_slot" "no")])
9613
9614 ; emitted at the end of the window in the literal table.
9615
9616 (define_insn "consttable_window_end"
9617   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9618   ""
9619   ""
9620   [(set_attr "length" "0")
9621    (set_attr "in_delay_slot" "no")])
9622
9623 ;; -------------------------------------------------------------------------
9624 ;; Misc
9625 ;; -------------------------------------------------------------------------
9626
9627 ;; String/block move insn.
9628
9629 (define_expand "movmemsi"
9630   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9631                    (mem:BLK (match_operand:BLK 1 "" "")))
9632               (use (match_operand:SI 2 "nonmemory_operand" ""))
9633               (use (match_operand:SI 3 "immediate_operand" ""))
9634               (clobber (reg:SI PR_REG))
9635               (clobber (reg:SI R4_REG))
9636               (clobber (reg:SI R5_REG))
9637               (clobber (reg:SI R0_REG))])]
9638   "TARGET_SH1 && ! TARGET_SH5"
9639   "
9640 {
9641   if(expand_block_move (operands))
9642      DONE;
9643   else FAIL;
9644 }")
9645
9646 (define_insn "block_move_real"
9647   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9648                    (mem:BLK (reg:SI R5_REG)))
9649               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9650               (clobber (reg:SI PR_REG))
9651               (clobber (reg:SI R0_REG))])]
9652   "TARGET_SH1 && ! TARGET_HARD_SH4"
9653   "jsr  @%0%#"
9654   [(set_attr "type" "sfunc")
9655    (set_attr "needs_delay_slot" "yes")])
9656
9657 (define_insn "block_lump_real"
9658   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9659                    (mem:BLK (reg:SI R5_REG)))
9660               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9661               (use (reg:SI R6_REG))
9662               (clobber (reg:SI PR_REG))
9663               (clobber (reg:SI T_REG))
9664               (clobber (reg:SI R4_REG))
9665               (clobber (reg:SI R5_REG))
9666               (clobber (reg:SI R6_REG))
9667               (clobber (reg:SI R0_REG))])]
9668   "TARGET_SH1 && ! TARGET_HARD_SH4"
9669   "jsr  @%0%#"
9670   [(set_attr "type" "sfunc")
9671    (set_attr "needs_delay_slot" "yes")])
9672
9673 (define_insn "block_move_real_i4"
9674   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9675                    (mem:BLK (reg:SI R5_REG)))
9676               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9677               (clobber (reg:SI PR_REG))
9678               (clobber (reg:SI R0_REG))
9679               (clobber (reg:SI R1_REG))
9680               (clobber (reg:SI R2_REG))])]
9681   "TARGET_HARD_SH4"
9682   "jsr  @%0%#"
9683   [(set_attr "type" "sfunc")
9684    (set_attr "needs_delay_slot" "yes")])
9685
9686 (define_insn "block_lump_real_i4"
9687   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9688                    (mem:BLK (reg:SI R5_REG)))
9689               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9690               (use (reg:SI R6_REG))
9691               (clobber (reg:SI PR_REG))
9692               (clobber (reg:SI T_REG))
9693               (clobber (reg:SI R4_REG))
9694               (clobber (reg:SI R5_REG))
9695               (clobber (reg:SI R6_REG))
9696               (clobber (reg:SI R0_REG))
9697               (clobber (reg:SI R1_REG))
9698               (clobber (reg:SI R2_REG))
9699               (clobber (reg:SI R3_REG))])]
9700   "TARGET_HARD_SH4"
9701   "jsr  @%0%#"
9702   [(set_attr "type" "sfunc")
9703    (set_attr "needs_delay_slot" "yes")])
9704 \f
9705 ;; -------------------------------------------------------------------------
9706 ;; Floating point instructions.
9707 ;; -------------------------------------------------------------------------
9708
9709 ;; ??? All patterns should have a type attribute.
9710
9711 (define_expand "movpsi"
9712   [(set (match_operand:PSI 0 "register_operand" "")
9713         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9714   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9715   "")
9716
9717 ;; The c / m alternative is a fake to guide reload to load directly into
9718 ;; fpscr, since reload doesn't know how to use post-increment.
9719 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9720 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9721 ;; predicate after reload.
9722 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9723 ;; like a mac -> gpr move.
9724 (define_insn "fpu_switch"
9725   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9726         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9727   "TARGET_SH2E
9728    && (! reload_completed
9729        || true_regnum (operands[0]) != FPSCR_REG
9730        || !MEM_P (operands[1])
9731        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9732   "@
9733         ! precision stays the same
9734         lds.l   %1,fpscr
9735         mov.l   %1,%0
9736         #
9737         lds     %1,fpscr
9738         mov     %1,%0
9739         mov.l   %1,%0
9740         sts     fpscr,%0
9741         sts.l   fpscr,%0"
9742   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9743    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9744
9745 (define_peephole2
9746   [(set (reg:PSI FPSCR_REG)
9747         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9748   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9749   [(const_int 0)]
9750 {
9751   rtx fpscr, mem, new_insn;
9752
9753   fpscr = SET_DEST (PATTERN (curr_insn));
9754   mem = SET_SRC (PATTERN (curr_insn));
9755   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9756
9757   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9758   add_reg_note (new_insn, REG_INC, operands[0]);
9759   DONE;
9760 })
9761
9762 (define_split
9763   [(set (reg:PSI FPSCR_REG)
9764         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9765   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9766    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9767   [(const_int 0)]
9768 {
9769   rtx fpscr, mem, new_insn;
9770
9771   fpscr = SET_DEST (PATTERN (curr_insn));
9772   mem = SET_SRC (PATTERN (curr_insn));
9773   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9774
9775   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9776   add_reg_note (new_insn, REG_INC, operands[0]);
9777
9778   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9779     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9780   DONE;
9781 })
9782
9783 ;; ??? This uses the fp unit, but has no type indicating that.
9784 ;; If we did that, this would either give a bogus latency or introduce
9785 ;; a bogus FIFO constraint.
9786 ;; Since this insn is currently only used for prologues/epilogues,
9787 ;; it is probably best to claim no function unit, which matches the
9788 ;; current setting.
9789 (define_insn "toggle_sz"
9790   [(set (reg:PSI FPSCR_REG)
9791         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9792   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9793   "fschg"
9794   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9795
9796 ;; There's no way we can use it today, since optimize mode switching
9797 ;; doesn't enable us to know from which mode we're switching to the
9798 ;; mode it requests, to tell whether we can use a relative mode switch
9799 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9800 ;; memory).
9801 (define_insn "toggle_pr"
9802   [(set (reg:PSI FPSCR_REG)
9803         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9804   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9805   "fpchg"
9806   [(set_attr "type" "fpscr_toggle")])
9807
9808 (define_expand "addsf3"
9809   [(set (match_operand:SF 0 "arith_reg_operand" "")
9810         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9811                  (match_operand:SF 2 "arith_reg_operand" "")))]
9812   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9813   "
9814 {
9815   if (TARGET_SH2E)
9816     {
9817       expand_sf_binop (&gen_addsf3_i, operands);
9818       DONE;
9819     }
9820 }")
9821
9822 (define_insn "*addsf3_media"
9823   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9824         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9825                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9826   "TARGET_SHMEDIA_FPU"
9827   "fadd.s       %1, %2, %0"
9828   [(set_attr "type" "fparith_media")])
9829
9830 (define_insn_and_split "unary_sf_op"
9831   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9832         (vec_select:V2SF
9833          (vec_concat:V2SF
9834           (vec_select:SF
9835            (match_dup 0)
9836            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9837           (match_operator:SF 2 "unary_float_operator"
9838             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9839                             (parallel [(match_operand 4
9840                                         "const_int_operand" "n")]))]))
9841          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9842   "TARGET_SHMEDIA_FPU"
9843   "#"
9844   "TARGET_SHMEDIA_FPU && reload_completed"
9845   [(set (match_dup 5) (match_dup 6))]
9846   "
9847 {
9848   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9849   rtx op1 = gen_rtx_REG (SFmode,
9850                          (true_regnum (operands[1])
9851                           + (INTVAL (operands[4]) ^ endian)));
9852
9853   operands[7] = gen_rtx_REG (SFmode,
9854                              (true_regnum (operands[0])
9855                               + (INTVAL (operands[3]) ^ endian)));
9856   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9857 }"
9858   [(set_attr "type" "fparith_media")])
9859
9860 (define_insn_and_split "binary_sf_op0"
9861   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9862         (vec_concat:V2SF
9863           (match_operator:SF 3 "binary_float_operator"
9864             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9865                             (parallel [(const_int 0)]))
9866              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9867                             (parallel [(const_int 0)]))])
9868           (vec_select:SF
9869            (match_dup 0)
9870            (parallel [(const_int 1)]))))]
9871   "TARGET_SHMEDIA_FPU"
9872   "#"
9873   "&& reload_completed"
9874   [(set (match_dup 4) (match_dup 5))]
9875   "
9876 {
9877   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9878   rtx op1 = gen_rtx_REG (SFmode,
9879                          true_regnum (operands[1]) + endian);
9880   rtx op2 = gen_rtx_REG (SFmode,
9881                          true_regnum (operands[2]) + endian);
9882
9883   operands[4] = gen_rtx_REG (SFmode,
9884                              true_regnum (operands[0]) + endian);
9885   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9886 }"
9887   [(set_attr "type" "fparith_media")])
9888
9889 (define_insn_and_split "binary_sf_op1"
9890   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9891         (vec_concat:V2SF
9892           (vec_select:SF
9893            (match_dup 0)
9894            (parallel [(const_int 0)]))
9895           (match_operator:SF 3 "binary_float_operator"
9896             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9897                             (parallel [(const_int 1)]))
9898              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9899                             (parallel [(const_int 1)]))])))]
9900   "TARGET_SHMEDIA_FPU"
9901   "#"
9902   "&& reload_completed"
9903   [(set (match_dup 4) (match_dup 5))]
9904   "
9905 {
9906   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9907   rtx op1 = gen_rtx_REG (SFmode,
9908                          true_regnum (operands[1]) + (1 ^ endian));
9909   rtx op2 = gen_rtx_REG (SFmode,
9910                          true_regnum (operands[2]) + (1 ^ endian));
9911
9912   operands[4] = gen_rtx_REG (SFmode,
9913                              true_regnum (operands[0]) + (1 ^ endian));
9914   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9915 }"
9916   [(set_attr "type" "fparith_media")])
9917
9918 (define_insn "addsf3_i"
9919   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9920         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9921                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9922    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9923   "TARGET_SH2E"
9924   "fadd %2,%0"
9925   [(set_attr "type" "fp")
9926    (set_attr "fp_mode" "single")])
9927
9928 (define_expand "subsf3"
9929   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9930         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9931                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9932   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9933   "
9934 {
9935   if (TARGET_SH2E)
9936     {
9937       expand_sf_binop (&gen_subsf3_i, operands);
9938       DONE;
9939     }
9940 }")
9941
9942 (define_insn "*subsf3_media"
9943   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9944         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9945                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9946   "TARGET_SHMEDIA_FPU"
9947   "fsub.s       %1, %2, %0"
9948   [(set_attr "type" "fparith_media")])
9949
9950 (define_insn "subsf3_i"
9951   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9952         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9953                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9954    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9955   "TARGET_SH2E"
9956   "fsub %2,%0"
9957   [(set_attr "type" "fp")
9958    (set_attr "fp_mode" "single")])
9959
9960 (define_expand "mulsf3"
9961   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9962         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9963                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9964   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9965   "")
9966
9967 (define_insn "*mulsf3_media"
9968   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9969         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9970                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9971   "TARGET_SHMEDIA_FPU"
9972   "fmul.s       %1, %2, %0"
9973   [(set_attr "type" "fparith_media")])
9974
9975 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9976 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
9977 ;; we start out with a mulsf pattern that does not depend on fpscr.
9978 ;; This is split after combine to introduce the dependency, in order to
9979 ;; get mode switching and scheduling right.
9980 (define_insn_and_split "mulsf3_ie"
9981   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9982         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9983                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9984   "TARGET_SH2E"
9985   "fmul %2,%0"
9986   "TARGET_SH4 || TARGET_SH2A_SINGLE"
9987   [(const_int 0)]
9988   "
9989 {
9990   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9991              get_fpscr_rtx ()));
9992   DONE;
9993 }"
9994   [(set_attr "type" "fp")])
9995
9996 (define_insn "mulsf3_i4"
9997   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9998         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9999                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10000    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10001   "TARGET_SH2E"
10002   "fmul %2,%0"
10003   [(set_attr "type" "fp")
10004    (set_attr "fp_mode" "single")])
10005
10006 (define_insn "mac_media"
10007   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10008         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10009                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10010                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10011   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10012   "fmac.s %1, %2, %0"
10013   [(set_attr "type" "fparith_media")])
10014
10015 (define_insn "*macsf3"
10016   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10017         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10018                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10019                  (match_operand:SF 3 "arith_reg_operand" "0")))
10020    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10021   "TARGET_SH2E && TARGET_FMAC"
10022   "fmac fr0,%2,%0"
10023   [(set_attr "type" "fp")
10024    (set_attr "fp_mode" "single")])
10025
10026 (define_expand "divsf3"
10027   [(set (match_operand:SF 0 "arith_reg_operand" "")
10028         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10029                 (match_operand:SF 2 "arith_reg_operand" "")))]
10030   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10031   "
10032 {
10033   if (TARGET_SH2E)
10034     {
10035       expand_sf_binop (&gen_divsf3_i, operands);
10036       DONE;
10037     }
10038 }")
10039
10040 (define_insn "*divsf3_media"
10041   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10042         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10043                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10044   "TARGET_SHMEDIA_FPU"
10045   "fdiv.s       %1, %2, %0"
10046   [(set_attr "type" "fdiv_media")])
10047
10048 (define_insn "divsf3_i"
10049   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10050         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10051                  (match_operand:SF 2 "arith_reg_operand" "f")))
10052    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10053   "TARGET_SH2E"
10054   "fdiv %2,%0"
10055   [(set_attr "type" "fdiv")
10056    (set_attr "fp_mode" "single")])
10057
10058 (define_insn "floatdisf2"
10059   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10060         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10061   "TARGET_SHMEDIA_FPU"
10062   "float.qs %1, %0"
10063   [(set_attr "type" "fpconv_media")])
10064
10065 (define_expand "floatsisf2"
10066   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10067         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10068   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10069   "
10070 {
10071   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10072     {
10073       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10074       DONE;
10075     }
10076 }")
10077
10078 (define_insn "*floatsisf2_media"
10079   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10080         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10081   "TARGET_SHMEDIA_FPU"
10082   "float.ls     %1, %0"
10083   [(set_attr "type" "fpconv_media")])
10084
10085 (define_insn "floatsisf2_i4"
10086   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10087         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10088    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10089   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10090   "float        %1,%0"
10091   [(set_attr "type" "fp")
10092    (set_attr "fp_mode" "single")])
10093
10094 (define_insn "*floatsisf2_ie"
10095   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10096         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10097   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10098   "float        %1,%0"
10099   [(set_attr "type" "fp")])
10100
10101 (define_insn "fix_truncsfdi2"
10102   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10103         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10104   "TARGET_SHMEDIA_FPU"
10105   "ftrc.sq %1, %0"
10106   [(set_attr "type" "fpconv_media")])
10107
10108 (define_expand "fix_truncsfsi2"
10109   [(set (match_operand:SI 0 "fpul_operand" "=y")
10110         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10111   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10112   "
10113 {
10114   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10115     {
10116       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10117       DONE;
10118     }
10119 }")
10120
10121 (define_insn "*fix_truncsfsi2_media"
10122   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10123         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10124   "TARGET_SHMEDIA_FPU"
10125   "ftrc.sl      %1, %0"
10126   [(set_attr "type" "fpconv_media")])
10127
10128 (define_insn "fix_truncsfsi2_i4"
10129   [(set (match_operand:SI 0 "fpul_operand" "=y")
10130         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10131    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10132   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10133   "ftrc %1,%0"
10134   [(set_attr "type" "ftrc_s")
10135    (set_attr "fp_mode" "single")])
10136
10137 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10138 ;; fix_truncsfsi2_i4.
10139 ;; (define_insn "fix_truncsfsi2_i4_2"
10140 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10141 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10142 ;;   (use (reg:PSI FPSCR_REG))
10143 ;;   (clobber (reg:SI FPUL_REG))]
10144 ;;  "TARGET_SH4"
10145 ;;  "#"
10146 ;;  [(set_attr "length" "4")
10147 ;;   (set_attr "fp_mode" "single")])
10148
10149 ;;(define_split
10150 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10151 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10152 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10153 ;;   (clobber (reg:SI FPUL_REG))]
10154 ;;  "TARGET_SH4"
10155 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10156 ;;            (use (match_dup 2))])
10157 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10158
10159 (define_insn "*fixsfsi"
10160   [(set (match_operand:SI 0 "fpul_operand" "=y")
10161         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10162   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10163   "ftrc %1,%0"
10164   [(set_attr "type" "fp")])
10165
10166 (define_insn "cmpgtsf_t"
10167   [(set (reg:SI T_REG)
10168         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10169                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10170   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10171   "fcmp/gt      %1,%0"
10172   [(set_attr "type" "fp_cmp")
10173    (set_attr "fp_mode" "single")])
10174
10175 (define_insn "cmpeqsf_t"
10176   [(set (reg:SI T_REG)
10177         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10178                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10179   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10180   "fcmp/eq      %1,%0"
10181   [(set_attr "type" "fp_cmp")
10182    (set_attr "fp_mode" "single")])
10183
10184 (define_insn "ieee_ccmpeqsf_t"
10185   [(set (reg:SI T_REG)
10186         (ior:SI (reg:SI T_REG)
10187                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10188                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10189   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10190   "* return output_ieee_ccmpeq (insn, operands);"
10191   [(set_attr "length" "4")])
10192
10193
10194 (define_insn "cmpgtsf_t_i4"
10195   [(set (reg:SI T_REG)
10196         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10197                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10198    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10199   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10200   "fcmp/gt      %1,%0"
10201   [(set_attr "type" "fp_cmp")
10202    (set_attr "fp_mode" "single")])
10203
10204 (define_insn "cmpeqsf_t_i4"
10205   [(set (reg:SI T_REG)
10206         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10207                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10208    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10209   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10210   "fcmp/eq      %1,%0"
10211   [(set_attr "type" "fp_cmp")
10212    (set_attr "fp_mode" "single")])
10213
10214 (define_insn "*ieee_ccmpeqsf_t_4"
10215   [(set (reg:SI T_REG)
10216         (ior:SI (reg:SI T_REG)
10217                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10218                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10219    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10220   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10221   "* return output_ieee_ccmpeq (insn, operands);"
10222   [(set_attr "length" "4")
10223    (set_attr "fp_mode" "single")])
10224
10225 (define_insn "cmpeqsf_media"
10226   [(set (match_operand:SI 0 "register_operand" "=r")
10227         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10228                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10229   "TARGET_SHMEDIA_FPU"
10230   "fcmpeq.s     %1, %2, %0"
10231   [(set_attr "type" "fcmp_media")])
10232
10233 (define_insn "cmpgtsf_media"
10234   [(set (match_operand:SI 0 "register_operand" "=r")
10235         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10236                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10237   "TARGET_SHMEDIA_FPU"
10238   "fcmpgt.s     %1, %2, %0"
10239   [(set_attr "type" "fcmp_media")])
10240
10241 (define_insn "cmpgesf_media"
10242   [(set (match_operand:SI 0 "register_operand" "=r")
10243         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10244                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10245   "TARGET_SHMEDIA_FPU"
10246   "fcmpge.s     %1, %2, %0"
10247   [(set_attr "type" "fcmp_media")])
10248
10249 (define_insn "cmpunsf_media"
10250   [(set (match_operand:SI 0 "register_operand" "=r")
10251         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10252                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10253   "TARGET_SHMEDIA_FPU"
10254   "fcmpun.s     %1, %2, %0"
10255   [(set_attr "type" "fcmp_media")])
10256
10257 (define_expand "cbranchsf4"
10258   [(set (pc)
10259         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10260                        [(match_operand:SF 1 "arith_operand" "")
10261                         (match_operand:SF 2 "arith_operand" "")])
10262                       (match_operand 3 "" "")
10263                       (pc)))]
10264   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10265   "
10266 {
10267   if (TARGET_SHMEDIA)
10268     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10269                                           operands[3]));
10270   else
10271     sh_emit_compare_and_branch (operands, SFmode);
10272   DONE;
10273 }")
10274
10275 (define_expand "negsf2"
10276   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10277         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10278   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10279   "
10280 {
10281   if (TARGET_SH2E)
10282     {
10283       expand_sf_unop (&gen_negsf2_i, operands);
10284       DONE;
10285     }
10286 }")
10287
10288 (define_insn "*negsf2_media"
10289   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10290         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10291   "TARGET_SHMEDIA_FPU"
10292   "fneg.s       %1, %0"
10293   [(set_attr "type" "fmove_media")])
10294
10295 (define_insn "negsf2_i"
10296   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10297         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10298    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10299   "TARGET_SH2E"
10300   "fneg %0"
10301   [(set_attr "type" "fmove")
10302    (set_attr "fp_mode" "single")])
10303
10304 (define_expand "sqrtsf2"
10305   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10306         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10307   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10308   "
10309 {
10310   if (TARGET_SH3E)
10311     {
10312       expand_sf_unop (&gen_sqrtsf2_i, operands);
10313       DONE;
10314     }
10315 }")
10316
10317 (define_insn "*sqrtsf2_media"
10318   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10319         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10320   "TARGET_SHMEDIA_FPU"
10321   "fsqrt.s      %1, %0"
10322   [(set_attr "type" "fdiv_media")])
10323
10324 (define_insn "sqrtsf2_i"
10325   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10326         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10327    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10328   "TARGET_SH3E"
10329   "fsqrt        %0"
10330   [(set_attr "type" "fdiv")
10331    (set_attr "fp_mode" "single")])
10332
10333 (define_insn "rsqrtsf2"
10334   [(set (match_operand:SF 0 "register_operand" "=f")
10335         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10336                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10337    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10338   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10339    && operands[1] == CONST1_RTX (SFmode)"
10340   "fsrra        %0"
10341   [(set_attr "type" "fsrra")
10342    (set_attr "fp_mode" "single")])
10343
10344 (define_insn "fsca"
10345   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10346         (vec_concat:V2SF
10347          (unspec:SF [(mult:SF
10348                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10349                       (match_operand:SF 2 "immediate_operand" "i"))
10350                     ] UNSPEC_FSINA)
10351          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10352                     ] UNSPEC_FCOSA)))
10353    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10354   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10355    && operands[2] == sh_fsca_int2sf ()"
10356   "fsca fpul,%d0"
10357   [(set_attr "type" "fsca")
10358    (set_attr "fp_mode" "single")])
10359
10360 (define_expand "sinsf2"
10361   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10362         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10363                    UNSPEC_FSINA))]
10364   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10365   "
10366 {
10367   rtx scaled = gen_reg_rtx (SFmode);
10368   rtx truncated = gen_reg_rtx (SImode);
10369   rtx fsca = gen_reg_rtx (V2SFmode);
10370   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10371
10372   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10373   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10374   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10375                           get_fpscr_rtx ()));
10376   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10377   DONE;
10378 }")
10379
10380 (define_expand "cossf2"
10381   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10382         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10383                    UNSPEC_FCOSA))]
10384   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10385   "
10386 {
10387   rtx scaled = gen_reg_rtx (SFmode);
10388   rtx truncated = gen_reg_rtx (SImode);
10389   rtx fsca = gen_reg_rtx (V2SFmode);
10390   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10391
10392   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10393   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10394   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10395                           get_fpscr_rtx ()));
10396   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10397   DONE;
10398 }")
10399
10400 (define_expand "sindf2"
10401   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10402         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10403                    UNSPEC_FSINA))]
10404   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10405   "
10406 {
10407   rtx scaled = gen_reg_rtx (DFmode);
10408   rtx truncated = gen_reg_rtx (SImode);
10409   rtx fsca = gen_reg_rtx (V2SFmode);
10410   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10411   rtx sfresult = gen_reg_rtx (SFmode);
10412
10413   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10414   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10415   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10416                           get_fpscr_rtx ()));
10417   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10418   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10419   DONE;
10420 }")
10421
10422 (define_expand "cosdf2"
10423   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10424         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10425                    UNSPEC_FCOSA))]
10426   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10427   "
10428 {
10429   rtx scaled = gen_reg_rtx (DFmode);
10430   rtx truncated = gen_reg_rtx (SImode);
10431   rtx fsca = gen_reg_rtx (V2SFmode);
10432   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10433   rtx sfresult = gen_reg_rtx (SFmode);
10434
10435   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10436   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10437   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10438                           get_fpscr_rtx ()));
10439   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10440   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10441   DONE;
10442 }")
10443
10444 (define_expand "abssf2"
10445   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10446         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10447   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10448   "
10449 {
10450   if (TARGET_SH2E)
10451     {
10452       expand_sf_unop (&gen_abssf2_i, operands);
10453       DONE;
10454     }
10455 }")
10456
10457 (define_insn "*abssf2_media"
10458   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10459         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10460   "TARGET_SHMEDIA_FPU"
10461   "fabs.s       %1, %0"
10462   [(set_attr "type" "fmove_media")])
10463
10464 (define_insn "abssf2_i"
10465   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10466         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10467    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10468   "TARGET_SH2E"
10469   "fabs %0"
10470   [(set_attr "type" "fmove")
10471    (set_attr "fp_mode" "single")])
10472
10473 (define_expand "adddf3"
10474   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10475         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10476                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10477   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10478   "
10479 {
10480   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10481     {
10482       expand_df_binop (&gen_adddf3_i, operands);
10483       DONE;
10484     }
10485 }")
10486
10487 (define_insn "*adddf3_media"
10488   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10489         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10490                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10491   "TARGET_SHMEDIA_FPU"
10492   "fadd.d       %1, %2, %0"
10493   [(set_attr "type" "dfparith_media")])
10494
10495 (define_insn "adddf3_i"
10496   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10497         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10498                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10499    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10500   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10501   "fadd %2,%0"
10502   [(set_attr "type" "dfp_arith")
10503    (set_attr "fp_mode" "double")])
10504
10505 (define_expand "subdf3"
10506   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10507         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10508                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10509   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10510   "
10511 {
10512   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10513     {
10514       expand_df_binop (&gen_subdf3_i, operands);
10515       DONE;
10516     }
10517 }")
10518
10519 (define_insn "*subdf3_media"
10520   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10521         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10522                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10523   "TARGET_SHMEDIA_FPU"
10524   "fsub.d       %1, %2, %0"
10525   [(set_attr "type" "dfparith_media")])
10526
10527 (define_insn "subdf3_i"
10528   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10529         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10530                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10531    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10532   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10533   "fsub %2,%0"
10534   [(set_attr "type" "dfp_arith")
10535    (set_attr "fp_mode" "double")])
10536
10537 (define_expand "muldf3"
10538   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10539         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10540                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10541   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10542   "
10543 {
10544   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10545     {
10546       expand_df_binop (&gen_muldf3_i, operands);
10547       DONE;
10548     }
10549 }")
10550
10551 (define_insn "*muldf3_media"
10552   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10553         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10554                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10555   "TARGET_SHMEDIA_FPU"
10556   "fmul.d       %1, %2, %0"
10557   [(set_attr "type" "dfmul_media")])
10558
10559 (define_insn "muldf3_i"
10560   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10561         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10562                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10563    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10564   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10565   "fmul %2,%0"
10566   [(set_attr "type" "dfp_mul")
10567    (set_attr "fp_mode" "double")])
10568
10569 (define_expand "divdf3"
10570   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10571         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10572                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10573   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10574   "
10575 {
10576   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10577     {
10578       expand_df_binop (&gen_divdf3_i, operands);
10579       DONE;
10580     }
10581 }")
10582
10583 (define_insn "*divdf3_media"
10584   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10585         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10586                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10587   "TARGET_SHMEDIA_FPU"
10588   "fdiv.d       %1, %2, %0"
10589   [(set_attr "type" "dfdiv_media")])
10590
10591 (define_insn "divdf3_i"
10592   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10593         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10594                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10595    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10596   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10597   "fdiv %2,%0"
10598   [(set_attr "type" "dfdiv")
10599    (set_attr "fp_mode" "double")])
10600
10601 (define_insn "floatdidf2"
10602   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10603         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10604   "TARGET_SHMEDIA_FPU"
10605   "float.qd     %1, %0"
10606   [(set_attr "type" "dfpconv_media")])
10607
10608 (define_expand "floatsidf2"
10609   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10610         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10611   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10612   "
10613 {
10614   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10615     {
10616       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10617                                       get_fpscr_rtx ()));
10618       DONE;
10619     }
10620 }")
10621
10622 (define_insn "*floatsidf2_media"
10623   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10624         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10625   "TARGET_SHMEDIA_FPU"
10626   "float.ld     %1, %0"
10627   [(set_attr "type" "dfpconv_media")])
10628
10629 (define_insn "floatsidf2_i"
10630   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10632    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10633   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10634   "float        %1,%0"
10635   [(set_attr "type" "dfp_conv")
10636    (set_attr "fp_mode" "double")])
10637
10638 (define_insn "fix_truncdfdi2"
10639   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10640         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10641   "TARGET_SHMEDIA_FPU"
10642   "ftrc.dq      %1, %0"
10643   [(set_attr "type" "dfpconv_media")])
10644
10645 (define_expand "fix_truncdfsi2"
10646   [(set (match_operand:SI 0 "fpul_operand" "")
10647         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10648   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10649   "
10650 {
10651   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10652     {
10653       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10654                                           get_fpscr_rtx ()));
10655       DONE;
10656     }
10657 }")
10658
10659 (define_insn "*fix_truncdfsi2_media"
10660   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10661         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10662   "TARGET_SHMEDIA_FPU"
10663   "ftrc.dl      %1, %0"
10664   [(set_attr "type" "dfpconv_media")])
10665
10666 (define_insn "fix_truncdfsi2_i"
10667   [(set (match_operand:SI 0 "fpul_operand" "=y")
10668         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10669    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10670   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10671   "ftrc %1,%0"
10672   [(set_attr "type" "dfp_conv")
10673    (set_attr "dfp_comp" "no")
10674    (set_attr "fp_mode" "double")])
10675
10676 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10677 ;; fix_truncdfsi2_i.
10678 ;; (define_insn "fix_truncdfsi2_i4"
10679 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10680 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10681 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10682 ;;    (clobber (reg:SI FPUL_REG))]
10683 ;;   "TARGET_SH4"
10684 ;;   "#"
10685 ;;   [(set_attr "length" "4")
10686 ;;    (set_attr "fp_mode" "double")])
10687 ;;
10688 ;; (define_split
10689 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10690 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10691 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10692 ;;    (clobber (reg:SI FPUL_REG))]
10693 ;;   "TARGET_SH4"
10694 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10695 ;;            (use (match_dup 2))])
10696 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10697
10698 (define_insn "cmpgtdf_t"
10699   [(set (reg:SI T_REG)
10700         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10701                (match_operand:DF 1 "arith_reg_operand" "f")))
10702    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10703   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10704   "fcmp/gt      %1,%0"
10705   [(set_attr "type" "dfp_cmp")
10706    (set_attr "fp_mode" "double")])
10707
10708 (define_insn "cmpeqdf_t"
10709   [(set (reg:SI T_REG)
10710         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10711                (match_operand:DF 1 "arith_reg_operand" "f")))
10712    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10713   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10714   "fcmp/eq      %1,%0"
10715   [(set_attr "type" "dfp_cmp")
10716    (set_attr "fp_mode" "double")])
10717
10718 (define_insn "*ieee_ccmpeqdf_t"
10719   [(set (reg:SI T_REG)
10720         (ior:SI (reg:SI T_REG)
10721                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10722                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10723    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10724   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10725   "* return output_ieee_ccmpeq (insn, operands);"
10726   [(set_attr "length" "4")
10727    (set_attr "fp_mode" "double")])
10728
10729 (define_insn "cmpeqdf_media"
10730   [(set (match_operand:SI 0 "register_operand" "=r")
10731         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10732                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10733   "TARGET_SHMEDIA_FPU"
10734   "fcmpeq.d     %1,%2,%0"
10735   [(set_attr "type" "fcmp_media")])
10736
10737 (define_insn "cmpgtdf_media"
10738   [(set (match_operand:SI 0 "register_operand" "=r")
10739         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10740                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10741   "TARGET_SHMEDIA_FPU"
10742   "fcmpgt.d     %1,%2,%0"
10743   [(set_attr "type" "fcmp_media")])
10744
10745 (define_insn "cmpgedf_media"
10746   [(set (match_operand:SI 0 "register_operand" "=r")
10747         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10748                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10749   "TARGET_SHMEDIA_FPU"
10750   "fcmpge.d     %1,%2,%0"
10751   [(set_attr "type" "fcmp_media")])
10752
10753 (define_insn "cmpundf_media"
10754   [(set (match_operand:SI 0 "register_operand" "=r")
10755         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10756                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10757   "TARGET_SHMEDIA_FPU"
10758   "fcmpun.d     %1,%2,%0"
10759   [(set_attr "type" "fcmp_media")])
10760
10761 (define_expand "cbranchdf4"
10762   [(set (pc)
10763         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10764                        [(match_operand:DF 1 "arith_operand" "")
10765                         (match_operand:DF 2 "arith_operand" "")])
10766                       (match_operand 3 "" "")
10767                       (pc)))]
10768   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10769   "
10770 {
10771   if (TARGET_SHMEDIA)
10772     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10773                                           operands[3]));
10774   else
10775     sh_emit_compare_and_branch (operands, DFmode);
10776   DONE;
10777 }")
10778
10779
10780 (define_expand "negdf2"
10781   [(set (match_operand:DF 0 "arith_reg_operand" "")
10782         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10783   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10784   "
10785 {
10786   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10787     {
10788       expand_df_unop (&gen_negdf2_i, operands);
10789       DONE;
10790     }
10791 }")
10792
10793 (define_insn "*negdf2_media"
10794   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10795         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10796   "TARGET_SHMEDIA_FPU"
10797   "fneg.d       %1, %0"
10798   [(set_attr "type" "fmove_media")])
10799
10800 (define_insn "negdf2_i"
10801   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10802         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10803    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10804   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10805   "fneg %0"
10806   [(set_attr "type" "fmove")
10807    (set_attr "fp_mode" "double")])
10808
10809 (define_expand "sqrtdf2"
10810   [(set (match_operand:DF 0 "arith_reg_operand" "")
10811         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10812   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10813   "
10814 {
10815   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10816     {
10817       expand_df_unop (&gen_sqrtdf2_i, operands);
10818       DONE;
10819     }
10820 }")
10821
10822 (define_insn "*sqrtdf2_media"
10823   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10824         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10825   "TARGET_SHMEDIA_FPU"
10826   "fsqrt.d      %1, %0"
10827   [(set_attr "type" "dfdiv_media")])
10828
10829 (define_insn "sqrtdf2_i"
10830   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10831         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10832    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10833   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10834   "fsqrt        %0"
10835   [(set_attr "type" "dfdiv")
10836    (set_attr "fp_mode" "double")])
10837
10838 (define_expand "absdf2"
10839   [(set (match_operand:DF 0 "arith_reg_operand" "")
10840         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10841   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10842   "
10843 {
10844   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10845     {
10846       expand_df_unop (&gen_absdf2_i, operands);
10847       DONE;
10848     }
10849 }")
10850
10851 (define_insn "*absdf2_media"
10852   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10853         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10854   "TARGET_SHMEDIA_FPU"
10855   "fabs.d       %1, %0"
10856   [(set_attr "type" "fmove_media")])
10857
10858 (define_insn "absdf2_i"
10859   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10860         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10861    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10862   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10863   "fabs %0"
10864   [(set_attr "type" "fmove")
10865    (set_attr "fp_mode" "double")])
10866
10867 (define_expand "extendsfdf2"
10868   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10869         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10870   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10871   "
10872 {
10873   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10874     {
10875       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10876                                         get_fpscr_rtx ()));
10877       DONE;
10878     }
10879 }")
10880
10881 (define_insn "*extendsfdf2_media"
10882   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10883         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10884   "TARGET_SHMEDIA_FPU"
10885   "fcnv.sd      %1, %0"
10886   [(set_attr "type" "dfpconv_media")])
10887
10888 (define_insn "extendsfdf2_i4"
10889   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10890         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10891    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10892   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10893   "fcnvsd  %1,%0"
10894   [(set_attr "type" "fp")
10895    (set_attr "fp_mode" "double")])
10896
10897 (define_expand "truncdfsf2"
10898   [(set (match_operand:SF 0 "fpul_operand" "")
10899         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10900   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10901   "
10902 {
10903   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10904     {
10905       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10906                                        get_fpscr_rtx ()));
10907       DONE;
10908     }
10909 }")
10910
10911 (define_insn "*truncdfsf2_media"
10912   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10913         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10914   "TARGET_SHMEDIA_FPU"
10915   "fcnv.ds      %1, %0"
10916   [(set_attr "type" "dfpconv_media")])
10917
10918 (define_insn "truncdfsf2_i4"
10919   [(set (match_operand:SF 0 "fpul_operand" "=y")
10920         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10921    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10922   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10923   "fcnvds  %1,%0"
10924   [(set_attr "type" "fp")
10925    (set_attr "fp_mode" "double")])
10926 \f
10927 ;; Bit field extract patterns.  These give better code for packed bitfields,
10928 ;; because they allow auto-increment addresses to be generated.
10929
10930 (define_expand "insv"
10931   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10932                          (match_operand:SI 1 "immediate_operand" "")
10933                          (match_operand:SI 2 "immediate_operand" ""))
10934         (match_operand:SI 3 "general_operand" ""))]
10935   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10936   "
10937 {
10938   rtx addr_target, orig_address, shift_reg, qi_val;
10939   HOST_WIDE_INT bitsize, size, v = 0;
10940   rtx x = operands[3];
10941
10942   if (TARGET_SH2A && TARGET_BITOPS
10943       && (satisfies_constraint_Sbw (operands[0])
10944           || satisfies_constraint_Sbv (operands[0]))
10945       && satisfies_constraint_M (operands[1])
10946       && satisfies_constraint_K03 (operands[2]))
10947     {
10948       if (satisfies_constraint_N (operands[3]))
10949         {
10950           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10951           DONE;
10952         }
10953       else if (satisfies_constraint_M (operands[3]))
10954         {
10955           emit_insn (gen_bset_m2a (operands[0], operands[2]));
10956           DONE;
10957         }
10958       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10959                 && satisfies_constraint_M (operands[1]))
10960         {
10961           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10962           DONE;
10963         }
10964       else if (REG_P (operands[3])
10965                && satisfies_constraint_M (operands[1]))
10966         {
10967           emit_insn (gen_bld_reg (operands[3], const0_rtx));
10968           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10969           DONE;
10970         }
10971     }
10972   /* ??? expmed doesn't care for non-register predicates.  */
10973   if (! memory_operand (operands[0], VOIDmode)
10974       || ! immediate_operand (operands[1], VOIDmode)
10975       || ! immediate_operand (operands[2], VOIDmode)
10976       || ! general_operand (x, VOIDmode))
10977     FAIL;
10978   /* If this isn't a 16 / 24 / 32 bit field, or if
10979      it doesn't start on a byte boundary, then fail.  */
10980   bitsize = INTVAL (operands[1]);
10981   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10982       || (INTVAL (operands[2]) % 8) != 0)
10983     FAIL;
10984
10985   size = bitsize / 8;
10986   orig_address = XEXP (operands[0], 0);
10987   shift_reg = gen_reg_rtx (SImode);
10988   if (CONST_INT_P (x))
10989     {
10990       v = INTVAL (x);
10991       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10992     }
10993   else
10994     {
10995       emit_insn (gen_movsi (shift_reg, operands[3]));
10996       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10997     }
10998   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10999
11000   operands[0] = replace_equiv_address (operands[0], addr_target);
11001   emit_insn (gen_movqi (operands[0], qi_val));
11002
11003   while (size -= 1)
11004     {
11005       if (CONST_INT_P (x))
11006         qi_val
11007           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11008       else
11009         {
11010           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11011           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11012         }
11013       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11014       emit_insn (gen_movqi (operands[0], qi_val));
11015     }
11016
11017   DONE;
11018 }")
11019
11020 (define_insn "movua"
11021   [(set (match_operand:SI 0 "register_operand" "=z")
11022         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11023                    UNSPEC_MOVUA))]
11024   "TARGET_SH4A_ARCH"
11025   "movua.l      %1,%0"
11026   [(set_attr "type" "movua")])
11027
11028 ;; We shouldn't need this, but cse replaces increments with references
11029 ;; to other regs before flow has a chance to create post_inc
11030 ;; addressing modes, and only postreload's cse_move2add brings the
11031 ;; increments back to a usable form.
11032 (define_peephole2
11033   [(set (match_operand:SI 0 "register_operand" "")
11034         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11035                          (const_int 32) (const_int 0)))
11036    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11037   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11038   [(set (match_operand:SI 0 "register_operand" "")
11039         (sign_extract:SI (mem:SI (post_inc:SI
11040                                   (match_operand:SI 1 "register_operand" "")))
11041                          (const_int 32) (const_int 0)))]
11042   "")
11043
11044 (define_expand "extv"
11045   [(set (match_operand:SI 0 "register_operand" "")
11046         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11047                          (match_operand 2 "const_int_operand" "")
11048                          (match_operand 3 "const_int_operand" "")))]
11049   "TARGET_SH4A_ARCH || TARGET_SH2A"
11050 {
11051   if (TARGET_SH2A && TARGET_BITOPS
11052       && (satisfies_constraint_Sbw (operands[1])
11053           || satisfies_constraint_Sbv (operands[1]))
11054       && satisfies_constraint_M (operands[2])
11055       && satisfies_constraint_K03 (operands[3]))
11056    {
11057       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11058       if (REGNO (operands[0]) != T_REG)
11059         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11060       DONE;
11061    }
11062   if (TARGET_SH4A_ARCH
11063       && INTVAL (operands[2]) == 32
11064       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11065       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11066     {
11067       rtx src = adjust_address (operands[1], BLKmode, 0);
11068       set_mem_size (src, 4);
11069       emit_insn (gen_movua (operands[0], src));
11070       DONE;
11071     }
11072
11073   FAIL;
11074 })
11075
11076 (define_expand "extzv"
11077   [(set (match_operand:SI 0 "register_operand" "")
11078         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11079                          (match_operand 2 "const_int_operand" "")
11080                          (match_operand 3 "const_int_operand" "")))]
11081   "TARGET_SH4A_ARCH || TARGET_SH2A"
11082 {
11083   if (TARGET_SH2A && TARGET_BITOPS
11084       && (satisfies_constraint_Sbw (operands[1])
11085           || satisfies_constraint_Sbv (operands[1]))
11086       && satisfies_constraint_M (operands[2])
11087       && satisfies_constraint_K03 (operands[3]))
11088     {
11089       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11090       if (REGNO (operands[0]) != T_REG)
11091         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11092       DONE;
11093     }
11094   if (TARGET_SH4A_ARCH
11095       && INTVAL (operands[2]) == 32
11096       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11097       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11098     {
11099       rtx src = adjust_address (operands[1], BLKmode, 0);
11100       set_mem_size (src, 4);
11101       emit_insn (gen_movua (operands[0], src));
11102       DONE;
11103     }
11104
11105   FAIL;
11106 })
11107
11108 ;; SH2A instructions for bitwise operations.
11109
11110 ;; Clear a bit in a memory location.
11111 (define_insn "bclr_m2a"
11112   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11113         (and:QI
11114             (not:QI (ashift:QI (const_int 1)
11115                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11116             (match_dup 0)))]
11117   "TARGET_SH2A && TARGET_BITOPS"
11118   "@
11119         bclr.b\\t%1,%0
11120         bclr.b\\t%1,@(0,%t0)"
11121 [(set_attr "length" "4,4")])
11122
11123 (define_insn "bclrmem_m2a"
11124   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11125         (and:QI (match_dup 0)
11126                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11127   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11128   "@
11129         bclr.b\\t%W1,%0
11130         bclr.b\\t%W1,@(0,%t0)"
11131   [(set_attr "length" "4,4")])
11132
11133 ;; Set a bit in a memory location.
11134 (define_insn "bset_m2a"
11135   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11136         (ior:QI
11137             (ashift:QI (const_int 1)
11138                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11139             (match_dup 0)))]
11140   "TARGET_SH2A && TARGET_BITOPS"
11141   "@
11142         bset.b\\t%1,%0
11143         bset.b\\t%1,@(0,%t0)"
11144   [(set_attr "length" "4,4")])
11145
11146 (define_insn "bsetmem_m2a"
11147   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11148         (ior:QI (match_dup 0)
11149                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11150   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11151   "@
11152         bset.b\\t%V1,%0
11153         bset.b\\t%V1,@(0,%t0)"
11154   [(set_attr "length" "4,4")])
11155
11156 ;;; Transfer the contents of the T bit to a specified bit of memory.
11157 (define_insn "bst_m2a"
11158   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11159         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11160             (and:QI
11161                 (not:QI (ashift:QI (const_int 1)
11162                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11163                 (match_dup 0))
11164             (ior:QI
11165                 (ashift:QI (const_int 1) (match_dup 1))
11166                 (match_dup 0))))]
11167   "TARGET_SH2A && TARGET_BITOPS"
11168   "@
11169         bst.b\\t%1,%0
11170         bst.b\\t%1,@(0,%t0)"
11171   [(set_attr "length" "4")])
11172
11173 ;; Store a specified bit of memory in the T bit.
11174 (define_insn "bld_m2a"
11175   [(set (reg:SI T_REG)
11176         (zero_extract:SI
11177             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11178             (const_int 1)
11179             (match_operand 1 "const_int_operand" "K03,K03")))]
11180   "TARGET_SH2A && TARGET_BITOPS"
11181   "@
11182         bld.b\\t%1,%0
11183         bld.b\\t%1,@(0,%t0)"
11184   [(set_attr "length" "4,4")])
11185
11186 ;; Store a specified bit of memory in the T bit.
11187 (define_insn "bldsign_m2a"
11188   [(set (reg:SI T_REG)
11189         (sign_extract:SI
11190             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11191             (const_int 1)
11192             (match_operand 1 "const_int_operand" "K03,K03")))]
11193   "TARGET_SH2A && TARGET_BITOPS"
11194   "@
11195         bld.b\\t%1,%0
11196         bld.b\\t%1,@(0,%t0)"
11197   [(set_attr "length" "4,4")])
11198
11199 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11200 (define_insn "bld_reg"
11201   [(set (reg:SI T_REG)
11202         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11203                          (const_int 1)
11204                          (match_operand 1 "const_int_operand" "K03")))]
11205   "TARGET_SH2A"
11206   "bld\\t%1,%0")
11207
11208 (define_insn "*bld_regqi"
11209   [(set (reg:SI T_REG)
11210         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11211                          (const_int 1)
11212                          (match_operand 1 "const_int_operand" "K03")))]
11213   "TARGET_SH2A"
11214   "bld\\t%1,%0")
11215
11216 ;; Take logical and of a specified bit of memory with the T bit and
11217 ;; store its result in the T bit.
11218 (define_insn "band_m2a"
11219   [(set (reg:SI T_REG)
11220         (and:SI (reg:SI T_REG)
11221                 (zero_extract:SI
11222                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11223                     (const_int 1)
11224                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11225   "TARGET_SH2A && TARGET_BITOPS"
11226   "@
11227         band.b\\t%1,%0
11228         band.b\\t%1,@(0,%t0)"
11229   [(set_attr "length" "4,4")])
11230
11231 (define_insn "bandreg_m2a"
11232   [(set (match_operand:SI 0 "register_operand" "=r,r")
11233         (and:SI (zero_extract:SI
11234                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11235                     (const_int 1)
11236                     (match_operand 2 "const_int_operand" "K03,K03"))
11237                 (match_operand:SI 3 "register_operand" "r,r")))]
11238   "TARGET_SH2A && TARGET_BITOPS"
11239   "@
11240         band.b\\t%2,%1\;movt\\t%0
11241         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11242   [(set_attr "length" "6,6")])
11243
11244 ;; Take logical or of a specified bit of memory with the T bit and
11245 ;; store its result in the T bit.
11246 (define_insn "bor_m2a"
11247   [(set (reg:SI T_REG)
11248         (ior:SI (reg:SI T_REG)
11249                 (zero_extract:SI
11250                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11251                     (const_int 1)
11252                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11253   "TARGET_SH2A && TARGET_BITOPS"
11254   "@
11255         bor.b\\t%1,%0
11256         bor.b\\t%1,@(0,%t0)"
11257   [(set_attr "length" "4,4")])
11258
11259 (define_insn "borreg_m2a"
11260   [(set (match_operand:SI 0 "register_operand" "=r,r")
11261         (ior:SI (zero_extract:SI
11262                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11263                     (const_int 1)
11264                     (match_operand 2 "const_int_operand" "K03,K03"))
11265                 (match_operand:SI 3 "register_operand" "=r,r")))]
11266   "TARGET_SH2A && TARGET_BITOPS"
11267   "@
11268         bor.b\\t%2,%1\;movt\\t%0
11269         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11270   [(set_attr "length" "6,6")])
11271
11272 ;; Take exclusive or of a specified bit of memory with the T bit and
11273 ;; store its result in the T bit.
11274 (define_insn "bxor_m2a"
11275   [(set (reg:SI T_REG)
11276         (xor:SI (reg:SI T_REG)
11277                 (zero_extract:SI
11278                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11279                     (const_int 1)
11280                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11281   "TARGET_SH2A && TARGET_BITOPS"
11282   "@
11283         bxor.b\\t%1,%0
11284         bxor.b\\t%1,@(0,%t0)"
11285   [(set_attr "length" "4,4")])
11286
11287 (define_insn "bxorreg_m2a"
11288   [(set (match_operand:SI 0 "register_operand" "=r,r")
11289         (xor:SI (zero_extract:SI
11290                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11291                     (const_int 1)
11292                     (match_operand 2 "const_int_operand" "K03,K03"))
11293                 (match_operand:SI 3 "register_operand" "=r,r")))]
11294   "TARGET_SH2A && TARGET_BITOPS"
11295   "@
11296         bxor.b\\t%2,%1\;movt\\t%0
11297         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11298   [(set_attr "length" "6,6")])
11299
11300 \f
11301 ;; -------------------------------------------------------------------------
11302 ;; Peepholes
11303 ;; -------------------------------------------------------------------------
11304 ;; This matches cases where the bit in a memory location is set.
11305 (define_peephole2
11306   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11307         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11308    (set (match_dup 0)
11309         (ior:SI (match_dup 0)
11310         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11311    (set (match_dup 1)
11312         (match_operand 3 "arith_reg_operand" "r,r"))]
11313   "TARGET_SH2A && TARGET_BITOPS
11314    && satisfies_constraint_Pso (operands[2])
11315    && REGNO (operands[0]) == REGNO (operands[3])"
11316   [(set (match_dup 1)
11317         (ior:QI (match_dup 1)
11318                 (match_dup 2)))]
11319   "")
11320
11321 ;; This matches cases where the bit in a memory location is cleared.
11322 (define_peephole2
11323   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11324         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11325    (set (match_dup 0)
11326         (and:SI (match_dup 0)
11327         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11328    (set (match_dup 1)
11329         (match_operand 3 "arith_reg_operand" "r,r"))]
11330   "TARGET_SH2A && TARGET_BITOPS
11331    && satisfies_constraint_Psz (operands[2])
11332    && REGNO (operands[0]) == REGNO (operands[3])"
11333   [(set (match_dup 1)
11334         (and:QI (match_dup 1)
11335                 (match_dup 2)))]
11336   "")
11337
11338 ;; This matches cases where a stack pointer increment at the start of the
11339 ;; epilogue combines with a stack slot read loading the return value.
11340
11341 (define_peephole
11342   [(set (match_operand:SI 0 "arith_reg_operand" "")
11343         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11344    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11345   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11346   "mov.l        @%1+,%0")
11347
11348 ;; See the comment on the dt combiner pattern above.
11349
11350 (define_peephole
11351   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11352         (plus:SI (match_dup 0)
11353                  (const_int -1)))
11354    (set (reg:SI T_REG)
11355         (eq:SI (match_dup 0)
11356                (const_int 0)))]
11357   "TARGET_SH2"
11358   "dt   %0")
11359
11360 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11361 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11362 ;; reload when the constant is too large for a reg+offset address.
11363
11364 ;; ??? We would get much better code if this was done in reload.  This would
11365 ;; require modifying find_reloads_address to recognize that if the constant
11366 ;; is out-of-range for an immediate add, then we get better code by reloading
11367 ;; the constant into a register than by reloading the sum into a register,
11368 ;; since the former is one instruction shorter if the address does not need
11369 ;; to be offsettable.  Unfortunately this does not work, because there is
11370 ;; only one register, r0, that can be used as an index register.  This register
11371 ;; is also the function return value register.  So, if we try to force reload
11372 ;; to use double-reg addresses, then we end up with some instructions that
11373 ;; need to use r0 twice.  The only way to fix this is to change the calling
11374 ;; convention so that r0 is not used to return values.
11375
11376 (define_peephole
11377   [(set (match_operand:SI 0 "register_operand" "=r")
11378         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11379    (set (mem:SI (match_dup 0))
11380         (match_operand:SI 2 "general_movsrc_operand" ""))]
11381   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11382   "mov.l        %2,@(%0,%1)")
11383
11384 (define_peephole
11385   [(set (match_operand:SI 0 "register_operand" "=r")
11386         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11387    (set (match_operand:SI 2 "general_movdst_operand" "")
11388         (mem:SI (match_dup 0)))]
11389   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11390   "mov.l        @(%0,%1),%2")
11391
11392 (define_peephole
11393   [(set (match_operand:SI 0 "register_operand" "=r")
11394         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11395    (set (mem:HI (match_dup 0))
11396         (match_operand:HI 2 "general_movsrc_operand" ""))]
11397   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11398   "mov.w        %2,@(%0,%1)")
11399
11400 (define_peephole
11401   [(set (match_operand:SI 0 "register_operand" "=r")
11402         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11403    (set (match_operand:HI 2 "general_movdst_operand" "")
11404         (mem:HI (match_dup 0)))]
11405   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11406   "mov.w        @(%0,%1),%2")
11407
11408 (define_peephole
11409   [(set (match_operand:SI 0 "register_operand" "=r")
11410         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11411    (set (mem:QI (match_dup 0))
11412         (match_operand:QI 2 "general_movsrc_operand" ""))]
11413   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11414   "mov.b        %2,@(%0,%1)")
11415
11416 (define_peephole
11417   [(set (match_operand:SI 0 "register_operand" "=r")
11418         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11419    (set (match_operand:QI 2 "general_movdst_operand" "")
11420         (mem:QI (match_dup 0)))]
11421   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11422   "mov.b        @(%0,%1),%2")
11423
11424 (define_peephole
11425   [(set (match_operand:SI 0 "register_operand" "=r")
11426         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11427    (set (mem:SF (match_dup 0))
11428         (match_operand:SF 2 "general_movsrc_operand" ""))]
11429   "TARGET_SH1 && REGNO (operands[0]) == 0
11430    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11431        || (GET_CODE (operands[2]) == SUBREG
11432            && REGNO (SUBREG_REG (operands[2])) < 16))
11433    && reg_unused_after (operands[0], insn)"
11434   "mov.l        %2,@(%0,%1)")
11435
11436 (define_peephole
11437   [(set (match_operand:SI 0 "register_operand" "=r")
11438         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11439    (set (match_operand:SF 2 "general_movdst_operand" "")
11440
11441         (mem:SF (match_dup 0)))]
11442   "TARGET_SH1 && REGNO (operands[0]) == 0
11443    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11444        || (GET_CODE (operands[2]) == SUBREG
11445            && REGNO (SUBREG_REG (operands[2])) < 16))
11446    && reg_unused_after (operands[0], insn)"
11447   "mov.l        @(%0,%1),%2")
11448
11449 (define_peephole
11450   [(set (match_operand:SI 0 "register_operand" "=r")
11451         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11452    (set (mem:SF (match_dup 0))
11453         (match_operand:SF 2 "general_movsrc_operand" ""))]
11454   "TARGET_SH2E && REGNO (operands[0]) == 0
11455    && ((REG_P (operands[2])
11456         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11457        || (GET_CODE (operands[2]) == SUBREG
11458            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11459    && reg_unused_after (operands[0], insn)"
11460   "fmov{.s|}    %2,@(%0,%1)")
11461
11462 (define_peephole
11463   [(set (match_operand:SI 0 "register_operand" "=r")
11464         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11465    (set (match_operand:SF 2 "general_movdst_operand" "")
11466
11467         (mem:SF (match_dup 0)))]
11468   "TARGET_SH2E && REGNO (operands[0]) == 0
11469    && ((REG_P (operands[2])
11470         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11471        || (GET_CODE (operands[2]) == SUBREG
11472            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11473    && reg_unused_after (operands[0], insn)"
11474   "fmov{.s|}    @(%0,%1),%2")
11475
11476 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11477 (define_insn "sp_switch_1"
11478   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11479   "TARGET_SH1"
11480   "*
11481 {
11482   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11483   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11484   return \"mov r0,r15\";
11485 }"
11486   [(set_attr "length" "10")])
11487
11488 ;; Switch back to the original stack for interrupt functions with the
11489 ;; sp_switch attribute.  */
11490 (define_insn "sp_switch_2"
11491   [(const_int 2)]
11492   "TARGET_SH1"
11493   "mov.l @r15+,r15\;mov.l @r15+,r0"
11494   [(set_attr "length" "4")])
11495
11496 ;; Integer vector moves
11497
11498 (define_expand "movv8qi"
11499   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11500         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11501   "TARGET_SHMEDIA"
11502   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11503
11504 (define_insn "movv8qi_i"
11505   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11506         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11507   "TARGET_SHMEDIA
11508    && (register_operand (operands[0], V8QImode)
11509        || sh_register_operand (operands[1], V8QImode))"
11510   "@
11511         add     %1, r63, %0
11512         movi    %1, %0
11513         #
11514         ld%M1.q %m1, %0
11515         st%M0.q %m0, %N1"
11516   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11517    (set_attr "length" "4,4,16,4,4")])
11518
11519 (define_split
11520   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11521         (subreg:V8QI (const_int 0) 0))]
11522   "TARGET_SHMEDIA"
11523   [(set (match_dup 0)
11524         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11525                             (const_int 0) (const_int 0) (const_int 0)
11526                             (const_int 0) (const_int 0)]))])
11527
11528 (define_split
11529   [(set (match_operand 0 "arith_reg_dest" "")
11530         (match_operand 1 "sh_rep_vec" ""))]
11531   "TARGET_SHMEDIA && reload_completed
11532    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11533    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11534    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11535    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11536        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11537    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11538        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11539   [(set (match_dup 0) (match_dup 1))
11540    (match_dup 2)]
11541   "
11542 {
11543   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11544   rtx elt1 = XVECEXP (operands[1], 0, 1);
11545
11546   if (unit_size > 2)
11547     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11548   else
11549     {
11550       if (unit_size < 2)
11551         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11552       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11553     }
11554   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11555   operands[1] = XVECEXP (operands[1], 0, 0);
11556   if (unit_size < 2)
11557     {
11558       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11559         operands[1]
11560           = GEN_INT (TARGET_LITTLE_ENDIAN
11561                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11562                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11563       else
11564         {
11565           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11566           operands[1]
11567             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11568         }
11569     }
11570 }")
11571
11572 (define_split
11573   [(set (match_operand 0 "arith_reg_dest" "")
11574         (match_operand 1 "sh_const_vec" ""))]
11575   "TARGET_SHMEDIA && reload_completed
11576    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11577    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11578   [(set (match_dup 0) (match_dup 1))]
11579   "
11580 {
11581   rtx v = operands[1];
11582   enum machine_mode new_mode
11583     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11584
11585   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11586   operands[1]
11587     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11588 }")
11589
11590 (define_expand "movv2hi"
11591   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11592         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11593   "TARGET_SHMEDIA"
11594   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11595
11596 (define_insn "movv2hi_i"
11597   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11598         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11599   "TARGET_SHMEDIA
11600    && (register_operand (operands[0], V2HImode)
11601        || sh_register_operand (operands[1], V2HImode))"
11602   "@
11603         add.l   %1, r63, %0
11604         movi    %1, %0
11605         #
11606         ld%M1.l %m1, %0
11607         st%M0.l %m0, %N1"
11608   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11609    (set_attr "length" "4,4,16,4,4")
11610    (set (attr "highpart")
11611         (cond [(match_test "sh_contains_memref_p (insn)")
11612                (const_string "user")]
11613               (const_string "ignore")))])
11614
11615 (define_expand "movv4hi"
11616   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11617         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11618   "TARGET_SHMEDIA"
11619   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11620
11621 (define_insn "movv4hi_i"
11622   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11623         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11624   "TARGET_SHMEDIA
11625    && (register_operand (operands[0], V4HImode)
11626        || sh_register_operand (operands[1], V4HImode))"
11627   "@
11628         add     %1, r63, %0
11629         movi    %1, %0
11630         #
11631         ld%M1.q %m1, %0
11632         st%M0.q %m0, %N1"
11633   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11634    (set_attr "length" "4,4,16,4,4")
11635    (set_attr "highpart" "depend")])
11636
11637 (define_expand "movv2si"
11638   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11639         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11640   "TARGET_SHMEDIA"
11641   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11642
11643 (define_insn "movv2si_i"
11644   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11645         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11646   "TARGET_SHMEDIA
11647    && (register_operand (operands[0], V2SImode)
11648        || sh_register_operand (operands[1], V2SImode))"
11649   "@
11650         add     %1, r63, %0
11651         #
11652         #
11653         ld%M1.q %m1, %0
11654         st%M0.q %m0, %N1"
11655   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11656    (set_attr "length" "4,4,16,4,4")
11657    (set_attr "highpart" "depend")])
11658
11659 ;; Multimedia Intrinsics
11660
11661 (define_insn "absv2si2"
11662   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11663         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11664   "TARGET_SHMEDIA"
11665   "mabs.l       %1, %0"
11666   [(set_attr "type" "mcmp_media")
11667    (set_attr "highpart" "depend")])
11668
11669 (define_insn "absv4hi2"
11670   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11671         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11672   "TARGET_SHMEDIA"
11673   "mabs.w       %1, %0"
11674   [(set_attr "type" "mcmp_media")
11675    (set_attr "highpart" "depend")])
11676
11677 (define_insn "addv2si3"
11678   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11679         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11680                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11681   "TARGET_SHMEDIA"
11682   "madd.l       %1, %2, %0"
11683   [(set_attr "type" "arith_media")
11684    (set_attr "highpart" "depend")])
11685
11686 (define_insn "addv4hi3"
11687   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11688         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11689                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11690   "TARGET_SHMEDIA"
11691   "madd.w       %1, %2, %0"
11692   [(set_attr "type" "arith_media")
11693    (set_attr "highpart" "depend")])
11694
11695 (define_insn_and_split "addv2hi3"
11696   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11697         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11698                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11699   "TARGET_SHMEDIA"
11700   "#"
11701   "TARGET_SHMEDIA"
11702   [(const_int 0)]
11703   "
11704 {
11705   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11706   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11707   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11708   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11709   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11710
11711   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11712   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11713   DONE;
11714 }"
11715   [(set_attr "highpart" "must_split")])
11716
11717 (define_insn "ssaddv2si3"
11718   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11719         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11720                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11721   "TARGET_SHMEDIA"
11722   "madds.l      %1, %2, %0"
11723   [(set_attr "type" "mcmp_media")
11724    (set_attr "highpart" "depend")])
11725
11726 (define_insn "usaddv8qi3"
11727   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11728         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11729                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11730   "TARGET_SHMEDIA"
11731   "madds.ub     %1, %2, %0"
11732   [(set_attr "type" "mcmp_media")
11733    (set_attr "highpart" "depend")])
11734
11735 (define_insn "ssaddv4hi3"
11736   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11737         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11738                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11739   "TARGET_SHMEDIA"
11740   "madds.w      %1, %2, %0"
11741   [(set_attr "type" "mcmp_media")
11742    (set_attr "highpart" "depend")])
11743
11744 (define_insn "negcmpeqv8qi"
11745   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11746         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11747                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11748   "TARGET_SHMEDIA"
11749   "mcmpeq.b     %N1, %N2, %0"
11750   [(set_attr "type" "mcmp_media")
11751    (set_attr "highpart" "depend")])
11752
11753 (define_insn "negcmpeqv2si"
11754   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11755         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11756                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11757   "TARGET_SHMEDIA"
11758   "mcmpeq.l     %N1, %N2, %0"
11759   [(set_attr "type" "mcmp_media")
11760    (set_attr "highpart" "depend")])
11761
11762 (define_insn "negcmpeqv4hi"
11763   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11764         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11765                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11766   "TARGET_SHMEDIA"
11767   "mcmpeq.w     %N1, %N2, %0"
11768   [(set_attr "type" "mcmp_media")
11769    (set_attr "highpart" "depend")])
11770
11771 (define_insn "negcmpgtuv8qi"
11772   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11773         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11774                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11775   "TARGET_SHMEDIA"
11776   "mcmpgt.ub    %N1, %N2, %0"
11777   [(set_attr "type" "mcmp_media")
11778    (set_attr "highpart" "depend")])
11779
11780 (define_insn "negcmpgtv2si"
11781   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11782         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11783                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11784   "TARGET_SHMEDIA"
11785   "mcmpgt.l     %N1, %N2, %0"
11786   [(set_attr "type" "mcmp_media")
11787    (set_attr "highpart" "depend")])
11788
11789 (define_insn "negcmpgtv4hi"
11790   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11791         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11792                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11793   "TARGET_SHMEDIA"
11794   "mcmpgt.w     %N1, %N2, %0"
11795   [(set_attr "type" "mcmp_media")
11796    (set_attr "highpart" "depend")])
11797
11798 (define_insn "mcmv"
11799   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11800         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11801                         (match_operand:DI 2 "arith_reg_operand" "r"))
11802                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11803                         (not:DI (match_dup 2)))))]
11804   "TARGET_SHMEDIA"
11805   "mcmv %N1, %2, %0"
11806   [(set_attr "type" "arith_media")
11807    (set_attr "highpart" "depend")])
11808
11809 (define_insn "mcnvs_lw"
11810   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11811         (vec_concat:V4HI
11812          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11813          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11814   "TARGET_SHMEDIA"
11815   "mcnvs.lw     %N1, %N2, %0"
11816   [(set_attr "type" "mcmp_media")])
11817
11818 (define_insn "mcnvs_wb"
11819   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11820         (vec_concat:V8QI
11821          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11822          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11823   "TARGET_SHMEDIA"
11824   "mcnvs.wb     %N1, %N2, %0"
11825   [(set_attr "type" "mcmp_media")])
11826
11827 (define_insn "mcnvs_wub"
11828   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11829         (vec_concat:V8QI
11830          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11831          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11832   "TARGET_SHMEDIA"
11833   "mcnvs.wub    %N1, %N2, %0"
11834   [(set_attr "type" "mcmp_media")])
11835
11836 (define_insn "mextr_rl"
11837   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11838         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11839                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11840                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11841                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11842   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11843   "*
11844 {
11845   static char templ[21];
11846
11847   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11848            (int) INTVAL (operands[3]) >> 3);
11849   return templ;
11850 }"
11851   [(set_attr "type" "arith_media")])
11852
11853 (define_insn "*mextr_lr"
11854   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11855         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11856                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11857                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11858                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11859   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11860   "*
11861 {
11862   static char templ[21];
11863
11864   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11865            (int) INTVAL (operands[4]) >> 3);
11866   return templ;
11867 }"
11868   [(set_attr "type" "arith_media")])
11869
11870 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11871 ; vector then varies depending on endianness.
11872 (define_expand "mextr1"
11873   [(match_operand:DI 0 "arith_reg_dest" "")
11874    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11875    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11876   "TARGET_SHMEDIA"
11877   "
11878 {
11879   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11880                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11881   DONE;
11882 }")
11883
11884 (define_expand "mextr2"
11885   [(match_operand:DI 0 "arith_reg_dest" "")
11886    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11887    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11888   "TARGET_SHMEDIA"
11889   "
11890 {
11891   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11892                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11893   DONE;
11894 }")
11895
11896 (define_expand "mextr3"
11897   [(match_operand:DI 0 "arith_reg_dest" "")
11898    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11899    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11900   "TARGET_SHMEDIA"
11901   "
11902 {
11903   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11904                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11905   DONE;
11906 }")
11907
11908 (define_expand "mextr4"
11909   [(match_operand:DI 0 "arith_reg_dest" "")
11910    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11911    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11912   "TARGET_SHMEDIA"
11913   "
11914 {
11915   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11916                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11917   DONE;
11918 }")
11919
11920 (define_expand "mextr5"
11921   [(match_operand:DI 0 "arith_reg_dest" "")
11922    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11923    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11924   "TARGET_SHMEDIA"
11925   "
11926 {
11927   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11928                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11929   DONE;
11930 }")
11931
11932 (define_expand "mextr6"
11933   [(match_operand:DI 0 "arith_reg_dest" "")
11934    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11935    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11936   "TARGET_SHMEDIA"
11937   "
11938 {
11939   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11940                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11941   DONE;
11942 }")
11943
11944 (define_expand "mextr7"
11945   [(match_operand:DI 0 "arith_reg_dest" "")
11946    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11947    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11948   "TARGET_SHMEDIA"
11949   "
11950 {
11951   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11952                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11953   DONE;
11954 }")
11955
11956 (define_expand "mmacfx_wl"
11957   [(match_operand:V2SI 0 "arith_reg_dest" "")
11958    (match_operand:V2HI 1 "extend_reg_operand" "")
11959    (match_operand:V2HI 2 "extend_reg_operand" "")
11960    (match_operand:V2SI 3 "arith_reg_operand" "")]
11961   "TARGET_SHMEDIA"
11962   "
11963 {
11964   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11965                               operands[1], operands[2]));
11966   DONE;
11967 }")
11968
11969 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11970 ;; is depend
11971 (define_insn "mmacfx_wl_i"
11972   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11973         (ss_plus:V2SI
11974          (match_operand:V2SI 1 "arith_reg_operand" "0")
11975          (ss_truncate:V2SI
11976           (ashift:V2DI
11977            (sign_extend:V2DI
11978             (mult:V2SI
11979              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11980              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11981            (const_int 1)))))]
11982   "TARGET_SHMEDIA"
11983   "mmacfx.wl    %2, %3, %0"
11984   [(set_attr "type" "mac_media")
11985    (set_attr "highpart" "depend")])
11986
11987 (define_expand "mmacnfx_wl"
11988   [(match_operand:V2SI 0 "arith_reg_dest" "")
11989    (match_operand:V2HI 1 "extend_reg_operand" "")
11990    (match_operand:V2HI 2 "extend_reg_operand" "")
11991    (match_operand:V2SI 3 "arith_reg_operand" "")]
11992   "TARGET_SHMEDIA"
11993   "
11994 {
11995   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11996                                operands[1], operands[2]));
11997   DONE;
11998 }")
11999
12000 (define_insn "mmacnfx_wl_i"
12001   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12002         (ss_minus:V2SI
12003          (match_operand:V2SI 1 "arith_reg_operand" "0")
12004          (ss_truncate:V2SI
12005           (ashift:V2DI
12006            (sign_extend:V2DI
12007             (mult:V2SI
12008              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12009              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12010            (const_int 1)))))]
12011   "TARGET_SHMEDIA"
12012   "mmacnfx.wl   %2, %3, %0"
12013   [(set_attr "type" "mac_media")
12014    (set_attr "highpart" "depend")])
12015
12016 (define_insn "mulv2si3"
12017   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12018         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12019                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12020   "TARGET_SHMEDIA"
12021   "mmul.l       %1, %2, %0"
12022   [(set_attr "type" "d2mpy_media")
12023    (set_attr "highpart" "depend")])
12024
12025 (define_insn "mulv4hi3"
12026   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12027         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12028                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12029   "TARGET_SHMEDIA"
12030   "mmul.w       %1, %2, %0"
12031   [(set_attr "type" "dmpy_media")
12032    (set_attr "highpart" "depend")])
12033
12034 (define_insn "mmulfx_l"
12035   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12036         (ss_truncate:V2SI
12037          (ashiftrt:V2DI
12038           (mult:V2DI
12039            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12040            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12041           (const_int 31))))]
12042   "TARGET_SHMEDIA"
12043   "mmulfx.l     %1, %2, %0"
12044   [(set_attr "type" "d2mpy_media")
12045    (set_attr "highpart" "depend")])
12046
12047 (define_insn "mmulfx_w"
12048   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12049         (ss_truncate:V4HI
12050          (ashiftrt:V4SI
12051           (mult:V4SI
12052            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12053            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12054           (const_int 15))))]
12055   "TARGET_SHMEDIA"
12056   "mmulfx.w     %1, %2, %0"
12057   [(set_attr "type" "dmpy_media")
12058    (set_attr "highpart" "depend")])
12059
12060 (define_insn "mmulfxrp_w"
12061   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12062         (ss_truncate:V4HI
12063          (ashiftrt:V4SI
12064           (plus:V4SI
12065            (mult:V4SI
12066             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12067             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12068            (const_int 16384))
12069           (const_int 15))))]
12070   "TARGET_SHMEDIA"
12071   "mmulfxrp.w   %1, %2, %0"
12072   [(set_attr "type" "dmpy_media")
12073    (set_attr "highpart" "depend")])
12074
12075
12076 (define_expand "mmulhi_wl"
12077   [(match_operand:V2SI 0 "arith_reg_dest" "")
12078    (match_operand:V4HI 1 "arith_reg_operand" "")
12079    (match_operand:V4HI 2 "arith_reg_operand" "")]
12080   "TARGET_SHMEDIA"
12081   "
12082 {
12083   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12084              (operands[0], operands[1], operands[2]));
12085   DONE;
12086 }")
12087
12088 (define_expand "mmullo_wl"
12089   [(match_operand:V2SI 0 "arith_reg_dest" "")
12090    (match_operand:V4HI 1 "arith_reg_operand" "")
12091    (match_operand:V4HI 2 "arith_reg_operand" "")]
12092   "TARGET_SHMEDIA"
12093   "
12094 {
12095   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12096              (operands[0], operands[1], operands[2]));
12097   DONE;
12098 }")
12099
12100 (define_insn "mmul23_wl"
12101   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12102         (vec_select:V2SI
12103          (mult:V4SI
12104           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12105           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12106          (parallel [(const_int 2) (const_int 3)])))]
12107   "TARGET_SHMEDIA"
12108   "* return (TARGET_LITTLE_ENDIAN
12109              ? \"mmulhi.wl      %1, %2, %0\"
12110              : \"mmullo.wl      %1, %2, %0\");"
12111   [(set_attr "type" "dmpy_media")
12112    (set (attr "highpart")
12113         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12114          (const_string "user")))])
12115
12116 (define_insn "mmul01_wl"
12117   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12118         (vec_select:V2SI
12119          (mult:V4SI
12120           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12121           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12122          (parallel [(const_int 0) (const_int 1)])))]
12123   "TARGET_SHMEDIA"
12124   "* return (TARGET_LITTLE_ENDIAN
12125              ? \"mmullo.wl      %1, %2, %0\"
12126              : \"mmulhi.wl      %1, %2, %0\");"
12127   [(set_attr "type" "dmpy_media")
12128    (set (attr "highpart")
12129         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12130          (const_string "user")))])
12131
12132
12133 (define_expand "mmulsum_wq"
12134   [(match_operand:DI 0 "arith_reg_dest" "")
12135    (match_operand:V4HI 1 "arith_reg_operand" "")
12136    (match_operand:V4HI 2 "arith_reg_operand" "")
12137    (match_operand:DI 3 "arith_reg_operand" "")]
12138   "TARGET_SHMEDIA"
12139   "
12140 {
12141   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12142                                operands[1], operands[2]));
12143   DONE;
12144 }")
12145
12146 (define_insn "mmulsum_wq_i"
12147   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12148         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12149          (plus:DI
12150           (plus:DI
12151            (vec_select:DI
12152             (mult:V4DI
12153              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12154              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12155             (parallel [(const_int 0)]))
12156            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12157                                      (sign_extend:V4DI (match_dup 3)))
12158                           (parallel [(const_int 1)])))
12159           (plus:DI
12160            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12161                                      (sign_extend:V4DI (match_dup 3)))
12162                           (parallel [(const_int 2)]))
12163            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12164                                      (sign_extend:V4DI (match_dup 3)))
12165                           (parallel [(const_int 3)]))))))]
12166   "TARGET_SHMEDIA"
12167   "mmulsum.wq   %2, %3, %0"
12168   [(set_attr "type" "mac_media")])
12169
12170 (define_expand "mperm_w"
12171   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12172    (match_operand:V4HI 1 "arith_reg_operand" "r")
12173    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12174   "TARGET_SHMEDIA"
12175   "
12176 {
12177   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12178              (operands[0], operands[1], operands[2]));
12179   DONE;
12180 }")
12181
12182 ; This use of vec_select isn't exactly correct according to rtl.texi
12183 ; (because not constant), but it seems a straightforward extension.
12184 (define_insn "mperm_w_little"
12185   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12186         (vec_select:V4HI
12187          (match_operand:V4HI 1 "arith_reg_operand" "r")
12188          (parallel
12189           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12190                             (const_int 2) (const_int 0))
12191            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12192            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12193            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12194   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12195   "mperm.w      %1, %N2, %0"
12196   [(set_attr "type" "arith_media")])
12197
12198 (define_insn "mperm_w_big"
12199   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12200         (vec_select:V4HI
12201          (match_operand:V4HI 1 "arith_reg_operand" "r")
12202          (parallel
12203           [(zero_extract:QI (not:QI (match_operand:QI 2
12204                                      "extend_reg_or_0_operand" "rZ"))
12205                             (const_int 2) (const_int 0))
12206            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12207            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12208            (zero_extract:QI (not:QI (match_dup 2))
12209                             (const_int 2) (const_int 6))])))]
12210   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12211   "mperm.w      %1, %N2, %0"
12212   [(set_attr "type" "arith_media")])
12213
12214 (define_insn "mperm_w0"
12215   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12216         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12217                                           "trunc_hi_operand" "r"))))]
12218   "TARGET_SHMEDIA"
12219   "mperm.w      %1, r63, %0"
12220   [(set_attr "type" "arith_media")
12221    (set_attr "highpart" "ignore")])
12222
12223 (define_expand "msad_ubq"
12224   [(match_operand:DI 0 "arith_reg_dest" "")
12225    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12226    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12227    (match_operand:DI 3 "arith_reg_operand" "")]
12228   "TARGET_SHMEDIA"
12229   "
12230 {
12231   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12232                              operands[1], operands[2]));
12233   DONE;
12234 }")
12235
12236 (define_insn "msad_ubq_i"
12237   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12238         (plus:DI
12239          (plus:DI
12240           (plus:DI
12241            (plus:DI
12242             (match_operand:DI 1 "arith_reg_operand" "0")
12243             (abs:DI (vec_select:DI
12244                      (minus:V8DI
12245                       (zero_extend:V8DI
12246                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12247                       (zero_extend:V8DI
12248                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12249                      (parallel [(const_int 0)]))))
12250            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12251                                               (zero_extend:V8DI (match_dup 3)))
12252                                   (parallel [(const_int 1)]))))
12253           (plus:DI
12254            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12255                                               (zero_extend:V8DI (match_dup 3)))
12256                                   (parallel [(const_int 2)])))
12257            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12258                                               (zero_extend:V8DI (match_dup 3)))
12259                                   (parallel [(const_int 3)])))))
12260          (plus:DI
12261           (plus:DI
12262            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12263                                               (zero_extend:V8DI (match_dup 3)))
12264                                   (parallel [(const_int 4)])))
12265            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12266                                               (zero_extend:V8DI (match_dup 3)))
12267                                   (parallel [(const_int 5)]))))
12268           (plus:DI
12269            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12270                                               (zero_extend:V8DI (match_dup 3)))
12271                                   (parallel [(const_int 6)])))
12272            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12273                                               (zero_extend:V8DI (match_dup 3)))
12274                                   (parallel [(const_int 7)])))))))]
12275   "TARGET_SHMEDIA"
12276   "msad.ubq     %N2, %N3, %0"
12277   [(set_attr "type" "mac_media")])
12278
12279 (define_insn "mshalds_l"
12280   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12281         (ss_truncate:V2SI
12282          (ashift:V2DI
12283           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12284           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12285                   (const_int 31)))))]
12286   "TARGET_SHMEDIA"
12287   "mshalds.l    %1, %2, %0"
12288   [(set_attr "type" "mcmp_media")
12289    (set_attr "highpart" "depend")])
12290
12291 (define_insn "mshalds_w"
12292   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12293         (ss_truncate:V4HI
12294          (ashift:V4SI
12295           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12296           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12297                   (const_int 15)))))]
12298   "TARGET_SHMEDIA"
12299   "mshalds.w    %1, %2, %0"
12300   [(set_attr "type" "mcmp_media")
12301    (set_attr "highpart" "depend")])
12302
12303 (define_insn "ashrv2si3"
12304   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12305         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12306                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12307   "TARGET_SHMEDIA"
12308   "mshard.l     %1, %2, %0"
12309   [(set_attr "type" "arith_media")
12310    (set_attr "highpart" "depend")])
12311
12312 (define_insn "ashrv4hi3"
12313   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12314         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12315                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12316   "TARGET_SHMEDIA"
12317   "mshard.w     %1, %2, %0"
12318   [(set_attr "type" "arith_media")
12319    (set_attr "highpart" "depend")])
12320
12321 (define_insn "mshards_q"
12322   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12323         (ss_truncate:HI
12324          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12325                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12326   "TARGET_SHMEDIA"
12327   "mshards.q    %1, %N2, %0"
12328   [(set_attr "type" "mcmp_media")])
12329
12330 (define_expand "mshfhi_b"
12331   [(match_operand:V8QI 0 "arith_reg_dest" "")
12332    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12333    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12334   "TARGET_SHMEDIA"
12335   "
12336 {
12337   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12338              (operands[0], operands[1], operands[2]));
12339   DONE;
12340 }")
12341
12342 (define_expand "mshflo_b"
12343   [(match_operand:V8QI 0 "arith_reg_dest" "")
12344    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12345    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12346   "TARGET_SHMEDIA"
12347   "
12348 {
12349   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12350              (operands[0], operands[1], operands[2]));
12351   DONE;
12352 }")
12353
12354 (define_insn "mshf4_b"
12355   [(set
12356     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12357     (vec_select:V8QI
12358      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12359                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12360      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12361                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12362   "TARGET_SHMEDIA"
12363   "* return (TARGET_LITTLE_ENDIAN
12364              ? \"mshfhi.b       %N1, %N2, %0\"
12365              : \"mshflo.b       %N1, %N2, %0\");"
12366   [(set_attr "type" "arith_media")
12367    (set (attr "highpart")
12368         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12369          (const_string "user")))])
12370
12371 (define_insn "mshf0_b"
12372   [(set
12373     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12374     (vec_select:V8QI
12375      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12376                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12377      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12378                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12379   "TARGET_SHMEDIA"
12380   "* return (TARGET_LITTLE_ENDIAN
12381              ? \"mshflo.b       %N1, %N2, %0\"
12382              : \"mshfhi.b       %N1, %N2, %0\");"
12383   [(set_attr "type" "arith_media")
12384    (set (attr "highpart")
12385         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12386          (const_string "user")))])
12387
12388 (define_expand "mshfhi_l"
12389   [(match_operand:V2SI 0 "arith_reg_dest" "")
12390    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12391    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12392   "TARGET_SHMEDIA"
12393   "
12394 {
12395   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12396              (operands[0], operands[1], operands[2]));
12397   DONE;
12398 }")
12399
12400 (define_expand "mshflo_l"
12401   [(match_operand:V2SI 0 "arith_reg_dest" "")
12402    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12403    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12404   "TARGET_SHMEDIA"
12405   "
12406 {
12407   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12408              (operands[0], operands[1], operands[2]));
12409   DONE;
12410 }")
12411
12412 (define_insn "mshf4_l"
12413   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12414         (vec_select:V2SI
12415          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12416                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12417          (parallel [(const_int 1) (const_int 3)])))]
12418   "TARGET_SHMEDIA"
12419   "* return (TARGET_LITTLE_ENDIAN
12420              ? \"mshfhi.l       %N1, %N2, %0\"
12421              : \"mshflo.l       %N1, %N2, %0\");"
12422   [(set_attr "type" "arith_media")
12423    (set (attr "highpart")
12424         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12425          (const_string "user")))])
12426
12427 (define_insn "mshf0_l"
12428   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12429         (vec_select:V2SI
12430          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12431                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12432          (parallel [(const_int 0) (const_int 2)])))]
12433   "TARGET_SHMEDIA"
12434   "* return (TARGET_LITTLE_ENDIAN
12435              ? \"mshflo.l       %N1, %N2, %0\"
12436              : \"mshfhi.l       %N1, %N2, %0\");"
12437   [(set_attr "type" "arith_media")
12438    (set (attr "highpart")
12439         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12440          (const_string "user")))])
12441
12442 (define_expand "mshfhi_w"
12443   [(match_operand:V4HI 0 "arith_reg_dest" "")
12444    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12445    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12446   "TARGET_SHMEDIA"
12447   "
12448 {
12449   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12450              (operands[0], operands[1], operands[2]));
12451   DONE;
12452 }")
12453
12454 (define_expand "mshflo_w"
12455   [(match_operand:V4HI 0 "arith_reg_dest" "")
12456    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12457    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12458   "TARGET_SHMEDIA"
12459   "
12460 {
12461   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12462              (operands[0], operands[1], operands[2]));
12463   DONE;
12464 }")
12465
12466 (define_insn "mshf4_w"
12467   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12468         (vec_select:V4HI
12469          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12470                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12471          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12472   "TARGET_SHMEDIA"
12473   "* return (TARGET_LITTLE_ENDIAN
12474              ? \"mshfhi.w       %N1, %N2, %0\"
12475              : \"mshflo.w       %N1, %N2, %0\");"
12476   [(set_attr "type" "arith_media")
12477    (set (attr "highpart")
12478         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12479          (const_string "user")))])
12480
12481 (define_insn "mshf0_w"
12482   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12483         (vec_select:V4HI
12484          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12485                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12486          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12487   "TARGET_SHMEDIA"
12488   "* return (TARGET_LITTLE_ENDIAN
12489              ? \"mshflo.w       %N1, %N2, %0\"
12490              : \"mshfhi.w       %N1, %N2, %0\");"
12491   [(set_attr "type" "arith_media")
12492    (set (attr "highpart")
12493         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12494          (const_string "user")))])
12495
12496 (define_insn "mshflo_w_x"
12497   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12498         (vec_select:V4HI
12499          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12500                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12501          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12502   "TARGET_SHMEDIA"
12503   "mshflo.w     %N1, %N2, %0"
12504   [(set_attr "type" "arith_media")
12505    (set_attr "highpart" "ignore")])
12506
12507 /* These are useful to expand ANDs and as combiner patterns.  */
12508 (define_insn_and_split "mshfhi_l_di"
12509   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12510         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12511                              (const_int 32))
12512                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12513                         (const_int -4294967296))))]
12514   "TARGET_SHMEDIA"
12515   "@
12516         mshfhi.l        %N1, %N2, %0
12517         #"
12518   "TARGET_SHMEDIA && reload_completed
12519    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12520   [(set (match_dup 3) (match_dup 4))
12521    (set (match_dup 5) (match_dup 6))]
12522   "
12523 {
12524   operands[3] = gen_lowpart (SImode, operands[0]);
12525   operands[4] = gen_highpart (SImode, operands[1]);
12526   operands[5] = gen_highpart (SImode, operands[0]);
12527   operands[6] = gen_highpart (SImode, operands[2]);
12528 }"
12529   [(set_attr "type" "arith_media")])
12530
12531 (define_insn "*mshfhi_l_di_rev"
12532   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12533         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12534                         (const_int -4294967296))
12535                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12536                              (const_int 32))))]
12537   "TARGET_SHMEDIA"
12538   "mshfhi.l     %N2, %N1, %0"
12539   [(set_attr "type" "arith_media")])
12540
12541 (define_split
12542   [(set (match_operand:DI 0 "arith_reg_dest" "")
12543         (ior:DI (zero_extend:DI (match_operand:SI 1
12544                                               "extend_reg_or_0_operand" ""))
12545                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12546                         (const_int -4294967296))))
12547    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12548   "TARGET_SHMEDIA"
12549   [(const_int 0)]
12550   "
12551 {
12552   emit_insn (gen_ashldi3_media (operands[3],
12553                                 simplify_gen_subreg (DImode, operands[1],
12554                                                      SImode, 0),
12555                                 GEN_INT (32)));
12556   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12557   DONE;
12558 }")
12559
12560 (define_insn "mshflo_l_di"
12561   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12562         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12563                         (const_int 4294967295))
12564                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12565                            (const_int 32))))]
12566
12567   "TARGET_SHMEDIA"
12568   "mshflo.l     %N1, %N2, %0"
12569   [(set_attr "type" "arith_media")
12570    (set_attr "highpart" "ignore")])
12571
12572 (define_insn "*mshflo_l_di_rev"
12573   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12574         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12575                            (const_int 32))
12576                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12577                         (const_int 4294967295))))]
12578
12579   "TARGET_SHMEDIA"
12580   "mshflo.l     %N2, %N1, %0"
12581   [(set_attr "type" "arith_media")
12582    (set_attr "highpart" "ignore")])
12583
12584 ;; Combiner pattern for trampoline initialization.
12585 (define_insn_and_split "*double_shori"
12586   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12587         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12588                            (const_int 32))
12589                 (match_operand:DI 2 "const_int_operand" "n")))]
12590   "TARGET_SHMEDIA
12591    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12592   "#"
12593   "rtx_equal_p (operands[0], operands[1])"
12594   [(const_int 0)]
12595   "
12596 {
12597   HOST_WIDE_INT v = INTVAL (operands[2]);
12598
12599   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12600   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12601   DONE;
12602 }"
12603   [(set_attr "highpart" "ignore")])
12604
12605
12606 (define_insn "*mshflo_l_di_x"
12607   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12608         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12609                                  "rZ"))
12610                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12611                            (const_int 32))))]
12612
12613   "TARGET_SHMEDIA"
12614   "mshflo.l     %N1, %N2, %0"
12615   [(set_attr "type" "arith_media")
12616    (set_attr "highpart" "ignore")])
12617
12618 (define_insn_and_split "concat_v2sf"
12619   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12620 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12621         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12622                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12623
12624   "TARGET_SHMEDIA"
12625   "@
12626         mshflo.l        %N1, %N2, %0
12627         #
12628         #"
12629   "TARGET_SHMEDIA && reload_completed
12630    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12631   [(set (match_dup 3) (match_dup 1))
12632    (set (match_dup 4) (match_dup 2))]
12633   "
12634 {
12635   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12636   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12637 }"
12638   [(set_attr "type" "arith_media")
12639    (set_attr "highpart" "ignore")])
12640
12641 (define_insn "*mshflo_l_di_x_rev"
12642   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12643         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12644                            (const_int 32))
12645                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12646
12647   "TARGET_SHMEDIA"
12648   "mshflo.l     %N2, %N1, %0"
12649   [(set_attr "type" "arith_media")
12650    (set_attr "highpart" "ignore")])
12651
12652 (define_insn "ashlv2si3"
12653   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12654         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12655                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12656   "TARGET_SHMEDIA"
12657   "mshlld.l     %1, %2, %0"
12658   [(set_attr "type" "arith_media")
12659    (set_attr "highpart" "depend")])
12660
12661 (define_split
12662   [(set (match_operand 0 "any_register_operand" "")
12663         (match_operator 3 "shift_operator"
12664           [(match_operand 1 "any_register_operand" "")
12665            (match_operand 2 "shift_count_reg_operand" "")]))]
12666   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12667   [(set (match_dup 0) (match_dup 3))]
12668   "
12669 {
12670   rtx count = operands[2];
12671   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12672
12673   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12674          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12675          || GET_CODE (count) == TRUNCATE)
12676     count = XEXP (count, 0);
12677   inner_mode = GET_MODE (count);
12678   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12679                                subreg_lowpart_offset (outer_mode, inner_mode));
12680   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12681                                 operands[1], count);
12682 }")
12683
12684 (define_insn "ashlv4hi3"
12685   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12686         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12687                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12688   "TARGET_SHMEDIA"
12689   "mshlld.w     %1, %2, %0"
12690   [(set_attr "type" "arith_media")
12691    (set_attr "highpart" "depend")])
12692
12693 (define_insn "lshrv2si3"
12694   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12695         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12696                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12697   "TARGET_SHMEDIA"
12698   "mshlrd.l     %1, %2, %0"
12699   [(set_attr "type" "arith_media")
12700    (set_attr "highpart" "depend")])
12701
12702 (define_insn "lshrv4hi3"
12703   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12704         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12705                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12706   "TARGET_SHMEDIA"
12707   "mshlrd.w     %1, %2, %0"
12708   [(set_attr "type" "arith_media")
12709    (set_attr "highpart" "depend")])
12710
12711 (define_insn "subv2si3"
12712   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12713         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12714                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12715   "TARGET_SHMEDIA"
12716   "msub.l       %N1, %2, %0"
12717   [(set_attr "type" "arith_media")
12718    (set_attr "highpart" "depend")])
12719
12720 (define_insn "subv4hi3"
12721   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12722         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12723                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12724   "TARGET_SHMEDIA"
12725   "msub.w       %N1, %2, %0"
12726   [(set_attr "type" "arith_media")
12727    (set_attr "highpart" "depend")])
12728
12729 (define_insn_and_split "subv2hi3"
12730   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12731         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12732                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12733   "TARGET_SHMEDIA"
12734   "#"
12735   "TARGET_SHMEDIA"
12736   [(const_int 0)]
12737   "
12738 {
12739   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12740   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12741   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12742   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12743   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12744
12745   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12746   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12747   DONE;
12748 }"
12749   [(set_attr "highpart" "must_split")])
12750
12751 (define_insn "sssubv2si3"
12752   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12753         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12754                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12755   "TARGET_SHMEDIA"
12756   "msubs.l      %N1, %2, %0"
12757   [(set_attr "type" "mcmp_media")
12758    (set_attr "highpart" "depend")])
12759
12760 (define_insn "ussubv8qi3"
12761   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12762         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12763                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12764   "TARGET_SHMEDIA"
12765   "msubs.ub     %N1, %2, %0"
12766   [(set_attr "type" "mcmp_media")
12767    (set_attr "highpart" "depend")])
12768
12769 (define_insn "sssubv4hi3"
12770   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12771         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12772                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12773   "TARGET_SHMEDIA"
12774   "msubs.w      %N1, %2, %0"
12775   [(set_attr "type" "mcmp_media")
12776    (set_attr "highpart" "depend")])
12777
12778 ;; Floating Point Intrinsics
12779
12780 (define_insn "fcosa_s"
12781   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12782         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12783                    UNSPEC_FCOSA))]
12784   "TARGET_SHMEDIA"
12785   "fcosa.s      %1, %0"
12786   [(set_attr "type" "atrans_media")])
12787
12788 (define_insn "fsina_s"
12789   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12790         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12791                    UNSPEC_FSINA))]
12792   "TARGET_SHMEDIA"
12793   "fsina.s      %1, %0"
12794   [(set_attr "type" "atrans_media")])
12795
12796 (define_insn "fipr"
12797   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12798         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12799                                                     "fp_arith_reg_operand" "f")
12800                                                    (match_operand:V4SF 2
12801                                                     "fp_arith_reg_operand" "f"))
12802                                          (parallel [(const_int 0)]))
12803                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12804                                          (parallel [(const_int 1)])))
12805                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12806                                          (parallel [(const_int 2)]))
12807                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12808                                          (parallel [(const_int 3)])))))]
12809   "TARGET_SHMEDIA"
12810   "fipr.s       %1, %2, %0"
12811   [(set_attr "type" "fparith_media")])
12812
12813 (define_insn "fsrra_s"
12814   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12815         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12816                    UNSPEC_FSRRA))]
12817   "TARGET_SHMEDIA"
12818   "fsrra.s      %1, %0"
12819   [(set_attr "type" "atrans_media")])
12820
12821 (define_insn "ftrv"
12822   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12823         (plus:V4SF
12824          (plus:V4SF
12825           (mult:V4SF
12826            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12827                             (parallel [(const_int 0) (const_int 5)
12828                                        (const_int 10) (const_int 15)]))
12829            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12830           (mult:V4SF
12831            (vec_select:V4SF (match_dup 1)
12832                             (parallel [(const_int 4) (const_int 9)
12833                                        (const_int 14) (const_int 3)]))
12834            (vec_select:V4SF (match_dup 2)
12835                             (parallel [(const_int 1) (const_int 2)
12836                                        (const_int 3) (const_int 0)]))))
12837          (plus:V4SF
12838           (mult:V4SF
12839            (vec_select:V4SF (match_dup 1)
12840                             (parallel [(const_int 8) (const_int 13)
12841                                        (const_int 2) (const_int 7)]))
12842            (vec_select:V4SF (match_dup 2)
12843                             (parallel [(const_int 2) (const_int 3)
12844                                        (const_int 0) (const_int 1)])))
12845           (mult:V4SF
12846            (vec_select:V4SF (match_dup 1)
12847                             (parallel [(const_int 12) (const_int 1)
12848                                        (const_int 6) (const_int 11)]))
12849            (vec_select:V4SF (match_dup 2)
12850                             (parallel [(const_int 3) (const_int 0)
12851                                        (const_int 1) (const_int 2)]))))))]
12852   "TARGET_SHMEDIA"
12853   "ftrv.s %1, %2, %0"
12854   [(set_attr "type" "fparith_media")])
12855
12856 (define_insn "ldhi_l"
12857   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12858         (zero_extract:SI
12859          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12860                                   (const_int 3))
12861                           (const_int -3)))
12862          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12863          (const_int 0)))]
12864   "TARGET_SHMEDIA32"
12865   "ldhi.l       %U1, %0"
12866   [(set_attr "type" "load_media")])
12867
12868 (define_insn "ldhi_q"
12869   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12870         (zero_extract:DI
12871          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12872                                   (const_int 7))
12873                           (const_int -7)))
12874          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12875          (const_int 0)))]
12876   "TARGET_SHMEDIA32"
12877   "ldhi.q       %U1, %0"
12878   [(set_attr "type" "load_media")])
12879
12880 (define_insn_and_split "*ldhi_q_comb0"
12881   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12882         (zero_extract:DI
12883          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12884                                             "register_operand" "r")
12885                                            (match_operand:SI 2
12886                                             "ua_offset" "I06"))
12887                                   (const_int 7))
12888                           (const_int -7)))
12889          (plus:SI (and:SI (match_dup 1) (const_int 7))
12890                   (const_int 1))
12891          (const_int 0)))]
12892   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12893   "#"
12894   ""
12895   [(pc)]
12896   "emit_insn (gen_ldhi_q (operands[0],
12897                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12898    DONE;")
12899
12900
12901 (define_insn_and_split "*ldhi_q_comb1"
12902   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12903         (zero_extract:DI
12904          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12905                                             "register_operand" "r")
12906                                            (match_operand:SI 2
12907                                             "ua_offset" "I06"))
12908                                   (const_int 7))
12909                           (const_int -7)))
12910          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12911                                                    "ua_offset" "I06"))
12912                           (const_int 7))
12913                   (const_int 1))
12914          (const_int 0)))]
12915   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12916    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12917   "#"
12918   ""
12919   [(pc)]
12920   "emit_insn (gen_ldhi_q (operands[0],
12921                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12922    DONE;")
12923
12924
12925 (define_insn "ldlo_l"
12926   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12927         (zero_extract:SI
12928          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12929                          (const_int -4)))
12930          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12931          (and:SI (match_dup 1) (const_int 3))))]
12932   "TARGET_SHMEDIA32"
12933   "ldlo.l       %U1, %0"
12934   [(set_attr "type" "load_media")])
12935
12936 (define_insn "ldlo_q"
12937   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12938         (zero_extract:DI
12939          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12940                          (const_int -8)))
12941          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12942          (and:SI (match_dup 1) (const_int 7))))]
12943   "TARGET_SHMEDIA32"
12944   "ldlo.q       %U1, %0"
12945   [(set_attr "type" "load_media")])
12946
12947 (define_insn_and_split "*ldlo_q_comb0"
12948   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12949         (zero_extract:DI
12950          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12951                                   (match_operand:SI 2 "ua_offset" "I06"))
12952                          (const_int -8)))
12953          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12954          (and:SI (match_dup 1) (const_int 7))))]
12955   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12956   "#"
12957   ""
12958   [(pc)]
12959   "emit_insn (gen_ldlo_q (operands[0],
12960                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12961    DONE;")
12962
12963 (define_insn_and_split "*ldlo_q_comb1"
12964   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12965         (zero_extract:DI
12966          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12967                                   (match_operand:SI 2 "ua_offset" "I06"))
12968                          (const_int -8)))
12969          (minus:SI (const_int 8)
12970                    (and:SI (plus:SI (match_dup 1)
12971                                     (match_operand:SI 3 "ua_offset" "I06"))
12972                            (const_int 7)))
12973          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12974   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12975    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12976   "#"
12977   ""
12978   [(pc)]
12979   "emit_insn (gen_ldlo_q (operands[0],
12980                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12981    DONE;")
12982
12983 (define_insn "sthi_l"
12984   [(set (zero_extract:SI
12985          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12986                                   (const_int 3))
12987                           (const_int -3)))
12988          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12989          (const_int 0))
12990         (match_operand:SI 1 "arith_reg_operand" "r"))]
12991   "TARGET_SHMEDIA32"
12992   "sthi.l       %U0, %1"
12993   [(set_attr "type" "ustore_media")])
12994
12995 ;; All unaligned stores are considered to be 'narrow' because they typically
12996 ;; operate on less that a quadword, and when they operate on a full quadword,
12997 ;; the vanilla store high / store low sequence will cause a stall if not
12998 ;; scheduled apart.
12999 (define_insn "sthi_q"
13000   [(set (zero_extract:DI
13001          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13002                                   (const_int 7))
13003                           (const_int -7)))
13004          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13005          (const_int 0))
13006         (match_operand:DI 1 "arith_reg_operand" "r"))]
13007   "TARGET_SHMEDIA32"
13008   "sthi.q       %U0, %1"
13009   [(set_attr "type" "ustore_media")])
13010
13011 (define_insn_and_split "*sthi_q_comb0"
13012   [(set (zero_extract:DI
13013          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13014                                             "register_operand" "r")
13015                                            (match_operand:SI 1 "ua_offset"
13016                                             "I06"))
13017                                   (const_int 7))
13018                           (const_int -7)))
13019          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13020          (const_int 0))
13021         (match_operand:DI 2 "arith_reg_operand" "r"))]
13022   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13023   "#"
13024   ""
13025   [(pc)]
13026   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13027                           operands[2]));
13028    DONE;")
13029
13030 (define_insn_and_split "*sthi_q_comb1"
13031   [(set (zero_extract:DI
13032          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13033                                             "register_operand" "r")
13034                                            (match_operand:SI 1 "ua_offset"
13035                                             "I06"))
13036                                   (const_int 7))
13037                           (const_int -7)))
13038          (plus:SI (and:SI (plus:SI (match_dup 0)
13039                                    (match_operand:SI 2 "ua_offset" "I06"))
13040                           (const_int 7))
13041                   (const_int 1))
13042          (const_int 0))
13043         (match_operand:DI 3 "arith_reg_operand" "r"))]
13044   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13045    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13046   "#"
13047   ""
13048   [(pc)]
13049   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13050                           operands[3]));
13051    DONE;")
13052
13053 ;; This is highpart user because the address is used as full 64 bit.
13054 (define_insn "stlo_l"
13055   [(set (zero_extract:SI
13056          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13057                          (const_int -4)))
13058          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13059          (and:SI (match_dup 0) (const_int 3)))
13060         (match_operand:SI 1 "arith_reg_operand" "r"))]
13061   "TARGET_SHMEDIA32"
13062   "stlo.l       %U0, %1"
13063   [(set_attr "type" "ustore_media")])
13064
13065 (define_insn "stlo_q"
13066   [(set (zero_extract:DI
13067          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13068                          (const_int -8)))
13069          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13070          (and:SI (match_dup 0) (const_int 7)))
13071         (match_operand:DI 1 "arith_reg_operand" "r"))]
13072   "TARGET_SHMEDIA32"
13073   "stlo.q       %U0, %1"
13074   [(set_attr "type" "ustore_media")])
13075
13076 (define_insn_and_split "*stlo_q_comb0"
13077   [(set (zero_extract:DI
13078          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13079                                   (match_operand:SI 1 "ua_offset" "I06"))
13080                          (const_int -8)))
13081          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13082          (and:SI (match_dup 0) (const_int 7)))
13083         (match_operand:DI 2 "arith_reg_operand" "r"))]
13084   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13085   "#"
13086   ""
13087   [(pc)]
13088   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13089                           operands[2]));
13090    DONE;")
13091
13092 (define_insn_and_split "*stlo_q_comb1"
13093   [(set (zero_extract:DI
13094          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13095                                   (match_operand:SI 1 "ua_offset" "I06"))
13096                          (const_int -8)))
13097          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13098                                                   (match_operand:SI 2
13099                                                    "ua_offset" "I06"))
13100                                          (const_int 7)))
13101          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13102         (match_operand:DI 3 "arith_reg_operand" "r"))]
13103   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13104   "#"
13105   ""
13106   [(pc)]
13107   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13108                           operands[3]));
13109    DONE;")
13110
13111 (define_insn "ldhi_l64"
13112   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13113         (zero_extract:SI
13114          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13115                                   (const_int 3))
13116                           (const_int -3)))
13117          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13118          (const_int 0)))]
13119   "TARGET_SHMEDIA64"
13120   "ldhi.l       %U1, %0"
13121   [(set_attr "type" "load_media")])
13122
13123 (define_insn "ldhi_q64"
13124   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13125         (zero_extract:DI
13126          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13127                                   (const_int 7))
13128                           (const_int -7)))
13129          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13130          (const_int 0)))]
13131   "TARGET_SHMEDIA64"
13132   "ldhi.q       %U1, %0"
13133   [(set_attr "type" "load_media")])
13134
13135 (define_insn "ldlo_l64"
13136   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13137         (zero_extract:SI
13138          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13139                          (const_int -4)))
13140          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13141          (and:DI (match_dup 1) (const_int 3))))]
13142   "TARGET_SHMEDIA64"
13143   "ldlo.l       %U1, %0"
13144   [(set_attr "type" "load_media")])
13145
13146 (define_insn "ldlo_q64"
13147   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13148         (zero_extract:DI
13149          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13150                          (const_int -8)))
13151          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13152          (and:DI (match_dup 1) (const_int 7))))]
13153   "TARGET_SHMEDIA64"
13154   "ldlo.q       %U1, %0"
13155   [(set_attr "type" "load_media")])
13156
13157 (define_insn "sthi_l64"
13158   [(set (zero_extract:SI
13159          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13160                                   (const_int 3))
13161                           (const_int -3)))
13162          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13163          (const_int 0))
13164         (match_operand:SI 1 "arith_reg_operand" "r"))]
13165   "TARGET_SHMEDIA64"
13166   "sthi.l       %U0, %1"
13167   [(set_attr "type" "ustore_media")])
13168
13169 (define_insn "sthi_q64"
13170   [(set (zero_extract:DI
13171          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13172                                   (const_int 7))
13173                           (const_int -7)))
13174          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13175          (const_int 0))
13176         (match_operand:DI 1 "arith_reg_operand" "r"))]
13177   "TARGET_SHMEDIA64"
13178   "sthi.q       %U0, %1"
13179   [(set_attr "type" "ustore_media")])
13180
13181 (define_insn "stlo_l64"
13182   [(set (zero_extract:SI
13183          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13184                          (const_int -4)))
13185          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13186          (and:DI (match_dup 0) (const_int 3)))
13187         (match_operand:SI 1 "arith_reg_operand" "r"))]
13188   "TARGET_SHMEDIA64"
13189   "stlo.l       %U0, %1"
13190   [(set_attr "type" "ustore_media")])
13191
13192 (define_insn "stlo_q64"
13193   [(set (zero_extract:DI
13194          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13195                          (const_int -8)))
13196          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13197          (and:DI (match_dup 0) (const_int 7)))
13198         (match_operand:DI 1 "arith_reg_operand" "r"))]
13199   "TARGET_SHMEDIA64"
13200   "stlo.q       %U0, %1"
13201   [(set_attr "type" "ustore_media")])
13202
13203 (define_insn "nsb"
13204   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13205         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13206                    UNSPEC_NSB))]
13207   "TARGET_SHMEDIA"
13208   "nsb  %1, %0"
13209   [(set_attr "type" "arith_media")])
13210
13211 (define_insn "nsbsi"
13212   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13213         (zero_extend:SI
13214          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13215                     UNSPEC_NSB)))]
13216   "TARGET_SHMEDIA"
13217   "nsb  %1, %0"
13218   [(set_attr "type" "arith_media")])
13219
13220 (define_insn "nsbdi"
13221   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13222         (zero_extend:DI
13223          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13224                     UNSPEC_NSB)))]
13225   "TARGET_SHMEDIA"
13226   "nsb  %1, %0"
13227   [(set_attr "type" "arith_media")])
13228
13229 (define_expand "ffsdi2"
13230   [(set (match_operand:DI 0 "arith_reg_dest" "")
13231         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13232   "TARGET_SHMEDIA"
13233   "
13234 {
13235   rtx scratch = gen_reg_rtx (DImode);
13236   rtx last;
13237
13238   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13239   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13240   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13241   emit_insn (gen_nsbdi (scratch, scratch));
13242   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13243   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13244   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13245   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13246
13247   DONE;
13248 }")
13249
13250 (define_expand "ffssi2"
13251   [(set (match_operand:SI 0 "arith_reg_dest" "")
13252         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13253   "TARGET_SHMEDIA"
13254   "
13255 {
13256   rtx scratch = gen_reg_rtx (SImode);
13257   rtx discratch = gen_reg_rtx (DImode);
13258   rtx last;
13259
13260   emit_insn (gen_adddi3 (discratch,
13261                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13262                          constm1_rtx));
13263   emit_insn (gen_andcdi3 (discratch,
13264                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13265                           discratch));
13266   emit_insn (gen_nsbsi (scratch, discratch));
13267   last = emit_insn (gen_subsi3 (operands[0],
13268                                 force_reg (SImode, GEN_INT (63)), scratch));
13269   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13270
13271   DONE;
13272 }")
13273
13274 (define_insn "byterev"
13275   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13276         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13277                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13278                                     (const_int 4) (const_int 3) (const_int 2)
13279                                     (const_int 1) (const_int 0)])))]
13280   "TARGET_SHMEDIA"
13281   "byterev      %1, %0"
13282   [(set_attr "type" "arith_media")])
13283
13284 (define_insn "*prefetch_media"
13285   [(prefetch (match_operand:QI 0 "address_operand" "p")
13286              (match_operand:SI 1 "const_int_operand" "n")
13287              (match_operand:SI 2 "const_int_operand" "n"))]
13288   "TARGET_SHMEDIA"
13289   "*
13290 {
13291   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13292   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13293   return \"\";
13294 }"
13295   [(set_attr "type" "other")])
13296
13297 (define_insn "*prefetch_i4"
13298   [(prefetch (match_operand:SI 0 "register_operand" "r")
13299              (match_operand:SI 1 "const_int_operand" "n")
13300              (match_operand:SI 2 "const_int_operand" "n"))]
13301   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13302   "*
13303 {
13304   return \"pref @%0\";
13305 }"
13306   [(set_attr "type" "other")])
13307
13308 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13309 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13310 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13311 (define_expand "prefetch"
13312   [(prefetch (match_operand 0 "address_operand" "p")
13313              (match_operand:SI 1 "const_int_operand" "n")
13314              (match_operand:SI 2 "const_int_operand" "n"))]
13315   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13316    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13317   "
13318 {
13319   if (GET_MODE (operands[0]) != Pmode
13320       || !CONST_INT_P (operands[1])
13321       || !CONST_INT_P (operands[2]))
13322     FAIL;
13323   if (! TARGET_SHMEDIA)
13324     operands[0] = force_reg (Pmode, operands[0]);
13325 }")
13326
13327 (define_insn "prefetch_m2a"
13328   [(prefetch (match_operand:SI 0 "register_operand" "r")
13329              (match_operand:SI 1 "const_int_operand" "n")
13330              (match_operand:SI 2 "const_int_operand" "n"))]
13331   "TARGET_SH2A"
13332   "pref\\t@%0"
13333   [(set_attr "type" "other")])
13334
13335 (define_insn "alloco_i"
13336   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13337         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13338   "TARGET_SHMEDIA32"
13339   "*
13340 {
13341   rtx xops[2];
13342
13343   if (GET_CODE (operands[0]) == PLUS)
13344     {
13345       xops[0] = XEXP (operands[0], 0);
13346       xops[1] = XEXP (operands[0], 1);
13347     }
13348   else
13349     {
13350       xops[0] = operands[0];
13351       xops[1] = const0_rtx;
13352     }
13353   output_asm_insn (\"alloco   %0, %1\", xops);
13354   return \"\";
13355 }"
13356   [(set_attr "type" "other")])
13357
13358 (define_split
13359   [(set (match_operand 0 "any_register_operand" "")
13360         (match_operand 1 "" ""))]
13361   "TARGET_SHMEDIA && reload_completed"
13362   [(set (match_dup 0) (match_dup 1))]
13363   "
13364 {
13365   int n_changes = 0;
13366
13367   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13368   if (!n_changes)
13369     FAIL;
13370 }")
13371
13372 ; Stack Protector Patterns
13373
13374 (define_expand "stack_protect_set"
13375   [(set (match_operand 0 "memory_operand" "")
13376         (match_operand 1 "memory_operand" ""))]
13377   ""
13378 {
13379   if (TARGET_SHMEDIA)
13380     {
13381       if (TARGET_SHMEDIA64)
13382         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13383       else
13384         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13385     }
13386   else
13387     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13388
13389   DONE;
13390 })
13391
13392 (define_insn "stack_protect_set_si"
13393   [(set (match_operand:SI 0 "memory_operand" "=m")
13394         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13395    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13396   "!TARGET_SHMEDIA"
13397   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13398   [(set_attr "type" "other")
13399    (set_attr "length" "6")])
13400
13401 (define_insn "stack_protect_set_si_media"
13402   [(set (match_operand:SI 0 "memory_operand" "=m")
13403         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13404    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13405   "TARGET_SHMEDIA"
13406   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13407   [(set_attr "type" "other")
13408    (set_attr "length" "12")])
13409
13410 (define_insn "stack_protect_set_di_media"
13411   [(set (match_operand:DI 0 "memory_operand" "=m")
13412         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13413    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13414   "TARGET_SHMEDIA64"
13415   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13416   [(set_attr "type" "other")
13417    (set_attr "length" "12")])
13418
13419 (define_expand "stack_protect_test"
13420   [(match_operand 0 "memory_operand" "")
13421    (match_operand 1 "memory_operand" "")
13422    (match_operand 2 "" "")]
13423   ""
13424 {
13425   if (TARGET_SHMEDIA)
13426     {
13427       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13428       rtx test;
13429
13430       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13431       if (TARGET_SHMEDIA64)
13432         {
13433           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13434                                                       operands[1]));
13435           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13436         }
13437       else
13438         {
13439           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13440                                                       operands[1]));
13441           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13442         }
13443     }
13444   else
13445     {
13446       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13447       emit_jump_insn (gen_branch_true (operands[2]));
13448     }
13449
13450   DONE;
13451 })
13452
13453 (define_insn "stack_protect_test_si"
13454   [(set (reg:SI T_REG)
13455         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13456                     (match_operand:SI 1 "memory_operand" "m")]
13457                    UNSPEC_SP_TEST))
13458   (set (match_scratch:SI 2 "=&r") (const_int 0))
13459   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13460   "!TARGET_SHMEDIA"
13461   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13462   [(set_attr "type" "other")
13463    (set_attr "length" "10")])
13464
13465 (define_insn "stack_protect_test_si_media"
13466   [(set (match_operand:SI 0 "register_operand" "=&r")
13467         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13468                     (match_operand:SI 2 "memory_operand" "m")]
13469                    UNSPEC_SP_TEST))
13470   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13471   "TARGET_SHMEDIA"
13472   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13473   [(set_attr "type" "other")
13474    (set_attr "length" "16")])
13475
13476 (define_insn "stack_protect_test_di_media"
13477   [(set (match_operand:DI 0 "register_operand" "=&r")
13478         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13479                     (match_operand:DI 2 "memory_operand" "m")]
13480                    UNSPEC_SP_TEST))
13481   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13482   "TARGET_SHMEDIA64"
13483   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13484   [(set_attr "type" "other")
13485    (set_attr "length" "16")])