Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993-2013 Free Software Foundation, Inc.
3 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
4 ;;  Improved by Jim Wilson (wilson@cygnus.com).
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22
23 ;; ??? Should prepend a * to all pattern names which are not used.
24 ;; This will make the compiler smaller, and rebuilds after changes faster.
25
26 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
27 ;; sequences.  Especially the sequences for arithmetic right shifts.
28
29 ;; ??? Should check all DImode patterns for consistency and usefulness.
30
31 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
32 ;; way to generate them.
33
34 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
35 ;; for a str* inline function.
36
37 ;; BSR is not generated by the compiler proper, but when relaxing, it
38 ;; generates .uses pseudo-ops that allow linker relaxation to create
39 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
40
41 ;; Special constraints for SH machine description:
42 ;;
43 ;;    t -- T
44 ;;    x -- mac
45 ;;    l -- pr
46 ;;    z -- r0
47 ;;
48 ;; Special formats used for outputting SH instructions:
49 ;;
50 ;;   %.  --  print a .s if insn needs delay slot
51 ;;   %@  --  print rte/rts if is/isn't an interrupt function
52 ;;   %#  --  output a nop if there is nothing to put in the delay slot
53 ;;   %O  --  print a constant without the #
54 ;;   %R  --  print the lsw reg of a double
55 ;;   %S  --  print the msw reg of a double
56 ;;   %T  --  print next word of a double REG or MEM
57 ;;
58 ;; Special predicates:
59 ;;
60 ;;  arith_operand          -- operand is valid source for arithmetic op
61 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
62 ;;  general_movdst_operand -- operand is valid move destination
63 ;;  general_movsrc_operand -- operand is valid move source
64 ;;  logical_operand        -- operand is valid source for logical op
65
66 ;; -------------------------------------------------------------------------
67 ;; Constants
68 ;; -------------------------------------------------------------------------
69
70 (define_constants [
71   (AP_REG       145)
72   (PR_REG       146)
73   (T_REG        147)
74   (GBR_REG      144)
75   (MACH_REG     148)
76   (MACL_REG     149)
77   (FPUL_REG     150)
78   (RAP_REG      152)
79
80   (FPSCR_REG    151)
81
82   (PIC_REG      12)
83   (FP_REG       14)
84   (SP_REG       15)
85
86   (PR_MEDIA_REG 18)
87   (T_MEDIA_REG  19)
88
89   (R0_REG       0)
90   (R1_REG       1)
91   (R2_REG       2)
92   (R3_REG       3)
93   (R4_REG       4)
94   (R5_REG       5)
95   (R6_REG       6)
96   (R7_REG       7)
97   (R8_REG       8)
98   (R9_REG       9)
99   (R10_REG      10)
100   (R20_REG      20)
101   (R21_REG      21)
102   (R22_REG      22)
103   (R23_REG      23)
104
105   (DR0_REG      64)
106   (DR2_REG      66)
107   (DR4_REG      68)
108   (FR23_REG     87)
109
110   (TR0_REG      128)
111   (TR1_REG      129)
112   (TR2_REG      130)
113
114   (XD0_REG      136)
115
116   ;; These are used with unspec.
117   (UNSPEC_COMPACT_ARGS  0)
118   (UNSPEC_MOVA          1)
119   (UNSPEC_CASESI        2)
120   (UNSPEC_DATALABEL     3)
121   (UNSPEC_BBR           4)
122   (UNSPEC_SFUNC         5)
123   (UNSPEC_PIC           6)
124   (UNSPEC_GOT           7)
125   (UNSPEC_GOTOFF        8)
126   (UNSPEC_PLT           9)
127   (UNSPEC_CALLER        10)
128   (UNSPEC_GOTPLT        11)
129   (UNSPEC_ICACHE        12)
130   (UNSPEC_INIT_TRAMP    13)
131   (UNSPEC_FCOSA         14)
132   (UNSPEC_FSRRA         15)
133   (UNSPEC_FSINA         16)
134   (UNSPEC_NSB           17)
135   (UNSPEC_ALLOCO        18)
136   (UNSPEC_TLSGD         20)
137   (UNSPEC_TLSLDM        21)
138   (UNSPEC_TLSIE         22)
139   (UNSPEC_DTPOFF        23)
140   (UNSPEC_GOTTPOFF      24)
141   (UNSPEC_TPOFF         25)
142   (UNSPEC_RA            26)
143   (UNSPEC_DIV_INV_M0    30)
144   (UNSPEC_DIV_INV_M1    31)
145   (UNSPEC_DIV_INV_M2    32)
146   (UNSPEC_DIV_INV_M3    33)
147   (UNSPEC_DIV_INV20     34)
148   (UNSPEC_DIV_INV_TABLE 37)
149   (UNSPEC_ASHIFTRT      35)
150   (UNSPEC_THUNK         36)
151   (UNSPEC_CHKADD        38)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
155
156   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158   (UNSPEC_EXTRACT_S16   43)
159   (UNSPEC_EXTRACT_U16   44)
160
161   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
162   (UNSPEC_SYMOFF        45)
163
164   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165   (UNSPEC_PCREL_SYMOFF  46)
166
167   ;; These are used with unspec_volatile.
168   (UNSPECV_BLOCKAGE     0)
169   (UNSPECV_ALIGN        1)
170   (UNSPECV_CONST2       2)
171   (UNSPECV_CONST4       4)
172   (UNSPECV_CONST8       6)
173   (UNSPECV_WINDOW_END   10)
174   (UNSPECV_CONST_END    11)
175   (UNSPECV_EH_RETURN    12)
176   (UNSPECV_GBR          13)
177   (UNSPECV_SP_SWITCH_B  14)
178   (UNSPECV_SP_SWITCH_E  15)
179 ])
180
181 ;; -------------------------------------------------------------------------
182 ;; Attributes
183 ;; -------------------------------------------------------------------------
184
185 ;; Target CPU.
186
187 (define_attr "cpu"
188  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
189   (const (symbol_ref "sh_cpu_attr")))
190
191 (define_attr "endian" "big,little"
192  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
193                       (const_string "little") (const_string "big"))))
194
195 ;; Indicate if the default fpu mode is single precision.
196 (define_attr "fpu_single" "yes,no"
197   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
198                        (const_string "yes") (const_string "no"))))
199
200 (define_attr "fmovd" "yes,no"
201   (const (if_then_else (symbol_ref "TARGET_FMOVD")
202                        (const_string "yes") (const_string "no"))))
203 ;; pipeline model
204 (define_attr "pipe_model" "sh1,sh4,sh5media"
205   (const
206    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
207           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
208          (const_string "sh1"))))
209
210 ;; cbranch      conditional branch instructions
211 ;; jump         unconditional jumps
212 ;; arith        ordinary arithmetic
213 ;; arith3       a compound insn that behaves similarly to a sequence of
214 ;;              three insns of type arith
215 ;; arith3b      like above, but might end with a redirected branch
216 ;; load         from memory
217 ;; load_si      Likewise, SImode variant for general register.
218 ;; fload        Likewise, but load to fp register.
219 ;; store        to memory
220 ;; fstore       floating point register to memory
221 ;; move         general purpose register to register
222 ;; movi8        8-bit immediate to general purpose register
223 ;; mt_group     other sh4 mt instructions
224 ;; fmove        register to register, floating point
225 ;; smpy         word precision integer multiply
226 ;; dmpy         longword or doublelongword precision integer multiply
227 ;; return       rts
228 ;; pload        load of pr reg, which can't be put into delay slot of rts
229 ;; prset        copy register to pr reg, ditto
230 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
231 ;; prget        copy pr to register, ditto
232 ;; pcload       pc relative load of constant value
233 ;; pcfload      Likewise, but load to fp register.
234 ;; pcload_si    Likewise, SImode variant for general register.
235 ;; rte          return from exception
236 ;; sfunc        special function call with known used registers
237 ;; call         function call
238 ;; fp           floating point
239 ;; fpscr_toggle toggle a bit in the fpscr
240 ;; fdiv         floating point divide (or square root)
241 ;; gp_fpul      move from general purpose register to fpul
242 ;; fpul_gp      move from fpul to general purpose register
243 ;; mac_gp       move from mac[lh] to general purpose register
244 ;; gp_mac       move from general purpose register to mac[lh]
245 ;; mac_mem      move from mac[lh] to memory
246 ;; mem_mac      move from memory to mac[lh]
247 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
248 ;; ftrc_s       fix_truncsfsi2_i4
249 ;; dfdiv        double precision floating point divide (or square root)
250 ;; cwb          ic_invalidate_line_i
251 ;; movua        SH4a unaligned load
252 ;; fsrra        square root reciprocal approximate
253 ;; fsca         sine and cosine approximate
254 ;; tls_load     load TLS related address
255 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
256 ;; cbranch_media SHmedia conditional branch instructions
257 ;; cmp_media    SHmedia compare instructions
258 ;; dfdiv_media  SHmedia double precision divide and square root
259 ;; dfmul_media  SHmedia double precision multiply instruction
260 ;; dfparith_media SHmedia double precision floating point arithmetic
261 ;; dfpconv_media SHmedia double precision floating point conversions
262 ;; dmpy_media   SHmedia longword multiply
263 ;; fcmp_media   SHmedia floating point compare instructions
264 ;; fdiv_media   SHmedia single precision divide and square root
265 ;; fload_media  SHmedia floating point register load instructions
266 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
267 ;; fparith_media SHmedia single precision floating point arithmetic
268 ;; fpconv_media SHmedia single precision floating point conversions
269 ;; fstore_media SHmedia floating point register store instructions
270 ;; gettr_media  SHmedia gettr instruction
271 ;; invalidate_line_media SHmedia invalidate_line sequence
272 ;; jump_media   SHmedia unconditional branch instructions
273 ;; load_media   SHmedia general register load instructions
274 ;; pt_media     SHmedia pt instruction (expanded by assembler)
275 ;; ptabs_media  SHmedia ptabs instruction
276 ;; store_media  SHmedia general register store instructions
277 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
278 ;; mac_media    SHmedia mac-style fixed point operations
279 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
280 ;; atrans_media SHmedia approximate transcendental functions
281 ;; ustore_media SHmedia unaligned stores
282 ;; nil          no-op move, will be deleted.
283
284 (define_attr "type"
285  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,
286   fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,
287   prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,
288   dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,
289   gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,
290   arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,
291   dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,
292   fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,
293   jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,
294   d2mpy_media,atrans_media,ustore_media,nil,other"
295   (const_string "other"))
296
297 ;; We define a new attribute namely "insn_class".We use
298 ;; this for the DFA based pipeline description.
299 ;;
300 ;; mt_group      SH4 "mt" group instructions.
301 ;;
302 ;; ex_group      SH4 "ex" group instructions.
303 ;;
304 ;; ls_group      SH4 "ls" group instructions.
305 ;;
306 (define_attr "insn_class"
307   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
308   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
309          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
310          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,
311                           store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
312          (eq_attr "type" "cbranch,jump") (const_string "br_group")
313          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
314            (const_string "fe_group")
315          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,
316                           prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,
317                           gp_mac,mac_mem,mem_mac") (const_string "co_group")]
318         (const_string "none")))
319
320 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
321 ;; so these do not belong in an insn group, although they are modeled
322 ;; with their own define_insn_reservations.
323
324 ;; Indicate what precision must be selected in fpscr for this insn, if any.
325 (define_attr "fp_mode" "single,double,none" (const_string "none"))
326
327 ;; Indicate if the fpu mode is set by this instruction
328 ;; "unknown" must have the value as "none" in fp_mode, and means
329 ;; that the instruction/abi has left the processor in an unknown
330 ;; state.
331 ;; "none" means that nothing has changed and no mode is set.
332 ;; This attribute is only used for the Renesas ABI.
333 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
334
335 ; If a conditional branch destination is within -252..258 bytes away
336 ; from the instruction it can be 2 bytes long.  Something in the
337 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
338 ; branches are initially assumed to be 16 bytes long.
339 ; In machine_dependent_reorg, we split all branches that are longer than
340 ; 2 bytes.
341
342 ;; The maximum range used for SImode constant pool entries is 1018.  A final
343 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
344 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
345 ;; instruction around the pool table, 2 bytes of alignment before the table,
346 ;; and 30 bytes of alignment after the table.  That gives a maximum total
347 ;; pool size of 1058 bytes.
348 ;; Worst case code/pool content size ratio is 1:2 (using asms).
349 ;; Thus, in the worst case, there is one instruction in front of a maximum
350 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
351 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
352 ;; If we have a forward branch, the initial table will be put after the
353 ;; unconditional branch.
354 ;;
355 ;; ??? We could do much better by keeping track of the actual pcloads within
356 ;; the branch range and in the pcload range in front of the branch range.
357
358 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
359 ;; inside an le.
360 (define_attr "short_cbranch_p" "no,yes"
361   (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
364          (const_string "yes")
365          (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
366          (const_string "no")
367          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
368          (const_string "yes")
369          ] (const_string "no")))
370
371 (define_attr "med_branch_p" "no,yes"
372   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
373               (const_int 1988))
374          (const_string "yes")
375          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
378               (const_int 8186))
379          (const_string "yes")
380          ] (const_string "no")))
381
382 (define_attr "med_cbranch_p" "no,yes"
383   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
384               (const_int 1986))
385          (const_string "yes")
386          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
387          (const_string "no")
388          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
389                (const_int 8184))
390          (const_string "yes")
391          ] (const_string "no")))
392
393 (define_attr "braf_branch_p" "no,yes"
394   (cond [(match_test "! TARGET_SH2")
395          (const_string "no")
396          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
397               (const_int 20660))
398          (const_string "yes")
399          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
400          (const_string "no")
401          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
402               (const_int 65530))
403          (const_string "yes")
404          ] (const_string "no")))
405
406 (define_attr "braf_cbranch_p" "no,yes"
407   (cond [(match_test "! TARGET_SH2")
408          (const_string "no")
409          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
410               (const_int 20658))
411          (const_string "yes")
412          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
413          (const_string "no")
414          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
415               (const_int 65528))
416          (const_string "yes")
417          ] (const_string "no")))
418
419 ;; An unconditional jump in the range -4092..4098 can be 2 bytes long.
420 ;; For wider ranges, we need a combination of a code and a data part.
421 ;; If we can get a scratch register for a long range jump, the code
422 ;; part can be 4 bytes long; otherwise, it must be 8 bytes long.
423 ;; If the jump is in the range -32764..32770, the data part can be 2 bytes
424 ;; long; otherwise, it must be 6 bytes long.
425
426 ;; All other instructions are two bytes long by default.
427
428 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
429 ;; but getattrtab doesn't understand this.
430 (define_attr "length" ""
431   (cond [(eq_attr "type" "cbranch")
432          (cond [(eq_attr "short_cbranch_p" "yes")
433                 (const_int 2)
434                 (eq_attr "med_cbranch_p" "yes")
435                 (const_int 6)
436                 (eq_attr "braf_cbranch_p" "yes")
437                 (const_int 12)
438 ;; ??? using pc is not computed transitively.
439                 (ne (match_dup 0) (match_dup 0))
440                 (const_int 14)
441                 (match_test "flag_pic")
442                 (const_int 24)
443                 ] (const_int 16))
444          (eq_attr "type" "jump")
445          (cond [(eq_attr "med_branch_p" "yes")
446                 (const_int 2)
447                 (and (match_test "prev_nonnote_insn (insn)")
448                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
449                               (symbol_ref "INSN"))
450                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
451                               (symbol_ref "code_for_indirect_jump_scratch"))))
452                 (cond [(eq_attr "braf_branch_p" "yes")
453                        (const_int 6)
454                        (not (match_test "flag_pic"))
455                        (const_int 10)
456                        (match_test "TARGET_SH2")
457                        (const_int 10)] (const_int 18))
458                 (eq_attr "braf_branch_p" "yes")
459                 (const_int 10)
460 ;; ??? using pc is not computed transitively.
461                 (ne (match_dup 0) (match_dup 0))
462                 (const_int 12)
463                 (match_test "flag_pic")
464                 (const_int 22)
465                 ] (const_int 14))
466          (eq_attr "type" "pt_media")
467          (if_then_else (match_test "TARGET_SHMEDIA64")
468                        (const_int 20) (const_int 12))
469          (and (eq_attr "type" "jump_media")
470               (match_test "TARGET_SH5_CUT2_WORKAROUND"))
471          (const_int 8)
472          ] (if_then_else (match_test "TARGET_SHMEDIA")
473                          (const_int 4)
474                          (const_int 2))))
475
476 ;; DFA descriptions for the pipelines
477
478 (include "sh1.md")
479 (include "shmedia.md")
480 (include "sh4.md")
481
482 (include "iterators.md")
483 (include "predicates.md")
484 (include "constraints.md")
485
486 ;; Definitions for filling delay slots
487
488 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
489
490 (define_attr "banked" "yes,no" 
491         (cond [(match_test "sh_loads_bankedreg_p (insn)")
492                (const_string "yes")]
493               (const_string "no")))
494
495 ;; ??? This should be (nil) instead of (const_int 0)
496 (define_attr "hit_stack" "yes,no"
497         (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
498                (const_string "no")]
499               (const_string "yes")))
500
501 (define_attr "interrupt_function" "no,yes"
502   (const (symbol_ref "current_function_interrupt")))
503
504 (define_attr "in_delay_slot" "yes,no"
505   (cond [(eq_attr "type" "cbranch") (const_string "no")
506          (eq_attr "type" "pcload,pcload_si") (const_string "no")
507          (eq_attr "needs_delay_slot" "yes") (const_string "no")
508          (eq_attr "length" "2") (const_string "yes")
509          ] (const_string "no")))
510
511 (define_attr "cond_delay_slot" "yes,no"
512   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
513          ] (const_string "no")))
514
515 (define_attr "is_sfunc" ""
516   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
517
518 (define_attr "is_mac_media" ""
519   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
520
521 (define_attr "branch_zero" "yes,no"
522   (cond [(eq_attr "type" "!cbranch") (const_string "no")
523          (ne (symbol_ref "(next_active_insn (insn)\
524                            == (prev_active_insn\
525                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
526                           && get_attr_length (next_active_insn (insn)) == 2")
527              (const_int 0))
528          (const_string "yes")]
529         (const_string "no")))
530
531 ;; SH4 Double-precision computation with double-precision result -
532 ;; the two halves are ready at different times.
533 (define_attr "dfp_comp" "yes,no"
534   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
535         (const_string "no")))
536
537 ;; Insns for which the latency of a preceding fp insn is decreased by one.
538 (define_attr "late_fp_use" "yes,no" (const_string "no"))
539 ;; And feeding insns for which this relevant.
540 (define_attr "any_fp_comp" "yes,no"
541   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
542          (const_string "yes")]
543         (const_string "no")))
544
545 (define_attr "any_int_load" "yes,no"
546   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
547          (const_string "yes")]
548         (const_string "no")))
549
550 (define_attr "highpart" "user, ignore, extend, depend, must_split"
551   (const_string "user"))
552
553 (define_delay
554   (eq_attr "needs_delay_slot" "yes")
555   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
556
557 ;; Since a normal return (rts) implicitly uses the PR register,
558 ;; we can't allow PR register loads in an rts delay slot.
559 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
560 ;; stack, and thus we can't put a pop instruction in its delay slot.
561 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
562 ;; pop instruction can go in the delay slot, unless it references a banked
563 ;; register (the register bank is switched by rte).
564 (define_delay
565   (eq_attr "type" "return")
566   [(and (eq_attr "in_delay_slot" "yes")
567         (ior (and (eq_attr "interrupt_function" "no")
568                   (eq_attr "type" "!pload,prset"))
569              (and (eq_attr "interrupt_function" "yes")
570                   (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
571                   (eq_attr "banked" "no"))))
572    (nil) (nil)])
573
574 ;; Since a call implicitly uses the PR register, we can't allow
575 ;; a PR register store in a jsr delay slot.
576
577 (define_delay
578   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
579   [(and (eq_attr "in_delay_slot" "yes")
580         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
581
582 ;; Say that we have annulled true branches, since this gives smaller and
583 ;; faster code when branches are predicted as not taken.
584
585 ;; ??? The non-annulled condition should really be "in_delay_slot",
586 ;; but insns that can be filled in non-annulled get priority over insns
587 ;; that can only be filled in anulled.
588
589 (define_delay
590   (and (eq_attr "type" "cbranch")
591        (match_test "TARGET_SH2"))
592   ;; SH2e has a hardware bug that pretty much prohibits the use of
593   ;; annulled delay slots.
594   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
595                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
596 \f
597 ;; -------------------------------------------------------------------------
598 ;; SImode signed integer comparisons
599 ;; -------------------------------------------------------------------------
600
601 ;; Various patterns to generate the TST #imm, R0 instruction.
602 ;; Although this adds some pressure on the R0 register, it can potentially
603 ;; result in faster code, even if the operand has to be moved to R0 first.
604 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group 
605 ;; instructions and thus will be executed in parallel.  On SH4A TST #imm, R0
606 ;; is an EX group instruction but still can be executed in parallel with the
607 ;; MT group MOV Rm, Rn instruction.
608
609 ;; Usual TST #imm, R0 patterns for SI, HI and QI
610 ;; This is usually used for bit patterns other than contiguous bits 
611 ;; and single bits.
612 (define_insn "tstsi_t"
613   [(set (reg:SI T_REG)
614         (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
615                        (match_operand:SI 1 "logical_operand" "K08,r"))
616                (const_int 0)))]
617   "TARGET_SH1"
618   "tst  %1,%0"
619   [(set_attr "type" "mt_group")])
620
621 (define_insn "tsthi_t"
622   [(set (reg:SI T_REG)
623         (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
624                                   (match_operand 1 "const_int_operand")) 0)
625                (const_int 0)))]
626   "TARGET_SH1
627    && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
628   "tst  %1,%0"
629   [(set_attr "type" "mt_group")])
630
631 (define_insn "tstqi_t"
632   [(set (reg:SI T_REG)
633         (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
634                                   (match_operand 1 "const_int_operand")) 0)
635                (const_int 0)))]
636   "TARGET_SH1
637    && (CONST_OK_FOR_K08 (INTVAL (operands[1])) 
638        || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
639 {
640   operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
641   return "tst   %1,%0";
642 }
643   [(set_attr "type" "mt_group")])
644
645 ;; Test low QI subreg against zero.
646 ;; This avoids unnecessary zero extension before the test.
647 (define_insn "*tstqi_t_zero"
648   [(set (reg:SI T_REG)
649         (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
650   "TARGET_SH1"
651   "tst  #255,%0"
652   [(set_attr "type" "mt_group")])
653
654 ;; This pattern might be risky because it also tests the upper bits and not
655 ;; only the subreg.  However, it seems that combine will get to this only
656 ;; when testing sign/zero extended values.  In this case the extended upper
657 ;; bits do not matter.
658 (define_insn "*tst<mode>_t_zero"
659   [(set (reg:SI T_REG)
660         (eq:SI
661           (subreg:QIHI
662             (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
663                     (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>)
664           (const_int 0)))]
665   "TARGET_SH1 && TARGET_LITTLE_ENDIAN"
666   "tst  %0,%1"
667   [(set_attr "type" "mt_group")])
668
669 (define_insn "*tst<mode>_t_zero"
670   [(set (reg:SI T_REG)
671         (eq:SI
672           (subreg:QIHI
673             (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
674                     (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>)
675           (const_int 0)))]
676   "TARGET_SH1 && !TARGET_LITTLE_ENDIAN"
677   "tst  %0,%1"
678   [(set_attr "type" "mt_group")])
679
680 ;; Extract LSB, negate and store in T bit.
681 (define_insn "tstsi_t_and_not"
682   [(set (reg:SI T_REG)
683          (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
684                  (const_int 1)))]
685   "TARGET_SH1"
686   "tst  #1,%0"
687   [(set_attr "type" "mt_group")])
688
689 ;; Extract contiguous bits and compare them against zero.
690 (define_insn "tst<mode>_t_zero_extract_eq"
691   [(set (reg:SI T_REG)
692         (eq:SI (zero_extract:SI (match_operand:QIHISIDI 0 "logical_operand" "z")
693                                 (match_operand:SI 1 "const_int_operand")
694                                 (match_operand:SI 2 "const_int_operand"))
695                (const_int 0)))]
696   "TARGET_SH1
697    && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
698 {
699   operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
700   return "tst   %1,%0";
701 }
702   [(set_attr "type" "mt_group")])
703
704 ;; This split is required when testing bits in a QI subreg.
705 (define_split
706   [(set (reg:SI T_REG)
707         (eq:SI
708           (if_then_else:SI
709             (zero_extract:SI (match_operand 0 "logical_operand")
710                              (match_operand 1 "const_int_operand")
711                              (match_operand 2 "const_int_operand"))
712             (match_operand 3 "const_int_operand")
713             (const_int 0))
714           (const_int 0)))]
715   "TARGET_SH1
716    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
717    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
718   [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
719                               (const_int 0)))]
720 {
721   if (GET_MODE (operands[0]) == QImode)
722     operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
723 })
724
725 ;; Extract single bit, negate and store it in the T bit.
726 ;; Not used for SH4A.
727 (define_insn "tstsi_t_zero_extract_xor"
728   [(set (reg:SI T_REG)
729         (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
730                                  (match_operand:SI 3 "const_int_operand"))
731                          (match_operand:SI 1 "const_int_operand")
732                          (match_operand:SI 2 "const_int_operand")))]
733   "TARGET_SH1
734    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
735    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
736   "tst  %3,%0"
737   [(set_attr "type" "mt_group")])
738
739 ;; Extract single bit, negate and store it in the T bit.
740 ;; Used for SH4A little endian.
741 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
742   [(set (reg:SI T_REG)
743         (zero_extract:SI
744          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
745                             (match_operand:SI 3 "const_int_operand")) 0)
746          (match_operand:SI 1 "const_int_operand")
747          (match_operand:SI 2 "const_int_operand")))]
748   "TARGET_SH1 && TARGET_LITTLE_ENDIAN
749    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
750       == (INTVAL (operands[3]) & 255)
751    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
752 {
753   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
754   return "tst   %3,%0";
755 }
756   [(set_attr "type" "mt_group")])
757
758 ;; Extract single bit, negate and store it in the T bit.
759 ;; Used for SH4A big endian.
760 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
761   [(set (reg:SI T_REG)
762         (zero_extract:SI
763          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
764                             (match_operand:SI 3 "const_int_operand")) 3)
765          (match_operand:SI 1 "const_int_operand")
766          (match_operand:SI 2 "const_int_operand")))]
767   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
768    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
769       == (INTVAL (operands[3]) & 255)
770    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
771 {
772   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
773   return "tst   %3,%0";
774 }
775   [(set_attr "type" "mt_group")])
776
777 (define_insn "cmpeqsi_t"
778   [(set (reg:SI T_REG)
779         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
780                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
781   "TARGET_SH1"
782   "@
783         tst     %0,%0
784         cmp/eq  %1,%0
785         cmp/eq  %1,%0"
786    [(set_attr "type" "mt_group")])
787
788 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
789 ;; pattern by itself.  What this actually does is:
790 ;;      x == 0: (1 >> 0-0) & 1 = 1
791 ;;      x != 0: (1 >> 0-x) & 1 = 0
792 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
793 (define_insn_and_split "*cmpeqsi_t"
794   [(set (reg:SI T_REG)
795         (and:SI (lshiftrt:SI
796                   (const_int 1)
797                   (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
798                 (const_int 1)))]
799   "TARGET_SH1"
800   "#"
801   "&& 1"
802   [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
803
804 (define_insn "cmpgtsi_t"
805   [(set (reg:SI T_REG)
806         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
807                (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
808   "TARGET_SH1"
809   "@
810         cmp/pl  %0
811         cmp/gt  %1,%0"
812    [(set_attr "type" "mt_group")])
813
814 (define_insn "cmpgesi_t"
815   [(set (reg:SI T_REG)
816         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
817                (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
818   "TARGET_SH1"
819   "@
820         cmp/pz  %0
821         cmp/ge  %1,%0"
822    [(set_attr "type" "mt_group")])
823
824 ;; FIXME: This is actually wrong.  There is no way to literally move a
825 ;; general reg to t reg.  Luckily, it seems that this pattern will be only
826 ;; used when the general reg is known be either '0' or '1' during combine.
827 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
828 ;; Due to interactions with other patterns, combine fails to pick the latter
829 ;; and invert the dependent logic.
830 (define_insn "*negtstsi"
831   [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
832   "TARGET_SH1"
833   "cmp/pl       %0"
834    [(set_attr "type" "mt_group")])
835
836 ;; Some integer sign comparison patterns can be realized with the div0s insn.
837 ;;      div0s   Rm,Rn           T = (Rm >> 31) ^ (Rn >> 31)
838 (define_insn "cmp_div0s_0"
839   [(set (reg:SI T_REG)
840         (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
841                              (match_operand:SI 1 "arith_reg_operand" "r"))
842                      (const_int 31)))]
843   "TARGET_SH1"
844   "div0s        %0,%1"
845   [(set_attr "type" "arith")])
846
847 (define_insn "cmp_div0s_1"
848   [(set (reg:SI T_REG)
849         (lt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
850                        (match_operand:SI 1 "arith_reg_operand" "r"))
851                (const_int 0)))]
852   "TARGET_SH1"
853   "div0s        %0,%1"
854   [(set_attr "type" "arith")])
855
856 (define_insn_and_split "*cmp_div0s_0"
857   [(set (match_operand:SI 0 "arith_reg_dest" "")
858         (lshiftrt:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
859                              (match_operand:SI 2 "arith_reg_operand" ""))
860                      (const_int 31)))
861    (clobber (reg:SI T_REG))]
862   "TARGET_SH1"
863   "#"
864   "&& 1"
865   [(set (reg:SI T_REG)
866         (lshiftrt:SI (xor:SI (match_dup 1) (match_dup 2)) (const_int 31)))
867    (set (match_dup 0) (reg:SI T_REG))])
868
869 (define_insn_and_split "*cmp_div0s_1"
870   [(set (match_operand:SI 0 "arith_reg_dest" "")
871         (ge:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
872                        (match_operand:SI 2 "arith_reg_operand" ""))
873                (const_int 0)))
874    (clobber (reg:SI T_REG))]
875   "TARGET_SH1"
876   "#"
877   "&& can_create_pseudo_p ()"
878   [(const_int 0)]
879 ;; We have to go through the movnegt expander here which will handle the
880 ;; SH2A vs non-SH2A cases.
881 {
882   emit_insn (gen_cmp_div0s_1 (operands[1], operands[2]));
883   emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
884   DONE;
885 })
886
887 (define_insn_and_split "*cmp_div0s_1"
888   [(set (reg:SI T_REG)
889         (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
890                        (match_operand:SI 1 "arith_reg_operand" ""))
891                (const_int 0)))]
892   "TARGET_SH1"
893   "#"
894   "&& can_create_pseudo_p ()"
895   [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
896                               (const_int 0)))
897    (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
898
899 ;; -------------------------------------------------------------------------
900 ;; SImode compare and branch
901 ;; -------------------------------------------------------------------------
902
903 (define_expand "cbranchsi4"
904   [(set (pc)
905         (if_then_else (match_operator 0 "comparison_operator"
906                         [(match_operand:SI 1 "arith_operand" "")
907                          (match_operand:SI 2 "arith_operand" "")])
908                       (label_ref (match_operand 3 "" ""))
909                       (pc)))
910    (clobber (reg:SI T_REG))]
911   ""
912 {
913   if (TARGET_SHMEDIA)
914     emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
915                                            operands[2], operands[3]));
916   else
917     expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
918
919   DONE;
920 })
921
922 ;; Combine patterns to invert compare and branch operations for which we
923 ;; don't have actual comparison insns.  These patterns are used in cases
924 ;; which appear after the initial cbranchsi expansion, which also does
925 ;; some condition inversion.
926 (define_split
927   [(set (pc)
928         (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
929                           (match_operand:SI 1 "arith_reg_or_0_operand" ""))
930                       (label_ref (match_operand 2))
931                       (pc)))
932    (clobber (reg:SI T_REG))]
933   "TARGET_SH1"
934   [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
935    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
936                            (label_ref (match_dup 2))
937                            (pc)))])
938
939 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
940 ;; and SH2A combine fails to simplify this pattern by itself.
941 ;; What this actually does is:
942 ;;      x == 0: (1 >> 0-0) & 1 = 1
943 ;;      x != 0: (1 >> 0-x) & 1 = 0
944 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
945 (define_split
946   [(set (pc)
947         (if_then_else
948           (eq (and:SI (lshiftrt:SI
949                         (const_int 1)
950                         (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
951                       (const_int 1))
952               (const_int 0))
953           (label_ref (match_operand 2))
954           (pc)))
955    (clobber (reg:SI T_REG))]
956   "TARGET_SH1"
957   [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
958    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
959                            (label_ref (match_dup 2))
960                            (pc)))])
961
962 ;; FIXME: These could probably use code iterators for the compare op.
963 (define_split
964   [(set (pc)
965         (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
966                           (match_operand:SI 1 "arith_reg_or_0_operand" ""))
967                       (label_ref (match_operand 2))
968                       (pc)))
969    (clobber (reg:SI T_REG))]
970   "TARGET_SH1"
971   [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
972    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
973                            (label_ref (match_dup 2))
974                            (pc)))])
975
976 (define_split
977   [(set (pc)
978         (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
979                           (match_operand:SI 1 "arith_reg_or_0_operand" ""))
980                       (label_ref (match_operand 2))
981                       (pc)))
982    (clobber (reg:SI T_REG))]
983   "TARGET_SH1"
984   [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
985    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
986                            (label_ref (match_dup 2))
987                            (pc)))])
988
989 (define_split
990   [(set (pc)
991         (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
992                            (match_operand:SI 1 "arith_reg_operand" ""))
993                       (label_ref (match_operand 2))
994                       (pc)))
995    (clobber (reg:SI T_REG))]
996   "TARGET_SH1"
997   [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
998    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
999                            (label_ref (match_dup 2))
1000                            (pc)))])
1001
1002 (define_split
1003   [(set (pc)
1004         (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
1005                            (match_operand:SI 1 "arith_reg_operand" ""))
1006                       (label_ref (match_operand 2))
1007                       (pc)))
1008    (clobber (reg:SI T_REG))]
1009   "TARGET_SH1"
1010   [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
1011    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1012                            (label_ref (match_dup 2))
1013                            (pc)))])
1014
1015 ;; Compare and branch combine patterns for div0s comparisons.
1016 (define_insn_and_split "*cbranch_div0s"
1017   [(set (pc)
1018         (if_then_else (lt (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1019                                   (match_operand:SI 1 "arith_reg_operand" ""))
1020                           (const_int 0))
1021                       (label_ref (match_operand 2))
1022                       (pc)))
1023    (clobber (reg:SI T_REG))]
1024   "TARGET_SH1"
1025   "#"
1026   "&& 1"
1027   [(set (reg:SI T_REG)
1028         (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1029    (set (pc)
1030         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1031                       (label_ref (match_dup 2))
1032                       (pc)))])
1033
1034 (define_insn_and_split "*cbranch_div0s"
1035   [(set (pc)
1036         (if_then_else (ge (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1037                                   (match_operand:SI 1 "arith_reg_operand" ""))
1038                           (const_int 0))
1039                       (label_ref (match_operand 2))
1040                       (pc)))
1041    (clobber (reg:SI T_REG))]
1042   "TARGET_SH1"
1043   "#"
1044   "&& 1"
1045   [(set (reg:SI T_REG)
1046         (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1047    (set (pc)
1048         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1049                       (label_ref (match_dup 2))
1050                       (pc)))])
1051
1052 ;; Conditional move combine pattern for div0s comparisons.
1053 ;; This is used when TARGET_PRETEND_CMOVE is in effect.
1054 (define_insn_and_split "*movsicc_div0s"
1055   [(set (match_operand:SI 0 "arith_reg_dest" "")
1056         (if_then_else:SI (ge (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
1057                                      (match_operand:SI 2 "arith_reg_operand" ""))
1058                              (const_int 0))
1059                          (match_operand:SI 3 "arith_reg_operand" "")
1060                          (match_operand:SI 4 "general_movsrc_operand" "")))
1061    (clobber (reg:SI T_REG))]
1062   "TARGET_PRETEND_CMOVE"
1063   "#"
1064   "&& 1"
1065   [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1066                               (const_int 0)))
1067    (set (match_dup 0)
1068         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1069                       (match_dup 4)
1070                       (match_dup 3)))])
1071
1072 ;; -------------------------------------------------------------------------
1073 ;; SImode unsigned integer comparisons
1074 ;; -------------------------------------------------------------------------
1075
1076 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1077 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1078 ;; might remain and we have to handle them.  If the '>= 0' case wasn't
1079 ;; handled here, something else would just load a '0' into the second operand
1080 ;; and do the comparison.  We can do slightly better by just setting the
1081 ;; T bit to '1'.
1082 (define_insn_and_split "cmpgeusi_t"
1083   [(set (reg:SI T_REG)
1084         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1085                 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1086   "TARGET_SH1"
1087   "cmp/hs       %1,%0"
1088   "&& satisfies_constraint_Z (operands[1])"
1089   [(set (reg:SI T_REG) (const_int 1))]
1090   ""
1091   [(set_attr "type" "mt_group")])
1092
1093 (define_insn "cmpgtusi_t"
1094   [(set (reg:SI T_REG)
1095         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1096                 (match_operand:SI 1 "arith_reg_operand" "r")))]
1097   "TARGET_SH1"
1098   "cmp/hi       %1,%0"
1099   [(set_attr "type" "mt_group")])
1100 \f
1101 ;; -------------------------------------------------------------------------
1102 ;; DImode compare and branch
1103 ;; -------------------------------------------------------------------------
1104
1105 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1106 ;; Therefore, we aim to have a set of three branches that go straight to the
1107 ;; destination, i.e. only one of them is taken at any one time.
1108 ;; This mechanism should also be slightly better for the sh4-200.
1109
1110 (define_expand "cbranchdi4"
1111   [(set (pc)
1112         (if_then_else (match_operator 0 "comparison_operator"
1113                         [(match_operand:DI 1 "arith_operand" "")
1114                          (match_operand:DI 2 "arith_operand" "")])
1115                       (label_ref (match_operand 3 "" ""))
1116                       (pc)))
1117    (clobber (match_dup 4))
1118    (clobber (reg:SI T_REG))]
1119   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1120 {
1121   enum rtx_code comparison;
1122
1123   if (TARGET_SHMEDIA)
1124     {
1125       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1126                                              operands[2], operands[3]));
1127       DONE;
1128     }
1129   else if (!TARGET_CBRANCHDI4)
1130     {
1131       sh_emit_compare_and_branch (operands, DImode);
1132       DONE;
1133     }
1134   else
1135     {
1136       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1137         DONE;
1138
1139       comparison = prepare_cbranch_operands (operands, DImode,
1140                                              LAST_AND_UNUSED_RTX_CODE);
1141       if (comparison != GET_CODE (operands[0]))
1142         operands[0]
1143           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1144        operands[4] = gen_rtx_SCRATCH (SImode);
1145     }
1146 })
1147
1148 (define_insn_and_split "cbranchdi4_i"
1149   [(set (pc)
1150         (if_then_else (match_operator 0 "comparison_operator"
1151                         [(match_operand:DI 1 "arith_operand" "r,r")
1152                          (match_operand:DI 2 "arith_operand" "rN,I08")])
1153                       (label_ref (match_operand 3 "" ""))
1154                       (pc)))
1155    (clobber (match_scratch:SI 4 "=X,&r"))
1156    (clobber (reg:SI T_REG))]
1157   "TARGET_CBRANCHDI4"
1158   "#"
1159   "&& reload_completed"
1160   [(pc)]
1161 {
1162   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1163     FAIL;
1164   DONE;
1165 })
1166
1167 ;; -------------------------------------------------------------------------
1168 ;; DImode signed integer comparisons
1169 ;; -------------------------------------------------------------------------
1170
1171 (define_insn ""
1172   [(set (reg:SI T_REG)
1173         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1174                        (match_operand:DI 1 "arith_operand" "r"))
1175                (const_int 0)))]
1176   "TARGET_SH1"
1177 {
1178   return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1179                               insn, operands);
1180 }
1181   [(set_attr "length" "6")
1182    (set_attr "type" "arith3b")])
1183
1184 (define_insn "cmpeqdi_t"
1185   [(set (reg:SI T_REG)
1186         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1187                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1188   "TARGET_SH1"
1189 {
1190   static const char* alt[] =
1191   {
1192        "tst     %S0,%S0"        "\n"
1193     "   bf      0f"             "\n"
1194     "   tst     %R0,%R0"        "\n"
1195     "0:",
1196
1197        "cmp/eq  %S1,%S0"        "\n"
1198     "   bf      0f"             "\n"
1199     "   cmp/eq  %R1,%R0"        "\n"
1200     "0:"
1201   };
1202   return alt[which_alternative];
1203 }
1204   [(set_attr "length" "6")
1205    (set_attr "type" "arith3b")])
1206
1207 (define_split
1208   [(set (reg:SI T_REG)
1209         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1210                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1211 ;; If we applied this split when not optimizing, it would only be
1212 ;; applied during the machine-dependent reorg, when no new basic blocks
1213 ;; may be created.
1214   "TARGET_SH1 && reload_completed && optimize"
1215   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1216    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1217                            (label_ref (match_dup 6))
1218                            (pc)))
1219    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1220    (match_dup 6)]
1221 {
1222   operands[2] = gen_highpart (SImode, operands[0]);
1223   operands[3] = operands[1] == const0_rtx
1224                 ? const0_rtx
1225                 : gen_highpart (SImode, operands[1]);
1226   operands[4] = gen_lowpart (SImode, operands[0]);
1227   operands[5] = gen_lowpart (SImode, operands[1]);
1228   operands[6] = gen_label_rtx ();
1229 })
1230
1231 (define_insn "cmpgtdi_t"
1232   [(set (reg:SI T_REG)
1233         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1234                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1235   "TARGET_SH2"
1236 {
1237   static const char* alt[] =
1238   {
1239        "cmp/eq  %S1,%S0"        "\n"
1240     "   bf{.|/}s        0f"     "\n"
1241     "   cmp/gt  %S1,%S0"        "\n"
1242     "   cmp/hi  %R1,%R0"        "\n"
1243     "0:",
1244
1245         "tst    %S0,%S0"        "\n"
1246     "   bf{.|/}s        0f"     "\n"
1247     "   cmp/pl  %S0"            "\n"
1248     "   cmp/hi  %S0,%R0"        "\n"
1249     "0:"
1250   };
1251   return alt[which_alternative];
1252 }
1253   [(set_attr "length" "8")
1254    (set_attr "type" "arith3")])
1255
1256 (define_insn "cmpgedi_t"
1257   [(set (reg:SI T_REG)
1258         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1259                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1260   "TARGET_SH2"
1261 {
1262   static const char* alt[] =
1263   {
1264        "cmp/eq  %S1,%S0"        "\n"
1265     "   bf{.|/}s        0f"     "\n"
1266     "   cmp/ge  %S1,%S0"        "\n"
1267     "   cmp/hs  %R1,%R0"        "\n"
1268     "0:",
1269
1270        "cmp/pz  %S0"
1271   };
1272   return alt[which_alternative];
1273 }
1274   [(set_attr "length" "8,2")
1275    (set_attr "type" "arith3,mt_group")])
1276 \f
1277 ;; -------------------------------------------------------------------------
1278 ;; DImode unsigned integer comparisons
1279 ;; -------------------------------------------------------------------------
1280
1281 (define_insn "cmpgeudi_t"
1282   [(set (reg:SI T_REG)
1283         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1284                 (match_operand:DI 1 "arith_reg_operand" "r")))]
1285   "TARGET_SH2"
1286 {
1287   return       "cmp/eq  %S1,%S0"        "\n"
1288          "      bf{.|/}s        0f"     "\n"
1289          "      cmp/hs  %S1,%S0"        "\n"
1290          "      cmp/hs  %R1,%R0"        "\n"
1291          "0:";
1292 }
1293   [(set_attr "length" "8")
1294    (set_attr "type" "arith3")])
1295
1296 (define_insn "cmpgtudi_t"
1297   [(set (reg:SI T_REG)
1298         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1299                 (match_operand:DI 1 "arith_reg_operand" "r")))]
1300   "TARGET_SH2"
1301 {
1302   return       "cmp/eq  %S1,%S0"        "\n"
1303          "      bf{.|/}s        0f"     "\n"
1304          "      cmp/hi  %S1,%S0"        "\n"
1305          "      cmp/hi  %R1,%R0"        "\n"
1306          "0:";
1307 }
1308   [(set_attr "length" "8")
1309    (set_attr "type" "arith3")])
1310
1311 (define_insn "cmpeqsi_media"
1312   [(set (match_operand:SI 0 "register_operand" "=r")
1313         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1314                (match_operand:SI 2 "cmp_operand" "Nr")))]
1315   "TARGET_SHMEDIA"
1316   "cmpeq        %1, %N2, %0"
1317   [(set_attr "type" "cmp_media")])
1318
1319 (define_insn "cmpeqdi_media"
1320   [(set (match_operand:SI 0 "register_operand" "=r")
1321         (eq:SI (match_operand:DI 1 "register_operand" "%r")
1322                (match_operand:DI 2 "cmp_operand" "Nr")))]
1323   "TARGET_SHMEDIA"
1324   "cmpeq        %1, %N2, %0"
1325   [(set_attr "type" "cmp_media")])
1326
1327 (define_insn "cmpgtsi_media"
1328   [(set (match_operand:SI 0 "register_operand" "=r")
1329         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1330                (match_operand:SI 2 "cmp_operand" "rN")))]
1331   "TARGET_SHMEDIA"
1332   "cmpgt        %N1, %N2, %0"
1333   [(set_attr "type" "cmp_media")])
1334
1335 (define_insn "cmpgtdi_media"
1336   [(set (match_operand:SI 0 "register_operand" "=r")
1337         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1338                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1339   "TARGET_SHMEDIA"
1340   "cmpgt        %N1, %N2, %0"
1341   [(set_attr "type" "cmp_media")])
1342
1343 (define_insn "cmpgtusi_media"
1344   [(set (match_operand:SI 0 "register_operand" "=r")
1345         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1346                 (match_operand:SI 2 "cmp_operand" "rN")))]
1347   "TARGET_SHMEDIA"
1348   "cmpgtu       %N1, %N2, %0"
1349   [(set_attr "type" "cmp_media")])
1350
1351 (define_insn "cmpgtudi_media"
1352   [(set (match_operand:SI 0 "register_operand" "=r")
1353         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1354                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1355   "TARGET_SHMEDIA"
1356   "cmpgtu       %N1, %N2, %0"
1357   [(set_attr "type" "cmp_media")])
1358
1359 ; This pattern is for combine.
1360 (define_insn "*cmpne0sisi_media"
1361   [(set (match_operand:SI 0 "register_operand" "=r")
1362         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1363   "TARGET_SHMEDIA"
1364   "cmpgtu       %1,r63,%0"
1365   [(set_attr "type" "cmp_media")])
1366
1367 ;; -------------------------------------------------------------------------
1368 ;; Conditional move instructions
1369 ;; -------------------------------------------------------------------------
1370
1371 ;; The insn names may seem reversed, but note that cmveq performs the move
1372 ;; if op1 == 0, and cmvne does it if op1 != 0.
1373
1374 (define_insn "movdicc_false"
1375   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1376         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1377                              (const_int 0))
1378          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1379          (match_operand:DI 3 "arith_reg_operand" "0")))]
1380   "TARGET_SHMEDIA"
1381   "cmveq        %1, %N2, %0"
1382   [(set_attr "type" "arith_media")])
1383
1384 (define_insn "movdicc_true"
1385   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1386         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1387                              (const_int 0))
1388          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1389          (match_operand:DI 3 "arith_reg_operand" "0")))]
1390   "TARGET_SHMEDIA"
1391   "cmvne        %1, %N2, %0"
1392   [(set_attr "type" "arith_media")])
1393
1394 (define_peephole2
1395   [(set (match_operand:DI 0 "arith_reg_dest" "")
1396         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1397                            [(match_operand:DI 1 "arith_reg_operand" "")
1398                             (const_int 0)])
1399          (match_operand:DI 2 "arith_reg_dest" "")
1400          (match_dup 0)))
1401    (set (match_dup 2) (match_dup 0))]
1402   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1403   [(set (match_dup 2)
1404         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1405 {
1406   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1407                                 VOIDmode, operands[1], CONST0_RTX (DImode));
1408 })
1409
1410 (define_peephole2
1411   [(set (match_operand:DI 0 "general_movdst_operand" "")
1412         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1413    (set (match_operand:DI 2 "arith_reg_dest" "")
1414         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1415                            [(match_operand:DI 3 "arith_reg_operand" "")
1416                             (const_int 0)])
1417          (match_dup 0)
1418          (match_dup 2)))]
1419   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1420   [(set (match_dup 2)
1421         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1422   "")
1423
1424 (define_expand "movdicc"
1425   [(set (match_operand:DI 0 "register_operand" "")
1426         (if_then_else:DI (match_operand 1 "comparison_operator" "")
1427                          (match_operand:DI 2 "register_operand" "")
1428                          (match_operand:DI 3 "register_operand" "")))]
1429   "TARGET_SHMEDIA"
1430 {
1431   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1432       && GET_MODE (XEXP (operands[1], 0)) == DImode
1433       && XEXP (operands[1], 1) == const0_rtx)
1434     ;
1435   else
1436     {
1437       if (!can_create_pseudo_p ())
1438         FAIL;
1439
1440       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1441                                               GET_CODE (operands[1]),
1442                                               XEXP (operands[1], 0),
1443                                               XEXP (operands[1], 1));
1444       if (!operands[1])
1445         FAIL;
1446     }
1447 })
1448
1449 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1450 ;; SImode to DImode.
1451 (define_insn "movsicc_false"
1452   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1453         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1454                           (const_int 0))
1455          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1456          (match_operand:SI 3 "arith_reg_operand" "0")))]
1457   "TARGET_SHMEDIA"
1458   "cmveq        %1, %N2, %0"
1459   [(set_attr "type" "arith_media")])
1460
1461 (define_insn "movsicc_true"
1462   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1463         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1464                           (const_int 0))
1465          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1466          (match_operand:SI 3 "arith_reg_operand" "0")))]
1467   "TARGET_SHMEDIA"
1468   "cmvne        %1, %N2, %0"
1469   [(set_attr "type" "arith_media")])
1470
1471 (define_peephole2
1472   [(set (match_operand:SI 0 "arith_reg_dest" "")
1473         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1474                            [(match_operand:SI 1 "arith_reg_operand" "")
1475                             (const_int 0)])
1476          (match_operand:SI 2 "arith_reg_dest" "")
1477          (match_dup 0)))
1478    (set (match_dup 2) (match_dup 0))]
1479   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1480   [(set (match_dup 2)
1481         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1482 {
1483   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1484                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1485 })
1486
1487 (define_peephole2
1488   [(set (match_operand:SI 0 "general_movdst_operand" "")
1489         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1490    (set (match_operand:SI 2 "arith_reg_dest" "")
1491         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1492                            [(match_operand:SI 3 "arith_reg_operand" "")
1493                             (const_int 0)])
1494          (match_dup 0)
1495          (match_dup 2)))]
1496   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1497    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1498   [(set (match_dup 2)
1499         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1500 {
1501   replace_rtx (operands[4], operands[0], operands[1]);
1502 })
1503
1504 (define_peephole2
1505   [(set (match_operand 0 "any_register_operand" "")
1506         (match_operand 1 "any_register_operand" ""))
1507    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1508    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1509   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1510     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1511    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1512    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1513    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1514    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1515    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1516    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1517    && (REGNO_REG_CLASS (REGNO (operands[0]))
1518        == REGNO_REG_CLASS (REGNO (operands[2])))
1519    && (REGNO_REG_CLASS (REGNO (operands[1]))
1520        == REGNO_REG_CLASS (REGNO (operands[0])))"
1521   [(set (match_dup 0) (match_dup 3))
1522    (set (match_dup 4) (match_dup 5))]
1523 {
1524   rtx set1, set2, insn2;
1525   rtx replacements[4];
1526
1527   /* We want to replace occurrences of operands[0] with operands[1] and
1528      operands[2] with operands[0] in operands[4]/operands[5].
1529      Doing just two replace_rtx calls naively would result in the second
1530      replacement undoing all that the first did if operands[1] and operands[2]
1531      are identical, so we must do this simultaneously.  */
1532   replacements[0] = operands[0];
1533   replacements[1] = operands[1];
1534   replacements[2] = operands[2];
1535   replacements[3] = operands[0];
1536   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1537       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1538       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1539     FAIL;
1540
1541   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1542   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1543   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1544   /* The operands array is aliased to recog_data.operand, which gets
1545      clobbered by extract_insn, so finish with it now.  */
1546   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1547   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1548   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1549      always uses emit_insn.  */
1550   /* Check that we don't violate matching constraints or earlyclobbers.  */
1551   extract_insn (emit_insn (set1));
1552   if (! constrain_operands (1))
1553     goto failure;
1554   insn2 = emit (set2);
1555   if (GET_CODE (insn2) == BARRIER)
1556     goto failure;
1557   extract_insn (insn2);
1558   if (! constrain_operands (1))
1559     {
1560       rtx tmp;
1561     failure:
1562       tmp = replacements[0];
1563       replacements[0] = replacements[1];
1564       replacements[1] = tmp;
1565       tmp = replacements[2];
1566       replacements[2] = replacements[3];
1567       replacements[3] = tmp;
1568       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1569       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1570       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1571       FAIL;
1572     }
1573   DONE;
1574 })
1575
1576 ;; The register allocator is rather clumsy in handling multi-way conditional
1577 ;; moves, so allow the combiner to make them, and we split them up after
1578 ;; reload.  */
1579 (define_insn_and_split "*movsicc_umin"
1580   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1581         (umin:SI (if_then_else:SI
1582                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1583                        (const_int 0))
1584                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1585                    (match_operand:SI 3 "register_operand" "0"))
1586                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1587    (clobber (match_scratch:SI 5 "=&r"))]
1588   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1589   "#"
1590   "TARGET_SHMEDIA && reload_completed"
1591   [(pc)]
1592 {
1593   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1594                                 operands[3]));
1595   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1596   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1597                                 operands[0]));
1598   DONE;
1599 })
1600
1601 (define_insn "*movsicc_t_false"
1602   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1603         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1604                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1605                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1606   "TARGET_PRETEND_CMOVE
1607    && (arith_reg_operand (operands[1], SImode)
1608        || (immediate_operand (operands[1], SImode)
1609            && satisfies_constraint_I08 (operands[1])))"
1610 {
1611   return       "bt      0f"     "\n"
1612          "      mov     %1,%0"  "\n"
1613          "0:";
1614 }
1615   [(set_attr "type" "mt_group,arith") ;; poor approximation
1616    (set_attr "length" "4")])
1617
1618 (define_insn "*movsicc_t_true"
1619   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1620         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1621                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1622                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1623   "TARGET_PRETEND_CMOVE
1624    && (arith_reg_operand (operands[1], SImode)
1625        || (immediate_operand (operands[1], SImode)
1626            && satisfies_constraint_I08 (operands[1])))"
1627 {
1628   return       "bf      0f"     "\n"
1629          "      mov     %1,%0"  "\n"
1630          "0:";
1631 }
1632   [(set_attr "type" "mt_group,arith") ;; poor approximation
1633    (set_attr "length" "4")])
1634
1635 (define_expand "movsicc"
1636   [(set (match_operand:SI 0 "arith_reg_dest" "")
1637         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1638                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1639                          (match_operand:SI 3 "arith_reg_operand" "")))]
1640   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1641 {
1642   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1643       && GET_MODE (XEXP (operands[1], 0)) == SImode
1644       && (TARGET_SHMEDIA
1645           || (REG_P (XEXP (operands[1], 0))
1646               && REGNO (XEXP (operands[1], 0)) == T_REG))
1647       && XEXP (operands[1], 1) == const0_rtx)
1648     ;
1649
1650   else if (TARGET_PRETEND_CMOVE)
1651     {
1652       enum rtx_code code = GET_CODE (operands[1]);
1653       enum rtx_code new_code = code;
1654       rtx op0 = XEXP (operands[1], 0);
1655       rtx op1 = XEXP (operands[1], 1);
1656
1657       if (! currently_expanding_to_rtl)
1658         FAIL;
1659       switch (code)
1660         {
1661         case LT: case LE: case LEU: case LTU:
1662           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1663             break;
1664         case NE:
1665           new_code = reverse_condition (code);
1666           break;
1667         case EQ: case GT: case GE: case GEU: case GTU:
1668           break;
1669         default:
1670           FAIL;
1671         }
1672       sh_emit_scc_to_t (new_code, op0, op1);
1673       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1674                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1675     }
1676   else
1677     {
1678       if (!can_create_pseudo_p ())
1679         FAIL;
1680
1681       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1682                                               GET_CODE (operands[1]),
1683                                               XEXP (operands[1], 0),
1684                                               XEXP (operands[1], 1));
1685       if (!operands[1])
1686         FAIL;
1687     }
1688 })
1689
1690 (define_expand "movqicc"
1691   [(set (match_operand:QI 0 "register_operand" "")
1692         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1693                          (match_operand:QI 2 "register_operand" "")
1694                          (match_operand:QI 3 "register_operand" "")))]
1695   "TARGET_SHMEDIA"
1696 {
1697   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1698   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1699   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1700   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1701   DONE;
1702 })
1703 \f
1704 ;; -------------------------------------------------------------------------
1705 ;; Addition instructions
1706 ;; -------------------------------------------------------------------------
1707
1708 (define_expand "adddi3"
1709   [(set (match_operand:DI 0 "arith_reg_operand" "")
1710         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1711                  (match_operand:DI 2 "arith_operand" "")))]
1712   ""
1713 {
1714   if (TARGET_SH1)
1715     {
1716       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1717         FAIL;
1718       operands[2] = force_reg (DImode, operands[2]);
1719       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1720       DONE;
1721     }
1722 })
1723
1724 (define_insn "*adddi3_media"
1725   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1726         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1727                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1728   "TARGET_SHMEDIA"
1729   "@
1730         add     %1, %2, %0
1731         addi    %1, %2, %0"
1732   [(set_attr "type" "arith_media")])
1733
1734 (define_insn "*adddisi3_media"
1735   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1736         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1737                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1738   "TARGET_SHMEDIA"
1739   "@
1740         add.l   %1, %2, %0
1741         addi.l  %1, %2, %0"
1742   [(set_attr "type" "arith_media")
1743    (set_attr "highpart" "ignore")])
1744
1745 (define_insn "adddi3z_media"
1746   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1747         (zero_extend:DI
1748          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1749                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1750   "TARGET_SHMEDIA"
1751   "addz.l       %1, %N2, %0"
1752   [(set_attr "type" "arith_media")
1753    (set_attr "highpart" "ignore")])
1754
1755 (define_insn_and_split "adddi3_compact"
1756   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1757         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1758                  (match_operand:DI 2 "arith_reg_operand" "r")))
1759    (clobber (reg:SI T_REG))]
1760   "TARGET_SH1"
1761   "#"
1762   "&& reload_completed"
1763   [(const_int 0)]
1764 {
1765   rtx high0 = gen_highpart (SImode, operands[0]);
1766   rtx high2 = gen_highpart (SImode, operands[2]);
1767   rtx low0 = gen_lowpart (SImode, operands[0]);
1768
1769   emit_insn (gen_clrt ());
1770   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1771   emit_insn (gen_addc (high0, high0, high2));
1772   DONE;
1773 })
1774
1775 (define_insn "addc"
1776   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1777         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1778                           (match_operand:SI 2 "arith_reg_operand" "r"))
1779                  (reg:SI T_REG)))
1780    (set (reg:SI T_REG)
1781         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1782   "TARGET_SH1"
1783   "addc %2,%0"
1784   [(set_attr "type" "arith")])
1785
1786 ;; A simplified version of the addc insn, where the exact value of the
1787 ;; T bit doesn't matter.  This is easier for combine to pick up.
1788 ;; We allow a reg or 0 for one of the operands in order to be able to
1789 ;; do 'reg + T' sequences.  Reload will load the constant 0 into the reg
1790 ;; as needed.
1791 (define_insn "*addc"
1792   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1793         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1794                           (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1795                  (match_operand:SI 3 "t_reg_operand" "")))
1796    (clobber (reg:SI T_REG))]
1797   "TARGET_SH1"
1798   "addc %2,%0"
1799   [(set_attr "type" "arith")])
1800
1801 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1802 ;; better, if the sett insn can be done early.
1803 (define_insn_and_split "*addc"
1804   [(set (match_operand:SI 0 "arith_reg_dest" "")
1805         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1806                           (match_operand:SI 2 "arith_reg_operand" ""))
1807                  (const_int 1)))
1808    (clobber (reg:SI T_REG))]
1809   "TARGET_SH1"
1810   "#"
1811   "&& 1"
1812   [(set (reg:SI T_REG) (const_int 1))
1813    (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1814                                           (reg:SI T_REG)))
1815               (clobber (reg:SI T_REG))])])
1816
1817 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1818 ;; clobbers.  Thus addc can also be used to do something like '(x << 1) + 1'.
1819 (define_insn_and_split "*addc"
1820   [(set (match_operand:SI 0 "arith_reg_dest")
1821         (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1822                           (const_int 2))
1823                  (const_int 1)))
1824    (clobber (reg:SI T_REG))]
1825   "TARGET_SH1"
1826   "#"
1827   "&& 1"
1828   [(set (reg:SI T_REG) (const_int 1))
1829    (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1830                                           (reg:SI T_REG)))
1831               (clobber (reg:SI T_REG))])])
1832
1833 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1834 ;; matched.  Split this up into a simple sub add sequence, as this will save
1835 ;; us one sett insn.
1836 (define_insn_and_split "*minus_plus_one"
1837   [(set (match_operand:SI 0 "arith_reg_dest" "")
1838         (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1839                            (match_operand:SI 2 "arith_reg_operand" ""))
1840                  (const_int 1)))]
1841   "TARGET_SH1"
1842   "#"
1843   "&& 1"
1844   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1845    (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1846
1847 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1848 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1849 ;; operation, as opposed to sequences such as
1850 ;;      movt    r2
1851 ;;      add     r2,r3
1852 ;;
1853 ;; Even if the constant is not CSE-ed, a sequence such as
1854 ;;      mov     #0,r2
1855 ;;      addc    r2,r3
1856 ;; can be scheduled much better since the load of the constant can be
1857 ;; done earlier, before any comparison insns that store the result in
1858 ;; the T bit.
1859 (define_insn_and_split "*addc"
1860   [(set (match_operand:SI 0 "arith_reg_dest" "")
1861         (plus:SI (match_operand:SI 1 "t_reg_operand" "")
1862                  (match_operand:SI 2 "arith_reg_operand" "")))
1863    (clobber (reg:SI T_REG))]
1864   "TARGET_SH1"
1865   "#"
1866   "&& 1"
1867   [(parallel [(set (match_dup 0)
1868                    (plus:SI (plus:SI (match_dup 2) (const_int 0))
1869                             (match_dup 1)))
1870               (clobber (reg:SI T_REG))])])
1871
1872 (define_expand "addsi3"
1873   [(set (match_operand:SI 0 "arith_reg_operand" "")
1874         (plus:SI (match_operand:SI 1 "arith_operand" "")
1875                  (match_operand:SI 2 "arith_operand" "")))]
1876   ""
1877 {
1878   if (TARGET_SHMEDIA)
1879     operands[1] = force_reg (SImode, operands[1]);
1880 })
1881
1882 (define_insn "addsi3_media"
1883   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1884         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1885                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1886   "TARGET_SHMEDIA"
1887   "@
1888         add.l   %1, %2, %0
1889         addi.l  %1, %2, %0"
1890   [(set_attr "type" "arith_media")
1891    (set_attr "highpart" "ignore")])
1892
1893 (define_insn "addsidi3_media"
1894   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1895         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1896                                   "%r,r")
1897                                  (match_operand:SI 2 "arith_operand"
1898                                   "r,I10"))))]
1899   "TARGET_SHMEDIA"
1900   "@
1901         add.l   %1, %2, %0
1902         addi.l  %1, %2, %0"
1903   [(set_attr "type" "arith_media")
1904    (set_attr "highpart" "ignore")])
1905
1906 (define_insn "*addsi3_compact"
1907   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1908         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1909                  (match_operand:SI 2 "arith_operand" "rI08")))]
1910   "TARGET_SH1"
1911   "add  %2,%0"
1912   [(set_attr "type" "arith")])
1913
1914 ;; -------------------------------------------------------------------------
1915 ;; Subtraction instructions
1916 ;; -------------------------------------------------------------------------
1917
1918 (define_expand "subdi3"
1919   [(set (match_operand:DI 0 "arith_reg_operand" "")
1920         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1921                   (match_operand:DI 2 "arith_reg_operand" "")))]
1922   ""
1923 {
1924   if (TARGET_SH1)
1925     {
1926       operands[1] = force_reg (DImode, operands[1]);
1927       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1928       DONE;
1929     }
1930 })
1931
1932 (define_insn "*subdi3_media"
1933   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1934         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1935                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1936   "TARGET_SHMEDIA"
1937   "sub  %N1, %2, %0"
1938   [(set_attr "type" "arith_media")])
1939   
1940 (define_insn "subdisi3_media"
1941   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1942         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1943                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1944   "TARGET_SHMEDIA"
1945   "sub.l        %N1, %2, %0"
1946   [(set_attr "type" "arith_media")
1947    (set_attr "highpart" "ignore")])
1948
1949 (define_insn_and_split "subdi3_compact"
1950   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1951         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1952                  (match_operand:DI 2 "arith_reg_operand" "r")))
1953    (clobber (reg:SI T_REG))]
1954   "TARGET_SH1"
1955   "#"
1956   "&& reload_completed"
1957   [(const_int 0)]
1958 {
1959   rtx high0 = gen_highpart (SImode, operands[0]);
1960   rtx high2 = gen_highpart (SImode, operands[2]);
1961   rtx low0 = gen_lowpart (SImode, operands[0]);
1962
1963   emit_insn (gen_clrt ());
1964   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1965   emit_insn (gen_subc (high0, high0, high2));
1966   DONE;
1967 })
1968
1969 (define_insn "subc"
1970   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1971         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1972                             (match_operand:SI 2 "arith_reg_operand" "r"))
1973                   (reg:SI T_REG)))
1974    (set (reg:SI T_REG)
1975         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1976                           (reg:SI T_REG))
1977                 (match_dup 1)))]
1978   "TARGET_SH1"
1979   "subc %2,%0"
1980   [(set_attr "type" "arith")])
1981
1982 ;; A simplified version of the subc insn, where the exact value of the
1983 ;; T bit doesn't matter.  This is easier for combine to pick up.
1984 ;; We allow a reg or 0 for one of the operands in order to be able to
1985 ;; do 'reg - T' sequences.  Reload will load the constant 0 into the reg
1986 ;; as needed.
1987 (define_insn "*subc"
1988   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1989         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1990                             (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1991                   (match_operand:SI 3 "t_reg_operand" "")))
1992    (clobber (reg:SI T_REG))]
1993   "TARGET_SH1"
1994   "subc %2,%0"
1995   [(set_attr "type" "arith")])
1996
1997 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
1998 ;; better, if the sett insn can be done early.
1999 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2000 (define_insn_and_split "*subc"
2001   [(set (match_operand:SI 0 "arith_reg_dest" "")
2002         (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2003                  (match_operand:SI 2 "arith_reg_operand" "")))
2004    (clobber (reg:SI T_REG))]
2005   "TARGET_SH1"
2006   "#"
2007   "&& 1"
2008   [(set (reg:SI T_REG) (const_int 1))
2009    (parallel [(set (match_dup 0)
2010                    (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2011                              (reg:SI T_REG)))
2012               (clobber (reg:SI T_REG))])])
2013
2014 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2015 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2016 ;; operation, as opposed to sequences such as
2017 ;;      movt    r2
2018 ;;      sub     r2,r3
2019 ;;
2020 ;; Even if the constant is not CSE-ed, a sequence such as
2021 ;;      mov     #0,r2
2022 ;;      subc    r2,r3
2023 ;; can be scheduled much better since the load of the constant can be
2024 ;; done earlier, before any comparison insns that store the result in
2025 ;; the T bit.
2026 (define_insn_and_split "*subc"
2027   [(set (match_operand:SI 0 "arith_reg_dest" "")
2028         (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2029                   (match_operand:SI 2 "t_reg_operand" "")))
2030    (clobber (reg:SI T_REG))]
2031   "TARGET_SH1"
2032   "#"
2033   "&& 1"
2034   [(parallel [(set (match_dup 0)
2035                    (minus:SI (minus:SI (match_dup 1) (const_int 0))
2036                              (match_dup 2)))
2037               (clobber (reg:SI T_REG))])])
2038
2039 (define_insn "*subsi3_internal"
2040   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2041         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2042                   (match_operand:SI 2 "arith_reg_operand" "r")))]
2043   "TARGET_SH1"
2044   "sub  %2,%0"
2045   [(set_attr "type" "arith")])
2046
2047 (define_insn_and_split "*subsi3_media"
2048   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2049         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2050                   (match_operand:SI 2 "extend_reg_operand" "r")))]
2051   "TARGET_SHMEDIA
2052    && (operands[1] != constm1_rtx
2053        || (GET_CODE (operands[2]) != TRUNCATE
2054            && GET_CODE (operands[2]) != SUBREG))"
2055   "sub.l        %N1, %2, %0"
2056   "operands[1] == constm1_rtx"
2057   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2058   ""
2059   [(set_attr "type" "arith_media")
2060    (set_attr "highpart" "ignore")])
2061
2062 (define_split
2063   [(set (match_operand:SI 0 "arith_reg_dest" "")
2064         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2065                                                        "general_extend_operand"
2066                                                        "") 0)) 0)))]
2067   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2068   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2069    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2070   "")
2071
2072 (define_split
2073   [(set (match_operand:SI 0 "arith_reg_dest" "")
2074         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2075                                                        "general_extend_operand"
2076                                                        "") 0)) 3)))]
2077   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
2078   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2079    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2080   "")
2081
2082 ;; Convert
2083 ;;      constant - reg
2084 ;; to
2085 ;;      neg reg
2086 ;;      add reg, #const
2087 ;; since this will sometimes save one instruction.
2088 ;; Otherwise we might get a sequence like
2089 ;;      mov #const, rY
2090 ;;      sub rY, rX
2091 ;;      mov rX, rY
2092 ;; if the source and dest regs are the same.
2093 (define_expand "subsi3"
2094   [(set (match_operand:SI 0 "arith_reg_operand" "")
2095         (minus:SI (match_operand:SI 1 "arith_operand" "")
2096                   (match_operand:SI 2 "arith_reg_operand" "")))]
2097   ""
2098 {
2099   if (TARGET_SH1 && CONST_INT_P (operands[1]))
2100     {
2101       emit_insn (gen_negsi2 (operands[0], operands[2]));
2102       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2103       DONE;
2104     }
2105   if (TARGET_SHMEDIA)
2106     {
2107       if (!can_create_pseudo_p ()
2108           && ! arith_reg_or_0_operand (operands[1], SImode))
2109         FAIL;
2110       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2111         operands[1] = force_reg (SImode, operands[1]);
2112     }
2113 })
2114 \f
2115 ;; -------------------------------------------------------------------------
2116 ;; Division instructions
2117 ;; -------------------------------------------------------------------------
2118
2119 ;; We take advantage of the library routines which don't clobber as many
2120 ;; registers as a normal function call would.
2121
2122 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2123 ;; also has an effect on the register that holds the address of the sfunc.
2124 ;; To make this work, we have an extra dummy insn that shows the use
2125 ;; of this register for reorg.
2126
2127 (define_insn "use_sfunc_addr"
2128   [(set (reg:SI PR_REG)
2129         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2130   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2131   ""
2132   [(set_attr "length" "0")])
2133
2134 (define_insn "udivsi3_sh2a"
2135   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2136         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2137                 (match_operand:SI 2 "arith_reg_operand" "z")))]
2138   "TARGET_SH2A"
2139   "divu %2,%1"
2140   [(set_attr "type" "arith")
2141    (set_attr "in_delay_slot" "no")])
2142
2143 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2144 ;; hard register 0.  If we used hard register 0, then the next instruction
2145 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
2146 ;; gets allocated to a stack slot that needs its address reloaded, then
2147 ;; there is nothing to prevent reload from using r0 to reload the address.
2148 ;; This reload would clobber the value in r0 we are trying to store.
2149 ;; If we let reload allocate r0, then this problem can never happen.
2150 (define_insn "udivsi3_i1"
2151   [(set (match_operand:SI 0 "register_operand" "=z")
2152         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2153    (clobber (reg:SI T_REG))
2154    (clobber (reg:SI PR_REG))
2155    (clobber (reg:SI R4_REG))
2156    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2157   "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2158   "jsr  @%1%#"
2159   [(set_attr "type" "sfunc")
2160    (set_attr "needs_delay_slot" "yes")])
2161
2162 ; Since shmedia-nofpu code could be linked against shcompact code, and
2163 ; the udivsi3 libcall has the same name, we must consider all registers
2164 ; clobbered that are in the union of the registers clobbered by the
2165 ; shmedia and the shcompact implementation.  Note, if the shcompact
2166 ; implementation actually used shcompact code, we'd need to clobber
2167 ; also r23 and fr23.
2168 (define_insn "udivsi3_i1_media"
2169   [(set (match_operand:SI 0 "register_operand" "=z")
2170         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2171    (clobber (reg:SI T_MEDIA_REG))
2172    (clobber (reg:SI PR_MEDIA_REG))
2173    (clobber (reg:SI R20_REG))
2174    (clobber (reg:SI R21_REG))
2175    (clobber (reg:SI R22_REG))
2176    (clobber (reg:DI TR0_REG))
2177    (clobber (reg:DI TR1_REG))
2178    (clobber (reg:DI TR2_REG))
2179    (use (match_operand 1 "target_reg_operand" "b"))]
2180   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2181   "blink        %1, r18"
2182   [(set_attr "type" "sfunc")
2183    (set_attr "needs_delay_slot" "yes")])
2184
2185 (define_expand "udivsi3_i4_media"
2186   [(set (match_dup 3)
2187         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2188    (set (match_dup 4)
2189         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2190    (set (match_dup 5) (float:DF (match_dup 3)))
2191    (set (match_dup 6) (float:DF (match_dup 4)))
2192    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2193    (set (match_dup 8) (fix:DI (match_dup 7)))
2194    (set (match_operand:SI 0 "register_operand" "")
2195         (truncate:SI (match_dup 8)))]
2196   "TARGET_SHMEDIA_FPU"
2197 {
2198   operands[3] = gen_reg_rtx (DImode);
2199   operands[4] = gen_reg_rtx (DImode);
2200   operands[5] = gen_reg_rtx (DFmode);
2201   operands[6] = gen_reg_rtx (DFmode);
2202   operands[7] = gen_reg_rtx (DFmode);
2203   operands[8] = gen_reg_rtx (DImode);
2204 })
2205
2206 (define_insn "udivsi3_i4"
2207   [(set (match_operand:SI 0 "register_operand" "=y")
2208         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2209    (clobber (reg:SI T_REG))
2210    (clobber (reg:SI PR_REG))
2211    (clobber (reg:DF DR0_REG))
2212    (clobber (reg:DF DR2_REG))
2213    (clobber (reg:DF DR4_REG))
2214    (clobber (reg:SI R0_REG))
2215    (clobber (reg:SI R1_REG))
2216    (clobber (reg:SI R4_REG))
2217    (clobber (reg:SI R5_REG))
2218    (use (reg:PSI FPSCR_REG))
2219    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2220   "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2221   "jsr  @%1%#"
2222   [(set_attr "type" "sfunc")
2223    (set_attr "fp_mode" "double")
2224    (set_attr "needs_delay_slot" "yes")])
2225
2226 (define_insn "udivsi3_i4_single"
2227   [(set (match_operand:SI 0 "register_operand" "=y")
2228         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2229    (clobber (reg:SI T_REG))
2230    (clobber (reg:SI PR_REG))
2231    (clobber (reg:DF DR0_REG))
2232    (clobber (reg:DF DR2_REG))
2233    (clobber (reg:DF DR4_REG))
2234    (clobber (reg:SI R0_REG))
2235    (clobber (reg:SI R1_REG))
2236    (clobber (reg:SI R4_REG))
2237    (clobber (reg:SI R5_REG))
2238    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2239   "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2240    && TARGET_FPU_SINGLE"
2241   "jsr  @%1%#"
2242   [(set_attr "type" "sfunc")
2243    (set_attr "needs_delay_slot" "yes")])
2244
2245 (define_insn "udivsi3_i4_int"
2246   [(set (match_operand:SI 0 "register_operand" "=z")
2247         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2248    (clobber (reg:SI T_REG))
2249    (clobber (reg:SI R1_REG))
2250    (clobber (reg:SI PR_REG))
2251    (clobber (reg:SI MACH_REG))
2252    (clobber (reg:SI MACL_REG))
2253    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2254   "TARGET_SH1"
2255   "jsr  @%1%#"
2256   [(set_attr "type" "sfunc")
2257    (set_attr "needs_delay_slot" "yes")])
2258
2259
2260 (define_expand "udivsi3"
2261   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2262    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2263    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2264    (parallel [(set (match_operand:SI 0 "register_operand" "")
2265                    (udiv:SI (reg:SI R4_REG)
2266                             (reg:SI R5_REG)))
2267               (clobber (reg:SI T_REG))
2268               (clobber (reg:SI PR_REG))
2269               (clobber (reg:SI R4_REG))
2270               (use (match_dup 3))])]
2271   ""
2272 {
2273   rtx last;
2274
2275   operands[3] = gen_reg_rtx (Pmode);
2276   /* Emit the move of the address to a pseudo outside of the libcall.  */
2277   if (TARGET_DIVIDE_CALL_TABLE)
2278     {
2279       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2280          that causes problems when the divide code is supposed to come from a
2281          separate library.  Division by zero is undefined, so dividing 1 can be
2282          implemented by comparing with the divisor.  */
2283       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2284         {
2285           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2286           emit_insn (gen_cstoresi4 (operands[0], test,
2287                                     operands[1], operands[2]));
2288           DONE;
2289         }
2290       else if (operands[2] == const0_rtx)
2291         {
2292           emit_move_insn (operands[0], operands[2]);
2293           DONE;
2294         }
2295       function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2296       last = gen_udivsi3_i4_int (operands[0], operands[3]);
2297     }
2298   else if (TARGET_DIVIDE_CALL_FP)
2299     {
2300       function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2301       if (TARGET_FPU_SINGLE)
2302         last = gen_udivsi3_i4_single (operands[0], operands[3]);
2303       else
2304         last = gen_udivsi3_i4 (operands[0], operands[3]);
2305     }
2306   else if (TARGET_SHMEDIA_FPU)
2307     {
2308       operands[1] = force_reg (SImode, operands[1]);
2309       operands[2] = force_reg (SImode, operands[2]);
2310       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2311       DONE;
2312     }
2313   else if (TARGET_SH2A)
2314     {
2315       operands[1] = force_reg (SImode, operands[1]);
2316       operands[2] = force_reg (SImode, operands[2]);
2317       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2318       DONE;
2319     }
2320   else if (TARGET_SH5)
2321     {
2322       function_symbol (operands[3],
2323                        TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2324                        SFUNC_STATIC);
2325
2326       if (TARGET_SHMEDIA)
2327         last = gen_udivsi3_i1_media (operands[0], operands[3]);
2328       else if (TARGET_FPU_ANY)
2329         last = gen_udivsi3_i4_single (operands[0], operands[3]);
2330       else
2331         last = gen_udivsi3_i1 (operands[0], operands[3]);
2332     }
2333   else
2334     {
2335       function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2336       last = gen_udivsi3_i1 (operands[0], operands[3]);
2337     }
2338   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2339   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2340   emit_insn (last);
2341   DONE;
2342 })
2343
2344 (define_insn "divsi3_sh2a"
2345   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2346         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2347                 (match_operand:SI 2 "arith_reg_operand" "z")))]
2348   "TARGET_SH2A"
2349   "divs %2,%1"
2350   [(set_attr "type" "arith")
2351    (set_attr "in_delay_slot" "no")])
2352
2353 (define_insn "divsi3_i1"
2354   [(set (match_operand:SI 0 "register_operand" "=z")
2355         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2356    (clobber (reg:SI T_REG))
2357    (clobber (reg:SI PR_REG))
2358    (clobber (reg:SI R1_REG))
2359    (clobber (reg:SI R2_REG))
2360    (clobber (reg:SI R3_REG))
2361    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2362   "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2363   "jsr  @%1%#"
2364   [(set_attr "type" "sfunc")
2365    (set_attr "needs_delay_slot" "yes")])
2366
2367 (define_insn "divsi3_i1_media"
2368   [(set (match_operand:SI 0 "register_operand" "=z")
2369         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2370    (clobber (reg:SI T_MEDIA_REG))
2371    (clobber (reg:SI PR_MEDIA_REG))
2372    (clobber (reg:SI R1_REG))
2373    (clobber (reg:SI R20_REG))
2374    (clobber (reg:SI R21_REG))
2375    (clobber (reg:SI TR0_REG))
2376    (use (match_operand 1 "target_reg_operand" "b"))]
2377   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2378   "blink        %1, r18"
2379   [(set_attr "type" "sfunc")])
2380
2381 (define_insn "divsi3_media_2"
2382   [(set (match_operand:SI 0 "register_operand" "=z")
2383         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2384    (clobber (reg:SI T_MEDIA_REG))
2385    (clobber (reg:SI PR_MEDIA_REG))
2386    (clobber (reg:SI R1_REG))
2387    (clobber (reg:SI R21_REG))
2388    (clobber (reg:SI TR0_REG))
2389    (use (reg:SI R20_REG))
2390    (use (match_operand 1 "target_reg_operand" "b"))]
2391   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2392   "blink        %1, r18"
2393   [(set_attr "type" "sfunc")])
2394
2395 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2396 ;; hard reg clobbers and data dependencies that we need when we want
2397 ;; to rematerialize the division into a call.
2398 (define_insn_and_split "divsi_inv_call"
2399   [(set (match_operand:SI 0 "register_operand" "=r")
2400         (div:SI (match_operand:SI 1 "register_operand" "r")
2401                 (match_operand:SI 2 "register_operand" "r")))
2402    (clobber (reg:SI R4_REG))
2403    (clobber (reg:SI R5_REG))
2404    (clobber (reg:SI T_MEDIA_REG))
2405    (clobber (reg:SI PR_MEDIA_REG))
2406    (clobber (reg:SI R1_REG))
2407    (clobber (reg:SI R21_REG))
2408    (clobber (reg:SI TR0_REG))
2409    (clobber (reg:SI R20_REG))
2410    (use (match_operand:SI 3 "register_operand" "r"))]
2411   "TARGET_SHMEDIA"
2412   "#"
2413   "&& (reload_in_progress || reload_completed)"
2414   [(set (match_dup 0) (match_dup 3))]
2415   ""
2416   [(set_attr "highpart" "must_split")])
2417
2418 ;; This is the combiner pattern for -mdiv=inv:call .
2419 (define_insn_and_split "*divsi_inv_call_combine"
2420   [(set (match_operand:SI 0 "register_operand" "=z")
2421         (div:SI (match_operand:SI 1 "register_operand" "r")
2422                 (match_operand:SI 2 "register_operand" "r")))
2423    (clobber (reg:SI R4_REG))
2424    (clobber (reg:SI R5_REG))
2425    (clobber (reg:SI T_MEDIA_REG))
2426    (clobber (reg:SI PR_MEDIA_REG))
2427    (clobber (reg:SI R1_REG))
2428    (clobber (reg:SI R21_REG))
2429    (clobber (reg:SI TR0_REG))
2430    (clobber (reg:SI R20_REG))
2431    (use (unspec:SI [(match_dup 1)
2432                     (match_operand:SI 3 "" "")
2433                     (unspec:SI [(match_operand:SI 4 "" "")
2434                                 (match_dup 3)
2435                                 (match_operand:DI 5 "" "")]
2436                      UNSPEC_DIV_INV_M2)
2437                     (match_operand:DI 6 "" "")
2438                     (const_int 0)
2439                     (const_int 0)]
2440          UNSPEC_DIV_INV_M3))]
2441   "TARGET_SHMEDIA"
2442   "#"
2443   "&& (reload_in_progress || reload_completed)"
2444   [(pc)]
2445 {
2446   const char *name = sh_divsi3_libfunc;
2447   enum sh_function_kind kind = SFUNC_GOT;
2448   rtx sym;
2449
2450   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2451   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2452   while (TARGET_DIVIDE_INV_CALL2)
2453     {
2454       rtx x = operands[3];
2455
2456       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2457         break;
2458       x = XVECEXP (x, 0, 0);
2459       name = "__sdivsi3_2";
2460       kind = SFUNC_STATIC;
2461       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2462       break;
2463     }
2464   sym = function_symbol (NULL, name, kind);
2465   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2466   DONE;
2467 }
2468   [(set_attr "highpart" "must_split")])
2469
2470 (define_expand "divsi3_i4_media"
2471   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2472    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2473    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2474    (set (match_operand:SI 0 "register_operand" "=r")
2475         (fix:SI (match_dup 5)))]
2476   "TARGET_SHMEDIA_FPU"
2477 {
2478   operands[3] = gen_reg_rtx (DFmode);
2479   operands[4] = gen_reg_rtx (DFmode);
2480   operands[5] = gen_reg_rtx (DFmode);
2481 })
2482
2483 (define_insn "divsi3_i4"
2484   [(set (match_operand:SI 0 "register_operand" "=y")
2485         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2486    (clobber (reg:SI PR_REG))
2487    (clobber (reg:DF DR0_REG))
2488    (clobber (reg:DF DR2_REG))
2489    (use (reg:PSI FPSCR_REG))
2490    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2491   "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2492   "jsr  @%1%#"
2493   [(set_attr "type" "sfunc")
2494    (set_attr "fp_mode" "double")
2495    (set_attr "needs_delay_slot" "yes")])
2496
2497 (define_insn "divsi3_i4_single"
2498   [(set (match_operand:SI 0 "register_operand" "=y")
2499         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2500    (clobber (reg:SI PR_REG))
2501    (clobber (reg:DF DR0_REG))
2502    (clobber (reg:DF DR2_REG))
2503    (clobber (reg:SI R2_REG))
2504    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2505   "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2506    && TARGET_FPU_SINGLE"
2507   "jsr  @%1%#"
2508   [(set_attr "type" "sfunc")
2509    (set_attr "needs_delay_slot" "yes")])
2510
2511 (define_insn "divsi3_i4_int"
2512   [(set (match_operand:SI 0 "register_operand" "=z")
2513         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2514    (clobber (reg:SI T_REG))
2515    (clobber (reg:SI PR_REG))
2516    (clobber (reg:SI R1_REG))
2517    (clobber (reg:SI MACH_REG))
2518    (clobber (reg:SI MACL_REG))
2519    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2520   "TARGET_SH1"
2521   "jsr  @%1%#"
2522   [(set_attr "type" "sfunc")
2523    (set_attr "needs_delay_slot" "yes")])
2524
2525 (define_expand "divsi3"
2526   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2527    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2528    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2529    (parallel [(set (match_operand:SI 0 "register_operand" "")
2530                    (div:SI (reg:SI R4_REG)
2531                            (reg:SI R5_REG)))
2532               (clobber (reg:SI T_REG))
2533               (clobber (reg:SI PR_REG))
2534               (clobber (reg:SI R1_REG))
2535               (clobber (reg:SI R2_REG))
2536               (clobber (reg:SI R3_REG))
2537               (use (match_dup 3))])]
2538   ""
2539 {
2540   rtx last;
2541
2542   operands[3] = gen_reg_rtx (Pmode);
2543   /* Emit the move of the address to a pseudo outside of the libcall.  */
2544   if (TARGET_DIVIDE_CALL_TABLE)
2545     {
2546       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2547       last = gen_divsi3_i4_int (operands[0], operands[3]);
2548     }
2549   else if (TARGET_DIVIDE_CALL_FP)
2550     {
2551       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2552       if (TARGET_FPU_SINGLE)
2553         last = gen_divsi3_i4_single (operands[0], operands[3]);
2554       else
2555         last = gen_divsi3_i4 (operands[0], operands[3]);
2556     }
2557   else if (TARGET_SH2A)
2558     {
2559       operands[1] = force_reg (SImode, operands[1]);
2560       operands[2] = force_reg (SImode, operands[2]);
2561       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2562       DONE;
2563     }
2564   else if (TARGET_DIVIDE_INV)
2565     {
2566       rtx dividend = operands[1];
2567       rtx divisor = operands[2];
2568       rtx tab_base;
2569       rtx nsb_res = gen_reg_rtx (DImode);
2570       rtx norm64 = gen_reg_rtx (DImode);
2571       rtx tab_ix = gen_reg_rtx (DImode);
2572       rtx norm32 = gen_reg_rtx (SImode);
2573       rtx i92 = force_reg (DImode, GEN_INT (92));
2574       rtx scratch0a = gen_reg_rtx (DImode);
2575       rtx scratch0b = gen_reg_rtx (DImode);
2576       rtx inv0 = gen_reg_rtx (SImode);
2577       rtx scratch1a = gen_reg_rtx (DImode);
2578       rtx scratch1b = gen_reg_rtx (DImode);
2579       rtx shift = gen_reg_rtx (DImode);
2580       rtx i2p27, i43;
2581       rtx inv1 = gen_reg_rtx (SImode);
2582       rtx scratch2a = gen_reg_rtx (DImode);
2583       rtx scratch2b = gen_reg_rtx (SImode);
2584       rtx inv2 = gen_reg_rtx (SImode);
2585       rtx scratch3a = gen_reg_rtx (DImode);
2586       rtx scratch3b = gen_reg_rtx (DImode);
2587       rtx scratch3c = gen_reg_rtx (DImode);
2588       rtx scratch3d = gen_reg_rtx (SImode);
2589       rtx scratch3e = gen_reg_rtx (DImode);
2590       rtx result = gen_reg_rtx (SImode);
2591
2592       if (! arith_reg_or_0_operand (dividend, SImode))
2593         dividend = force_reg (SImode, dividend);
2594       if (! arith_reg_operand (divisor, SImode))
2595         divisor = force_reg (SImode, divisor);
2596       if (flag_pic && Pmode != DImode)
2597         {
2598           tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2599           tab_base = gen_datalabel_ref (tab_base);
2600           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2601         }
2602       else
2603         {
2604           tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2605           tab_base = gen_datalabel_ref (tab_base);
2606           tab_base = force_reg (DImode, tab_base);
2607         }
2608       if (TARGET_DIVIDE_INV20U)
2609         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2610       else
2611         i2p27 = GEN_INT (0);
2612       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2613         i43 = force_reg (DImode, GEN_INT (43));
2614       else
2615         i43 = GEN_INT (0);
2616       emit_insn (gen_nsbdi (nsb_res,
2617                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2618       emit_insn (gen_ashldi3_media (norm64,
2619                                     gen_rtx_SUBREG (DImode, divisor, 0),
2620                                     nsb_res));
2621       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2622       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2623       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2624                                    inv0, scratch0a, scratch0b,
2625                                    scratch1a, scratch1b));
2626       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2627       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2628                                    scratch2a));
2629       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2630                                    i2p27, i43,
2631                                    scratch3a, scratch3b, scratch3c,
2632                                    scratch2a, scratch2b, scratch3d, scratch3e));
2633       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2634         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2635       else if (TARGET_DIVIDE_INV_FP)
2636         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2637                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2638                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2639                                      gen_reg_rtx (DFmode)));
2640       else
2641         emit_move_insn (operands[0], result);
2642       DONE;
2643     }
2644   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2645     {
2646       operands[1] = force_reg (SImode, operands[1]);
2647       operands[2] = force_reg (SImode, operands[2]);
2648       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2649       DONE;
2650     }
2651   else if (TARGET_SH5)
2652     {
2653       if (TARGET_DIVIDE_CALL2)
2654         {
2655           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2656           tab_base = gen_datalabel_ref (tab_base);
2657           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2658         }
2659       if (TARGET_FPU_ANY && TARGET_SH1)
2660         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2661       else if (TARGET_DIVIDE_CALL2)
2662         function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2663       else
2664         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2665
2666       if (TARGET_SHMEDIA)
2667         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2668                 (operands[0], operands[3]));
2669       else if (TARGET_FPU_ANY)
2670         last = gen_divsi3_i4_single (operands[0], operands[3]);
2671       else
2672         last = gen_divsi3_i1 (operands[0], operands[3]);
2673     }
2674   else
2675     {
2676       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2677       last = gen_divsi3_i1 (operands[0], operands[3]);
2678     }
2679   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2680   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2681   emit_insn (last);
2682   DONE;
2683 })
2684
2685 ;; operands: scratch, tab_base, tab_ix
2686 ;; These are unspecs because we could generate an indexed addressing mode
2687 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2688 ;; confuse reload.  See PR27117.
2689 (define_insn "divsi_inv_qitable"
2690   [(set (match_operand:DI 0 "register_operand" "=r")
2691         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2692                                     (match_operand:DI 2 "register_operand" "r")]
2693                          UNSPEC_DIV_INV_TABLE)))]
2694   "TARGET_SHMEDIA"
2695   "ldx.ub       %1, %2, %0"
2696   [(set_attr "type" "load_media")
2697    (set_attr "highpart" "user")])
2698
2699 ;; operands: scratch, tab_base, tab_ix
2700 (define_insn "divsi_inv_hitable"
2701   [(set (match_operand:DI 0 "register_operand" "=r")
2702         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2703                                     (match_operand:DI 2 "register_operand" "r")]
2704                          UNSPEC_DIV_INV_TABLE)))]
2705   "TARGET_SHMEDIA"
2706   "ldx.w        %1, %2, %0"
2707   [(set_attr "type" "load_media")
2708    (set_attr "highpart" "user")])
2709
2710 ;; operands: inv0, tab_base, tab_ix, norm32
2711 ;; scratch equiv in sdivsi3_2: r19, r21
2712 (define_expand "divsi_inv_m0"
2713   [(set (match_operand:SI 0 "register_operand" "=r")
2714         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2715                     (match_operand:DI 2 "register_operand" "r")
2716                     (match_operand:SI 3 "register_operand" "r")]
2717          UNSPEC_DIV_INV_M0))
2718    (clobber (match_operand:DI 4 "register_operand" "=r"))
2719    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2720   "TARGET_SHMEDIA"
2721 {
2722 /*
2723 tab_base: r20
2724 tab_ix: r21
2725 norm32: r25
2726  ldx.ub r20, r21, r19 // u0.8
2727  shlli r21, 1, r21
2728  muls.l r25, r19, r19 // s2.38
2729  ldx.w r20, r21, r21  // s2.14
2730  shari r19, 24, r19   // truncate to s2.14
2731  sub r21, r19, r19    // some 11 bit inverse in s1.14
2732 */
2733
2734   rtx inv0 = operands[0];
2735   rtx tab_base = operands[1];
2736   rtx tab_ix = operands[2];
2737   rtx norm32 = operands[3];
2738   rtx scratch0 = operands[4];
2739   rtx scratch0_si = gen_lowpart (SImode, scratch0);
2740   rtx scratch1 = operands[5];
2741
2742   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2743   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2744   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2745   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2746   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2747   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2748   DONE;
2749 })
2750
2751 ;; operands: inv1, tab_base, tab_ix, norm32
2752 (define_insn_and_split "divsi_inv_m1"
2753   [(set (match_operand:SI 0 "register_operand" "=r")
2754         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2755                     (match_operand:DI 2 "register_operand" "r")
2756                     (match_operand:SI 3 "register_operand" "r")]
2757          UNSPEC_DIV_INV_M1))
2758    (clobber (match_operand:SI 4 "register_operand" "=r"))
2759    (clobber (match_operand:DI 5 "register_operand" "=r"))
2760    (clobber (match_operand:DI 6 "register_operand" "=r"))
2761    (clobber (match_operand:DI 7 "register_operand" "=r"))
2762    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2763   "TARGET_SHMEDIA"
2764   "#"
2765   "&& !can_create_pseudo_p ()"
2766   [(pc)]
2767 {
2768 /* inv0: r19
2769  muls.l r19, r19, r18 // u0.28
2770  muls.l r25, r18, r18 // s2.58
2771  shlli r19, 45, r0    // multiply by two and convert to s2.58
2772  sub r0, r18, r18
2773  shari r18, 28, r18   // some 18 bit inverse in s1.30
2774 */
2775
2776   rtx inv1 = operands[0];
2777   rtx tab_base = operands[1];
2778   rtx tab_ix = operands[2];
2779   rtx norm32 = operands[3];
2780   rtx inv0 = operands[4];
2781   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2782   rtx scratch0a = operands[5];
2783   rtx scratch0b = operands[6];
2784   rtx scratch0 = operands[7];
2785   rtx scratch1 = operands[8];
2786   rtx scratch1_si = gen_lowpart (SImode, scratch1);
2787
2788   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2789                                scratch0a, scratch0b));
2790   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2791   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2792   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2793   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2794   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2795   DONE;
2796 })
2797
2798 ;; operands: inv2, norm32, inv1, i92
2799 (define_insn_and_split "divsi_inv_m2"
2800   [(set (match_operand:SI 0 "register_operand" "=r")
2801         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2802                     (match_operand:SI 2 "register_operand" "r")
2803                     (match_operand:DI 3 "register_operand" "r")]
2804          UNSPEC_DIV_INV_M2))
2805    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2806   "TARGET_SHMEDIA"
2807   "#"
2808   "&& !can_create_pseudo_p ()"
2809   [(pc)]
2810 {
2811 /*
2812  muls.l r18, r25, r0  // s2.60
2813  shari r0, 16, r0     // s-16.44
2814   sub
2815  muls.l r0, r18, r19  // s-16.74
2816  shari r19, 30, r19   // s-16.44
2817 */
2818   rtx inv2 = operands[0];
2819   rtx norm32 = operands[1];
2820   rtx inv1 = operands[2];
2821   rtx i92 = operands[3];
2822   rtx scratch0 = operands[4];
2823   rtx scratch0_si = gen_lowpart (SImode, scratch0);
2824
2825   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2826   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2827   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2828   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2829   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2830   DONE;
2831 })
2832
2833 (define_insn_and_split "divsi_inv_m3"
2834   [(set (match_operand:SI 0 "register_operand" "=r")
2835         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2836                     (match_operand:SI 2 "register_operand" "r")
2837                     (match_operand:SI 3 "register_operand" "r")
2838                     (match_operand:DI 4 "register_operand" "r")
2839                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2840                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2841          UNSPEC_DIV_INV_M3))
2842    (clobber (match_operand:DI 7 "register_operand" "=r"))
2843    (clobber (match_operand:DI 8 "register_operand" "=r"))
2844    (clobber (match_operand:DI 9 "register_operand" "=r"))
2845    (clobber (match_operand:DI 10 "register_operand" "=r"))
2846    (clobber (match_operand:SI 11 "register_operand" "=r"))
2847    (clobber (match_operand:SI 12 "register_operand" "=r"))
2848    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2849   "TARGET_SHMEDIA"
2850   "#"
2851   "&& !can_create_pseudo_p ()"
2852   [(pc)]
2853 {
2854 /*
2855   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2856   r0: scratch0  r19: scratch1 r21: scratch2
2857
2858   muls.l r18, r4, r25 // s32.30
2859  muls.l r19, r4, r19  // s15.30
2860  shari r25, 63, r21
2861   shari r19, 14, r19  // s18.-14
2862  sub r25, r19, r0
2863  shard r0, r1, r0
2864  sub r0, r21, r0
2865 */
2866
2867   rtx result = operands[0];
2868   rtx dividend = operands[1];
2869   rtx inv1 = operands[2];
2870   rtx inv2 = operands[3];
2871   rtx shift = operands[4];
2872   rtx scratch0 = operands[7];
2873   rtx scratch1 = operands[8];
2874   rtx scratch2 = operands[9];
2875
2876   if (satisfies_constraint_N (dividend))
2877     {
2878       emit_move_insn (result, dividend);
2879       DONE;
2880     }
2881
2882   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2883   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2884   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2885   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2886   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2887   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2888   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2889   DONE;
2890 })
2891
2892 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2893 ;; inv1: tab_base, tab_ix, norm32
2894 ;; inv2: norm32, inv1, i92
2895 (define_insn_and_split "divsi_inv_m1_3"
2896   [(set (match_operand:SI 0 "register_operand" "=r")
2897         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2898                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2899                                 (match_operand:DI 3 "register_operand" "r")
2900                                 (match_operand:SI 4 "register_operand" "r")]
2901                      UNSPEC_DIV_INV_M1)
2902                     (unspec:SI [(match_dup 4)
2903                                 (unspec:SI [(match_dup 2)
2904                                             (match_dup 3)
2905                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2906                                 (match_operand:SI 5 "" "")]
2907                      UNSPEC_DIV_INV_M2)
2908                     (match_operand:DI 6 "register_operand" "r")
2909                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2910                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2911          UNSPEC_DIV_INV_M3))
2912    (clobber (match_operand:DI 9 "register_operand" "=r"))
2913    (clobber (match_operand:DI 10 "register_operand" "=r"))
2914    (clobber (match_operand:DI 11 "register_operand" "=r"))
2915    (clobber (match_operand:DI 12 "register_operand" "=r"))
2916    (clobber (match_operand:SI 13 "register_operand" "=r"))
2917    (clobber (match_operand:SI 14 "register_operand" "=r"))
2918    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2919   "TARGET_SHMEDIA
2920    && (TARGET_DIVIDE_INV_MINLAT
2921        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2922   "#"
2923   "&& !can_create_pseudo_p ()"
2924   [(pc)]
2925 {
2926   rtx result = operands[0];
2927   rtx dividend = operands[1];
2928   rtx tab_base = operands[2];
2929   rtx tab_ix = operands[3];
2930   rtx norm32 = operands[4];
2931   /* rtx i92 = operands[5]; */
2932   rtx shift = operands[6];
2933   rtx i2p27 = operands[7];
2934   rtx i43 = operands[8];
2935   rtx scratch0 = operands[9];
2936   rtx scratch0_si = gen_lowpart (SImode, scratch0);
2937   rtx scratch1 = operands[10];
2938   rtx scratch1_si = gen_lowpart (SImode, scratch1);
2939   rtx scratch2 = operands[11];
2940   rtx scratch3 = operands[12];
2941   rtx scratch4 = operands[13];
2942   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2943   rtx scratch5 = operands[14];
2944   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2945   rtx scratch6 = operands[15];
2946
2947   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2948                                scratch0, scratch1));
2949   /* inv0 == scratch4 */
2950   if (! TARGET_DIVIDE_INV20U)
2951     {
2952       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2953       i2p27 = scratch0;
2954       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2955     }
2956   else
2957     {
2958       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2959       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2960     }
2961   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2962   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2963   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2964   /* inv1 == scratch4 */
2965
2966   if (TARGET_DIVIDE_INV_MINLAT)
2967     {
2968       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2969       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2970       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2971       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2972       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2973       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2974       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2975       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2976       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2977       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2978       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2979     }
2980   else
2981     {
2982       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2983       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2984       emit_insn (gen_nsbdi (scratch6,
2985                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2986       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2987       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2988       emit_insn (gen_divsi_inv20 (scratch2,
2989                                   norm32, scratch4, dividend,
2990                                   scratch6, scratch3, i43,
2991                                   /* scratch0 may be shared with i2p27.  */
2992                                   scratch0, scratch1, scratch5,
2993                                   label, label, i2p27));
2994     }
2995   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2996   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2997   DONE;
2998 })
2999
3000 (define_insn "divsi_inv20"
3001   [(set (match_operand:DI 0 "register_operand" "=&r")
3002         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
3003                     (match_operand:SI 2 "register_operand" "r")
3004                     (match_operand:SI 3 "register_operand" "r")
3005                     (match_operand:DI 4 "register_operand" "r")
3006                     (match_operand:DI 5 "register_operand" "r")
3007                     (match_operand:DI 6 "register_operand" "r")
3008                     (match_operand:DI 12 "register_operand" "r")
3009                     (match_operand 10 "target_operand" "b")
3010                     (match_operand 11 "immediate_operand" "i")]
3011          UNSPEC_DIV_INV20))
3012    (clobber (match_operand:DI 7 "register_operand" "=&r"))
3013    (clobber (match_operand:DI 8 "register_operand" "=&r"))
3014    (clobber (match_operand:SI 9 "register_operand" "=r"))]
3015   "TARGET_SHMEDIA
3016    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3017 {
3018 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3019              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3020              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3021              %10 label (tr), %11 label (imm)
3022
3023  muls.l inv1, norm32, scratch0  // s2.60
3024   muls.l inv1, dividend, result // s32.30
3025   xor i2p27, result_sign, round_scratch
3026  bge/u dividend_nsb, i43, tr.. (label)
3027  shari scratch0, 16, scratch0   // s-16.44
3028  muls.l sratch0_si, inv1, scratch0 // s-16.74
3029   sub result, round_scratch, result
3030   shari dividend, 14, scratch1   // s19.-14
3031  shari scratch0, 30, scratch0   // s-16.44
3032  muls.l scratch0, scratch1, round_scratch // s15.30
3033 label:
3034  sub result, round_scratch, result */
3035
3036   const bool likely = TARGET_DIVIDE_INV20L;
3037   if (likely)
3038     return
3039                "muls.l  %2, %3, %0"     "\n"
3040         "       xor     %12, %5, %7"    "\n"
3041         "       bge/l   %4, %6, %10"    "\n"
3042         "       muls.l  %2, %1, %8"     "\n"
3043         "       shari   %8, 16, %8"     "\n"
3044         "       muls.l  %8, %2, %8"     "\n"
3045         "       shari   %3, 14, %9"     "\n"
3046         "       shari   %8, 30, %8"     "\n"
3047         "       muls.l  %8, %9, %8"     "\n"
3048         "       sub     %0, %8, %0"     "\n"
3049         "%11:   add     %0, %7, %0";
3050   else
3051     return
3052                "muls.l  %2, %1, %8"     "\n"
3053         "       muls.l  %2, %3, %0"     "\n"
3054         "       xor     %12, %5, %7"    "\n"
3055         "       bge/u   %4, %6, %10"    "\n"
3056         "       shari   %8, 16, %8"     "\n"
3057         "       muls.l  %8, %2, %8"     "\n"
3058         "       sub     %0, %7, %0"     "\n"
3059         "       shari   %3, 14, %9"     "\n"
3060         "       shari   %8, 30, %8"     "\n"
3061         "       muls.l  %8, %9, %7"     "\n"
3062         "%11:   sub     %0, %7, %0";
3063 })
3064
3065 (define_insn_and_split "divsi_inv_fp"
3066   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3067         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3068                 (match_operand:SI 2 "register_operand" "rf")))
3069    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3070    (clobber (match_operand:SI 4 "register_operand" "=r"))
3071    (clobber (match_operand:SI 5 "register_operand" "=r"))
3072    (clobber (match_operand:DF 6 "register_operand" "=r"))
3073    (clobber (match_operand:DF 7 "register_operand" "=r"))
3074    (clobber (match_operand:DF 8 "register_operand" "=r"))]
3075   "TARGET_SHMEDIA_FPU"
3076   "#"
3077   "&& (reload_in_progress || reload_completed)"
3078   [(set (match_dup 0) (match_dup 3))]
3079   ""
3080   [(set_attr "highpart" "must_split")])
3081
3082 ;; If a matching group of divide-by-inverse instructions is in the same
3083 ;; basic block after gcse & loop optimizations, we want to transform them
3084 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3085 (define_insn_and_split "*divsi_inv_fp_combine"
3086   [(set (match_operand:SI 0 "register_operand" "=f")
3087         (div:SI (match_operand:SI 1 "register_operand" "f")
3088                 (match_operand:SI 2 "register_operand" "f")))
3089    (use (unspec:SI [(match_dup 1)
3090                     (match_operand:SI 3 "" "")
3091                     (unspec:SI [(match_operand:SI 4 "" "")
3092                                 (match_dup 3)
3093                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3094                     (match_operand:DI 6 "" "")
3095                     (const_int 0)
3096                     (const_int 0)] UNSPEC_DIV_INV_M3))
3097    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3098    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3099    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3100    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3101    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3102   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3103   "#"
3104   "&& 1"
3105   [(set (match_dup 9) (float:DF (match_dup 1)))
3106    (set (match_dup 10) (float:DF (match_dup 2)))
3107    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3108    (set (match_dup 8)
3109         (fix:SI (match_dup 11)))
3110    (set (match_dup 0) (match_dup 8))]
3111 {
3112   if (! fp_arith_reg_operand (operands[1], SImode))
3113     {
3114       emit_move_insn (operands[7], operands[1]);
3115       operands[1] = operands[7];
3116     }
3117   if (! fp_arith_reg_operand (operands[2], SImode))
3118     {
3119       emit_move_insn (operands[8], operands[2]);
3120       operands[2] = operands[8];
3121     }
3122 }
3123   [(set_attr "highpart" "must_split")])
3124 \f
3125 ;; -------------------------------------------------------------------------
3126 ;; Multiplication instructions
3127 ;; -------------------------------------------------------------------------
3128
3129 (define_insn "umulhisi3_i"
3130   [(set (reg:SI MACL_REG)
3131         (mult:SI (zero_extend:SI
3132                   (match_operand:HI 0 "arith_reg_operand" "r"))
3133                  (zero_extend:SI
3134                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
3135   "TARGET_SH1"
3136   "mulu.w       %1,%0"
3137   [(set_attr "type" "smpy")])
3138
3139 (define_insn "mulhisi3_i"
3140   [(set (reg:SI MACL_REG)
3141         (mult:SI (sign_extend:SI
3142                   (match_operand:HI 0 "arith_reg_operand" "r"))
3143                  (sign_extend:SI
3144                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
3145   "TARGET_SH1"
3146   "muls.w       %1,%0"
3147   [(set_attr "type" "smpy")])
3148
3149 (define_expand "mulhisi3"
3150   [(set (reg:SI MACL_REG)
3151         (mult:SI (sign_extend:SI
3152                   (match_operand:HI 1 "arith_reg_operand" ""))
3153                  (sign_extend:SI
3154                   (match_operand:HI 2 "arith_reg_operand" ""))))
3155    (set (match_operand:SI 0 "arith_reg_operand" "")
3156         (reg:SI MACL_REG))]
3157   "TARGET_SH1"
3158 {
3159   rtx insn, macl;
3160
3161   macl = gen_rtx_REG (SImode, MACL_REG);
3162   start_sequence ();
3163   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3164   insn = get_insns ();  
3165   end_sequence ();
3166   /* expand_binop can't find a suitable code in umul_widen_optab to
3167      make a REG_EQUAL note from, so make one here.
3168      See also smulsi3_highpart.
3169      ??? Alternatively, we could put this at the calling site of expand_binop,
3170      i.e. expand_expr.  */
3171   /* Use emit_libcall_block for loop invariant code motion and to make
3172      a REG_EQUAL note.  */
3173   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3174
3175   DONE;
3176 })
3177
3178 (define_expand "umulhisi3"
3179   [(set (reg:SI MACL_REG)
3180         (mult:SI (zero_extend:SI
3181                   (match_operand:HI 1 "arith_reg_operand" ""))
3182                  (zero_extend:SI
3183                   (match_operand:HI 2 "arith_reg_operand" ""))))
3184    (set (match_operand:SI 0 "arith_reg_operand" "")
3185         (reg:SI MACL_REG))]
3186   "TARGET_SH1"
3187 {
3188   rtx insn, macl;
3189
3190   macl = gen_rtx_REG (SImode, MACL_REG);
3191   start_sequence ();
3192   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3193   insn = get_insns ();  
3194   end_sequence ();
3195   /* expand_binop can't find a suitable code in umul_widen_optab to
3196      make a REG_EQUAL note from, so make one here.
3197      See also smulsi3_highpart.
3198      ??? Alternatively, we could put this at the calling site of expand_binop,
3199      i.e. expand_expr.  */
3200   /* Use emit_libcall_block for loop invariant code motion and to make
3201      a REG_EQUAL note.  */
3202   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3203
3204   DONE;
3205 })
3206
3207 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3208 ;; a call to a routine which clobbers known registers.
3209 (define_insn ""
3210   [(set (match_operand:SI 1 "register_operand" "=z")
3211         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3212    (clobber (reg:SI MACL_REG))
3213    (clobber (reg:SI T_REG))
3214    (clobber (reg:SI PR_REG))
3215    (clobber (reg:SI R3_REG))
3216    (clobber (reg:SI R2_REG))
3217    (clobber (reg:SI R1_REG))
3218    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3219   "TARGET_SH1"
3220   "jsr  @%0%#"
3221   [(set_attr "type" "sfunc")
3222    (set_attr "needs_delay_slot" "yes")])
3223
3224 (define_expand "mulsi3_call"
3225   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3226    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3227    (parallel[(set (match_operand:SI 0 "register_operand" "")
3228                   (mult:SI (reg:SI R4_REG)
3229                            (reg:SI R5_REG)))
3230              (clobber (reg:SI MACL_REG))
3231              (clobber (reg:SI T_REG))
3232              (clobber (reg:SI PR_REG))
3233              (clobber (reg:SI R3_REG))
3234              (clobber (reg:SI R2_REG))
3235              (clobber (reg:SI R1_REG))
3236              (use (match_operand:SI 3 "register_operand" ""))])]
3237   "TARGET_SH1"
3238   "")
3239
3240 (define_insn "mul_r"
3241   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3242         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3243                  (match_operand:SI 2 "arith_reg_operand" "z")))]
3244   "TARGET_SH2A"
3245   "mulr %2,%0"
3246   [(set_attr "type" "dmpy")])
3247
3248 (define_insn "mul_l"
3249   [(set (reg:SI MACL_REG)
3250         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3251                  (match_operand:SI 1 "arith_reg_operand" "r")))]
3252   "TARGET_SH2"
3253   "mul.l        %1,%0"
3254   [(set_attr "type" "dmpy")])
3255
3256 (define_expand "mulsi3"
3257   [(set (reg:SI MACL_REG)
3258         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
3259                   (match_operand:SI 2 "arith_reg_operand" "")))
3260    (set (match_operand:SI 0 "arith_reg_operand" "")
3261         (reg:SI MACL_REG))]
3262   "TARGET_SH1"
3263 {
3264   if (!TARGET_SH2)
3265     {
3266       /* The address must be set outside the libcall,
3267          since it goes into a pseudo.  */
3268       rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3269       rtx addr = force_reg (SImode, sym);
3270       rtx insns = gen_mulsi3_call (operands[0], operands[1],
3271                                    operands[2], addr);
3272       emit_insn (insns);
3273     }
3274   else
3275     {
3276       rtx macl = gen_rtx_REG (SImode, MACL_REG);
3277
3278       emit_insn (gen_mul_l (operands[1], operands[2]));
3279       /* consec_sets_giv can only recognize the first insn that sets a
3280          giv as the giv insn.  So we must tag this also with a REG_EQUAL
3281          note.  */
3282       emit_insn (gen_movsi_i ((operands[0]), macl));
3283     }
3284   DONE;
3285 })
3286
3287 (define_insn "mulsidi3_i"
3288   [(set (reg:SI MACH_REG)
3289         (truncate:SI
3290          (lshiftrt:DI
3291           (mult:DI
3292            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3293            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3294           (const_int 32))))
3295    (set (reg:SI MACL_REG)
3296         (mult:SI (match_dup 0)
3297                  (match_dup 1)))]
3298   "TARGET_SH2"
3299   "dmuls.l      %1,%0"
3300   [(set_attr "type" "dmpy")])
3301
3302 (define_expand "mulsidi3"
3303   [(set (match_operand:DI 0 "arith_reg_dest" "")
3304         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3305                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3306   "TARGET_SH2 || TARGET_SHMEDIA"
3307 {
3308   if (TARGET_SH2)
3309     {
3310       emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3311       DONE;
3312     }
3313 })
3314
3315 (define_insn "mulsidi3_media"
3316   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3317         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3318                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3319   "TARGET_SHMEDIA"
3320   "muls.l       %1, %2, %0"
3321   [(set_attr "type" "dmpy_media")
3322    (set_attr "highpart" "ignore")])
3323
3324 (define_insn_and_split "mulsidi3_compact"
3325   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3326         (mult:DI
3327          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3328          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3329    (clobber (reg:SI MACH_REG))
3330    (clobber (reg:SI MACL_REG))]
3331   "TARGET_SH2"
3332   "#"
3333   "&& 1"
3334   [(const_int 0)]
3335 {
3336   rtx low_dst = gen_lowpart (SImode, operands[0]);
3337   rtx high_dst = gen_highpart (SImode, operands[0]);
3338
3339   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3340
3341   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3342   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3343   /* We need something to tag the possible REG_EQUAL notes on to.  */
3344   emit_move_insn (operands[0], operands[0]);
3345   DONE;
3346 })
3347
3348 (define_insn "umulsidi3_i"
3349   [(set (reg:SI MACH_REG)
3350         (truncate:SI
3351          (lshiftrt:DI
3352           (mult:DI
3353            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3354            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3355           (const_int 32))))
3356    (set (reg:SI MACL_REG)
3357         (mult:SI (match_dup 0)
3358                  (match_dup 1)))]
3359   "TARGET_SH2"
3360   "dmulu.l      %1,%0"
3361   [(set_attr "type" "dmpy")])
3362
3363 (define_expand "umulsidi3"
3364   [(set (match_operand:DI 0 "arith_reg_dest" "")
3365         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3366                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3367   "TARGET_SH2 || TARGET_SHMEDIA"
3368 {
3369   if (TARGET_SH2)
3370     {
3371       emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3372       DONE;
3373     }
3374 })
3375
3376 (define_insn "umulsidi3_media"
3377   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3378         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3379                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3380   "TARGET_SHMEDIA"
3381   "mulu.l       %1, %2, %0"
3382   [(set_attr "type" "dmpy_media")
3383    (set_attr "highpart" "ignore")])
3384
3385 (define_insn_and_split "umulsidi3_compact"
3386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387         (mult:DI
3388          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3389          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3390    (clobber (reg:SI MACH_REG))
3391    (clobber (reg:SI MACL_REG))]
3392   "TARGET_SH2"
3393   "#"
3394   "&& 1"
3395   [(const_int 0)]
3396 {
3397   rtx low_dst = gen_lowpart (SImode, operands[0]);
3398   rtx high_dst = gen_highpart (SImode, operands[0]);
3399
3400   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3401
3402   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3403   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3404   /* We need something to tag the possible REG_EQUAL notes on to.  */
3405   emit_move_insn (operands[0], operands[0]);
3406   DONE;
3407 })
3408
3409 (define_insn "smulsi3_highpart_i"
3410   [(set (reg:SI MACH_REG)
3411         (truncate:SI
3412          (lshiftrt:DI
3413           (mult:DI
3414            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3415            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3416           (const_int 32))))
3417    (clobber (reg:SI MACL_REG))]
3418   "TARGET_SH2"
3419   "dmuls.l      %1,%0"
3420   [(set_attr "type" "dmpy")])
3421
3422 (define_expand "smulsi3_highpart"
3423   [(parallel
3424     [(set (reg:SI MACH_REG)
3425           (truncate:SI
3426            (lshiftrt:DI
3427             (mult:DI
3428              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3429              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3430             (const_int 32))))
3431     (clobber (reg:SI MACL_REG))])
3432    (set (match_operand:SI 0 "arith_reg_operand" "")
3433         (reg:SI MACH_REG))]
3434   "TARGET_SH2"
3435 {
3436   rtx insn, mach;
3437
3438   mach = gen_rtx_REG (SImode, MACH_REG);
3439   start_sequence ();
3440   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3441   insn = get_insns ();  
3442   end_sequence ();
3443   /* expand_binop can't find a suitable code in mul_highpart_optab to
3444      make a REG_EQUAL note from, so make one here.
3445      See also {,u}mulhisi.
3446      ??? Alternatively, we could put this at the calling site of expand_binop,
3447      i.e. expand_mult_highpart.  */
3448   /* Use emit_libcall_block for loop invariant code motion and to make
3449      a REG_EQUAL note.  */
3450   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3451
3452   DONE;
3453 })
3454
3455 (define_insn "umulsi3_highpart_i"
3456   [(set (reg:SI MACH_REG)
3457         (truncate:SI
3458          (lshiftrt:DI
3459           (mult:DI
3460            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3461            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3462           (const_int 32))))
3463    (clobber (reg:SI MACL_REG))]
3464   "TARGET_SH2"
3465   "dmulu.l      %1,%0"
3466   [(set_attr "type" "dmpy")])
3467
3468 (define_expand "umulsi3_highpart"
3469   [(parallel
3470     [(set (reg:SI MACH_REG)
3471           (truncate:SI
3472            (lshiftrt:DI
3473             (mult:DI
3474              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3475              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3476             (const_int 32))))
3477     (clobber (reg:SI MACL_REG))])
3478    (set (match_operand:SI 0 "arith_reg_operand" "")
3479         (reg:SI MACH_REG))]
3480   "TARGET_SH2"
3481 {
3482   rtx insn, mach;
3483
3484   mach = gen_rtx_REG (SImode, MACH_REG);
3485   start_sequence ();
3486   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3487   insn = get_insns ();  
3488   end_sequence ();
3489   /* Use emit_libcall_block for loop invariant code motion and to make
3490      a REG_EQUAL note.  */
3491   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3492
3493   DONE;
3494 })
3495
3496 (define_insn_and_split "muldi3"
3497   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3498         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3499                  (match_operand:DI 2 "arith_reg_operand" "r")))
3500    (clobber (match_scratch:DI 3 "=&r"))
3501    (clobber (match_scratch:DI 4 "=r"))]
3502   "TARGET_SHMEDIA"
3503   "#"
3504   "reload_completed"
3505   [(const_int 0)]
3506 {
3507   rtx op3_v2si, op2_v2si;
3508
3509   op3_v2si = operands[3];
3510   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3511     {
3512       op3_v2si = XEXP (op3_v2si, 0);
3513       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3514     }
3515   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3516   op2_v2si = operands[2];
3517   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3518     {
3519       op2_v2si = XEXP (op2_v2si, 0);
3520       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3521     }
3522   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3523   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3524   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3525   emit_insn (gen_umulsidi3_media (operands[4],
3526                                  sh_gen_truncate (SImode, operands[1], 0),
3527                                  sh_gen_truncate (SImode, operands[2], 0)));
3528   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3529   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3530   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3531   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3532   DONE;
3533 })
3534 \f
3535 ;; -------------------------------------------------------------------------
3536 ;; Logical operations
3537 ;; -------------------------------------------------------------------------
3538
3539 (define_expand "andsi3"
3540   [(set (match_operand:SI 0 "arith_reg_operand" "")
3541         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3542                 (match_operand:SI 2 "logical_and_operand" "")))]
3543   ""
3544 {
3545   /* If it is possible to turn the and insn into a zero extension
3546      already, redundant zero extensions will be folded, which results
3547      in better code.  
3548      Ideally the splitter of *andsi_compact would be enough, if redundant
3549      zero extensions were detected after the combine pass, which does not
3550      happen at the moment.  */
3551   if (TARGET_SH1)
3552     {
3553       if (satisfies_constraint_Jmb (operands[2]))
3554         {
3555           emit_insn (gen_zero_extendqisi2 (operands[0],
3556                                            gen_lowpart (QImode, operands[1])));
3557           DONE;
3558         }
3559       else if (satisfies_constraint_Jmw (operands[2]))
3560         {
3561           emit_insn (gen_zero_extendhisi2 (operands[0],
3562                                            gen_lowpart (HImode, operands[1])));
3563           DONE;
3564         }
3565     }
3566 })
3567
3568 (define_insn_and_split "*andsi_compact"
3569   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3570         (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3571                 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3572   "TARGET_SH1"
3573   "@
3574         extu.b  %1,%0
3575         extu.w  %1,%0
3576         and     %2,%0
3577         and     %2,%0"
3578   "&& 1"
3579  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3580 {
3581   if (satisfies_constraint_Jmb (operands[2]))
3582     operands[1] = gen_lowpart (QImode, operands[1]);
3583   else if (satisfies_constraint_Jmw (operands[2]))
3584     operands[1] = gen_lowpart (HImode, operands[1]);
3585   else
3586     FAIL;
3587 }
3588   [(set_attr "type" "arith")])
3589
3590 (define_insn "*andsi3_media"
3591   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3592         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3593                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3594   "TARGET_SHMEDIA"
3595   "@
3596         and     %1, %2, %0
3597         andi    %1, %2, %0"
3598   [(set_attr "type" "arith_media")])
3599
3600 (define_insn "*andsi3_bclr"
3601   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3602         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3603                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3604   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3605   "bclr %W2,%0"
3606   [(set_attr "type" "arith")])
3607
3608 (define_insn_and_split "anddi3"
3609   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3610         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3611                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3612   "TARGET_SHMEDIA"
3613   "@
3614         and     %1, %2, %0
3615         andi    %1, %2, %0
3616         #"
3617   "reload_completed
3618    && ! logical_operand (operands[2], DImode)"
3619   [(const_int 0)]
3620 {
3621   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3622     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3623   else
3624     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3625   DONE;
3626 }
3627   [(set_attr "type" "arith_media")])
3628
3629 (define_insn "andcsi3"
3630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3631         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3632                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633   "TARGET_SHMEDIA"
3634   "andc %1,%2,%0"
3635   [(set_attr "type" "arith_media")])
3636
3637 (define_insn "andcdi3"
3638   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3639         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3640                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3641   "TARGET_SHMEDIA"
3642   "andc %1,%2,%0"
3643   [(set_attr "type" "arith_media")])
3644
3645 (define_expand "iorsi3"
3646   [(set (match_operand:SI 0 "arith_reg_operand" "")
3647         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3648                 (match_operand:SI 2 "logical_operand" "")))]
3649   ""
3650   "")
3651
3652 (define_insn "*iorsi3_compact"
3653   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3654         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3655                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3656   "TARGET_SH1
3657    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3658   "or   %2,%0"
3659   [(set_attr "type" "arith")])
3660
3661 (define_insn "*iorsi3_media"
3662   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3663         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3664                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3665   "TARGET_SHMEDIA"
3666   "@
3667         or      %1, %2, %0
3668         ori     %1, %2, %0"
3669   [(set_attr "type" "arith_media")])
3670
3671 (define_insn "*iorsi3_bset"
3672   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3673         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3674         (match_operand:SI 2 "const_int_operand" "Pso")))]
3675   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3676   "bset %V2,%0"
3677   [(set_attr "type" "arith")])
3678
3679 (define_insn "iordi3"
3680   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3681         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3682                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3683   "TARGET_SHMEDIA"
3684   "@
3685         or      %1, %2, %0
3686         ori     %1, %2, %0"
3687   [(set_attr "type" "arith_media")])
3688
3689 (define_insn_and_split "*logical_sidi3"
3690   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3691         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3692                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3693                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3694   "TARGET_SHMEDIA"
3695   "#"
3696   "&& reload_completed"
3697   [(set (match_dup 0) (match_dup 3))]
3698 {
3699   operands[3]
3700     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3701                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3702                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3703 })
3704
3705 (define_insn_and_split "*logical_sidisi3"
3706   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3707         (truncate:SI (sign_extend:DI
3708                         (match_operator:SI 3 "logical_operator"
3709                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3710                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3711   "TARGET_SHMEDIA"
3712   "#"
3713   "&& 1"
3714   [(set (match_dup 0) (match_dup 3))])
3715
3716 (define_insn_and_split "*logical_sidi3_2"
3717   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3718         (sign_extend:DI (truncate:SI (sign_extend:DI
3719                         (match_operator:SI 3 "logical_operator"
3720                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3721                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3722   "TARGET_SHMEDIA"
3723   "#"
3724   "&& 1"
3725   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3726
3727 (define_expand "xorsi3"
3728   [(set (match_operand:SI 0 "arith_reg_operand" "")
3729         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3730                 (match_operand:SI 2 "xor_operand" "")))]
3731   ""
3732   "")
3733
3734 (define_insn "*xorsi3_compact"
3735   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3736         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3737                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3738   "TARGET_SH1"
3739   "xor  %2,%0"
3740   [(set_attr "type" "arith")])
3741
3742 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3743 ;; of results where one of the inputs is a T bit store.  Notice that this
3744 ;; pattern must not match during reload.  If reload picks this pattern it
3745 ;; will be impossible to split it afterwards.
3746 (define_insn_and_split "*logical_op_t"
3747   [(set (match_operand:SI 0 "arith_reg_dest")
3748         (match_operator:SI 3 "logical_operator"
3749           [(match_operand:SI 1 "arith_reg_operand")
3750            (match_operand:SI 2 "t_reg_operand")]))]
3751   "TARGET_SH1 && can_create_pseudo_p ()"
3752   "#"
3753   "&& 1"
3754   [(set (match_dup 4) (reg:SI T_REG))
3755    (set (match_dup 0) (match_dup 3))]
3756 {
3757   operands[4] = gen_reg_rtx (SImode);
3758   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3759                                 operands[1], operands[4]);
3760 })
3761
3762 (define_insn "*xorsi3_media"
3763   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3764         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3765                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3766   "TARGET_SHMEDIA"
3767   "@
3768         xor     %1, %2, %0
3769         xori    %1, %2, %0"
3770   [(set_attr "type" "arith_media")])
3771
3772 (define_insn "xordi3"
3773   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3774         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3775                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3776   "TARGET_SHMEDIA"
3777   "@
3778         xor     %1, %2, %0
3779         xori    %1, %2, %0"
3780   [(set_attr "type" "arith_media")])
3781
3782 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3783 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3784 (define_split
3785   [(set (match_operand:DI 0 "arith_reg_dest" "")
3786         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3787                           [(match_operand 1 "any_register_operand" "")
3788                            (match_operand 2 "any_register_operand" "")])))]
3789   "TARGET_SHMEDIA"
3790   [(set (match_dup 5) (match_dup 4))
3791    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3792 {
3793   enum machine_mode inmode = GET_MODE (operands[1]);
3794   int offset = 0;
3795
3796   if (GET_CODE (operands[0]) == SUBREG)
3797     {
3798       offset = SUBREG_BYTE (operands[0]);
3799       operands[0] = SUBREG_REG (operands[0]);
3800     }
3801   gcc_assert (REG_P (operands[0]));
3802   if (! TARGET_LITTLE_ENDIAN)
3803     offset += 8 - GET_MODE_SIZE (inmode);
3804   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3805 })
3806 \f
3807 ;; -------------------------------------------------------------------------
3808 ;; Shifts and rotates
3809 ;; -------------------------------------------------------------------------
3810
3811 (define_expand "rotldi3"
3812   [(set (match_operand:DI 0 "arith_reg_dest" "")
3813         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
3814                    (match_operand:HI 2 "mextr_bit_offset" "")))]
3815   "TARGET_SHMEDIA"
3816 {
3817   if (! mextr_bit_offset (operands[2], HImode))
3818     FAIL;
3819 })
3820
3821 (define_insn "rotldi3_mextr"
3822   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3823         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3824                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3825   "TARGET_SHMEDIA"
3826 {
3827   static char templ[16];
3828   sprintf (templ, "mextr%d      %%1,%%1,%%0",
3829            8 - (int) (INTVAL (operands[2]) >> 3));
3830   return templ;
3831 }
3832   [(set_attr "type" "arith_media")])
3833
3834 (define_expand "rotrdi3"
3835   [(set (match_operand:DI 0 "arith_reg_dest" "")
3836         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
3837                      (match_operand:HI 2 "mextr_bit_offset" "")))]
3838   "TARGET_SHMEDIA"
3839 {
3840   if (! mextr_bit_offset (operands[2], HImode))
3841     FAIL;
3842 })
3843
3844 (define_insn "rotrdi3_mextr"
3845   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3846         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3847                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3848   "TARGET_SHMEDIA"
3849 {
3850   static char templ[16];
3851   sprintf (templ, "mextr%d      %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3852   return templ;
3853 }
3854   [(set_attr "type" "arith_media")])
3855
3856 (define_split
3857   [(set (match_operand:DI 0 "arith_reg_dest" "")
3858         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3859                                          "ua_address_operand" "")))
3860                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3861                            (const_int 8))))
3862    (clobber (match_operand:DI 3 "register_operand" ""))]
3863   "TARGET_SHMEDIA"
3864   [(match_dup 4) (match_dup 5)]
3865 {
3866   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3867                  (operands[3], operands[1]));
3868   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3869                               GEN_INT (56), GEN_INT (8));
3870 })
3871
3872 (define_expand "rotrsi3"
3873   [(set (match_operand:SI 0 "arith_reg_dest")
3874         (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
3875                      (match_operand:SI 2 "const_int_operand")))]
3876   "TARGET_SH1"
3877 {
3878   HOST_WIDE_INT ival = INTVAL (operands[2]);
3879   if (ival == 1)
3880     {
3881       emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
3882       DONE;
3883     }
3884
3885   FAIL;
3886 })
3887
3888 (define_insn "rotrsi3_1"
3889   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3890         (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3891                      (const_int 1)))
3892    (set (reg:SI T_REG)
3893         (and:SI (match_dup 1) (const_int 1)))]
3894   "TARGET_SH1"
3895   "rotr %0"
3896   [(set_attr "type" "arith")])
3897
3898 ;; A slimplified version of rotr for combine.
3899 (define_insn "*rotrsi3_1"
3900   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3901         (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3902                      (const_int 1)))
3903    (clobber (reg:SI T_REG))]
3904   "TARGET_SH1"
3905   "rotr %0"
3906   [(set_attr "type" "arith")])
3907
3908 (define_insn "rotlsi3_1"
3909   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3910         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3911                    (const_int 1)))
3912    (set (reg:SI T_REG)
3913         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3914   "TARGET_SH1"
3915   "rotl %0"
3916   [(set_attr "type" "arith")])
3917
3918 ;; A simplified version of rotl for combine.
3919 (define_insn "*rotlsi3_1"
3920   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3922                    (const_int 1)))
3923    (clobber (reg:SI T_REG))]
3924   "TARGET_SH1"
3925   "rotl %0"
3926   [(set_attr "type" "arith")])
3927
3928 (define_insn "rotlsi3_31"
3929   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3930         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3931                    (const_int 31)))
3932    (clobber (reg:SI T_REG))]
3933   "TARGET_SH1"
3934   "rotr %0"
3935   [(set_attr "type" "arith")])
3936
3937 (define_insn "rotlsi3_16"
3938   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3939         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3940                    (const_int 16)))]
3941   "TARGET_SH1"
3942   "swap.w       %1,%0"
3943   [(set_attr "type" "arith")])
3944
3945 (define_expand "rotlsi3"
3946   [(set (match_operand:SI 0 "arith_reg_dest")
3947         (rotate:SI (match_operand:SI 1 "arith_reg_operand")
3948                    (match_operand:SI 2 "const_int_operand")))]
3949   "TARGET_SH1"
3950 {
3951   static const char rot_tab[] = {
3952     000, 000, 000, 000, 000, 000, 010, 001,
3953     001, 001, 011, 013, 003, 003, 003, 003,
3954     003, 003, 003, 003, 003, 013, 012, 002,
3955     002, 002, 010, 000, 000, 000, 000, 000,
3956   };
3957
3958   int count = INTVAL (operands[2]);
3959   int choice = rot_tab[count];
3960   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3961     FAIL;
3962   choice &= 7;
3963   switch (choice)
3964     {
3965     case 0:
3966       emit_move_insn (operands[0], operands[1]);
3967       count -= (count & 16) * 2;
3968       break;
3969     case 3:
3970      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3971      count -= 16;
3972      break;
3973     case 1:
3974     case 2:
3975       {
3976         rtx parts[2];
3977         parts[0] = gen_reg_rtx (SImode);
3978         parts[1] = gen_reg_rtx (SImode);
3979         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3980         emit_move_insn (parts[choice-1], operands[1]);
3981         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3982         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3983         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3984         count = (count & ~16) - 8;
3985       }
3986     }
3987
3988   for (; count > 0; count--)
3989     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3990   for (; count < 0; count++)
3991     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3992
3993   DONE;
3994 })
3995
3996 (define_insn "*rotlhi3_8"
3997   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3998         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3999                    (const_int 8)))]
4000   "TARGET_SH1"
4001   "swap.b       %1,%0"
4002   [(set_attr "type" "arith")])
4003
4004 (define_expand "rotlhi3"
4005   [(set (match_operand:HI 0 "arith_reg_operand")
4006         (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4007                    (match_operand:HI 2 "const_int_operand")))]
4008   "TARGET_SH1"
4009 {
4010   if (INTVAL (operands[2]) != 8)
4011     FAIL;
4012 })
4013
4014 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4015 ;; They can also be used to implement things like
4016 ;;      bool t = a == b;
4017 ;;      int x0 = (y >> 1) | (t << 31);  // rotcr
4018 ;;      int x1 = (y << 1) | t;          // rotcl
4019 (define_insn "rotcr"
4020   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4021         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4022                              (const_int 1))
4023                 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4024                            (const_int 31))))
4025    (set (reg:SI T_REG)
4026         (and:SI (match_dup 1) (const_int 1)))]
4027   "TARGET_SH1"
4028   "rotcr        %0"
4029   [(set_attr "type" "arith")])
4030
4031 (define_insn "rotcl"
4032   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4033         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4034                            (const_int 1))
4035                 (match_operand:SI 2 "t_reg_operand")))
4036    (set (reg:SI T_REG)
4037         (lshiftrt:SI (match_dup 1) (const_int 31)))]
4038   "TARGET_SH1"
4039   "rotcl        %0"
4040   [(set_attr "type" "arith")])
4041
4042 ;; Simplified rotcr version for combine, which allows arbitrary shift
4043 ;; amounts for the reg.  If the shift amount is '1' rotcr can be used
4044 ;; directly.  Otherwise we have to insert a shift in between.
4045 (define_insn_and_split "*rotcr"
4046   [(set (match_operand:SI 0 "arith_reg_dest")
4047         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4048                              (match_operand:SI 2 "const_int_operand"))
4049                 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4050                            (const_int 31))))
4051    (clobber (reg:SI T_REG))]
4052   "TARGET_SH1"
4053   "#"
4054   "&& can_create_pseudo_p ()"
4055   [(const_int 0)]
4056 {
4057   if (INTVAL (operands[2]) > 1)
4058     {
4059       const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4060       rtx prev_set_t_insn = NULL_RTX;
4061       rtx tmp_t_reg = NULL_RTX;
4062
4063       /* If we're going to emit a shift sequence that clobbers the T_REG,
4064          try to find the previous insn that sets the T_REG and emit the 
4065          shift insn before that insn, to remove the T_REG dependency.
4066          If the insn that sets the T_REG cannot be found, store the T_REG
4067          in a temporary reg and restore it after the shift.  */
4068       if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4069           && ! sh_dynamicalize_shift_p (shift_count))
4070         {
4071           prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4072
4073           /* Skip the nott insn, which was probably inserted by the splitter
4074              of *rotcr_neg_t.  Don't use one of the recog functions
4075              here during insn splitting, since that causes problems in later
4076              passes.  */
4077           if (prev_set_t_insn != NULL_RTX)
4078             {
4079               rtx pat = PATTERN (prev_set_t_insn);
4080               if (GET_CODE (pat) == SET
4081                   && t_reg_operand (XEXP (pat, 0), SImode)
4082                   && negt_reg_operand (XEXP (pat, 1), SImode))
4083               prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4084             }
4085
4086           if (! (prev_set_t_insn != NULL_RTX
4087                  && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4088                  && ! reg_referenced_p (get_t_reg_rtx (),
4089                                         PATTERN (prev_set_t_insn))))
4090             {
4091               prev_set_t_insn = NULL_RTX;
4092               tmp_t_reg = gen_reg_rtx (SImode);
4093               emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4094             } 
4095         }
4096
4097       rtx shift_result = gen_reg_rtx (SImode);
4098       rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4099       operands[1] = shift_result;
4100
4101       /* Emit the shift insn before the insn that sets T_REG, if possible.  */
4102       if (prev_set_t_insn != NULL_RTX)
4103         emit_insn_before (shift_insn, prev_set_t_insn);
4104       else
4105         emit_insn (shift_insn);
4106
4107       /* Restore T_REG if it has been saved before.  */
4108       if (tmp_t_reg != NULL_RTX)
4109         emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4110     }
4111
4112   /* For the rotcr insn to work, operands[3] must be in T_REG.
4113      If it is not we can get it there by shifting it right one bit.
4114      In this case T_REG is not an input for this insn, thus we don't have to
4115      pay attention as of where to insert the shlr insn.  */
4116   if (! t_reg_operand (operands[3], SImode))
4117     {
4118       /* We don't care about the shifted result here, only the T_REG.  */
4119       emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4120       operands[3] = get_t_reg_rtx ();
4121     }
4122
4123   emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4124   DONE;
4125 })
4126
4127 ;; If combine tries the same as above but with swapped operands, split
4128 ;; it so that it will try the pattern above.
4129 (define_split
4130   [(set (match_operand:SI 0 "arith_reg_dest")
4131         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4132                            (const_int 31))
4133                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4134                              (match_operand:SI 3 "const_int_operand"))))]
4135   "TARGET_SH1 && can_create_pseudo_p ()"
4136   [(parallel [(set (match_dup 0)
4137                    (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4138                            (ashift:SI (match_dup 1) (const_int 31))))
4139               (clobber (reg:SI T_REG))])])
4140
4141 ;; Basically the same as the rotcr pattern above, but for rotcl.
4142 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4143 (define_insn_and_split "*rotcl"
4144   [(set (match_operand:SI 0 "arith_reg_dest")
4145         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4146                            (match_operand:SI 2 "const_int_operand"))
4147                 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4148                         (const_int 1))))
4149    (clobber (reg:SI T_REG))]
4150   "TARGET_SH1"
4151   "#"
4152   "&& can_create_pseudo_p ()"
4153   [(const_int 0)]
4154 {
4155   gcc_assert (INTVAL (operands[2]) > 0);
4156
4157   if (INTVAL (operands[2]) > 1)
4158     {
4159       const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4160       rtx prev_set_t_insn = NULL_RTX;
4161       rtx tmp_t_reg = NULL_RTX;
4162
4163       /* If we're going to emit a shift sequence that clobbers the T_REG,
4164          try to find the previous insn that sets the T_REG and emit the 
4165          shift insn before that insn, to remove the T_REG dependency.
4166          If the insn that sets the T_REG cannot be found, store the T_REG
4167          in a temporary reg and restore it after the shift.  */
4168       if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4169           && ! sh_dynamicalize_shift_p (shift_count))
4170         {
4171           prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4172
4173           /* Skip the nott insn, which was probably inserted by the splitter
4174              of *rotcl_neg_t.  Don't use one of the recog functions
4175              here during insn splitting, since that causes problems in later
4176              passes.  */
4177           if (prev_set_t_insn != NULL_RTX)
4178             {
4179               rtx pat = PATTERN (prev_set_t_insn);
4180               if (GET_CODE (pat) == SET
4181                   && t_reg_operand (XEXP (pat, 0), SImode)
4182                   && negt_reg_operand (XEXP (pat, 1), SImode))
4183               prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4184             }
4185
4186           if (! (prev_set_t_insn != NULL_RTX
4187                  && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4188                  && ! reg_referenced_p (get_t_reg_rtx (),
4189                                         PATTERN (prev_set_t_insn))))
4190             {
4191               prev_set_t_insn = NULL_RTX;
4192               tmp_t_reg = gen_reg_rtx (SImode);
4193               emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4194             } 
4195         }
4196
4197       rtx shift_result = gen_reg_rtx (SImode);
4198       rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4199       operands[1] = shift_result;
4200
4201       /* Emit the shift insn before the insn that sets T_REG, if possible.  */
4202       if (prev_set_t_insn != NULL_RTX)
4203         emit_insn_before (shift_insn, prev_set_t_insn);
4204       else
4205         emit_insn (shift_insn);
4206
4207       /* Restore T_REG if it has been saved before.  */
4208       if (tmp_t_reg != NULL_RTX)
4209         emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4210     }
4211
4212   /* For the rotcl insn to work, operands[3] must be in T_REG.
4213      If it is not we can get it there by shifting it right one bit.
4214      In this case T_REG is not an input for this insn, thus we don't have to
4215      pay attention as of where to insert the shlr insn.  */
4216   if (! t_reg_operand (operands[3], SImode))
4217     {
4218       /* We don't care about the shifted result here, only the T_REG.  */
4219       emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4220       operands[3] = get_t_reg_rtx ();
4221     }
4222
4223   emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4224   DONE;
4225 })
4226
4227 ;; rotcl combine pattern variations
4228 (define_insn_and_split "*rotcl"
4229   [(set (match_operand:SI 0 "arith_reg_dest")
4230         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4231                            (match_operand:SI 2 "const_int_operand"))
4232                 (match_operand:SI 3 "t_reg_operand")))
4233    (clobber (reg:SI T_REG))]
4234   "TARGET_SH1"
4235   "#"
4236   "&& can_create_pseudo_p ()"
4237   [(parallel [(set (match_dup 0)
4238                    (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4239                            (and:SI (match_dup 3) (const_int 1))))
4240               (clobber (reg:SI T_REG))])])
4241
4242 (define_insn_and_split "*rotcl"
4243   [(set (match_operand:SI 0 "arith_reg_dest")
4244         (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4245                         (const_int 1))
4246                 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4247                            (match_operand:SI 3 "const_int_operand"))))
4248    (clobber (reg:SI T_REG))]
4249   "TARGET_SH1"
4250   "#"
4251   "&& can_create_pseudo_p ()"
4252   [(parallel [(set (match_dup 0)
4253                    (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4254                            (and:SI (match_dup 1) (const_int 1))))
4255               (clobber (reg:SI T_REG))])])
4256
4257 (define_insn_and_split "*rotcl"
4258   [(set (match_operand:SI 0 "arith_reg_dest")
4259         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4260                            (match_operand:SI 2 "const_int_operand"))
4261                 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4262                              (const_int 31))))
4263    (clobber (reg:SI T_REG))]
4264   "TARGET_SH1"
4265   "#"
4266   "&& can_create_pseudo_p ()"
4267   [(parallel [(set (match_dup 0)
4268                    (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4269                            (and:SI (reg:SI T_REG) (const_int 1))))
4270               (clobber (reg:SI T_REG))])]
4271 {
4272   /* We don't care about the result of the left shift, only the T_REG.  */
4273   emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4274 })
4275
4276 (define_insn_and_split "*rotcl"
4277   [(set (match_operand:SI 0 "arith_reg_dest")
4278         (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4279                              (const_int 31))
4280                 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4281                            (match_operand:SI 2 "const_int_operand"))))
4282    (clobber (reg:SI T_REG))]
4283   "TARGET_SH1"
4284   "#"
4285   "&& can_create_pseudo_p ()"
4286   [(parallel [(set (match_dup 0)
4287                    (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4288                            (and:SI (reg:SI T_REG) (const_int 1))))
4289               (clobber (reg:SI T_REG))])]
4290 {
4291   /* We don't care about the result of the left shift, only the T_REG.  */
4292   emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4293 })
4294
4295 ;; rotcr combine bridge pattern which will make combine try out more
4296 ;; complex patterns.
4297 (define_insn_and_split "*rotcr"
4298   [(set (match_operand:SI 0 "arith_reg_dest")
4299         (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4300   "TARGET_SH1"
4301   "#"
4302   "&& 1"
4303   [(set (match_dup 0) (match_dup 1))
4304    (parallel [(set (match_dup 0)
4305                    (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4306                            (ashift:SI (match_dup 1) (const_int 31))))
4307               (set (reg:SI T_REG)
4308                    (and:SI (match_dup 0) (const_int 1)))])])
4309
4310 (define_insn_and_split "*rotcr"
4311   [(set (match_operand:SI 0 "arith_reg_dest")
4312         (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4313                         (const_int -2147483648)) ;; 0xffffffff80000000
4314                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4315                              (const_int 1))))
4316    (clobber (reg:SI T_REG))]
4317   "TARGET_SH1"
4318   "#"
4319   "&& can_create_pseudo_p ()"
4320   [(const_int 0)]
4321 {
4322   rtx tmp = gen_reg_rtx (SImode);
4323   emit_insn (gen_shll (tmp, operands[1]));
4324   emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4325   DONE;
4326 })
4327
4328 ;; rotcr combine patterns for rotating in the negated T_REG value.
4329 (define_insn_and_split "*rotcr_neg_t"
4330   [(set (match_operand:SI 0 "arith_reg_dest")
4331         (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4332                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4333                              (match_operand:SI 3 "const_int_operand"))))
4334    (clobber (reg:SI T_REG))]
4335   "TARGET_SH1"
4336   "#"
4337   "&& can_create_pseudo_p ()"
4338   [(parallel [(set (match_dup 0)
4339                    (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4340                            (ashift:SI (reg:SI T_REG) (const_int 31))))
4341               (clobber (reg:SI T_REG))])]
4342 {
4343   emit_insn (gen_nott (get_t_reg_rtx ()));
4344 })
4345
4346 (define_insn_and_split "*rotcr_neg_t"
4347   [(set (match_operand:SI 0 "arith_reg_dest")
4348         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4349                              (match_operand:SI 2 "const_int_operand"))
4350                 (match_operand:SI 3 "negt_reg_shl31_operand")))
4351    (clobber (reg:SI T_REG))]
4352   "TARGET_SH1"
4353   "#"
4354   "&& can_create_pseudo_p ()"
4355   [(parallel [(set (match_dup 0)
4356                    (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4357                            (ashift:SI (reg:SI T_REG) (const_int 31))))
4358               (clobber (reg:SI T_REG))])]
4359 {
4360   emit_insn (gen_nott (get_t_reg_rtx ()));
4361 })
4362
4363 ;; rotcl combine patterns for rotating in the negated T_REG value.
4364 ;; For some strange reason these have to be specified as splits which combine
4365 ;; will pick up.  If they are specified as insn_and_split like the
4366 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4367 ;; but not emit them on non-SH2A targets.
4368 (define_split
4369   [(set (match_operand:SI 0 "arith_reg_dest")
4370         (ior:SI (match_operand:SI 1 "negt_reg_operand")
4371                 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4372                            (match_operand:SI 3 "const_int_operand"))))]
4373   "TARGET_SH1"
4374   [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4375    (parallel [(set (match_dup 0)
4376                    (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4377                            (and:SI (reg:SI T_REG) (const_int 1))))
4378               (clobber (reg:SI T_REG))])])
4379
4380 (define_split
4381   [(set (match_operand:SI 0 "arith_reg_dest")
4382         (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4383                            (match_operand:SI 3 "const_int_operand"))
4384                 (match_operand:SI 1 "negt_reg_operand")))]
4385   "TARGET_SH1"
4386   [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4387    (parallel [(set (match_dup 0)
4388                    (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4389                            (and:SI (reg:SI T_REG) (const_int 1))))
4390               (clobber (reg:SI T_REG))])])
4391
4392 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4393 ;; SImode shift left
4394
4395 (define_expand "ashlsi3"
4396   [(set (match_operand:SI 0 "arith_reg_operand" "")
4397         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4398                    (match_operand:SI 2 "shift_count_operand" "")))]
4399   ""
4400 {
4401   if (TARGET_SHMEDIA)
4402     {
4403       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4404       DONE;
4405     }
4406   if (TARGET_DYNSHIFT
4407       && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4408       operands[2] = force_reg (SImode, operands[2]);
4409
4410   /*  If the ashlsi3_* insn is going to clobber the T_REG it must be
4411       expanded here.  */
4412   if (CONST_INT_P (operands[2])
4413       && sh_ashlsi_clobbers_t_reg_p (operands[2])
4414       && ! sh_dynamicalize_shift_p (operands[2]))
4415     {
4416       emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4417                                            operands[2]));
4418       DONE;
4419     }
4420
4421   /* Expand a library call for the dynamic shift.  */
4422   if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4423     {
4424       emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4425       rtx funcaddr = gen_reg_rtx (Pmode);
4426       function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4427       emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4428
4429       DONE;
4430     }
4431 })
4432
4433 (define_insn "ashlsi3_k"
4434   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4435         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4436                    (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4437   "TARGET_SH1"
4438   "@
4439         add     %0,%0
4440         shll%O2 %0"
4441   [(set_attr "type" "arith")])
4442
4443 (define_insn_and_split "ashlsi3_d"
4444   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4445         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4446                    (match_operand:SI 2 "shift_count_operand" "r")))]
4447   "TARGET_DYNSHIFT"
4448   "shld %2,%0"
4449   "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4450    && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4451   [(const_int 0)]
4452 {
4453   if (satisfies_constraint_P27 (operands[2]))
4454     {
4455       emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4456       DONE;
4457     }
4458   else if (! satisfies_constraint_P27 (operands[2]))
4459     {
4460       /* This must happen before reload, otherwise the constant will be moved
4461          into a register due to the "r" constraint, after which this split
4462          cannot be done anymore.
4463          Unfortunately the move insn will not always be eliminated.
4464          Also, here we must not create a shift sequence that clobbers the
4465          T_REG.  */
4466       emit_move_insn (operands[0], operands[1]);
4467       gen_shifty_op (ASHIFT, operands);
4468       DONE;
4469     }
4470
4471   FAIL;
4472 }
4473   [(set_attr "type" "dyn_shift")])
4474
4475 ;; If dynamic shifts are not available use a library function.
4476 ;; By specifying the pattern we reduce the number of call clobbered regs.
4477 ;; In order to make combine understand the truncation of the shift amount
4478 ;; operand we have to allow it to use pseudo regs for the shift operands.
4479 (define_insn "ashlsi3_d_call"
4480   [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4481         (ashift:SI (reg:SI R4_REG)
4482                    (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4483                            (const_int 31))))
4484    (use (match_operand:SI 2 "arith_reg_operand" "r"))
4485    (clobber (reg:SI T_REG))
4486    (clobber (reg:SI PR_REG))]
4487   "TARGET_SH1 && !TARGET_DYNSHIFT"
4488   "jsr  @%2%#"
4489   [(set_attr "type" "sfunc")
4490    (set_attr "needs_delay_slot" "yes")])
4491
4492 (define_insn_and_split "ashlsi3_n"
4493   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4494         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4495                    (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4496   "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4497   "#"
4498   "&& (reload_completed
4499        || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4500   [(const_int 0)]
4501 {
4502   if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4503     {
4504       /* If this pattern was picked and dynamic shifts are supported, switch
4505          to dynamic shift pattern before reload.  */
4506       operands[2] = force_reg (SImode, operands[2]);
4507       emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4508     }
4509   else
4510     gen_shifty_op (ASHIFT, operands);
4511
4512   DONE;
4513 })
4514
4515 (define_insn_and_split "ashlsi3_n_clobbers_t"
4516   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4517         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4518                    (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4519    (clobber (reg:SI T_REG))]
4520   "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4521   "#"
4522   "&& (reload_completed || INTVAL (operands[2]) == 31
4523        || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4524   [(const_int 0)]
4525 {
4526   if (INTVAL (operands[2]) == 31)
4527     {
4528       /* If the shift amount is 31 we split into a different sequence before
4529          reload so that it gets a chance to allocate R0 for the sequence.
4530          If it fails to do so (due to pressure on R0), it will take one insn
4531          more for the and.  */
4532       emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4533       emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4534     }
4535   else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4536     {
4537       /* If this pattern was picked and dynamic shifts are supported, switch
4538          to dynamic shift pattern before reload.  */
4539       operands[2] = force_reg (SImode, operands[2]);
4540       emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4541     }
4542   else
4543     gen_shifty_op (ASHIFT, operands);
4544
4545   DONE;
4546 })
4547
4548 (define_insn "shll"
4549   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4550         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4551    (set (reg:SI T_REG)
4552         (lt:SI (match_dup 1) (const_int 0)))]
4553   "TARGET_SH1"
4554   "shll %0"
4555   [(set_attr "type" "arith")])
4556
4557 (define_insn "*ashlsi_c_void"
4558   [(set (reg:SI T_REG)
4559         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4560    (clobber (match_scratch:SI 1 "=0"))]
4561   "TARGET_SH1 && cse_not_expected"
4562   "shll %0"
4563   [(set_attr "type" "arith")])
4564
4565 (define_peephole2
4566   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4567    (set (reg:SI T_REG)
4568         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4569   "TARGET_SH1
4570    && peep2_reg_dead_p (2, operands[0])
4571    && peep2_reg_dead_p (2, operands[1])"
4572   [(const_int 0)]
4573 {
4574   emit_insn (gen_shll (operands[1], operands[1]));
4575   DONE;
4576 })
4577
4578 (define_insn "ashlsi3_media"
4579   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4580         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4581                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
4582   "TARGET_SHMEDIA"
4583   "@
4584         shlld.l %1, %2, %0
4585         shlli.l %1, %2, %0"
4586   [(set_attr "type" "arith_media")
4587    (set_attr "highpart" "ignore")])
4588
4589 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4590 ;; HImode shift left
4591
4592 (define_expand "ashlhi3"
4593   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4594                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4595                               (match_operand:SI 2 "nonmemory_operand" "")))
4596               (clobber (reg:SI T_REG))])]
4597   "TARGET_SH1"
4598 {
4599   if (!CONST_INT_P (operands[2]))
4600     FAIL;
4601   /* It may be possible to call gen_ashlhi3 directly with more generic
4602      operands.  Make sure operands[1] is a HImode register here.  */
4603   if (!arith_reg_operand (operands[1], HImode))
4604     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4605 })
4606
4607 (define_insn "ashlhi3_k"
4608   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4609         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4610                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
4611   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4612   "@
4613         add     %0,%0
4614         shll%O2 %0"
4615   [(set_attr "type" "arith")])
4616
4617 (define_insn_and_split "*ashlhi3_n"
4618   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4619         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4620                    (match_operand:HI 2 "const_int_operand" "n")))
4621    (clobber (reg:SI T_REG))]
4622   "TARGET_SH1"
4623   "#"
4624   "&& reload_completed"
4625   [(use (reg:SI R0_REG))]
4626 {
4627   gen_shifty_hi_op (ASHIFT, operands);
4628   DONE;
4629 })
4630
4631 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4632 ;; DImode shift left
4633
4634 (define_expand "ashldi3"
4635   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4636                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4637                               (match_operand:DI 2 "immediate_operand" "")))
4638               (clobber (reg:SI T_REG))])]
4639   ""
4640 {
4641   if (TARGET_SHMEDIA)
4642     {
4643       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4644       DONE;
4645     }
4646   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4647     {
4648       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4649       DONE;
4650     }
4651   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4652     {
4653       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4654       DONE;
4655     }
4656   else
4657     FAIL;
4658 })
4659
4660 ;; Expander for DImode shift left with SImode operations.
4661 (define_expand "ashldi3_std"
4662   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4663         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4664                    (match_operand:DI 2 "const_int_operand" "n")))]
4665   "TARGET_SH1 && INTVAL (operands[2]) < 32"
4666 {
4667   rtx low_src = gen_lowpart (SImode, operands[1]);
4668   rtx high_src = gen_highpart (SImode, operands[1]);
4669   rtx dst = gen_reg_rtx (DImode);
4670   rtx low_dst = gen_lowpart (SImode, dst);
4671   rtx high_dst = gen_highpart (SImode, dst);
4672   rtx tmp0 = gen_reg_rtx (SImode);
4673   rtx tmp1 = gen_reg_rtx (SImode);
4674
4675   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4676   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
4677   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
4678   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4679   emit_move_insn (operands[0], dst);
4680   DONE;
4681 })
4682
4683 (define_insn_and_split "ashldi3_k"
4684   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4685         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4686                    (const_int 1)))
4687    (clobber (reg:SI T_REG))]
4688   "TARGET_SH1"
4689   "#"
4690   "&& reload_completed"
4691   [(const_int 0)]
4692 {
4693   rtx high = gen_highpart (SImode, operands[0]);
4694   rtx low = gen_lowpart (SImode, operands[0]);
4695   emit_insn (gen_shll (low, low));
4696   emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
4697   DONE;
4698 })
4699
4700 (define_insn "ashldi3_media"
4701   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4702         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4703                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
4704   "TARGET_SHMEDIA"
4705   "@
4706         shlld   %1, %2, %0
4707         shlli   %1, %2, %0"
4708   [(set_attr "type" "arith_media")])
4709
4710 (define_insn "*ashldisi3_media"
4711   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4712         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4713                    (match_operand:DI 2 "const_int_operand" "n")))]
4714   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4715   "shlli.l      %1, %2, %0"
4716   [(set_attr "type" "arith_media")
4717    (set_attr "highpart" "ignore")])
4718
4719 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4720 ;; SImode arithmetic shift right
4721 ;;
4722 ;; We can't do HImode right shifts correctly unless we start out with an
4723 ;; explicit zero / sign extension; doing that would result in worse overall
4724 ;; code, so just let the machine independent code widen the mode.
4725 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4726
4727 (define_expand "ashrsi3"
4728   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4729                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4730                                 (match_operand:SI 2 "nonmemory_operand" "")))
4731               (clobber (reg:SI T_REG))])]
4732   ""
4733 {
4734   if (TARGET_SHMEDIA)
4735     {
4736       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4737       DONE;
4738     }
4739   if (expand_ashiftrt (operands))
4740     DONE;
4741   else
4742     FAIL;
4743 })
4744
4745 (define_insn "shar"
4746   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4747         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4748                      (const_int 1)))
4749    (set (reg:SI T_REG)
4750         (and:SI (match_dup 1) (const_int 1)))]
4751   "TARGET_SH1"
4752   "shar %0"
4753   [(set_attr "type" "arith")])
4754
4755 (define_insn "ashrsi3_k"
4756   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4757         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4758                      (match_operand:SI 2 "const_int_operand" "M")))
4759    (clobber (reg:SI T_REG))]
4760   "TARGET_SH1 && INTVAL (operands[2]) == 1"
4761   "shar %0"
4762   [(set_attr "type" "arith")])
4763
4764 (define_insn_and_split "ashrsi2_16"
4765   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4766         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4767                      (const_int 16)))]
4768   "TARGET_SH1"
4769   "#"
4770   "&& 1"
4771   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4772    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4773 {
4774   operands[2] = gen_lowpart (HImode, operands[0]);
4775 })
4776
4777 (define_insn_and_split "ashrsi2_31"
4778   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4779         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4780                      (const_int 31)))
4781    (clobber (reg:SI T_REG))]
4782   "TARGET_SH1"
4783   "#"
4784   "&& 1"
4785   [(const_int 0)]
4786 {
4787   emit_insn (gen_shll (operands[0], operands[1]));
4788   emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
4789   DONE;
4790 })
4791
4792 (define_insn "ashrsi3_d"
4793   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4794         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4795                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4796   "TARGET_DYNSHIFT"
4797   "shad %2,%0"
4798   [(set_attr "type" "dyn_shift")])
4799
4800 (define_insn "ashrsi3_n"
4801   [(set (reg:SI R4_REG)
4802         (ashiftrt:SI (reg:SI R4_REG)
4803                      (match_operand:SI 0 "const_int_operand" "i")))
4804    (clobber (reg:SI T_REG))
4805    (clobber (reg:SI PR_REG))
4806    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
4807   "TARGET_SH1"
4808   "jsr  @%1%#"
4809   [(set_attr "type" "sfunc")
4810    (set_attr "needs_delay_slot" "yes")])
4811
4812 (define_insn "ashrsi3_media"
4813   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4814         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4815                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
4816   "TARGET_SHMEDIA"
4817   "@
4818         shard.l %1, %2, %0
4819         shari.l %1, %2, %0"
4820   [(set_attr "type" "arith_media")
4821    (set_attr "highpart" "ignore")])
4822
4823 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4824 ;; DImode arithmetic shift right
4825
4826 (define_expand "ashrdi3"
4827   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4828                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4829                                 (match_operand:DI 2 "immediate_operand" "")))
4830               (clobber (reg:SI T_REG))])]
4831   ""
4832 {
4833   if (TARGET_SHMEDIA)
4834     {
4835       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4836       DONE;
4837     }
4838   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4839     FAIL;
4840 })
4841
4842 (define_insn_and_split "ashrdi3_k"
4843   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4844         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4845                      (const_int 1)))
4846    (clobber (reg:SI T_REG))]
4847   "TARGET_SH1"
4848   "#"
4849   "&& reload_completed"
4850   [(const_int 0)]
4851 {
4852   rtx high = gen_highpart (SImode, operands[0]);
4853   rtx low = gen_lowpart (SImode, operands[0]);
4854   emit_insn (gen_shar (high, high));
4855   emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
4856   DONE;
4857 })
4858
4859 (define_insn "ashrdi3_media"
4860   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4861         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4862                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4863   "TARGET_SHMEDIA
4864    && (arith_reg_dest (operands[0], DImode)
4865        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4866   "@
4867         shard   %1, %2, %0
4868         shari   %1, %2, %0"
4869   [(set_attr "type" "arith_media")])
4870
4871 (define_insn "*ashrdisi3_media"
4872   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4873         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4874                      (match_operand:DI 2 "const_int_operand" "n")))]
4875   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4876   "shari.l      %1, %2, %0"
4877   [(set_attr "type" "arith_media")
4878    (set_attr "highpart" "ignore")])
4879
4880 (define_insn "ashrdisi3_media_high"
4881   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4882         (truncate:SI
4883            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4884                         (match_operand:DI 2 "const_int_operand" "n"))))]
4885   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4886   "shari        %1, %2, %0"
4887   [(set_attr "type" "arith_media")])
4888
4889 (define_insn "ashrdisi3_media_opaque"
4890   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4891         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4892                     (match_operand:DI 2 "const_int_operand" "n")]
4893          UNSPEC_ASHIFTRT))]
4894   "TARGET_SHMEDIA"
4895   "shari        %1, %2, %0"
4896   [(set_attr "type" "arith_media")])
4897
4898 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4899 ;; SImode logical shift right
4900
4901 (define_expand "lshrsi3"
4902   [(set (match_operand:SI 0 "arith_reg_dest" "")
4903         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4904                      (match_operand:SI 2 "shift_count_operand" "")))]
4905   ""
4906 {
4907   if (TARGET_SHMEDIA)
4908     {
4909       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
4910       DONE;
4911     }
4912
4913   /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
4914      here, otherwise the pattern will never match due to the shift amount reg
4915      negation.  */
4916   if (TARGET_DYNSHIFT
4917       && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4918     {
4919       rtx neg_count = force_reg (SImode,
4920                                  gen_int_mode (- INTVAL (operands[2]), SImode));
4921       emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4922       DONE;
4923     }
4924
4925   if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
4926     {
4927       rtx neg_count = gen_reg_rtx (SImode);
4928       emit_insn (gen_negsi2 (neg_count, operands[2]));
4929       emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4930       DONE;
4931     }
4932
4933   /* If the lshrsi3_* insn is going to clobber the T_REG it must be
4934      expanded here.  */
4935   if (CONST_INT_P (operands[2])
4936       && sh_lshrsi_clobbers_t_reg_p (operands[2])
4937       && ! sh_dynamicalize_shift_p (operands[2]))
4938     {
4939       emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
4940                  operands[2]));
4941       DONE;
4942     }
4943
4944   /* Expand a library call for the dynamic shift.  */
4945   if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4946     {
4947       emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4948       rtx funcaddr = gen_reg_rtx (Pmode);
4949       function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
4950       emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
4951       DONE;
4952     }
4953 })
4954
4955 (define_insn "lshrsi3_k"
4956   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4957         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4958                      (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
4959   "TARGET_SH1"
4960   "shlr%O2      %0"
4961   [(set_attr "type" "arith")])
4962
4963 (define_insn_and_split "lshrsi3_d"
4964   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4965         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4966                      (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
4967   "TARGET_DYNSHIFT"
4968   "shld %2,%0"
4969   "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4970    && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
4971   [(const_int 0)]
4972 {
4973   if (satisfies_constraint_P27 (operands[2]))
4974     {
4975       /* This will not be done for a shift amount of 1, because it would
4976          clobber the T_REG.  */
4977       emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
4978       DONE;
4979     }
4980   else if (! satisfies_constraint_P27 (operands[2]))
4981     {
4982       /* This must happen before reload, otherwise the constant will be moved
4983          into a register due to the "r" constraint, after which this split
4984          cannot be done anymore.
4985          Unfortunately the move insn will not always be eliminated.
4986          Also, here we must not create a shift sequence that clobbers the
4987          T_REG.  */
4988       emit_move_insn (operands[0], operands[1]);
4989       gen_shifty_op (LSHIFTRT, operands);
4990       DONE;
4991     }
4992
4993   FAIL;
4994 }
4995   [(set_attr "type" "dyn_shift")])
4996
4997 ;; If dynamic shifts are not available use a library function.
4998 ;; By specifying the pattern we reduce the number of call clobbered regs.
4999 ;; In order to make combine understand the truncation of the shift amount
5000 ;; operand we have to allow it to use pseudo regs for the shift operands.
5001 (define_insn "lshrsi3_d_call"
5002   [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5003         (lshiftrt:SI (reg:SI R4_REG)
5004                      (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5005                              (const_int 31))))
5006    (use (match_operand:SI 2 "arith_reg_operand" "r"))
5007    (clobber (reg:SI T_REG))
5008    (clobber (reg:SI PR_REG))]
5009   "TARGET_SH1 && !TARGET_DYNSHIFT"
5010   "jsr  @%2%#"
5011   [(set_attr "type" "sfunc")
5012    (set_attr "needs_delay_slot" "yes")])
5013
5014 (define_insn_and_split "lshrsi3_n"
5015   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5016         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5017                      (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5018   "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5019   "#"
5020   "&& (reload_completed
5021        || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5022   [(const_int 0)]
5023 {
5024   if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5025     {
5026       /* If this pattern was picked and dynamic shifts are supported, switch
5027          to dynamic shift pattern before reload.  */
5028       operands[2] = force_reg (SImode,
5029                                gen_int_mode (- INTVAL (operands[2]), SImode));
5030       emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5031     }
5032   else
5033     gen_shifty_op (LSHIFTRT, operands);
5034
5035   DONE;
5036 })
5037
5038 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5039 ;; the shlr pattern.
5040 (define_insn_and_split "lshrsi3_n_clobbers_t"
5041   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5042         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5043                      (match_operand:SI 2 "not_p27_rshift_count_operand")))
5044    (clobber (reg:SI T_REG))]
5045   "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5046   "#"
5047   "&& (reload_completed || INTVAL (operands[2]) == 31
5048        || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5049   [(const_int 0)]
5050 {
5051   if (INTVAL (operands[2]) == 31)
5052     {
5053       emit_insn (gen_shll (operands[0], operands[1]));
5054       emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5055     }
5056   else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5057     {
5058       /* If this pattern was picked and dynamic shifts are supported, switch
5059          to dynamic shift pattern before reload.  */
5060       operands[2] = force_reg (SImode,
5061                                gen_int_mode (- INTVAL (operands[2]), SImode));
5062       emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5063     }
5064   else
5065     gen_shifty_op (LSHIFTRT, operands);
5066
5067   DONE;
5068 })
5069
5070 (define_insn "shlr"
5071   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5072         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5073                      (const_int 1)))
5074    (set (reg:SI T_REG)
5075         (and:SI (match_dup 1) (const_int 1)))]
5076   "TARGET_SH1"
5077   "shlr %0"
5078   [(set_attr "type" "arith")])
5079
5080 (define_insn "lshrsi3_media"
5081   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5082         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5083                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
5084   "TARGET_SHMEDIA"
5085   "@
5086         shlrd.l %1, %2, %0
5087         shlri.l %1, %2, %0"
5088   [(set_attr "type" "arith_media")
5089    (set_attr "highpart" "ignore")])
5090
5091 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5092 ;; DImode logical shift right
5093
5094 (define_expand "lshrdi3"
5095   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5096                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5097                                (match_operand:DI 2 "immediate_operand" "")))
5098              (clobber (reg:SI T_REG))])]
5099   ""
5100 {
5101   if (TARGET_SHMEDIA)
5102     {
5103       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5104       DONE;
5105     }
5106   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5107     FAIL;
5108 })
5109
5110 (define_insn_and_split "lshrdi3_k"
5111   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5112         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5113                      (const_int 1)))
5114    (clobber (reg:SI T_REG))]
5115   "TARGET_SH1"
5116   "#"
5117   "&& reload_completed"
5118   [(const_int 0)]
5119 {
5120   rtx high = gen_highpart (SImode, operands[0]);
5121   rtx low = gen_lowpart (SImode, operands[0]);
5122   emit_insn (gen_shlr (high, high));
5123   emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5124   DONE;
5125 })
5126
5127 (define_insn "lshrdi3_media"
5128   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5129         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5130                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
5131   "TARGET_SHMEDIA
5132    && (arith_reg_dest (operands[0], DImode)
5133        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5134   "@
5135         shlrd   %1, %2, %0
5136         shlri   %1, %2, %0"
5137   [(set_attr "type" "arith_media")])
5138
5139 (define_insn "*lshrdisi3_media"
5140   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5141         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5142                      (match_operand:DI 2 "const_int_operand" "n")))]
5143   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5144   "shlri.l      %1, %2, %0"
5145   [(set_attr "type" "arith_media")
5146    (set_attr "highpart" "ignore")])
5147
5148 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5149 ;; Combined left/right shifts
5150
5151 (define_split
5152   [(set (match_operand:SI 0 "register_operand" "")
5153         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5154                            (match_operand:SI 2 "const_int_operand" ""))
5155                 (match_operand:SI 3 "const_int_operand" "")))]
5156   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5157   [(use (reg:SI R0_REG))]
5158 {
5159   if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5160     FAIL;
5161   DONE;
5162 })
5163
5164 (define_split
5165   [(set (match_operand:SI 0 "register_operand" "")
5166         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5167                            (match_operand:SI 2 "const_int_operand" ""))
5168                 (match_operand:SI 3 "const_int_operand" "")))
5169    (clobber (reg:SI T_REG))]
5170   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5171   [(use (reg:SI R0_REG))]
5172 {
5173   if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5174     FAIL;
5175   DONE;
5176 })
5177
5178 (define_insn ""
5179   [(set (match_operand:SI 0 "register_operand" "=r")
5180         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5181                            (match_operand:SI 2 "const_int_operand" "n"))
5182                 (match_operand:SI 3 "const_int_operand" "n")))
5183    (clobber (reg:SI T_REG))]
5184   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5185   "#"
5186   [(set (attr "length")
5187         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5188                (const_string "4")
5189                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5190                (const_string "6")
5191                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5192                (const_string "8")
5193                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5194                (const_string "10")
5195                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5196                (const_string "12")
5197                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5198                (const_string "14")
5199                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5200                (const_string "16")]
5201               (const_string "18")))
5202    (set_attr "type" "arith")])
5203
5204 (define_insn ""
5205   [(set (match_operand:SI 0 "register_operand" "=z")
5206         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5207                            (match_operand:SI 2 "const_int_operand" "n"))
5208                 (match_operand:SI 3 "const_int_operand" "n")))
5209    (clobber (reg:SI T_REG))]
5210   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5211   "#"
5212   [(set (attr "length")
5213         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5214                (const_string "4")
5215                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5216                (const_string "6")
5217                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5218                (const_string "8")]
5219               (const_string "10")))
5220    (set_attr "type" "arith")])
5221
5222 ;; shift left / and combination with a scratch register: The combine pass
5223 ;; does not accept the individual instructions, even though they are
5224 ;; cheap.  But it needs a precise description so that it is usable after
5225 ;; reload.
5226 (define_insn "and_shl_scratch"
5227   [(set (match_operand:SI 0 "register_operand" "=r,&r")
5228         (lshiftrt:SI
5229          (ashift:SI
5230           (and:SI
5231            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5232                         (match_operand:SI 2 "const_int_operand" "N,n"))
5233            (match_operand:SI 3 "" "0,r"))
5234           (match_operand:SI 4 "const_int_operand" "n,n"))
5235          (match_operand:SI 5 "const_int_operand" "n,n")))
5236    (clobber (reg:SI T_REG))]
5237   "TARGET_SH1"
5238   "#"
5239   [(set (attr "length")
5240         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5241                (const_string "4")
5242                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5243                (const_string "6")
5244                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5245                (const_string "8")
5246                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5247                (const_string "10")]
5248               (const_string "12")))
5249    (set_attr "type" "arith")])
5250
5251 (define_split
5252   [(set (match_operand:SI 0 "register_operand" "")
5253         (lshiftrt:SI
5254          (ashift:SI
5255           (and:SI
5256            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5257                         (match_operand:SI 2 "const_int_operand" ""))
5258            (match_operand:SI 3 "register_operand" ""))
5259           (match_operand:SI 4 "const_int_operand" ""))
5260          (match_operand:SI 5 "const_int_operand" "")))
5261    (clobber (reg:SI T_REG))]
5262   "TARGET_SH1"
5263   [(use (reg:SI R0_REG))]
5264 {
5265   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5266
5267   if (INTVAL (operands[2]))
5268     {
5269       gen_shifty_op (LSHIFTRT, operands);
5270     }
5271   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5272   operands[2] = operands[4];
5273   gen_shifty_op (ASHIFT, operands);
5274   if (INTVAL (operands[5]))
5275     {
5276       operands[2] = operands[5];
5277       gen_shifty_op (LSHIFTRT, operands);
5278     }
5279   DONE;
5280 })
5281
5282 ;; signed left/right shift combination.
5283 (define_split
5284   [(set (match_operand:SI 0 "register_operand" "")
5285         (sign_extract:SI
5286          (ashift:SI (match_operand:SI 1 "register_operand" "")
5287                     (match_operand:SI 2 "const_int_operand" ""))
5288          (match_operand:SI 3 "const_int_operand" "")
5289          (const_int 0)))
5290    (clobber (reg:SI T_REG))]
5291   "TARGET_SH1"
5292   [(use (reg:SI R0_REG))]
5293 {
5294   if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5295     FAIL;
5296   DONE;
5297 })
5298
5299 (define_insn "shl_sext_ext"
5300   [(set (match_operand:SI 0 "register_operand" "=r")
5301         (sign_extract:SI
5302          (ashift:SI (match_operand:SI 1 "register_operand" "0")
5303                     (match_operand:SI 2 "const_int_operand" "n"))
5304          (match_operand:SI 3 "const_int_operand" "n")
5305          (const_int 0)))
5306    (clobber (reg:SI T_REG))]
5307   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5308   "#"
5309   [(set (attr "length")
5310         (cond [(match_test "shl_sext_length (insn)")
5311                (const_string "2")
5312                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5313                (const_string "4")
5314                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5315                (const_string "6")
5316                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5317                (const_string "8")
5318                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5319                (const_string "10")
5320                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5321                (const_string "12")
5322                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5323                (const_string "14")
5324                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5325                (const_string "16")]
5326               (const_string "18")))
5327     (set_attr "type" "arith")])
5328
5329 (define_insn "shl_sext_sub"
5330   [(set (match_operand:SI 0 "register_operand" "=z")
5331         (sign_extract:SI
5332          (ashift:SI (match_operand:SI 1 "register_operand" "0")
5333                     (match_operand:SI 2 "const_int_operand" "n"))
5334          (match_operand:SI 3 "const_int_operand" "n")
5335          (const_int 0)))
5336    (clobber (reg:SI T_REG))]
5337   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5338   "#"
5339   [(set (attr "length")
5340         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5341                (const_string "6")
5342                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5343                (const_string "8")
5344                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5345                (const_string "10")
5346                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5347                (const_string "12")]
5348               (const_string "14")))
5349     (set_attr "type" "arith")])
5350
5351 ;; The xtrct_left and xtrct_right patterns are used in expansions of DImode
5352 ;; shifts by 16, and allow the xtrct instruction to be generated from C
5353 ;; source.
5354 (define_insn "xtrct_left"
5355   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5356         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5357                            (const_int 16))
5358                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5359                              (const_int 16))))]
5360   "TARGET_SH1"
5361   "xtrct        %1,%0"
5362   [(set_attr "type" "arith")])
5363
5364 (define_insn "xtrct_right"
5365   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5366         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5367                              (const_int 16))
5368                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5369                            (const_int 16))))]
5370   "TARGET_SH1"
5371   "xtrct        %2,%0"
5372   [(set_attr "type" "arith")])
5373
5374 ;; -------------------------------------------------------------------------
5375 ;; Unary arithmetic
5376 ;; -------------------------------------------------------------------------
5377
5378 (define_insn "negc"
5379   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5380         (neg:SI (plus:SI (reg:SI T_REG)
5381                          (match_operand:SI 1 "arith_reg_operand" "r"))))
5382    (set (reg:SI T_REG)
5383         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5384                (const_int 0)))]
5385   "TARGET_SH1"
5386   "negc %1,%0"
5387   [(set_attr "type" "arith")])
5388
5389 ;; A simplified version of the negc insn, where the exact value of the
5390 ;; T bit doesn't matter.  This is easier for combine to pick up.
5391 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5392 ;; extra patterns for this case.
5393 (define_insn "*negc"
5394   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5395         (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5396                   (match_operand:SI 2 "t_reg_operand" "")))
5397    (clobber (reg:SI T_REG))]
5398   "TARGET_SH1"
5399   "negc %1,%0"
5400   [(set_attr "type" "arith")])
5401
5402 (define_insn "*negdi_media"
5403   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5404         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5405   "TARGET_SHMEDIA"
5406   "sub  r63, %1, %0"
5407   [(set_attr "type" "arith_media")])
5408
5409 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
5410 ;; combined.
5411 (define_expand "negdi2"
5412   [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
5413                    (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5414               (clobber (reg:SI T_REG))])]
5415   "TARGET_SH1")
5416
5417 (define_insn_and_split "*negdi2"
5418   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
5419         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))
5420    (clobber (reg:SI T_REG))]
5421   "TARGET_SH1"
5422   "#"
5423   "&& reload_completed"
5424   [(const_int 0)]
5425 {
5426   emit_insn (gen_clrt ());
5427   emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5428                        gen_lowpart (SImode, operands[1])));
5429   emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5430                        gen_highpart (SImode, operands[1])));
5431   DONE;
5432 })
5433
5434 (define_insn "negsi2"
5435   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5436         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5437   "TARGET_SH1"
5438   "neg  %1,%0"
5439   [(set_attr "type" "arith")])
5440
5441 (define_insn_and_split "one_cmplsi2"
5442   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5443         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5444   "TARGET_SH1"
5445   "not  %1,%0"
5446   "&& can_create_pseudo_p ()"
5447   [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5448    (set (match_dup 0) (reg:SI T_REG))]
5449 {
5450 /* PR 54685
5451    If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5452    sequence:
5453
5454      (set (reg0) (not:SI (reg0) (reg1)))
5455      (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5456                 (clobber (reg:SI T_REG))])
5457
5458    ... match and combine the sequence manually in the split pass after the
5459    combine pass.  Notice that combine does try the target pattern of this
5460    split, but if the pattern is added it interferes with other patterns, in
5461    particular with the div0s comparisons.
5462    This could also be done with a peephole but doing it here before register
5463    allocation can save one temporary.
5464    When we're here, the not:SI pattern obviously has been matched already
5465    and we only have to see whether the following insn is the left shift.  */
5466
5467   rtx i = next_nonnote_insn_bb (curr_insn);
5468   if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5469     FAIL;
5470
5471   rtx p = PATTERN (i);
5472   if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5473     FAIL;
5474
5475   rtx p0 = XVECEXP (p, 0, 0);
5476   rtx p1 = XVECEXP (p, 0, 1);
5477
5478   if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31)))  */
5479       GET_CODE (p0) == SET
5480       && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5481       && REG_P (XEXP (XEXP (p0, 1), 0))
5482       && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5483       && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5484       && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5485
5486       /* (clobber (reg:SI T_REG))  */
5487       && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5488       && REGNO (XEXP (p1, 0)) == T_REG)
5489     {
5490       operands[0] = XEXP (p0, 0);
5491       set_insn_deleted (i);
5492     }
5493   else
5494     FAIL;
5495 }
5496   [(set_attr "type" "arith")])
5497
5498 (define_expand "one_cmpldi2"
5499   [(set (match_operand:DI 0 "arith_reg_dest" "")
5500         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5501                 (const_int -1)))]
5502   "TARGET_SHMEDIA" "")
5503
5504 (define_expand "abs<mode>2"
5505   [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
5506                    (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5507               (clobber (reg:SI T_REG))])]
5508   "TARGET_SH1")
5509
5510 (define_insn_and_split "*abs<mode>2"
5511   [(set (match_operand:SIDI 0 "arith_reg_dest")
5512         (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5513    (clobber (reg:SI T_REG))]
5514   "TARGET_SH1"
5515   "#"
5516   "&& can_create_pseudo_p ()"
5517   [(const_int 0)]
5518 {
5519   if (<MODE>mode == SImode)
5520     emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5521   else
5522     {
5523       rtx high_src = gen_highpart (SImode, operands[1]);
5524       emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5525     }
5526
5527   emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5528                                  const1_rtx));
5529   DONE;
5530 })
5531
5532 (define_insn_and_split "*negabs<mode>2"
5533   [(set (match_operand:SIDI 0 "arith_reg_dest")
5534         (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
5535    (clobber (reg:SI T_REG))]
5536   "TARGET_SH1"
5537   "#"
5538   "&& can_create_pseudo_p ()"
5539   [(const_int 0)]
5540 {
5541   if (<MODE>mode == SImode)
5542     emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5543   else
5544     {
5545       rtx high_src = gen_highpart (SImode, operands[1]);
5546       emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5547     }
5548
5549   emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5550                                  const0_rtx));
5551   DONE;
5552 })
5553
5554 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5555 ;; This can be used as some kind of conditional execution, which is useful
5556 ;; for abs.
5557 ;; Actually the instruction scheduling should decide whether to use a
5558 ;; zero-offset branch or not for any generic case involving a single
5559 ;; instruction on SH4 202.
5560 (define_insn_and_split "negsi_cond"
5561   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5562         (if_then_else
5563           (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
5564           (match_operand:SI 1 "arith_reg_operand" "0,0")
5565           (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5566   "TARGET_SH1 && TARGET_ZDCBRANCH"
5567 {
5568   static const char* alt[] =
5569   {
5570        "bt      0f"     "\n"
5571     "   neg     %2,%0"  "\n"
5572     "0:",
5573
5574        "bf      0f"     "\n"
5575     "   neg     %2,%0"  "\n"
5576     "0:"
5577   };
5578   return alt[which_alternative];
5579 }
5580   "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5581   [(const_int 0)]
5582 {
5583   rtx skip_neg_label = gen_label_rtx ();
5584
5585   emit_move_insn (operands[0], operands[1]);
5586
5587   emit_jump_insn (INTVAL (operands[3])
5588                   ? gen_branch_true (skip_neg_label)
5589                   : gen_branch_false (skip_neg_label));
5590
5591   emit_label_after (skip_neg_label,
5592                     emit_insn (gen_negsi2 (operands[0], operands[1])));
5593   DONE;
5594 }
5595   [(set_attr "type" "arith") ;; poor approximation
5596    (set_attr "length" "4")])
5597
5598 (define_insn_and_split "negdi_cond"
5599   [(set (match_operand:DI 0 "arith_reg_dest")
5600         (if_then_else
5601           (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
5602           (match_operand:DI 1 "arith_reg_operand")
5603           (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
5604    (clobber (reg:SI T_REG))]
5605   "TARGET_SH1"
5606   "#"
5607   "&& can_create_pseudo_p ()"
5608   [(const_int 0)]
5609 {
5610   rtx skip_neg_label = gen_label_rtx ();
5611
5612   emit_move_insn (operands[0], operands[1]);
5613
5614   emit_jump_insn (INTVAL (operands[3]) 
5615                   ? gen_branch_true (skip_neg_label)
5616                   : gen_branch_false (skip_neg_label));
5617
5618   if (!INTVAL (operands[3]))
5619     emit_insn (gen_clrt ());
5620
5621   emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5622                        gen_lowpart (SImode, operands[1])));
5623   emit_label_after (skip_neg_label,
5624                     emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5625                                          gen_highpart (SImode, operands[1]))));
5626   DONE;
5627 })
5628
5629 (define_expand "bswapsi2"
5630   [(set (match_operand:SI 0 "arith_reg_dest" "")
5631         (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5632   "TARGET_SH1"
5633 {
5634   if (! can_create_pseudo_p ())
5635     FAIL;
5636   else
5637     {
5638       rtx tmp0 = gen_reg_rtx (SImode);
5639       rtx tmp1 = gen_reg_rtx (SImode);
5640
5641       emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5642       emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5643       emit_insn (gen_swapbsi2 (operands[0], tmp1));
5644       DONE;
5645     }
5646 })
5647
5648 (define_insn "swapbsi2"
5649   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5650         (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5651                         (const_int 4294901760))
5652                 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5653                                 (const_int 65280))
5654                         (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5655                                 (const_int 255)))))]
5656   "TARGET_SH1"
5657   "swap.b       %1,%0"
5658   [(set_attr "type" "arith")])
5659
5660 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5661 ;; partial byte swap expressions such as...
5662 ;;   ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5663 ;; ...which are currently not handled by the tree optimizers.
5664 ;; The combine pass will not initially try to combine the full expression,
5665 ;; but only some sub-expressions.  In such a case the *swapbisi2_and_shl8
5666 ;; pattern acts as an intermediate pattern that will eventually lead combine
5667 ;; to the swapbsi2 pattern above.
5668 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5669 ;; or (x << 8) & 0xFF00.
5670 (define_insn_and_split "*swapbisi2_and_shl8"
5671   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5672         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5673                                    (const_int 8))
5674                         (const_int 65280))
5675                 (match_operand:SI 2 "arith_reg_operand" "r")))]
5676   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5677   "#"
5678   "&& can_create_pseudo_p ()"
5679   [(const_int 0)]
5680 {
5681   rtx tmp0 = gen_reg_rtx (SImode);
5682   rtx tmp1 = gen_reg_rtx (SImode);
5683
5684   emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5685   emit_insn (gen_swapbsi2 (tmp1, tmp0));
5686   emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5687   DONE;
5688 })
5689
5690 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5691 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5692 (define_insn_and_split "*swapbhisi2"
5693   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5694         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5695                                    (const_int 8))
5696                         (const_int 65280))
5697                 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5698   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5699   "#"
5700   "&& can_create_pseudo_p ()"
5701   [(const_int 0)]
5702 {
5703   rtx tmp = gen_reg_rtx (SImode);
5704
5705   emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5706   emit_insn (gen_swapbsi2 (operands[0], tmp));
5707   DONE;
5708 })
5709
5710 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5711 ;;   swap.b  r4,r4
5712 ;;   mov     r4,r0
5713 ;;
5714 ;; which can be simplified to...
5715 ;;   swap.b  r4,r0
5716 (define_peephole2
5717   [(set (match_operand:SI 0 "arith_reg_dest" "")
5718         (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5719                         (const_int 4294901760))
5720                 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5721                                 (const_int 65280))
5722                         (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5723                                 (const_int 255)))))
5724    (set (match_operand:SI 2 "arith_reg_dest" "")
5725         (match_dup 0))]
5726   "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5727   [(set (match_dup 2)
5728         (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5729                         (const_int 4294901760))
5730                 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5731                                 (const_int 65280))
5732                         (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5733                                 (const_int 255)))))])
5734 \f
5735 ;; -------------------------------------------------------------------------
5736 ;; Zero extension instructions
5737 ;; -------------------------------------------------------------------------
5738
5739 (define_insn "zero_extendsidi2"
5740   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5741         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5742   "TARGET_SHMEDIA"
5743   "addz.l       %1, r63, %0"
5744   [(set_attr "type" "arith_media")
5745    (set_attr "highpart" "extend")])
5746
5747 (define_insn "zero_extendhidi2"
5748   [(set (match_operand:DI 0 "register_operand" "=r,r")
5749         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5750   "TARGET_SHMEDIA"
5751   "@
5752         #
5753         ld%M1.uw        %m1, %0"
5754   [(set_attr "type" "*,load_media")
5755    (set (attr "highpart")
5756         (cond [(match_test "sh_contains_memref_p (insn)")
5757                (const_string "user")]
5758               (const_string "ignore")))])
5759
5760 (define_split
5761   [(set (match_operand:DI 0 "register_operand" "")
5762         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5763   "TARGET_SHMEDIA && reload_completed"
5764   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5765    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
5766 {
5767   if (GET_CODE (operands[1]) == TRUNCATE)
5768     operands[1] = XEXP (operands[1], 0);
5769 })
5770
5771 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
5772 ;; reload the entire truncate expression.
5773 (define_insn_and_split "*loaddi_trunc"
5774   [(set (match_operand 0 "any_register_operand" "=r")
5775         (truncate (match_operand:DI 1 "memory_operand" "m")))]
5776   "TARGET_SHMEDIA && reload_completed"
5777   "#"
5778   "TARGET_SHMEDIA && reload_completed"
5779   [(set (match_dup 0) (match_dup 1))]
5780 {
5781   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5782 })
5783
5784 (define_insn "zero_extendqidi2"
5785   [(set (match_operand:DI 0 "register_operand" "=r,r")
5786         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5787   "TARGET_SHMEDIA"
5788   "@
5789         andi    %1, 255, %0
5790         ld%M1.ub        %m1, %0"
5791   [(set_attr "type" "arith_media,load_media")
5792    (set (attr "highpart")
5793         (cond [(match_test "sh_contains_memref_p (insn)")
5794                (const_string "user")]
5795               (const_string "ignore")))])
5796
5797 (define_expand "zero_extend<mode>si2"
5798   [(set (match_operand:SI 0 "arith_reg_dest")
5799         (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
5800
5801 (define_insn_and_split "*zero_extend<mode>si2_compact"
5802   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5803         (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
5804   "TARGET_SH1"
5805   "extu.<bw>    %1,%0"
5806   "&& can_create_pseudo_p ()"
5807   [(set (match_dup 0) (match_dup 2))]
5808 {
5809   /* Sometimes combine fails to combine a T bit or negated T bit store to a
5810      reg with a following zero extension.  In the split pass after combine,
5811      try to figure out how the extended reg was set.  If it originated from
5812      the T bit we can replace the zero extension with a reg move, which will
5813      be eliminated.  Notice that this also helps the *cbranch_t splitter when
5814      it tries to post-combine tests and conditional branches, as it does not
5815      check for zero extensions.  */
5816   operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
5817   if (operands[2] == NULL_RTX)
5818     FAIL;
5819 }
5820   [(set_attr "type" "arith")])
5821
5822 (define_insn "*zero_extendhisi2_media"
5823   [(set (match_operand:SI 0 "register_operand" "=r,r")
5824         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5825   "TARGET_SHMEDIA"
5826   "@
5827         #
5828         ld%M1.uw        %m1, %0"
5829   [(set_attr "type" "arith_media,load_media")
5830    (set (attr "highpart")
5831         (cond [(match_test "sh_contains_memref_p (insn)")
5832                (const_string "user")]
5833               (const_string "ignore")))])
5834
5835 (define_split
5836   [(set (match_operand:SI 0 "register_operand" "")
5837         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
5838   "TARGET_SHMEDIA && reload_completed"
5839   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5840    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5841 {
5842   rtx op1 = operands[1];
5843
5844   if (GET_CODE (op1) == TRUNCATE)
5845     op1 = XEXP (op1, 0);
5846   operands[2]
5847     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5848                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
5849 })
5850
5851 (define_insn "*zero_extendqisi2_media"
5852   [(set (match_operand:SI 0 "register_operand" "=r,r")
5853         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5854   "TARGET_SHMEDIA"
5855   "@
5856         andi    %1, 255, %0
5857         ld%M1.ub        %m1, %0"
5858   [(set_attr "type" "arith_media,load_media")
5859    (set (attr "highpart")
5860         (cond [(match_test "sh_contains_memref_p (insn)")
5861                (const_string "user")]
5862               (const_string "ignore")))])
5863
5864 (define_insn "zero_extendqihi2"
5865   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5866         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
5867   "TARGET_SH1"
5868   "extu.b       %1,%0"
5869   [(set_attr "type" "arith")])
5870
5871 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
5872 ;; They could also be used for simple memory addresses like @Rn by setting
5873 ;; the displacement value to zero.  However, doing so too early results in
5874 ;; missed opportunities for other optimizations such as post-inc or index
5875 ;; addressing loads.
5876 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
5877 ;; register addresses (an address without a displacement, index, post-inc),
5878 ;; zero-displacement addresses might be generated during reload, wich are
5879 ;; simplified to simple register addresses in turn.  Thus, we have to
5880 ;; provide the Sdd and Sra alternatives in the patterns.
5881 (define_insn "*zero_extend<mode>si2_disp_mem"
5882   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5883         (zero_extend:SI
5884           (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
5885   "TARGET_SH2A"
5886   "@
5887         movu.<bw>       %1,%0
5888         movu.<bw>       @(0,%t1),%0"
5889   [(set_attr "type" "load")
5890    (set_attr "length" "4")])
5891
5892 ;; Convert the zero extending loads in sequences such as:
5893 ;;      movu.b  @(1,r5),r0      movu.w  @(2,r5),r0
5894 ;;      mov.b   r0,@(1,r4)      mov.b   r0,@(1,r4)
5895 ;;
5896 ;; back to sign extending loads like:
5897 ;;      mov.b   @(1,r5),r0      mov.w   @(2,r5),r0
5898 ;;      mov.b   r0,@(1,r4)      mov.b   r0,@(1,r4)
5899 ;;
5900 ;; if the extension type is irrelevant.  The sign extending mov.{b|w} insn
5901 ;; is only 2 bytes in size if the displacement is {K04|K05}.
5902 ;; If the displacement is greater it doesn't matter, so we convert anyways.
5903 (define_peephole2
5904   [(set (match_operand:SI 0 "arith_reg_dest" "")
5905         (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
5906    (set (match_operand 2 "general_operand" "")
5907         (match_operand 3 "arith_reg_operand" ""))]
5908   "TARGET_SH2A
5909    && REGNO (operands[0]) == REGNO (operands[3])
5910    && peep2_reg_dead_p (2, operands[0])
5911    && GET_MODE_SIZE (GET_MODE (operands[2]))
5912       <= GET_MODE_SIZE (GET_MODE (operands[1]))"
5913   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
5914    (set (match_dup 2) (match_dup 3))])
5915
5916 ;; Fold sequences such as
5917 ;;      mov.b   @r3,r7
5918 ;;      extu.b  r7,r7
5919 ;; into
5920 ;;      movu.b  @(0,r3),r7
5921 ;; This does not reduce the code size but the number of instructions is
5922 ;; halved, which results in faster code.
5923 (define_peephole2
5924   [(set (match_operand:SI 0 "arith_reg_dest" "")
5925         (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
5926    (set (match_operand:SI 2 "arith_reg_dest" "")
5927         (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
5928   "TARGET_SH2A
5929    && GET_MODE (operands[1]) == GET_MODE (operands[3])
5930    && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
5931    && REGNO (operands[0]) == REGNO (operands[3])
5932    && (REGNO (operands[2]) == REGNO (operands[0])
5933        || peep2_reg_dead_p (2, operands[0]))"
5934   [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
5935 {
5936   operands[4]
5937     = replace_equiv_address (operands[1],
5938                              gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
5939                                            const0_rtx));
5940 })
5941
5942 ;; -------------------------------------------------------------------------
5943 ;; Sign extension instructions
5944 ;; -------------------------------------------------------------------------
5945
5946 ;; ??? This should be a define expand.
5947 ;; ??? Or perhaps it should be dropped?
5948
5949 ;; convert_move generates good code for SH[1-4].
5950 (define_insn "extendsidi2"
5951   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5952         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
5953   "TARGET_SHMEDIA"
5954   "@
5955         add.l   %1, r63, %0
5956         ld%M1.l %m1, %0
5957         fmov.sl %1, %0"
5958   [(set_attr "type" "arith_media,load_media,fpconv_media")
5959    (set (attr "highpart")
5960         (cond [(match_test "sh_contains_memref_p (insn)")
5961                (const_string "user")]
5962               (const_string "extend")))])
5963
5964 (define_insn "extendhidi2"
5965   [(set (match_operand:DI 0 "register_operand" "=r,r")
5966         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5967   "TARGET_SHMEDIA"
5968   "@
5969         #
5970         ld%M1.w %m1, %0"
5971   [(set_attr "type" "*,load_media")
5972    (set (attr "highpart")
5973         (cond [(match_test "sh_contains_memref_p (insn)")
5974                (const_string "user")]
5975               (const_string "ignore")))])
5976
5977 (define_split
5978   [(set (match_operand:DI 0 "register_operand" "")
5979         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5980   "TARGET_SHMEDIA && reload_completed"
5981   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5982    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
5983 {
5984   if (GET_CODE (operands[1]) == TRUNCATE)
5985     operands[1] = XEXP (operands[1], 0);
5986 })
5987
5988 (define_insn "extendqidi2"
5989   [(set (match_operand:DI 0 "register_operand" "=r,r")
5990         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5991   "TARGET_SHMEDIA"
5992   "@
5993         #
5994         ld%M1.b %m1, %0"
5995   [(set_attr "type" "*,load_media")
5996    (set (attr "highpart")
5997         (cond [(match_test "sh_contains_memref_p (insn)")
5998                (const_string "user")]
5999               (const_string "ignore")))])
6000
6001 (define_split
6002   [(set (match_operand:DI 0 "register_operand" "")
6003         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6004   "TARGET_SHMEDIA && reload_completed"
6005   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6006    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6007 {
6008   if (GET_CODE (operands[1]) == TRUNCATE)
6009     operands[1] = XEXP (operands[1], 0);
6010 })
6011
6012 (define_expand "extend<mode>si2"
6013   [(set (match_operand:SI 0 "arith_reg_dest")
6014         (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6015
6016 (define_insn "*extendhisi2_media"
6017   [(set (match_operand:SI 0 "register_operand" "=r,r")
6018         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6019   "TARGET_SHMEDIA"
6020   "@
6021         #
6022         ld%M1.w %m1, %0"
6023   [(set_attr "type" "arith_media,load_media")
6024    (set (attr "highpart")
6025         (cond [(match_test "sh_contains_memref_p (insn)")
6026                (const_string "user")]
6027               (const_string "ignore")))])
6028
6029 (define_split
6030   [(set (match_operand:SI 0 "register_operand" "")
6031         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6032   "TARGET_SHMEDIA && reload_completed"
6033   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6034    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6035 {
6036   rtx op1 = operands[1];
6037   if (GET_CODE (op1) == TRUNCATE)
6038     op1 = XEXP (op1, 0);
6039   operands[2]
6040     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6041                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
6042 })
6043
6044 (define_insn_and_split "*extend<mode>si2_compact_reg"
6045   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6046         (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6047   "TARGET_SH1"
6048   "exts.<bw>    %1,%0"
6049   "&& can_create_pseudo_p ()"
6050   [(set (match_dup 0) (match_dup 2))]
6051 {
6052   /* Sometimes combine fails to combine a T bit or negated T bit store to a
6053      reg with a following sign extension.  In the split pass after combine,
6054      try to figure the extended reg was set.  If it originated from the T
6055      bit we can replace the sign extension with a reg move, which will be
6056      eliminated.  */
6057   operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6058   if (operands[2] == NULL_RTX)
6059     FAIL;
6060 }
6061   [(set_attr "type" "arith")])
6062
6063 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6064 ;; See movqi insns.
6065 (define_insn "*extend<mode>si2_compact_mem_disp"
6066   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6067         (sign_extend:SI
6068           (mem:QIHI
6069             (plus:SI
6070               (match_operand:SI 1 "arith_reg_operand" "%r,r")
6071               (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6072   "TARGET_SH1 && ! TARGET_SH2A
6073    && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6074   "@
6075         mov.<bw>        @(%O2,%1),%0
6076         mov.<bw>        @%1,%0"
6077   [(set_attr "type" "load")])
6078
6079 (define_insn "*extend<mode>si2_compact_mem_disp"
6080   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6081         (sign_extend:SI
6082           (mem:QIHI
6083             (plus:SI
6084               (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6085               (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6086   "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6087   "@
6088         mov.<bw>        @(%O2,%1),%0
6089         mov.<bw>        @%1,%0
6090         mov.<bw>        @(%O2,%1),%0"
6091   [(set_attr "type" "load")
6092    (set_attr "length" "2,2,4")])
6093
6094 ;; The *_snd patterns will take care of other QImode/HImode addressing
6095 ;; modes than displacement addressing.  They must be defined _after_ the
6096 ;; displacement addressing patterns.  Otherwise the displacement addressing
6097 ;; patterns will not be picked.
6098 (define_insn "*extend<mode>si2_compact_snd"
6099   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6100         (sign_extend:SI
6101           (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6102   "TARGET_SH1"
6103   "mov.<bw>     %1,%0"
6104   [(set_attr "type" "load")])
6105
6106 (define_insn "*extendqisi2_media"
6107   [(set (match_operand:SI 0 "register_operand" "=r,r")
6108         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6109   "TARGET_SHMEDIA"
6110   "@
6111         #
6112         ld%M1.b %m1, %0"
6113   [(set_attr "type" "arith_media,load_media")
6114    (set (attr "highpart")
6115         (cond [(match_test "sh_contains_memref_p (insn)")
6116                (const_string "user")]
6117               (const_string "ignore")))])
6118
6119 (define_split
6120   [(set (match_operand:SI 0 "register_operand" "")
6121         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6122   "TARGET_SHMEDIA && reload_completed"
6123   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6124    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6125 {
6126   rtx op1 = operands[1];
6127   if (GET_CODE (op1) == TRUNCATE)
6128     op1 = XEXP (op1, 0);
6129   operands[2]
6130     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6131                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
6132 })
6133
6134 (define_expand "extendqihi2"
6135   [(set (match_operand:HI 0 "arith_reg_dest" "")
6136         (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
6137   ""
6138   "")
6139
6140 (define_insn "*extendqihi2_compact_reg"
6141   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6142         (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6143   "TARGET_SH1"
6144   "exts.b       %1,%0"
6145   [(set_attr "type" "arith")])
6146
6147 ;; It would seem useful to combine the truncXi patterns into the movXi
6148 ;; patterns, but unary operators are ignored when matching constraints,
6149 ;; so we need separate patterns.
6150 (define_insn "truncdisi2"
6151   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6152         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6153   "TARGET_SHMEDIA"
6154   "@
6155         add.l   %1, r63, %0
6156         st%M0.l %m0, %1
6157         fst%M0.s        %m0, %T1
6158         fmov.ls %1, %0
6159         fmov.sl %T1, %0
6160         fmov.s  %T1, %0"
6161   [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,
6162                      fpconv_media,fmove_media")
6163    (set (attr "highpart")
6164         (cond [(match_test "sh_contains_memref_p (insn)")
6165                (const_string "user")]
6166               (const_string "extend")))])
6167
6168 (define_insn "truncdihi2"
6169   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6170         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6171   "TARGET_SHMEDIA"
6172 {
6173   static const char* alt[] =
6174   {
6175        "shlli   %1,48,%0"       "\n"
6176     "   shlri   %0,48,%0",
6177
6178        "st%M0.w %m0, %1"
6179   };
6180   return alt[which_alternative];
6181 }
6182   [(set_attr "type"   "arith_media,store_media")
6183    (set_attr "length" "8,4")
6184    (set (attr "highpart")
6185         (cond [(match_test "sh_contains_memref_p (insn)")
6186                (const_string "user")]
6187               (const_string "extend")))])
6188
6189 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6190 ; Because we use zero extension, we can't provide signed QImode compares
6191 ; using a simple compare or conditional branch insn.
6192 (define_insn "truncdiqi2"
6193   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6194         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6195   "TARGET_SHMEDIA"
6196   "@
6197         andi    %1, 255, %0
6198         st%M0.b %m0, %1"
6199   [(set_attr "type"   "arith_media,store")
6200    (set (attr "highpart")
6201         (cond [(match_test "sh_contains_memref_p (insn)")
6202                (const_string "user")]
6203               (const_string "extend")))])
6204
6205 ;; -------------------------------------------------------------------------
6206 ;; Move instructions
6207 ;; -------------------------------------------------------------------------
6208
6209 ;; define push and pop so it is easy for sh.c
6210 ;; We can't use push and pop on SHcompact because the stack must always
6211 ;; be 8-byte aligned.
6212 (define_expand "push"
6213   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6214         (match_operand:SI 0 "register_operand" "r,l,x"))]
6215   "TARGET_SH1 && ! TARGET_SH5"
6216   "")
6217
6218 (define_expand "pop"
6219   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6220         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6221   "TARGET_SH1 && ! TARGET_SH5"
6222   "")
6223
6224 (define_expand "push_e"
6225   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6226                    (match_operand:SF 0 "" ""))
6227               (use (reg:PSI FPSCR_REG))
6228               (clobber (scratch:SI))])]
6229   "TARGET_SH1 && ! TARGET_SH5"
6230   "")
6231
6232 (define_insn "push_fpul"
6233   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6234   "TARGET_SH2E && ! TARGET_SH5"
6235   "sts.l        fpul,@-r15"
6236   [(set_attr "type" "fstore")
6237    (set_attr "late_fp_use" "yes")
6238    (set_attr "hit_stack" "yes")])
6239
6240 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6241 ;; so use that.
6242 (define_expand "push_4"
6243   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6244                    (match_operand:DF 0 "" ""))
6245               (use (reg:PSI FPSCR_REG))
6246               (clobber (scratch:SI))])]
6247   "TARGET_SH1 && ! TARGET_SH5"
6248   "")
6249
6250 (define_expand "pop_e"
6251   [(parallel [(set (match_operand:SF 0 "" "")
6252               (mem:SF (post_inc:SI (reg:SI SP_REG))))
6253               (use (reg:PSI FPSCR_REG))
6254               (clobber (scratch:SI))])]
6255   "TARGET_SH1 && ! TARGET_SH5"
6256   "")
6257
6258 (define_insn "pop_fpul"
6259   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6260   "TARGET_SH2E && ! TARGET_SH5"
6261   "lds.l        @r15+,fpul"
6262   [(set_attr "type" "load")
6263    (set_attr "hit_stack" "yes")])
6264
6265 (define_expand "pop_4"
6266   [(parallel [(set (match_operand:DF 0 "" "")
6267                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
6268               (use (reg:PSI FPSCR_REG))
6269               (clobber (scratch:SI))])]
6270   "TARGET_SH1 && ! TARGET_SH5"
6271   "")
6272
6273 (define_expand "push_fpscr"
6274   [(const_int 0)]
6275   "TARGET_SH2E"
6276 {
6277   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
6278                                                  gen_rtx_PRE_DEC (Pmode,
6279                                                           stack_pointer_rtx)),
6280                                         get_fpscr_rtx ()));
6281   add_reg_note (insn, REG_INC, stack_pointer_rtx);
6282   DONE;
6283 })
6284
6285 (define_expand "pop_fpscr"
6286   [(const_int 0)]
6287   "TARGET_SH2E"
6288 {
6289   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
6290                                         gen_frame_mem (PSImode,
6291                                                  gen_rtx_POST_INC (Pmode,
6292                                                           stack_pointer_rtx))));
6293   add_reg_note (insn, REG_INC, stack_pointer_rtx);
6294   DONE;
6295 })
6296
6297 ;; The clrt and sett patterns can happen as the result of optimization and
6298 ;; insn expansion.
6299 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6300 ;; In this case they might not disappear completely, because the T reg is
6301 ;; a fixed hard reg.
6302 ;; When DImode operations that use the T reg as carry/borrow are split into
6303 ;; individual SImode operations, the T reg is usually cleared before the
6304 ;; first SImode insn.
6305 (define_insn "clrt"
6306   [(set (reg:SI T_REG) (const_int 0))]
6307   "TARGET_SH1"
6308   "clrt"
6309   [(set_attr "type" "mt_group")])
6310
6311 (define_insn "sett"
6312   [(set (reg:SI T_REG) (const_int 1))]
6313   "TARGET_SH1"
6314   "sett"
6315   [(set_attr "type" "mt_group")])
6316
6317 ;; Use the combine pass to transform sequences such as
6318 ;;      mov     r5,r0
6319 ;;      add     #1,r0
6320 ;;      shll2   r0
6321 ;;      mov.l   @(r0,r4),r0
6322 ;; into
6323 ;;      shll2   r5
6324 ;;      add     r4,r5
6325 ;;      mov.l   @(4,r5),r0
6326 ;;
6327 ;; See also PR 39423.
6328 ;; Notice that these patterns have a T_REG clobber, because the shift
6329 ;; sequence that will be split out might clobber the T_REG.  Ideally, the
6330 ;; clobber would be added conditionally, depending on the result of
6331 ;; sh_ashlsi_clobbers_t_reg_p.  When splitting out the shifts we must go
6332 ;; through the ashlsi3 expander in order to get the right shift insn --
6333 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6334 ;; FIXME: Combine never tries this kind of patterns for DImode.
6335 (define_insn_and_split "*movsi_index_disp_load"
6336   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6337         (match_operand:SI 1 "mem_index_disp_operand" "m"))
6338    (clobber (reg:SI T_REG))]
6339   "TARGET_SH1"
6340   "#"
6341   "&& can_create_pseudo_p ()"
6342   [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6343    (set (match_dup 0) (match_dup 7))]
6344 {
6345   rtx mem = operands[1];
6346   rtx plus0_rtx = XEXP (mem, 0);
6347   rtx plus1_rtx = XEXP (plus0_rtx, 0);
6348   rtx mult_rtx = XEXP (plus1_rtx, 0);
6349
6350   operands[1] = XEXP (mult_rtx, 0);
6351   operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6352   operands[3] = XEXP (plus1_rtx, 1);
6353   operands[4] = XEXP (plus0_rtx, 1);
6354   operands[5] = gen_reg_rtx (SImode);
6355   operands[6] = gen_reg_rtx (SImode);
6356   operands[7] =
6357     replace_equiv_address (mem,
6358                            gen_rtx_PLUS (SImode, operands[6], operands[4]));
6359
6360   emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6361 })
6362
6363 (define_insn_and_split "*movhi_index_disp_load"
6364   [(set (match_operand:SI 0 "arith_reg_dest")
6365         (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6366    (clobber (reg:SI T_REG))]
6367   "TARGET_SH1"
6368   "#"
6369   "&& can_create_pseudo_p ()"
6370   [(const_int 0)]
6371 {
6372   rtx mem = operands[1];
6373   rtx plus0_rtx = XEXP (mem, 0);
6374   rtx plus1_rtx = XEXP (plus0_rtx, 0);
6375   rtx mult_rtx = XEXP (plus1_rtx, 0);
6376
6377   rtx op_1 = XEXP (mult_rtx, 0);
6378   rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6379   rtx op_3 = XEXP (plus1_rtx, 1);
6380   rtx op_4 = XEXP (plus0_rtx, 1);
6381   rtx op_5 = gen_reg_rtx (SImode);
6382   rtx op_6 = gen_reg_rtx (SImode);
6383   rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6384
6385   emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6386   emit_insn (gen_addsi3 (op_6, op_5, op_3));
6387
6388   if (<CODE> == SIGN_EXTEND)
6389     {
6390       emit_insn (gen_extendhisi2 (operands[0], op_7));
6391       DONE;
6392     }
6393   else if (<CODE> == ZERO_EXTEND)
6394     {
6395       /* On SH2A the movu.w insn can be used for zero extending loads.  */
6396       if (TARGET_SH2A)
6397         emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6398       else
6399         {
6400           emit_insn (gen_extendhisi2 (operands[0], op_7));
6401           emit_insn (gen_zero_extendhisi2 (operands[0],
6402                                            gen_lowpart (HImode, operands[0])));
6403         }
6404       DONE;
6405     }
6406   else
6407     FAIL;
6408 })
6409
6410 (define_insn_and_split "*mov<mode>_index_disp_store"
6411   [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6412         (match_operand:HISI 1 "arith_reg_operand" "r"))
6413    (clobber (reg:SI T_REG))]
6414   "TARGET_SH1"
6415   "#"
6416   "&& can_create_pseudo_p ()"
6417   [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6418    (set (match_dup 7) (match_dup 1))]
6419 {
6420   rtx mem = operands[0];
6421   rtx plus0_rtx = XEXP (mem, 0);
6422   rtx plus1_rtx = XEXP (plus0_rtx, 0);
6423   rtx mult_rtx = XEXP (plus1_rtx, 0);
6424
6425   operands[0] = XEXP (mult_rtx, 0);
6426   operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6427   operands[3] = XEXP (plus1_rtx, 1);
6428   operands[4] = XEXP (plus0_rtx, 1);
6429   operands[5] = gen_reg_rtx (SImode);
6430   operands[6] = gen_reg_rtx (SImode);
6431   operands[7] =
6432     replace_equiv_address (mem,
6433                            gen_rtx_PLUS (SImode, operands[6], operands[4]));
6434
6435   emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6436 })
6437
6438 ;; t/r must come after r/r, lest reload will try to reload stuff like
6439 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6440 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6441 (define_insn "movsi_i"
6442   [(set (match_operand:SI 0 "general_movdst_operand"
6443             "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6444         (match_operand:SI 1 "general_movsrc_operand"
6445          "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6446   "TARGET_SH1
6447    && ! TARGET_SH2E
6448    && ! TARGET_SH2A
6449    && (register_operand (operands[0], SImode)
6450        || register_operand (operands[1], SImode))"
6451   "@
6452         mov.l   %1,%0
6453         mov     %1,%0
6454         mov     %1,%0
6455         mov.l   %1,%0
6456         sts     %1,%0
6457         sts     %1,%0
6458         mov.l   %1,%0
6459         sts.l   %1,%0
6460         sts.l   %1,%0
6461         lds     %1,%0
6462         lds     %1,%0
6463         lds.l   %1,%0
6464         lds.l   %1,%0
6465         fake    %1,%0"
6466   [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
6467                      pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6468    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6469
6470 ;; t/r must come after r/r, lest reload will try to reload stuff like
6471 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6472 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6473 ;; will require a reload.
6474 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6475 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6476 (define_insn "movsi_ie"
6477   [(set (match_operand:SI 0 "general_movdst_operand"
6478             "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6479         (match_operand:SI 1 "general_movsrc_operand"
6480          "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6481   "(TARGET_SH2E || TARGET_SH2A)
6482    && (register_operand (operands[0], SImode)
6483        || register_operand (operands[1], SImode))"
6484   "@
6485         mov.l   %1,%0
6486         mov     %1,%0
6487         mov     %1,%0
6488         movi20  %1,%0
6489         movi20s %1,%0
6490         mov.l   %1,%0
6491         sts     %1,%0
6492         sts     %1,%0
6493         mov.l   %1,%0
6494         sts.l   %1,%0
6495         sts.l   %1,%0
6496         lds     %1,%0
6497         lds     %1,%0
6498         lds.l   %1,%0
6499         lds.l   %1,%0
6500         lds.l   %1,%0
6501         sts.l   %1,%0
6502         fake    %1,%0
6503         lds     %1,%0
6504         sts     %1,%0
6505         fsts    fpul,%0
6506         flds    %1,fpul
6507         fmov    %1,%0
6508         ! move optimized away"
6509   [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
6510                      mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,
6511                      pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6512    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6513    (set_attr_alternative "length"
6514      [(const_int 2)
6515       (const_int 2)
6516       (const_int 2)
6517       (const_int 4)
6518       (const_int 4)
6519       (if_then_else
6520         (match_test "TARGET_SH2A")
6521         (const_int 4) (const_int 2))
6522       (const_int 2)
6523       (const_int 2)
6524       (if_then_else
6525         (match_test "TARGET_SH2A")
6526         (const_int 4) (const_int 2))
6527       (const_int 2)
6528       (const_int 2)
6529       (const_int 2)
6530       (const_int 2)
6531       (const_int 2)
6532       (const_int 2)
6533       (const_int 2)
6534       (const_int 2)
6535       (const_int 2)
6536       (const_int 2)
6537       (const_int 2)
6538       (const_int 2)
6539       (const_int 2)
6540       (const_int 2)
6541       (const_int 0)])])
6542
6543 (define_insn "movsi_i_lowpart"
6544   [(set (strict_low_part
6545           (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6546         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6547    "TARGET_SH1
6548     && (register_operand (operands[0], SImode)
6549         || register_operand (operands[1], SImode))"
6550   "@
6551         mov.l   %1,%0
6552         mov     %1,%0
6553         mov     %1,%0
6554         mov.l   %1,%0
6555         sts     %1,%0
6556         sts     %1,%0
6557         mov.l   %1,%0
6558         fake    %1,%0"
6559   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6560
6561 (define_insn_and_split "load_ra"
6562   [(set (match_operand:SI 0 "general_movdst_operand" "")
6563         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6564   "TARGET_SH1"
6565   "#"
6566   "&& ! currently_expanding_to_rtl"
6567   [(set (match_dup 0) (match_dup 1))]
6568 {
6569   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6570     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6571 })
6572
6573 ;; The '?'s in the following constraints may not reflect the time taken
6574 ;; to perform the move. They are there to discourage the use of floating-
6575 ;; point registers for storing integer values.
6576 (define_insn "*movsi_media"
6577   [(set (match_operand:SI 0 "general_movdst_operand"
6578                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6579         (match_operand:SI 1 "general_movsrc_operand"
6580          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6581   "TARGET_SHMEDIA_FPU
6582    && (register_operand (operands[0], SImode)
6583        || sh_register_operand (operands[1], SImode)
6584        || GET_CODE (operands[1]) == TRUNCATE)"
6585   "@
6586         add.l   %1, r63, %0
6587         movi    %1, %0
6588         #
6589         ld%M1.l %m1, %0
6590         st%M0.l %m0, %N1
6591         fld%M1.s        %m1, %0
6592         fst%M0.s        %m0, %1
6593         fmov.ls %N1, %0
6594         fmov.sl %1, %0
6595         fmov.s  %1, %0
6596         ptabs   %1, %0
6597         gettr   %1, %0
6598         pt      %1, %0"
6599   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,
6600                        fload_media,fstore_media,fload_media,fpconv_media,
6601                        fmove_media,ptabs_media,gettr_media,pt_media")
6602    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
6603    (set (attr "highpart")
6604         (cond [(match_test "sh_contains_memref_p (insn)")
6605                (const_string "user")]
6606               (const_string "ignore")))])
6607
6608 (define_insn "*movsi_media_nofpu"
6609   [(set (match_operand:SI 0 "general_movdst_operand"
6610                 "=r,r,r,r,m,*b,r,*b")
6611         (match_operand:SI 1 "general_movsrc_operand"
6612          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6613   "TARGET_SHMEDIA
6614    && (register_operand (operands[0], SImode)
6615        || sh_register_operand (operands[1], SImode)
6616        || GET_CODE (operands[1]) == TRUNCATE)"
6617   "@
6618         add.l   %1, r63, %0
6619         movi    %1, %0
6620         #
6621         ld%M1.l %m1, %0
6622         st%M0.l %m0, %N1
6623         ptabs   %1, %0
6624         gettr   %1, %0
6625         pt      %1, %0"
6626   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6627                      ptabs_media,gettr_media,pt_media")
6628    (set_attr "length" "4,4,8,4,4,4,4,12")
6629    (set (attr "highpart")
6630         (cond [(match_test "sh_contains_memref_p (insn)")
6631                (const_string "user")]
6632               (const_string "ignore")))])
6633
6634 (define_expand "movsi_const"
6635   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6636         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6637                               (const_int 16)] UNSPEC_EXTRACT_S16)))
6638    (set (match_dup 0)
6639         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6640                 (const:SI (unspec:SI [(match_dup 1)
6641                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
6642   "TARGET_SHMEDIA && reload_completed
6643    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6644 {
6645   if (GET_CODE (operands[1]) == LABEL_REF
6646       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6647     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6648   else if (GOTOFF_P (operands[1]))
6649     {
6650       rtx unspec = XEXP (operands[1], 0);
6651
6652       if (! UNSPEC_GOTOFF_P (unspec))
6653         {
6654           unspec = XEXP (unspec, 0);
6655           if (! UNSPEC_GOTOFF_P (unspec))
6656             abort ();
6657         }
6658       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6659           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6660         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6661     }
6662 })
6663
6664 (define_expand "movsi_const_16bit"
6665   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6666         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6667                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
6668   "TARGET_SHMEDIA && flag_pic && reload_completed
6669    && GET_CODE (operands[1]) == SYMBOL_REF"
6670   "")
6671
6672 (define_split
6673   [(set (match_operand:SI 0 "arith_reg_dest" "")
6674         (match_operand:SI 1 "immediate_operand" ""))]
6675   "TARGET_SHMEDIA && reload_completed
6676    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6677   [(const_int 0)]
6678 {
6679   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6680
6681   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6682
6683   DONE;
6684 })
6685
6686 (define_split
6687   [(set (match_operand:SI 0 "register_operand" "")
6688         (match_operand:SI 1 "immediate_operand" ""))]
6689   "TARGET_SHMEDIA && reload_completed
6690    && ((CONST_INT_P (operands[1])
6691         && ! satisfies_constraint_I16 (operands[1]))
6692        || GET_CODE (operands[1]) == CONST_DOUBLE)"
6693   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6694
6695 (define_expand "movsi"
6696   [(set (match_operand:SI 0 "general_movdst_operand" "")
6697         (match_operand:SI 1 "general_movsrc_operand" ""))]
6698   ""
6699 {
6700   prepare_move_operands (operands, SImode);
6701 })
6702
6703 (define_expand "ic_invalidate_line"
6704   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6705                                 (match_dup 1)] UNSPEC_ICACHE)
6706               (clobber (scratch:SI))])]
6707   "TARGET_HARD_SH4 || TARGET_SH5"
6708 {
6709   if (TARGET_SHMEDIA)
6710     {
6711       emit_insn (gen_ic_invalidate_line_media (operands[0]));
6712       DONE;
6713     }
6714   else if (TARGET_SHCOMPACT)
6715     {
6716       operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6717       operands[1] = force_reg (Pmode, operands[1]);
6718       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6719       DONE;
6720     }
6721   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
6722     {
6723       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6724       DONE;
6725     }
6726   operands[0] = force_reg (Pmode, operands[0]);
6727   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6728                                                                Pmode)));
6729 })
6730
6731 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
6732 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6733 ;; the requirement *1*00 for associative address writes.  The alignment of
6734 ;; %0 implies that its least significant bit is cleared,
6735 ;; thus we clear the V bit of a matching entry if there is one.
6736 (define_insn "ic_invalidate_line_i"
6737   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6738                      (match_operand:SI 1 "register_operand" "r")]
6739                      UNSPEC_ICACHE)
6740    (clobber (match_scratch:SI 2 "=&r"))]
6741   "TARGET_HARD_SH4"
6742 {
6743   return       "ocbwb   @%0"    "\n"
6744          "      extu.w  %0,%2"  "\n"
6745          "      or      %1,%2"  "\n"
6746          "      mov.l   %0,@%2";
6747 }
6748   [(set_attr "length" "8")
6749    (set_attr "type" "cwb")])
6750
6751 (define_insn "ic_invalidate_line_sh4a"
6752   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6753                     UNSPEC_ICACHE)]
6754   "TARGET_SH4A_ARCH || TARGET_SH4_300"
6755 {
6756   return       "ocbwb   @%0"    "\n"
6757          "      synco"          "\n"
6758          "      icbi    @%0";
6759 }
6760   [(set_attr "length" "16")     ;; FIXME: Why 16 and not 6?  Looks like typo.
6761    (set_attr "type" "cwb")])
6762
6763 ;; ??? could make arg 0 an offsettable memory operand to allow to save
6764 ;; an add in the code that calculates the address.
6765 (define_insn "ic_invalidate_line_media"
6766   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
6767                     UNSPEC_ICACHE)]
6768   "TARGET_SHMEDIA"
6769 {
6770   return       "ocbwb   %0,0"   "\n"
6771          "      synco"          "\n"
6772          "      icbi    %0,0"   "\n"
6773          "      synci";
6774 }
6775   [(set_attr "length" "16")
6776    (set_attr "type" "invalidate_line_media")])
6777
6778 (define_insn "ic_invalidate_line_compact"
6779   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6780                      (match_operand:SI 1 "register_operand" "r")]
6781                     UNSPEC_ICACHE)
6782    (clobber (reg:SI PR_REG))]
6783   "TARGET_SHCOMPACT"
6784   "jsr @%1%#"
6785   [(set_attr "type" "sfunc")
6786    (set_attr "needs_delay_slot" "yes")])
6787
6788 (define_expand "initialize_trampoline"
6789   [(match_operand:SI 0 "" "")
6790    (match_operand:SI 1 "" "")
6791    (match_operand:SI 2 "" "")]
6792   "TARGET_SHCOMPACT"
6793 {
6794   rtx sfun, tramp;
6795
6796   tramp = force_reg (Pmode, operands[0]);
6797   sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
6798                                             SFUNC_STATIC));
6799   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
6800   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
6801
6802   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
6803   DONE;
6804 })
6805
6806 (define_insn "initialize_trampoline_compact"
6807   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6808                      (match_operand:SI 1 "register_operand" "r")
6809                      (reg:SI R2_REG) (reg:SI R3_REG)]
6810                     UNSPEC_INIT_TRAMP)
6811
6812    (clobber (reg:SI PR_REG))]
6813   "TARGET_SHCOMPACT"
6814   "jsr @%1%#"
6815   [(set_attr "type" "sfunc")
6816    (set_attr "needs_delay_slot" "yes")])
6817
6818 (define_expand "movhi"
6819   [(set (match_operand:HI 0 "general_movdst_operand" "")
6820         (match_operand:HI 1 "general_movsrc_operand" ""))]
6821   ""
6822 {
6823   prepare_move_operands (operands, HImode);
6824 })
6825
6826 (define_expand "movqi"
6827   [(set (match_operand:QI 0 "general_operand" "")
6828         (match_operand:QI 1 "general_operand" ""))]
6829   ""
6830 {
6831   prepare_move_operands (operands, QImode);
6832 })
6833
6834 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
6835 ;; selected to copy QImode regs.  If one of them happens to be allocated
6836 ;; on the stack, reload will stick to movqi insn and generate wrong
6837 ;; displacement addressing because of the generic m alternatives.  
6838 ;; With the movqi_reg_reg being specified before movqi it will be initially 
6839 ;; picked to load/store regs.  If the regs regs are on the stack reload will
6840 ;; try other insns and not stick to movqi_reg_reg.
6841 ;; The same applies to the movhi variants.
6842 ;;
6843 ;; Notice, that T bit is not allowed as a mov src operand here.  This is to
6844 ;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
6845 ;; introduces zero extensions after T bit stores and redundant reg copies.
6846 ;;
6847 ;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
6848 ;; predicate for the mov src operand because reload will have trouble
6849 ;; reloading MAC subregs otherwise.  For that probably special patterns
6850 ;; would be required.
6851 (define_insn "*mov<mode>_reg_reg"
6852   [(set (match_operand:QIHI 0 "arith_reg_dest" "=r")
6853         (match_operand:QIHI 1 "register_operand" "r"))]
6854   "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
6855   "mov  %1,%0"
6856   [(set_attr "type" "move")])
6857
6858 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
6859 ;; "enabled" attribute as it is done in other targets.
6860 (define_insn "*mov<mode>_store_mem_disp04"
6861   [(set (mem:QIHI
6862           (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
6863                    (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
6864         (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
6865   "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
6866   "@
6867         mov.<bw>        %2,@(%O1,%0)
6868         mov.<bw>        %2,@%0"
6869   [(set_attr "type" "store")])
6870
6871 (define_insn "*mov<mode>_store_mem_disp12"
6872   [(set (mem:QIHI
6873           (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
6874                    (match_operand:SI 1 "const_int_operand" "<disp12>")))
6875         (match_operand:QIHI 2 "arith_reg_operand" "r"))]
6876   "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
6877   "mov.<bw>     %2,@(%O1,%0)"
6878   [(set_attr "type" "store")
6879    (set_attr "length" "4")])
6880
6881 (define_insn "*mov<mode>_load_mem_disp04"
6882   [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
6883         (mem:QIHI
6884           (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
6885                    (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
6886   "TARGET_SH1 && ! TARGET_SH2A
6887    && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6888   "@
6889         mov.<bw>        @(%O2,%1),%0
6890         mov.<bw>        @%1,%0"
6891   [(set_attr "type" "load")])
6892
6893 (define_insn "*mov<mode>_load_mem_disp12"
6894   [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
6895         (mem:QIHI
6896           (plus:SI
6897             (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6898             (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
6899   "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6900   "@
6901         mov.<bw>        @(%O2,%1),%0
6902         mov.<bw>        @%1,%0
6903         mov.<bw>        @(%O2,%1),%0"
6904   [(set_attr "type" "load")
6905    (set_attr "length" "2,2,4")])
6906
6907 ;; The m constraints basically allow any kind of addresses to be used with any
6908 ;; source/target register as the other operand.  This is not true for 
6909 ;; displacement addressing modes on anything but SH2A.  That's why the
6910 ;; specialized load/store insns are specified above.
6911 (define_insn "*movqi"
6912   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
6913         (match_operand:QI 1 "general_movsrc_operand"  "i,m,r,l,r"))]
6914   "TARGET_SH1
6915    && (arith_reg_operand (operands[0], QImode)
6916        || arith_reg_operand (operands[1], QImode))"
6917   "@
6918         mov     %1,%0
6919         mov.b   %1,%0
6920         mov.b   %1,%0
6921         sts     %1,%0
6922         lds     %1,%0"
6923  [(set_attr "type" "movi8,load,store,prget,prset")])
6924
6925 (define_insn "*movhi"
6926   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
6927         (match_operand:HI 1 "general_movsrc_operand"  "Q,i,m,r,l,r"))]
6928   "TARGET_SH1
6929    && (arith_reg_operand (operands[0], HImode)
6930        || arith_reg_operand (operands[1], HImode))"
6931   "@
6932         mov.w   %1,%0
6933         mov     %1,%0
6934         mov.w   %1,%0
6935         mov.w   %1,%0
6936         sts     %1,%0
6937         lds     %1,%0"
6938  [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
6939
6940 (define_insn "*movqi_media"
6941   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
6942         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
6943   "TARGET_SHMEDIA
6944    && (arith_reg_operand (operands[0], QImode)
6945        || extend_reg_or_0_operand (operands[1], QImode))"
6946   "@
6947         add.l   %1, r63, %0
6948         movi    %1, %0
6949         ld%M1.ub        %m1, %0
6950         st%M0.b %m0, %N1"
6951   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
6952    (set (attr "highpart")
6953         (cond [(match_test "sh_contains_memref_p (insn)")
6954                (const_string "user")]
6955               (const_string "ignore")))])
6956
6957 (define_expand "reload_inqi"
6958   [(set (match_operand:SI 2 "" "=&r")
6959         (match_operand:QI 1 "inqhi_operand" ""))
6960    (set (match_operand:QI 0 "arith_reg_operand" "=r")
6961         (truncate:QI (match_dup 3)))]
6962   "TARGET_SHMEDIA"
6963 {
6964   rtx inner = XEXP (operands[1], 0);
6965   int regno = REGNO (inner);
6966
6967   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6968   operands[1] = gen_rtx_REG (SImode, regno);
6969   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
6970 })
6971
6972 (define_insn "*movhi_media"
6973   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
6974         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
6975   "TARGET_SHMEDIA
6976    && (arith_reg_operand (operands[0], HImode)
6977        || arith_reg_or_0_operand (operands[1], HImode))"
6978   "@
6979         add.l   %1, r63, %0
6980         movi    %1, %0
6981         #
6982         ld%M1.w %m1, %0
6983         st%M0.w %m0, %N1"
6984   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
6985    (set (attr "highpart")
6986         (cond [(match_test "sh_contains_memref_p (insn)")
6987                (const_string "user")]
6988               (const_string "ignore")))])
6989
6990 (define_split
6991   [(set (match_operand:HI 0 "register_operand" "")
6992         (match_operand:HI 1 "immediate_operand" ""))]
6993   "TARGET_SHMEDIA && reload_completed
6994    && ! satisfies_constraint_I16 (operands[1])"
6995   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6996
6997 (define_expand "reload_inhi"
6998   [(set (match_operand:SI 2 "" "=&r")
6999         (match_operand:HI 1 "inqhi_operand" ""))
7000    (set (match_operand:HI 0 "arith_reg_operand" "=r")
7001         (truncate:HI (match_dup 3)))]
7002   "TARGET_SHMEDIA"
7003 {
7004   rtx inner = XEXP (operands[1], 0);
7005   int regno = REGNO (inner);
7006
7007   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7008   operands[1] = gen_rtx_REG (SImode, regno);
7009   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7010 })
7011
7012 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7013 ;; compiled with -m2 -ml -O3 -funroll-loops
7014 (define_insn "*movdi_i"
7015   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7016         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7017   "TARGET_SH1
7018    && (arith_reg_operand (operands[0], DImode)
7019        || arith_reg_operand (operands[1], DImode))"
7020 {
7021   return output_movedouble (insn, operands, DImode);
7022 }
7023   [(set_attr "length" "4")
7024    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7025
7026 ;; If the output is a register and the input is memory or a register, we have
7027 ;; to be careful and see which word needs to be loaded first.
7028 (define_split
7029   [(set (match_operand:DI 0 "general_movdst_operand" "")
7030         (match_operand:DI 1 "general_movsrc_operand" ""))]
7031   "TARGET_SH1 && reload_completed"
7032   [(set (match_dup 2) (match_dup 3))
7033    (set (match_dup 4) (match_dup 5))]
7034 {
7035   int regno;
7036
7037   if ((MEM_P (operands[0])
7038        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7039       || (MEM_P (operands[1])
7040           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7041     FAIL;
7042
7043   switch (GET_CODE (operands[0]))
7044     {
7045     case REG:
7046       regno = REGNO (operands[0]);
7047       break;
7048     case SUBREG:
7049       regno = subreg_regno (operands[0]);
7050       break;
7051     case MEM:
7052       regno = -1;
7053       break;
7054     default:
7055       gcc_unreachable ();
7056     }
7057
7058   if (regno == -1
7059       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7060     {
7061       operands[2] = operand_subword (operands[0], 0, 0, DImode);
7062       operands[3] = operand_subword (operands[1], 0, 0, DImode);
7063       operands[4] = operand_subword (operands[0], 1, 0, DImode);
7064       operands[5] = operand_subword (operands[1], 1, 0, DImode);
7065     }
7066   else
7067     {
7068       operands[2] = operand_subword (operands[0], 1, 0, DImode);
7069       operands[3] = operand_subword (operands[1], 1, 0, DImode);
7070       operands[4] = operand_subword (operands[0], 0, 0, DImode);
7071       operands[5] = operand_subword (operands[1], 0, 0, DImode);
7072     }
7073
7074   if (operands[2] == 0 || operands[3] == 0
7075       || operands[4] == 0 || operands[5] == 0)
7076     FAIL;
7077 })
7078
7079 ;; The '?'s in the following constraints may not reflect the time taken
7080 ;; to perform the move. They are there to discourage the use of floating-
7081 ;; point registers for storing integer values.
7082 (define_insn "*movdi_media"
7083   [(set (match_operand:DI 0 "general_movdst_operand"
7084                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7085         (match_operand:DI 1 "general_movsrc_operand"
7086          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7087   "TARGET_SHMEDIA_FPU
7088    && (register_operand (operands[0], DImode)
7089        || sh_register_operand (operands[1], DImode))"
7090   "@
7091         add     %1, r63, %0
7092         movi    %1, %0
7093         #
7094         ld%M1.q %m1, %0
7095         st%M0.q %m0, %N1
7096         fld%M1.d        %m1, %0
7097         fst%M0.d        %m0, %1
7098         fmov.qd %N1, %0
7099         fmov.dq %1, %0
7100         fmov.d  %1, %0
7101         ptabs   %1, %0
7102         gettr   %1, %0
7103         pt      %1, %0"
7104   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7105                      fload_media,fstore_media,fload_media,dfpconv_media,
7106                      fmove_media,ptabs_media,gettr_media,pt_media")
7107    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7108
7109 (define_insn "*movdi_media_nofpu"
7110   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7111         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7112   "TARGET_SHMEDIA
7113    && (register_operand (operands[0], DImode)
7114        || sh_register_operand (operands[1], DImode))"
7115   "@
7116         add     %1, r63, %0
7117         movi    %1, %0
7118         #
7119         ld%M1.q %m1, %0
7120         st%M0.q %m0, %N1
7121         ptabs   %1, %0
7122         gettr   %1, %0
7123         pt      %1, %0"
7124   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7125                      ptabs_media,gettr_media,pt_media")
7126    (set_attr "length" "4,4,16,4,4,4,4,*")])
7127
7128 (define_insn "*movdi_media_I16"
7129   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7130         (match_operand:DI 1 "const_int_operand" "I16"))]
7131   "TARGET_SHMEDIA && reload_completed"
7132   "movi %1, %0"
7133   [(set_attr "type" "arith_media")
7134    (set_attr "length" "4")])
7135
7136 (define_split
7137   [(set (match_operand:DI 0 "arith_reg_dest" "")
7138         (match_operand:DI 1 "immediate_operand" ""))]
7139   "TARGET_SHMEDIA && reload_completed
7140    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7141   [(set (match_dup 0) (match_dup 1))]
7142 {
7143   rtx insn;
7144
7145   if (TARGET_SHMEDIA64)
7146     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7147   else
7148     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7149
7150   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7151
7152   DONE;
7153 })
7154
7155 (define_expand "movdi_const"
7156   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7157         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7158                               (const_int 48)] UNSPEC_EXTRACT_S16)))
7159    (set (match_dup 0)
7160         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7161                 (const:DI (unspec:DI [(match_dup 1)
7162                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
7163    (set (match_dup 0)
7164         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7165                 (const:DI (unspec:DI [(match_dup 1)
7166                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
7167    (set (match_dup 0)
7168         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7169                 (const:DI (unspec:DI [(match_dup 1)
7170                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
7171   "TARGET_SHMEDIA64 && reload_completed
7172    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7173 {
7174   sh_mark_label (operands[1], 4);
7175 })
7176
7177 (define_expand "movdi_const_32bit"
7178   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7179         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7180                               (const_int 16)] UNSPEC_EXTRACT_S16)))
7181    (set (match_dup 0)
7182         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7183                 (const:DI (unspec:DI [(match_dup 1)
7184                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
7185   "TARGET_SHMEDIA32 && reload_completed
7186    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7187 {
7188   sh_mark_label (operands[1], 2);
7189 })
7190
7191 (define_expand "movdi_const_16bit"
7192   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7193         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7194                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
7195   "TARGET_SHMEDIA && flag_pic && reload_completed
7196    && GET_CODE (operands[1]) == SYMBOL_REF"
7197   "")
7198
7199 (define_split
7200   [(set (match_operand:DI 0 "ext_dest_operand" "")
7201         (match_operand:DI 1 "immediate_operand" ""))]
7202   "TARGET_SHMEDIA && reload_completed
7203    && CONST_INT_P (operands[1])
7204    && ! satisfies_constraint_I16 (operands[1])"
7205   [(set (match_dup 0) (match_dup 2))
7206    (match_dup 1)]
7207 {
7208   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7209   unsigned HOST_WIDE_INT low = val;
7210   unsigned HOST_WIDE_INT high = val;
7211   unsigned HOST_WIDE_INT sign;
7212   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7213
7214   /* Zero-extend the 16 least-significant bits.  */
7215   low &= 0xffff;
7216
7217   /* Arithmetic shift right the word by 16 bits.  */
7218   high >>= 16;
7219   if (GET_CODE (operands[0]) == SUBREG
7220       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7221     {
7222       high &= 0xffff;
7223       high ^= 0x8000;
7224       high -= 0x8000;
7225     }
7226   else
7227     {
7228       sign = 1;
7229       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7230       high ^= sign;
7231       high -= sign;
7232     }
7233   do
7234     {
7235       /* If we can't generate the constant with a two-insn movi / shori
7236          sequence, try some other strategies.  */
7237       if (! CONST_OK_FOR_I16 (high))
7238         {
7239           /* Try constant load / left shift.  We know VAL != 0.  */
7240           val2 = val ^ (val-1);
7241           if (val2 > 0x1ffff)
7242             {
7243               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7244
7245               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7246                   || (! CONST_OK_FOR_I16 (high >> 16)
7247                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7248                 {
7249                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7250                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
7251                                                    GEN_INT (trailing_zeroes));
7252                   break;
7253                 }
7254             }
7255           /* Try constant load / right shift.  */
7256           val2 = (val >> 15) + 1;
7257           if (val2 == (val2 & -val2))
7258             {
7259               int shift = 49 - exact_log2 (val2);
7260
7261               val2 = trunc_int_for_mode (val << shift, DImode);
7262               if (CONST_OK_FOR_I16 (val2))
7263                 {
7264                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7265                                                    GEN_INT (shift));
7266                   break;
7267                 }
7268             }
7269           /* Try mperm.w .  */
7270           val2 = val & 0xffff;
7271           if ((val >> 16 & 0xffff) == val2
7272               && (val >> 32 & 0xffff) == val2
7273               && (val >> 48 & 0xffff) == val2)
7274             {
7275               val2 = (HOST_WIDE_INT) val >> 48;
7276               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7277               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7278               break;
7279             }
7280           /* Try movi / mshflo.l  */
7281           val2 = (HOST_WIDE_INT) val >> 32;
7282           if (val2 == ((unsigned HOST_WIDE_INT)
7283                         trunc_int_for_mode (val, SImode)))
7284             {
7285               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7286                                              operands[0]);
7287               break;
7288             }
7289           /* Try movi / mshflo.l w/ r63.  */
7290           val2 = val + ((HOST_WIDE_INT) -1 << 32);
7291           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7292             {
7293               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7294                                              const0_rtx);
7295               break;
7296             }
7297         }
7298       val2 = high;
7299       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7300     }
7301   while (0);
7302   operands[2] = GEN_INT (val2);
7303 })
7304
7305 (define_split
7306   [(set (match_operand:DI 0 "ext_dest_operand" "")
7307         (match_operand:DI 1 "immediate_operand" ""))]
7308   "TARGET_SHMEDIA && reload_completed
7309    && GET_CODE (operands[1]) == CONST_DOUBLE"
7310   [(set (match_dup 0) (match_dup 2))
7311   (set (match_dup 0)
7312        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7313 {
7314   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7315   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7316   unsigned HOST_WIDE_INT val = low;
7317   unsigned HOST_WIDE_INT sign;
7318
7319   /* Zero-extend the 16 least-significant bits.  */
7320   val &= 0xffff;
7321   operands[1] = GEN_INT (val);
7322
7323   /* Arithmetic shift right the double-word by 16 bits.  */
7324   low >>= 16;
7325   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7326   high >>= 16;
7327   sign = 1;
7328   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7329   high ^= sign;
7330   high -= sign;
7331
7332   /* This will only be true if high is a sign-extension of low, i.e.,
7333      it must be either 0 or (unsigned)-1, and be zero iff the
7334      most-significant bit of low is set.  */
7335   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7336     operands[2] = GEN_INT (low);
7337   else
7338     operands[2] = immed_double_const (low, high, DImode);
7339 })
7340
7341 (define_insn "shori_media"
7342   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7343         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7344                            (const_int 16))
7345                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7346   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7347   "@
7348         shori   %u2, %0
7349         #"
7350   [(set_attr "type" "arith_media,*")])
7351
7352 (define_insn "*shori_media_si"
7353   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7354         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7355                            (const_int 16))
7356                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7357   "TARGET_SHMEDIA"
7358   "shori        %u2, %0")
7359
7360 (define_expand "movdi"
7361   [(set (match_operand:DI 0 "general_movdst_operand" "")
7362         (match_operand:DI 1 "general_movsrc_operand" ""))]
7363   ""
7364 {
7365   prepare_move_operands (operands, DImode);
7366 })
7367
7368 (define_insn "movdf_media"
7369   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7370         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7371   "TARGET_SHMEDIA_FPU
7372    && (register_operand (operands[0], DFmode)
7373        || sh_register_operand (operands[1], DFmode))"
7374   "@
7375         fmov.d  %1, %0
7376         fmov.qd %N1, %0
7377         fmov.dq %1, %0
7378         add     %1, r63, %0
7379         #
7380         fld%M1.d        %m1, %0
7381         fst%M0.d        %m0, %1
7382         ld%M1.q %m1, %0
7383         st%M0.q %m0, %N1"
7384   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7385                      fload_media,fstore_media,load_media,store_media")])
7386
7387 (define_insn "movdf_media_nofpu"
7388   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7389         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7390   "TARGET_SHMEDIA
7391    && (register_operand (operands[0], DFmode)
7392        || sh_register_operand (operands[1], DFmode))"
7393   "@
7394         add     %1, r63, %0
7395         #
7396         ld%M1.q %m1, %0
7397         st%M0.q %m0, %N1"
7398   [(set_attr "type" "arith_media,*,load_media,store_media")])
7399
7400 (define_split
7401   [(set (match_operand:DF 0 "arith_reg_dest" "")
7402         (match_operand:DF 1 "immediate_operand" ""))]
7403   "TARGET_SHMEDIA && reload_completed"
7404   [(set (match_dup 3) (match_dup 2))]
7405 {
7406   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7407   long values[2];
7408   REAL_VALUE_TYPE value;
7409
7410   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7411   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7412
7413   if (HOST_BITS_PER_WIDE_INT >= 64)
7414     operands[2] = immed_double_const ((unsigned long) values[endian]
7415                                       | ((HOST_WIDE_INT) values[1 - endian]
7416                                          << 32), 0, DImode);
7417   else
7418     {
7419       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7420       operands[2] = immed_double_const (values[endian], values[1 - endian],
7421                                         DImode);
7422     }
7423
7424   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7425 })
7426
7427 ;; FIXME: This should be a define_insn_and_split.
7428 (define_insn "movdf_k"
7429   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7430         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7431   "TARGET_SH1
7432    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7433        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7434        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7435        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7436    && (arith_reg_operand (operands[0], DFmode)
7437        || arith_reg_operand (operands[1], DFmode))"
7438 {
7439   return output_movedouble (insn, operands, DFmode);
7440 }
7441   [(set_attr "length" "4")
7442    (set_attr "type" "move,pcload,load,store")])
7443
7444 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7445 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7446 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7447 ;; the d/m/c/X alternative, which is split later into single-precision
7448 ;; instructions.  And when not optimizing, no splits are done before fixing
7449 ;; up pcloads, so we need usable length information for that.
7450 (define_insn "movdf_i4"
7451   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7452         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
7453    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
7454    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
7455   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7456    && (arith_reg_operand (operands[0], DFmode)
7457        || arith_reg_operand (operands[1], DFmode))"
7458   {
7459     switch (which_alternative)
7460     {
7461     case 0:
7462       if (TARGET_FMOVD)
7463         return "fmov    %1,%0";
7464       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7465         return         "fmov    %R1,%R0"        "\n"
7466                "        fmov    %S1,%S0";
7467       else
7468         return         "fmov    %S1,%S0"        "\n"
7469                "        fmov    %R1,%R0";
7470     case 3:
7471     case 4:
7472       return "fmov.d    %1,%0";
7473     default:
7474       return "#";
7475     }
7476   }
7477   [(set_attr_alternative "length"
7478      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7479       (const_int 4)
7480       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7481       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7482       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7483       (const_int 4)
7484       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7485       ;; We can't use 4-byte push/pop on SHcompact, so we have to
7486       ;; increment or decrement r15 explicitly.
7487       (if_then_else
7488        (match_test "TARGET_SHCOMPACT")
7489        (const_int 10) (const_int 8))
7490       (if_then_else
7491        (match_test "TARGET_SHCOMPACT")
7492        (const_int 10) (const_int 8))])
7493    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7494    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7495    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7496                                            (const_string "double")
7497                                            (const_string "none")))])
7498
7499 ;; Moving DFmode between fp/general registers through memory
7500 ;; (the top of the stack) is faster than moving through fpul even for
7501 ;; little endian.  Because the type of an instruction is important for its
7502 ;; scheduling,  it is beneficial to split these operations, rather than
7503 ;; emitting them in one single chunk, even if this will expose a stack
7504 ;; use that will prevent scheduling of other stack accesses beyond this
7505 ;; instruction.
7506 (define_split
7507   [(set (match_operand:DF 0 "register_operand" "")
7508         (match_operand:DF 1 "register_operand" ""))
7509    (use (match_operand:PSI 2 "fpscr_operand" ""))
7510    (clobber (match_scratch:SI 3 "=X"))]
7511   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7512    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7513   [(const_int 0)]
7514 {
7515   rtx insn, tos;
7516
7517   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7518     {
7519       emit_move_insn (stack_pointer_rtx,
7520                       plus_constant (Pmode, stack_pointer_rtx, -8));
7521       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7522     }
7523   else
7524     tos = gen_tmp_stack_mem (DFmode,
7525                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7526   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
7527   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7528     add_reg_note (insn, REG_INC, stack_pointer_rtx);
7529   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7530     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7531   else
7532     tos = gen_tmp_stack_mem (DFmode,
7533                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7534   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
7535   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7536     emit_move_insn (stack_pointer_rtx,
7537                     plus_constant (Pmode, stack_pointer_rtx, 8));
7538   else
7539     add_reg_note (insn, REG_INC, stack_pointer_rtx);
7540   DONE;
7541 })
7542
7543 ;; local-alloc sometimes allocates scratch registers even when not required,
7544 ;; so we must be prepared to handle these.
7545
7546 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7547 (define_split
7548   [(set (match_operand:DF 0 "general_movdst_operand" "")
7549         (match_operand:DF 1 "general_movsrc_operand"  ""))
7550    (use (match_operand:PSI 2 "fpscr_operand" ""))
7551    (clobber (match_scratch:SI 3 ""))]
7552   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7553    && reload_completed
7554    && true_regnum (operands[0]) < 16
7555    && true_regnum (operands[1]) < 16"
7556   [(set (match_dup 0) (match_dup 1))]
7557 {
7558   /* If this was a reg <-> mem operation with base + index reg addressing,
7559      we have to handle this in a special way.  */
7560   rtx mem = operands[0];
7561   int store_p = 1;
7562   if (! memory_operand (mem, DFmode))
7563     {
7564       mem = operands[1];
7565       store_p = 0;
7566     }
7567   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7568     mem = SUBREG_REG (mem);
7569   if (MEM_P (mem))
7570     {
7571       rtx addr = XEXP (mem, 0);
7572       if (GET_CODE (addr) == PLUS
7573           && REG_P (XEXP (addr, 0))
7574           && REG_P (XEXP (addr, 1)))
7575         {
7576           int offset;
7577           rtx reg0 = gen_rtx_REG (Pmode, 0);
7578           rtx regop = operands[store_p], word0 ,word1;
7579
7580           if (GET_CODE (regop) == SUBREG)
7581             alter_subreg (&regop, true);
7582           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7583             offset = 2;
7584           else
7585             offset = 4;
7586           mem = copy_rtx (mem);
7587           PUT_MODE (mem, SImode);
7588           word0 = gen_rtx_SUBREG (SImode, regop, 0);
7589           alter_subreg (&word0, true);
7590           word1 = gen_rtx_SUBREG (SImode, regop, 4);
7591           alter_subreg (&word1, true);
7592           if (store_p || ! refers_to_regno_p (REGNO (word0),
7593                                               REGNO (word0) + 1, addr, 0))
7594             {
7595               emit_insn (store_p
7596                          ? gen_movsi_ie (mem, word0)
7597                          : gen_movsi_ie (word0, mem));
7598               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7599               mem = copy_rtx (mem);
7600               emit_insn (store_p
7601                          ? gen_movsi_ie (mem, word1)
7602                          : gen_movsi_ie (word1, mem));
7603               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7604             }
7605           else
7606             {
7607               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7608               emit_insn (gen_movsi_ie (word1, mem));
7609               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7610               mem = copy_rtx (mem);
7611               emit_insn (gen_movsi_ie (word0, mem));
7612             }
7613           DONE;
7614         }
7615     }
7616 })
7617
7618 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7619 (define_split
7620   [(set (match_operand:DF 0 "register_operand" "")
7621         (match_operand:DF 1 "memory_operand"  ""))
7622    (use (match_operand:PSI 2 "fpscr_operand" ""))
7623    (clobber (reg:SI R0_REG))]
7624   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7625   [(parallel [(set (match_dup 0) (match_dup 1))
7626               (use (match_dup 2))
7627               (clobber (scratch:SI))])]
7628   "")
7629
7630 (define_expand "reload_indf__frn"
7631   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7632                    (match_operand:DF 1 "immediate_operand" "FQ"))
7633               (use (reg:PSI FPSCR_REG))
7634               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7635   "TARGET_SH1"
7636   "")
7637
7638 (define_expand "reload_outdf__RnFRm"
7639   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7640                    (match_operand:DF 1 "register_operand" "af,r"))
7641               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7642   "TARGET_SH1"
7643   "")
7644
7645 ;; Simplify no-op moves.
7646 (define_split
7647   [(set (match_operand:SF 0 "register_operand" "")
7648         (match_operand:SF 1 "register_operand" ""))
7649    (use (match_operand:PSI 2 "fpscr_operand" ""))
7650    (clobber (match_scratch:SI 3 ""))]
7651   "TARGET_SH2E && reload_completed
7652    && true_regnum (operands[0]) == true_regnum (operands[1])"
7653   [(set (match_dup 0) (match_dup 0))]
7654   "")
7655
7656 ;; fmovd substitute post-reload splits
7657 (define_split
7658   [(set (match_operand:DF 0 "register_operand" "")
7659         (match_operand:DF 1 "register_operand" ""))
7660    (use (match_operand:PSI 2 "fpscr_operand" ""))
7661    (clobber (match_scratch:SI 3 ""))]
7662   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7663    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7664    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7665   [(const_int 0)]
7666 {
7667   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7668   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7669                            gen_rtx_REG (SFmode, src), operands[2]));
7670   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7671                            gen_rtx_REG (SFmode, src + 1), operands[2]));
7672   DONE;
7673 })
7674
7675 (define_split
7676   [(set (match_operand:DF 0 "register_operand" "")
7677         (mem:DF (match_operand:SI 1 "register_operand" "")))
7678    (use (match_operand:PSI 2 "fpscr_operand" ""))
7679    (clobber (match_scratch:SI 3 ""))]
7680   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7681    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7682    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7683   [(const_int 0)]
7684 {
7685   int regno = true_regnum (operands[0]);
7686   rtx insn;
7687   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7688   rtx mem2
7689     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7690   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7691                                            regno + !! TARGET_LITTLE_ENDIAN),
7692                                   mem2, operands[2]));
7693   add_reg_note (insn, REG_INC, operands[1]);
7694   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7695                                                regno + ! TARGET_LITTLE_ENDIAN),
7696                                   change_address (mem, SFmode, NULL_RTX),
7697                                   operands[2]));
7698   DONE;
7699 })
7700
7701 (define_split
7702   [(set (match_operand:DF 0 "register_operand" "")
7703         (match_operand:DF 1 "memory_operand" ""))
7704    (use (match_operand:PSI 2 "fpscr_operand" ""))
7705    (clobber (match_scratch:SI 3 ""))]
7706   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7707    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7708   [(const_int 0)]
7709 {
7710   int regno = true_regnum (operands[0]);
7711   rtx addr, insn;
7712   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7713   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7714   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7715
7716   operands[1] = copy_rtx (mem2);
7717   addr = XEXP (mem2, 0);
7718
7719   switch (GET_CODE (addr))
7720     {
7721     case REG:
7722       /* This is complicated.  If the register is an arithmetic register
7723          we can just fall through to the REG+DISP case below.  Otherwise
7724          we have to use a combination of POST_INC and REG addressing...  */
7725       if (! arith_reg_operand (operands[1], SFmode))
7726         {
7727           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7728           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
7729           add_reg_note (insn, REG_INC, XEXP (addr, 0));
7730           
7731           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7732
7733           /* If we have modified the stack pointer, the value that we have
7734              read with post-increment might be modified by an interrupt,
7735              so write it back.  */
7736           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7737             emit_insn (gen_push_e (reg0));
7738           else
7739             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
7740                                    GEN_INT (-4)));
7741           break;
7742         }
7743       /* Fall through.  */
7744
7745     case PLUS:
7746       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7747       operands[1] = copy_rtx (operands[1]);
7748       XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7749       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7750       break;
7751
7752     case POST_INC:
7753       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7754       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7755
7756       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7757       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7758       break;
7759
7760     default:
7761       debug_rtx (addr);
7762       gcc_unreachable ();
7763     }
7764
7765   DONE;
7766 })
7767
7768 (define_split
7769   [(set (match_operand:DF 0 "memory_operand" "")
7770         (match_operand:DF 1 "register_operand" ""))
7771    (use (match_operand:PSI 2 "fpscr_operand" ""))
7772    (clobber (match_scratch:SI 3 ""))]
7773   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7774    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7775   [(const_int 0)]
7776 {
7777   int regno = true_regnum (operands[1]);
7778   rtx insn, addr;
7779   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7780   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7781
7782   operands[0] = copy_rtx (operands[0]);
7783   PUT_MODE (operands[0], SFmode);
7784   addr = XEXP (operands[0], 0);
7785
7786   switch (GET_CODE (addr))
7787     {
7788     case REG:
7789       /* This is complicated.  If the register is an arithmetic register
7790          we can just fall through to the REG+DISP case below.  Otherwise
7791          we have to use a combination of REG and PRE_DEC addressing...  */
7792       if (! arith_reg_operand (operands[0], SFmode))
7793         {
7794           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7795           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7796
7797           operands[0] = copy_rtx (operands[0]);
7798           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7799           
7800           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7801           add_reg_note (insn, REG_INC, XEXP (addr, 0));
7802           break;
7803         }
7804       /* Fall through.  */
7805
7806     case PLUS:
7807       /* Since REG+DISP addressing has already been decided upon by gcc
7808          we can rely upon it having chosen an arithmetic register as the
7809          register component of the address.  Just emit the lower numbered
7810          register first, to the lower address, then the higher numbered
7811          register to the higher address.  */
7812       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7813
7814       operands[0] = copy_rtx (operands[0]);
7815       XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
7816
7817       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7818       break;
7819
7820     case PRE_DEC:
7821       /* This is easy.  Output the word to go to the higher address
7822          first (ie the word in the higher numbered register) then the
7823          word to go to the lower address.  */
7824
7825       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7826       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7827
7828       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7829       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7830       break;
7831
7832     default:
7833       /* FAIL; */
7834       debug_rtx (addr);
7835       gcc_unreachable ();
7836     }
7837
7838   DONE;
7839 })
7840
7841 ;; If the output is a register and the input is memory or a register, we have
7842 ;; to be careful and see which word needs to be loaded first.
7843 (define_split
7844   [(set (match_operand:DF 0 "general_movdst_operand" "")
7845         (match_operand:DF 1 "general_movsrc_operand" ""))]
7846   "TARGET_SH1 && reload_completed"
7847   [(set (match_dup 2) (match_dup 3))
7848    (set (match_dup 4) (match_dup 5))]
7849 {
7850   int regno;
7851
7852   if ((MEM_P (operands[0])
7853        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7854       || (MEM_P (operands[1])
7855           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7856     FAIL;
7857
7858   switch (GET_CODE (operands[0]))
7859     {
7860     case REG:
7861       regno = REGNO (operands[0]);
7862       break;
7863     case SUBREG:
7864       regno = subreg_regno (operands[0]);
7865       break;
7866     case MEM:
7867       regno = -1;
7868       break;
7869     default:
7870       gcc_unreachable ();
7871     }
7872
7873   if (regno == -1
7874       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7875     {
7876       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
7877       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
7878       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
7879       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
7880     }
7881   else
7882     {
7883       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
7884       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
7885       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
7886       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
7887     }
7888
7889   if (operands[2] == 0 || operands[3] == 0
7890       || operands[4] == 0 || operands[5] == 0)
7891     FAIL;
7892 })
7893
7894 (define_expand "movdf"
7895   [(set (match_operand:DF 0 "general_movdst_operand" "")
7896         (match_operand:DF 1 "general_movsrc_operand" ""))]
7897   ""
7898 {
7899   prepare_move_operands (operands, DFmode);
7900   if (TARGET_SHMEDIA)
7901     {
7902       if (TARGET_SHMEDIA_FPU)
7903         emit_insn (gen_movdf_media (operands[0], operands[1]));
7904       else
7905         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
7906       DONE;
7907     }
7908   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
7909     {
7910       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7911       DONE;
7912     }
7913 })
7914
7915 ;;This is incompatible with the way gcc uses subregs.
7916 ;;(define_insn "movv2sf_i"
7917 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
7918 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
7919 ;;  "TARGET_SHMEDIA_FPU
7920 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
7921 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
7922 ;;  "@
7923 ;;      #
7924 ;;      fld%M1.p        %m1, %0
7925 ;;      fst%M0.p        %m0, %1"
7926 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
7927 (define_insn_and_split "movv2sf_i"
7928   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7929         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7930   "TARGET_SHMEDIA_FPU"
7931   "#"
7932   "TARGET_SHMEDIA_FPU && reload_completed"
7933   [(set (match_dup 0) (match_dup 1))]
7934 {
7935   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
7936   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
7937 })
7938
7939 (define_expand "movv2sf"
7940   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
7941         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
7942   "TARGET_SHMEDIA_FPU"
7943 {
7944   prepare_move_operands (operands, V2SFmode);
7945 })
7946
7947 (define_expand "addv2sf3"
7948   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7949    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7950    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7951   "TARGET_SHMEDIA_FPU"
7952 {
7953   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
7954   DONE;
7955 })
7956
7957 (define_expand "subv2sf3"
7958   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7959    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7960    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7961   "TARGET_SHMEDIA_FPU"
7962 {
7963   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
7964   DONE;
7965 })
7966
7967 (define_expand "mulv2sf3"
7968   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7969    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7970    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7971   "TARGET_SHMEDIA_FPU"
7972 {
7973   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
7974   DONE;
7975 })
7976
7977 (define_expand "divv2sf3"
7978   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7979    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7980    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7981   "TARGET_SHMEDIA_FPU"
7982 {
7983   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
7984   DONE;
7985 })
7986
7987 (define_insn_and_split "*movv4sf_i"
7988   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7989         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7990   "TARGET_SHMEDIA_FPU"
7991   "#"
7992   "&& reload_completed"
7993   [(const_int 0)]
7994 {
7995   for (int i = 0; i < 4/2; i++)
7996     {
7997       rtx x, y;
7998
7999       if (MEM_P (operands[0]))
8000         x = adjust_address (operands[0], V2SFmode,
8001                             i * GET_MODE_SIZE (V2SFmode));
8002       else
8003         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8004
8005       if (MEM_P (operands[1]))
8006         y = adjust_address (operands[1], V2SFmode,
8007                             i * GET_MODE_SIZE (V2SFmode));
8008       else
8009         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8010
8011       emit_insn (gen_movv2sf_i (x, y));
8012     }
8013
8014   DONE;
8015 }
8016   [(set_attr "length" "8")])
8017
8018 (define_expand "movv4sf"
8019   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8020         (match_operand:V4SF 1 "general_operand" ""))]
8021   "TARGET_SHMEDIA_FPU"
8022 {
8023   prepare_move_operands (operands, V4SFmode);
8024 })
8025
8026 (define_insn_and_split "*movv16sf_i"
8027   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8028         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8029   "TARGET_SHMEDIA_FPU"
8030   "#"
8031   "&& reload_completed"
8032   [(const_int 0)]
8033 {
8034   for (int i = 0; i < 16/2; i++)
8035     {
8036       rtx x, y;
8037
8038       if (MEM_P (operands[0]))
8039         x = adjust_address (operands[0], V2SFmode,
8040                             i * GET_MODE_SIZE (V2SFmode));
8041       else
8042         {
8043           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8044           alter_subreg (&x, true);
8045         }
8046
8047       if (MEM_P (operands[1]))
8048         y = adjust_address (operands[1], V2SFmode,
8049                             i * GET_MODE_SIZE (V2SFmode));
8050       else
8051         {
8052           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8053           alter_subreg (&y, true);
8054         }
8055
8056       emit_insn (gen_movv2sf_i (x, y));
8057     }
8058
8059   DONE;
8060 }
8061   [(set_attr "length" "32")])
8062
8063 (define_expand "movv16sf"
8064   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8065         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8066   "TARGET_SHMEDIA_FPU"
8067 {
8068   prepare_move_operands (operands, V16SFmode);
8069 })
8070
8071 (define_insn "movsf_media"
8072   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8073         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8074   "TARGET_SHMEDIA_FPU
8075    && (register_operand (operands[0], SFmode)
8076        || sh_register_operand (operands[1], SFmode))"
8077   "@
8078         fmov.s  %1, %0
8079         fmov.ls %N1, %0
8080         fmov.sl %1, %0
8081         add.l   %1, r63, %0
8082         #
8083         fld%M1.s        %m1, %0
8084         fst%M0.s        %m0, %1
8085         ld%M1.l %m1, %0
8086         st%M0.l %m0, %N1"
8087   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8088    (set (attr "highpart")
8089         (cond [(match_test "sh_contains_memref_p (insn)")
8090                (const_string "user")]
8091               (const_string "ignore")))])
8092
8093 (define_insn "movsf_media_nofpu"
8094   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8095         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8096   "TARGET_SHMEDIA
8097    && (register_operand (operands[0], SFmode)
8098        || sh_register_operand (operands[1], SFmode))"
8099   "@
8100         add.l   %1, r63, %0
8101         #
8102         ld%M1.l %m1, %0
8103         st%M0.l %m0, %N1"
8104   [(set_attr "type" "arith_media,*,load_media,store_media")
8105    (set (attr "highpart")
8106         (cond [(match_test "sh_contains_memref_p (insn)")
8107                (const_string "user")]
8108               (const_string "ignore")))])
8109
8110 (define_split
8111   [(set (match_operand:SF 0 "arith_reg_dest" "")
8112         (match_operand:SF 1 "immediate_operand" ""))]
8113   "TARGET_SHMEDIA && reload_completed
8114    && ! FP_REGISTER_P (true_regnum (operands[0]))"
8115   [(set (match_dup 3) (match_dup 2))]
8116 {
8117   long values;
8118   REAL_VALUE_TYPE value;
8119
8120   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8121   REAL_VALUE_TO_TARGET_SINGLE (value, values);
8122   operands[2] = GEN_INT (values);
8123
8124   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8125 })
8126
8127 (define_insn "movsf_i"
8128   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8129         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
8130   "TARGET_SH1
8131    && (! TARGET_SH2E
8132        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8133        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8134        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8135    && (arith_reg_operand (operands[0], SFmode)
8136        || arith_reg_operand (operands[1], SFmode))"
8137   "@
8138         mov     %1,%0
8139         mov     #0,%0
8140         mov.l   %1,%0
8141         mov.l   %1,%0
8142         mov.l   %1,%0
8143         lds     %1,%0
8144         sts     %1,%0"
8145   [(set_attr "type" "move,move,pcload,load,store,move,move")])
8146
8147 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8148 ;; update_flow_info would not know where to put REG_EQUAL notes
8149 ;; when the destination changes mode.
8150 (define_insn "movsf_ie"
8151   [(set (match_operand:SF 0 "general_movdst_operand"
8152          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8153         (match_operand:SF 1 "general_movsrc_operand"
8154           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8155    (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"))
8156    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8157   "TARGET_SH2E
8158    && (arith_reg_operand (operands[0], SFmode)
8159        || arith_reg_operand (operands[1], SFmode)
8160        || arith_reg_operand (operands[3], SImode)
8161        || (fpul_operand (operands[0], SFmode)
8162            && memory_operand (operands[1], SFmode)
8163            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
8164        || (fpul_operand (operands[1], SFmode)
8165            && memory_operand (operands[0], SFmode)
8166            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
8167   "@
8168         fmov    %1,%0
8169         mov     %1,%0
8170         fldi0   %0
8171         fldi1   %0
8172         #
8173         fmov.s  %1,%0
8174         fmov.s  %1,%0
8175         mov.l   %1,%0
8176         mov.l   %1,%0
8177         mov.l   %1,%0
8178         fsts    fpul,%0
8179         flds    %1,fpul
8180         lds.l   %1,%0
8181         #
8182         sts     %1,%0
8183         lds     %1,%0
8184         sts.l   %1,%0
8185         lds.l   %1,%0
8186         ! move optimized away"
8187   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8188                      store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8189    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8190    (set_attr_alternative "length"
8191      [(const_int 2)
8192       (const_int 2)
8193       (const_int 2)
8194       (const_int 2)
8195       (const_int 4)
8196       (if_then_else
8197         (match_test "TARGET_SH2A")
8198         (const_int 4) (const_int 2))
8199       (if_then_else
8200         (match_test "TARGET_SH2A")
8201         (const_int 4) (const_int 2))
8202       (const_int 2)
8203       (if_then_else
8204         (match_test "TARGET_SH2A")
8205         (const_int 4) (const_int 2))
8206       (if_then_else
8207         (match_test "TARGET_SH2A")
8208         (const_int 4) (const_int 2))
8209       (const_int 2)
8210       (const_int 2)
8211       (const_int 2)
8212       (const_int 4)
8213       (const_int 2)
8214       (const_int 2)
8215       (const_int 2)
8216       (const_int 2)
8217       (const_int 0)])
8218    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8219                                            (const_string "single")
8220                                            (const_string "single")))])
8221
8222 (define_split
8223   [(set (match_operand:SF 0 "register_operand" "")
8224         (match_operand:SF 1 "register_operand" ""))
8225    (use (match_operand:PSI 2 "fpscr_operand" ""))
8226    (clobber (reg:SI FPUL_REG))]
8227   "TARGET_SH1"
8228   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8229               (use (match_dup 2))
8230               (clobber (scratch:SI))])
8231    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8232               (use (match_dup 2))
8233               (clobber (scratch:SI))])]
8234   "")
8235
8236 (define_expand "movsf"
8237   [(set (match_operand:SF 0 "general_movdst_operand" "")
8238         (match_operand:SF 1 "general_movsrc_operand" ""))]
8239   ""
8240 {
8241   prepare_move_operands (operands, SFmode);
8242   if (TARGET_SHMEDIA)
8243     {
8244       if (TARGET_SHMEDIA_FPU)
8245         emit_insn (gen_movsf_media (operands[0], operands[1]));
8246       else
8247         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8248       DONE;
8249     }
8250   if (TARGET_SH2E)
8251     {
8252       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
8253       DONE;
8254     }
8255 })
8256
8257 (define_insn "mov_nop"
8258   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8259   "TARGET_SH2E"
8260   ""
8261   [(set_attr "length" "0")
8262    (set_attr "type" "nil")])
8263
8264 (define_expand "reload_insf__frn"
8265   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8266                    (match_operand:SF 1 "immediate_operand" "FQ"))
8267               (use (reg:PSI FPSCR_REG))
8268               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8269   "TARGET_SH1"
8270   "")
8271
8272 (define_expand "reload_insi__i_fpul"
8273   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8274                    (match_operand:SI 1 "immediate_operand" "i"))
8275               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8276   "TARGET_SH1"
8277   "")
8278
8279 (define_expand "ptabs"
8280   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8281   "TARGET_SHMEDIA"
8282 {
8283   if (!TARGET_PT_FIXED)
8284     {
8285       rtx eq = operands[1];
8286
8287       /* ??? For canonical RTL we really should remove any CONST from EQ
8288          before wrapping it in the AND, and finally wrap the EQ into a
8289          const if is constant.  However, for reload we must expose the
8290          input register or symbolic constant, and we can't have
8291          different insn structures outside of the operands for different
8292          alternatives of the same pattern.  */
8293       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8294                        GEN_INT (3));
8295       operands[1]
8296         = (gen_rtx_IF_THEN_ELSE
8297             (PDImode,
8298              eq,
8299              gen_rtx_MEM (PDImode, operands[1]),
8300              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8301                             PDImode, operands[1])));
8302     }
8303 })
8304
8305 ;; expanded by ptabs expander.
8306 (define_insn "*extendsipdi_media"
8307   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8308         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8309                                                           "r,Csy")
8310                                       (const_int 3))
8311                               (const_int 3))
8312                           (mem:PDI (match_dup 1))
8313                           (sign_extend:PDI (match_dup 1))))]
8314   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8315   "@
8316         ptabs   %1, %0
8317         pt      %1, %0"
8318   [(set_attr "type"   "ptabs_media,pt_media")
8319    (set_attr "length" "4,*")])
8320
8321 (define_insn "*truncdipdi_media"
8322   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8323         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8324                                                           "r,Csy")
8325                                       (const_int 3))
8326                               (const_int 3))
8327                           (mem:PDI (match_dup 1))
8328                           (truncate:PDI (match_dup 1))))]
8329   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8330   "@
8331         ptabs   %1, %0
8332         pt      %1, %0"
8333   [(set_attr "type"   "ptabs_media,pt_media")
8334    (set_attr "length" "4,*")])
8335
8336 (define_insn "*movsi_y"
8337   [(set (match_operand:SI 0 "register_operand" "=y,y")
8338         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8339    (clobber (match_scratch:SI 2 "=&z,r"))]
8340   "TARGET_SH2E
8341    && (reload_in_progress || reload_completed)"
8342   "#"
8343   [(set_attr "length" "4")
8344    (set_attr "type" "pcload,move")])
8345
8346 (define_split
8347   [(set (match_operand:SI 0 "register_operand" "")
8348         (match_operand:SI 1 "immediate_operand" ""))
8349    (clobber (match_operand:SI 2 "register_operand" ""))]
8350   "TARGET_SH1"
8351   [(set (match_dup 2) (match_dup 1))
8352    (set (match_dup 0) (match_dup 2))]
8353   "")
8354 \f
8355 ;; ------------------------------------------------------------------------
8356 ;; Define the real conditional branch instructions.
8357 ;; ------------------------------------------------------------------------
8358
8359 (define_expand "branch_true"
8360   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8361                            (label_ref (match_operand 0))
8362                            (pc)))]
8363   "TARGET_SH1")
8364
8365 (define_expand "branch_false"
8366   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8367                            (label_ref (match_operand 0))
8368                            (pc)))]
8369   "TARGET_SH1")
8370
8371 (define_insn_and_split "*cbranch_t"
8372   [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8373                            (label_ref (match_operand 0))
8374                            (pc)))]
8375   "TARGET_SH1"
8376 {
8377   return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8378 }
8379   "&& 1"
8380   [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
8381                            (label_ref (match_dup 0))
8382                            (pc)))]
8383 {
8384   /* Try to find missed test and branch combine opportunities which result
8385      in redundant T bit tests before conditional branches.
8386      This is done not only after combine (and before reload) but in every
8387      split pass, because some opportunities are formed also after combine.
8388      FIXME: Probably this would not be needed if CCmode was used
8389      together with TARGET_FIXED_CONDITION_CODE_REGS.  */
8390
8391   const int treg_value = sh_eval_treg_value (operands[1]);
8392   operands[2] = NULL_RTX;
8393
8394   /* Scan the insns backwards for an insn that sets the T bit by testing a
8395      reg against zero like:
8396         (set (reg T_REG) (eq (reg) (const_int 0)))  */
8397   rtx testing_insn = NULL_RTX;
8398   rtx tested_reg = NULL_RTX;
8399
8400   set_of_reg s0 = sh_find_set_of_reg (get_t_reg_rtx (), curr_insn,
8401                                       prev_nonnote_insn_bb);
8402   if (s0.set_src != NULL_RTX
8403       && GET_CODE (s0.set_src) == EQ
8404       && REG_P (XEXP (s0.set_src, 0))
8405       && satisfies_constraint_Z (XEXP (s0.set_src, 1)))
8406     {
8407       testing_insn = s0.insn;
8408       tested_reg = XEXP (s0.set_src, 0);
8409     }
8410   else
8411     FAIL;
8412
8413   /* Continue scanning the insns backwards and try to find the insn that
8414      sets the tested reg which we found above.  If the reg is set by storing
8415      the T bit or the negated T bit we can eliminate the test insn before
8416      the branch.  Notice that the branch condition has to be inverted if the
8417      test is eliminated.  */
8418
8419   /* If the T bit is used between the testing insn and the brach insn
8420      leave it alone.  */
8421   if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
8422     FAIL;
8423
8424   while (true)
8425     {
8426       /* It's not safe to go beyond the current basic block after reload.  */
8427       set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
8428                                           reload_completed
8429                                           ? prev_nonnote_insn_bb
8430                                           : prev_nonnote_insn);
8431       if (s1.set_src == NULL_RTX)
8432         break;
8433
8434       if (t_reg_operand (s1.set_src, VOIDmode))
8435         operands[2] = GEN_INT (treg_value ^ 1);
8436       else if (negt_reg_operand (s1.set_src, VOIDmode))
8437         operands[2] = GEN_INT (treg_value);
8438       else if (REG_P (s1.set_src))
8439         {
8440            /* If it's a reg-reg copy follow the copied reg.  This can
8441               happen e.g. when T bit store zero-extensions are
8442               eliminated.  */
8443           tested_reg = s1.set_src;
8444           s0.insn = s1.insn;
8445           continue;
8446         }
8447
8448         /* It's only safe to remove the testing insn if the T bit is not
8449            modified between the testing insn and the insn that stores the
8450            T bit.  Notice that some T bit stores such as negc also modify
8451            the T bit.  */
8452         if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
8453             || modified_in_p (get_t_reg_rtx (), s1.insn))
8454           operands[2] = NULL_RTX;
8455
8456         break;
8457     }
8458
8459   if (operands[2] == NULL_RTX)
8460     FAIL;
8461
8462   set_insn_deleted (testing_insn);
8463 }
8464   [(set_attr "type" "cbranch")])
8465
8466 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8467 ;; which destination is too far away.
8468 ;; The const_int_operand is distinct for each branch target; it avoids
8469 ;; unwanted matches with redundant_insn.
8470 (define_insn "block_branch_redirect"
8471   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8472   "TARGET_SH1"
8473   ""
8474   [(set_attr "length" "0")])
8475
8476 ;; This one has the additional purpose to record a possible scratch register
8477 ;; for the following branch.
8478 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8479 ;; because the insn then might be deemed dead and deleted.  And we can't
8480 ;; make the use in the jump insn explicit because that would disable
8481 ;; delay slot scheduling from the target.
8482 (define_insn "indirect_jump_scratch"
8483   [(set (match_operand:SI 0 "register_operand" "=r")
8484         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8485    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8486   "TARGET_SH1"
8487   ""
8488   [(set_attr "length" "0")])
8489
8490 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8491 ;; being pulled into the delay slot of a condbranch that has been made to
8492 ;; jump around the unconditional jump because it was out of range.
8493 (define_insn "stuff_delay_slot"
8494   [(set (pc)
8495         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8496                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8497   "TARGET_SH1"
8498   ""
8499   [(set_attr "length" "0")
8500    (set_attr "cond_delay_slot" "yes")])
8501 \f
8502 ;; Conditional branch insns
8503
8504 (define_expand "cbranchint4_media"
8505   [(set (pc)
8506         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8507                        [(match_operand 1 "" "")
8508                         (match_operand 2 "" "")])
8509                       (match_operand 3 "" "")
8510                       (pc)))]
8511   "TARGET_SHMEDIA"
8512 {
8513   enum machine_mode mode = GET_MODE (operands[1]);
8514   if (mode == VOIDmode)
8515     mode = GET_MODE (operands[2]);
8516   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8517     {
8518       operands[1] = force_reg (mode, operands[1]);
8519       if (CONSTANT_P (operands[2])
8520           && (! satisfies_constraint_I06 (operands[2])))
8521         operands[2] = force_reg (mode, operands[2]);
8522     }
8523   else
8524     {
8525       if (operands[1] != const0_rtx)
8526         operands[1] = force_reg (mode, operands[1]);
8527       if (operands[2] != const0_rtx)
8528         operands[2] = force_reg (mode, operands[2]);
8529     }
8530   switch (GET_CODE (operands[0]))
8531     {
8532     case LEU:
8533     case LE:
8534     case LTU:
8535     case LT:
8536       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8537                                     VOIDmode, operands[2], operands[1]);
8538       operands[1] = XEXP (operands[0], 0);
8539       operands[2] = XEXP (operands[0], 1);
8540       break;
8541     default:
8542       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8543                                     VOIDmode, operands[1], operands[2]);
8544       break;
8545     }
8546   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8547 })
8548
8549 (define_expand "cbranchfp4_media"
8550   [(set (pc)
8551         (if_then_else (match_operator 0 "sh_float_comparison_operator"
8552                        [(match_operand 1 "" "")
8553                         (match_operand 2 "" "")])
8554                       (match_operand 3 "" "")
8555                       (pc)))]
8556   "TARGET_SHMEDIA"
8557 {
8558   rtx tmp = gen_reg_rtx (SImode);
8559   rtx cmp;
8560   if (GET_CODE (operands[0]) == NE)
8561     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8562   else
8563     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8564                           operands[1], operands[2]);
8565
8566   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8567
8568   if (GET_CODE (cmp) == GET_CODE (operands[0]))
8569     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8570   else
8571     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8572   operands[1] = tmp;
8573   operands[2] = const0_rtx;
8574   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8575 })
8576
8577 (define_insn "*beq_media_i"
8578   [(set (pc)
8579         (if_then_else (match_operator 3 "equality_comparison_operator"
8580                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
8581                          (match_operand:DI 2 "arith_operand" "r,I06")])
8582                       (match_operand 0 "target_operand" "b,b")
8583                       (pc)))]
8584   "TARGET_SHMEDIA"
8585   "@
8586         b%o3%'  %1, %2, %0%>
8587         b%o3i%' %1, %2, %0%>"
8588   [(set_attr "type" "cbranch_media")])
8589
8590 (define_insn "*beq_media_i32"
8591   [(set (pc)
8592         (if_then_else (match_operator 3 "equality_comparison_operator"
8593                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
8594                          (match_operand:SI 2 "arith_operand" "r,I06")])
8595                       (match_operand 0 "target_operand" "b,b")
8596                       (pc)))]
8597   "TARGET_SHMEDIA"
8598   "@
8599         b%o3%'  %1, %2, %0%>
8600         b%o3i%' %1, %2, %0%>"
8601   [(set_attr "type" "cbranch_media")])
8602
8603 (define_insn "*bgt_media_i"
8604   [(set (pc)
8605         (if_then_else (match_operator 3 "greater_comparison_operator"
8606                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8607                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8608                       (match_operand 0 "target_operand" "b")
8609                       (pc)))]
8610   "TARGET_SHMEDIA"
8611   "b%o3%'       %N1, %N2, %0%>"
8612   [(set_attr "type" "cbranch_media")])
8613
8614 (define_insn "*bgt_media_i32"
8615   [(set (pc)
8616         (if_then_else (match_operator 3 "greater_comparison_operator"
8617                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8618                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8619                       (match_operand 0 "target_operand" "b")
8620                       (pc)))]
8621   "TARGET_SHMEDIA"
8622   "b%o3%'       %N1, %N2, %0%>"
8623   [(set_attr "type" "cbranch_media")])
8624
8625 ;; These are only needed to make invert_jump() happy - otherwise, jump
8626 ;; optimization will be silently disabled.
8627 (define_insn "*blt_media_i"
8628   [(set (pc)
8629         (if_then_else (match_operator 3 "less_comparison_operator"
8630                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8631                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8632                       (match_operand 0 "target_operand" "b")
8633                       (pc)))]
8634   "TARGET_SHMEDIA"
8635   "b%o3%'       %N2, %N1, %0%>"
8636   [(set_attr "type" "cbranch_media")])
8637
8638 (define_insn "*blt_media_i32"
8639   [(set (pc)
8640         (if_then_else (match_operator 3 "less_comparison_operator"
8641                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8642                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8643                       (match_operand 0 "target_operand" "b")
8644                       (pc)))]
8645   "TARGET_SHMEDIA"
8646   "b%o3%'       %N2, %N1, %0%>"
8647   [(set_attr "type" "cbranch_media")])
8648
8649 ;; combiner splitter for test-and-branch on single bit in register.  This
8650 ;; is endian dependent because the non-paradoxical subreg looks different
8651 ;; on big endian.
8652 (define_split
8653   [(set (pc)
8654         (if_then_else
8655           (match_operator 3 "equality_comparison_operator"
8656             [(subreg:SI
8657                (zero_extract:DI
8658                  (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
8659                  (const_int 1)
8660                  (match_operand 2 "const_int_operand" "")) 0)
8661              (const_int 0)])
8662           (match_operand 0 "target_operand" "")
8663           (pc)))
8664    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8665   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8666   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8667    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8668 {
8669   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8670   operands[6] = (GET_CODE (operands[3]) == EQ
8671                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8672                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8673 })
8674
8675 ; operand 0 is the loop count pseudo register
8676 ; operand 1 is the number of loop iterations or 0 if it is unknown
8677 ; operand 2 is the maximum number of loop iterations
8678 ; operand 3 is the number of levels of enclosed loops
8679 ; operand 4 is the label to jump to at the top of the loop
8680 (define_expand "doloop_end"
8681   [(parallel [(set (pc)
8682                    (if_then_else (ne:SI (match_operand:SI 0 "" "")
8683                                         (const_int 1))
8684                                  (label_ref (match_operand 4 "" ""))
8685                                  (pc)))
8686               (set (match_dup 0)
8687                    (plus:SI (match_dup 0) (const_int -1)))
8688               (clobber (reg:SI T_REG))])
8689    (match_operand 5 "" "")]
8690   "TARGET_SH2"
8691 {
8692   if (GET_MODE (operands[0]) != SImode)
8693     FAIL;
8694   emit_jump_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
8695   DONE;
8696 })
8697
8698 (define_insn_and_split "doloop_end_split"
8699   [(set (pc)
8700         (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8701                              (const_int 1))
8702                       (label_ref (match_operand 1 "" ""))
8703                       (pc)))
8704    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8705         (plus (match_dup 2) (const_int -1)))
8706    (clobber (reg:SI T_REG))]
8707   "TARGET_SH2"
8708   "#"
8709   ""
8710   [(parallel [(set (reg:SI T_REG)
8711                    (eq:SI (match_dup 2) (const_int 1)))
8712               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8713    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8714                            (label_ref (match_dup 1))
8715                            (pc)))]
8716   ""
8717   [(set_attr "type" "cbranch")])
8718 \f
8719 ;; ------------------------------------------------------------------------
8720 ;; Jump and linkage insns
8721 ;; ------------------------------------------------------------------------
8722
8723 (define_insn "jump_compact"
8724   [(set (pc)
8725         (label_ref (match_operand 0 "" "")))]
8726   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
8727 {
8728   /* The length is 16 if the delay slot is unfilled.  */
8729   if (get_attr_length(insn) > 4)
8730     return output_far_jump(insn, operands[0]);
8731   else
8732     return "bra %l0%#";
8733 }
8734   [(set_attr "type" "jump")
8735    (set_attr "needs_delay_slot" "yes")])
8736
8737 ;; ??? It would be much saner to explicitly use the scratch register
8738 ;; in the jump insn, and have indirect_jump_scratch only set it,
8739 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8740 ;; from the target then, as it uses simplejump_p.
8741 ;;(define_insn "jump_compact_far"
8742 ;;  [(set (pc)
8743 ;;      (label_ref (match_operand 0 "" "")))
8744 ;;   (use (match_operand 1 "register_operand" "r")]
8745 ;;  "TARGET_SH1"
8746 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
8747 ;;  [(set_attr "type" "jump")
8748 ;;   (set_attr "needs_delay_slot" "yes")])
8749
8750 (define_insn "jump_media"
8751   [(set (pc)
8752         (match_operand 0 "target_operand" "b"))]
8753   "TARGET_SHMEDIA"
8754   "blink        %0, r63%>"
8755   [(set_attr "type" "jump_media")])
8756
8757 (define_expand "jump"
8758   [(set (pc)
8759         (label_ref (match_operand 0 "" "")))]
8760   ""
8761 {
8762   if (TARGET_SH1)
8763     emit_jump_insn (gen_jump_compact (operands[0]));
8764   else if (TARGET_SHMEDIA)
8765     {
8766       if (reload_in_progress || reload_completed)
8767         FAIL;
8768       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
8769     }
8770   DONE;
8771 })
8772
8773 (define_insn "force_mode_for_call"
8774   [(use (reg:PSI FPSCR_REG))]
8775   "TARGET_SHCOMPACT"
8776   ""
8777   [(set_attr "length" "0")
8778    (set (attr "fp_mode")
8779         (if_then_else (eq_attr "fpu_single" "yes")
8780                       (const_string "single") (const_string "double")))])
8781
8782 (define_insn "calli"
8783   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8784          (match_operand 1 "" ""))
8785    (use (reg:PSI FPSCR_REG))
8786    (clobber (reg:SI PR_REG))]
8787   "TARGET_SH1"
8788 {
8789   if (TARGET_SH2A && (dbr_sequence_length () == 0))
8790     return "jsr/n       @%0";
8791   else
8792     return "jsr @%0%#";
8793 }
8794   [(set_attr "type" "call")
8795    (set (attr "fp_mode")
8796         (if_then_else (eq_attr "fpu_single" "yes")
8797                       (const_string "single") (const_string "double")))
8798    (set_attr "needs_delay_slot" "yes")
8799    (set_attr "fp_set" "unknown")])
8800
8801 ;; This is TBR relative jump instruction for SH2A architecture.
8802 ;; Its use is enabled by assigning an attribute "function_vector"
8803 ;; and the vector number to a function during its declaration.
8804 (define_insn "calli_tbr_rel"
8805   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8806          (match_operand 1 "" ""))
8807    (use (reg:PSI FPSCR_REG))
8808    (clobber (reg:SI PR_REG))]
8809   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8810 {
8811   unsigned HOST_WIDE_INT vect_num;
8812   vect_num = sh2a_get_function_vector_number (operands[0]);
8813   operands[2] = GEN_INT (vect_num * 4);
8814
8815   return "jsr/n @@(%O2,tbr)";
8816 }
8817   [(set_attr "type" "call")
8818    (set (attr "fp_mode")
8819         (if_then_else (eq_attr "fpu_single" "yes")
8820                       (const_string "single") (const_string "double")))
8821    (set_attr "needs_delay_slot" "no")
8822    (set_attr "fp_set" "unknown")])
8823
8824 ;; This is a pc-rel call, using bsrf, for use with PIC.
8825 (define_insn "calli_pcrel"
8826   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8827          (match_operand 1 "" ""))
8828    (use (reg:PSI FPSCR_REG))
8829    (use (reg:SI PIC_REG))
8830    (use (match_operand 2 "" ""))
8831    (clobber (reg:SI PR_REG))]
8832   "TARGET_SH2"
8833 {
8834   return       "bsrf    %0"     "\n"
8835          "%O2:%#";
8836 }
8837   [(set_attr "type" "call")
8838    (set (attr "fp_mode")
8839         (if_then_else (eq_attr "fpu_single" "yes")
8840                       (const_string "single") (const_string "double")))
8841    (set_attr "needs_delay_slot" "yes")
8842    (set_attr "fp_set" "unknown")])
8843
8844 (define_insn_and_split "call_pcrel"
8845   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8846          (match_operand 1 "" ""))
8847    (use (reg:PSI FPSCR_REG))
8848    (use (reg:SI PIC_REG))
8849    (clobber (reg:SI PR_REG))
8850    (clobber (match_scratch:SI 2 "=r"))]
8851   "TARGET_SH2"
8852   "#"
8853   "reload_completed"
8854   [(const_int 0)]
8855 {
8856   rtx lab = PATTERN (gen_call_site ());
8857
8858   if (SYMBOL_REF_LOCAL_P (operands[0]))
8859     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8860   else
8861     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
8862   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
8863   DONE;
8864 }
8865   [(set_attr "type" "call")
8866    (set (attr "fp_mode")
8867         (if_then_else (eq_attr "fpu_single" "yes")
8868                       (const_string "single") (const_string "double")))
8869    (set_attr "needs_delay_slot" "yes")
8870    (set_attr "fp_set" "unknown")])
8871
8872 (define_insn "call_compact"
8873   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8874          (match_operand 1 "" ""))
8875    (match_operand 2 "immediate_operand" "n")
8876    (use (reg:SI R0_REG))
8877    (use (reg:SI R1_REG))
8878    (use (reg:PSI FPSCR_REG))
8879    (clobber (reg:SI PR_REG))]
8880   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8881   "jsr  @%0%#"
8882   [(set_attr "type" "call")
8883    (set (attr "fp_mode")
8884         (if_then_else (eq_attr "fpu_single" "yes")
8885                       (const_string "single") (const_string "double")))
8886    (set_attr "needs_delay_slot" "yes")])
8887
8888 (define_insn "call_compact_rettramp"
8889   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8890          (match_operand 1 "" ""))
8891    (match_operand 2 "immediate_operand" "n")
8892    (use (reg:SI R0_REG))
8893    (use (reg:SI R1_REG))
8894    (use (reg:PSI FPSCR_REG))
8895    (clobber (reg:SI R10_REG))
8896    (clobber (reg:SI PR_REG))]
8897   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8898   "jsr  @%0%#"
8899   [(set_attr "type" "call")
8900    (set (attr "fp_mode")
8901         (if_then_else (eq_attr "fpu_single" "yes")
8902                       (const_string "single") (const_string "double")))
8903    (set_attr "needs_delay_slot" "yes")])
8904
8905 (define_insn "call_media"
8906   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
8907          (match_operand 1 "" ""))
8908    (clobber (reg:DI PR_MEDIA_REG))]
8909   "TARGET_SHMEDIA"
8910   "blink        %0, r18"
8911   [(set_attr "type" "jump_media")])
8912
8913 (define_insn "call_valuei"
8914   [(set (match_operand 0 "" "=rf")
8915         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8916               (match_operand 2 "" "")))
8917    (use (reg:PSI FPSCR_REG))
8918    (clobber (reg:SI PR_REG))]
8919   "TARGET_SH1"
8920 {
8921   if (TARGET_SH2A && (dbr_sequence_length () == 0))
8922     return "jsr/n       @%1";
8923   else
8924     return "jsr @%1%#";
8925 }
8926   [(set_attr "type" "call")
8927    (set (attr "fp_mode")
8928         (if_then_else (eq_attr "fpu_single" "yes")
8929                       (const_string "single") (const_string "double")))
8930    (set_attr "needs_delay_slot" "yes")
8931    (set_attr "fp_set" "unknown")])
8932
8933 ;; This is TBR relative jump instruction for SH2A architecture.
8934 ;; Its use is enabled by assigning an attribute "function_vector"
8935 ;; and the vector number to a function during its declaration.
8936 (define_insn "call_valuei_tbr_rel"
8937   [(set (match_operand 0 "" "=rf")
8938         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8939               (match_operand 2 "" "")))
8940    (use (reg:PSI FPSCR_REG))
8941    (clobber (reg:SI PR_REG))]
8942   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
8943 {
8944   unsigned HOST_WIDE_INT vect_num;
8945   vect_num = sh2a_get_function_vector_number (operands[1]);
8946   operands[3] = GEN_INT (vect_num * 4);
8947
8948   return "jsr/n @@(%O3,tbr)";
8949 }
8950   [(set_attr "type" "call")
8951    (set (attr "fp_mode")
8952         (if_then_else (eq_attr "fpu_single" "yes")
8953                       (const_string "single") (const_string "double")))
8954    (set_attr "needs_delay_slot" "no")
8955    (set_attr "fp_set" "unknown")])
8956
8957 (define_insn "call_valuei_pcrel"
8958   [(set (match_operand 0 "" "=rf")
8959         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8960               (match_operand 2 "" "")))
8961    (use (reg:PSI FPSCR_REG))
8962    (use (reg:SI PIC_REG))
8963    (use (match_operand 3 "" ""))
8964    (clobber (reg:SI PR_REG))]
8965   "TARGET_SH2"
8966 {
8967   return       "bsrf    %1"     "\n"
8968          "%O3:%#";
8969 }
8970   [(set_attr "type" "call")
8971    (set (attr "fp_mode")
8972         (if_then_else (eq_attr "fpu_single" "yes")
8973                       (const_string "single") (const_string "double")))
8974    (set_attr "needs_delay_slot" "yes")
8975    (set_attr "fp_set" "unknown")])
8976
8977 (define_insn_and_split "call_value_pcrel"
8978   [(set (match_operand 0 "" "=rf")
8979         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8980               (match_operand 2 "" "")))
8981    (use (reg:PSI FPSCR_REG))
8982    (use (reg:SI PIC_REG))
8983    (clobber (reg:SI PR_REG))
8984    (clobber (match_scratch:SI 3 "=r"))]
8985   "TARGET_SH2"
8986   "#"
8987   "reload_completed"
8988   [(const_int 0)]
8989 {
8990   rtx lab = PATTERN (gen_call_site ());
8991
8992   if (SYMBOL_REF_LOCAL_P (operands[1]))
8993     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8994   else
8995     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
8996   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
8997                                          operands[2], copy_rtx (lab)));
8998   DONE;
8999 }
9000   [(set_attr "type" "call")
9001    (set (attr "fp_mode")
9002         (if_then_else (eq_attr "fpu_single" "yes")
9003                       (const_string "single") (const_string "double")))
9004    (set_attr "needs_delay_slot" "yes")
9005    (set_attr "fp_set" "unknown")])
9006
9007 (define_insn "call_value_compact"
9008   [(set (match_operand 0 "" "=rf")
9009         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9010               (match_operand 2 "" "")))
9011    (match_operand 3 "immediate_operand" "n")
9012    (use (reg:SI R0_REG))
9013    (use (reg:SI R1_REG))
9014    (use (reg:PSI FPSCR_REG))
9015    (clobber (reg:SI PR_REG))]
9016   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9017   "jsr  @%1%#"
9018   [(set_attr "type" "call")
9019    (set (attr "fp_mode")
9020         (if_then_else (eq_attr "fpu_single" "yes")
9021                       (const_string "single") (const_string "double")))
9022    (set_attr "needs_delay_slot" "yes")])
9023
9024 (define_insn "call_value_compact_rettramp"
9025   [(set (match_operand 0 "" "=rf")
9026         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9027               (match_operand 2 "" "")))
9028    (match_operand 3 "immediate_operand" "n")
9029    (use (reg:SI R0_REG))
9030    (use (reg:SI R1_REG))
9031    (use (reg:PSI FPSCR_REG))
9032    (clobber (reg:SI R10_REG))
9033    (clobber (reg:SI PR_REG))]
9034   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9035   "jsr  @%1%#"
9036   [(set_attr "type" "call")
9037    (set (attr "fp_mode")
9038         (if_then_else (eq_attr "fpu_single" "yes")
9039                       (const_string "single") (const_string "double")))
9040    (set_attr "needs_delay_slot" "yes")])
9041
9042 (define_insn "call_value_media"
9043   [(set (match_operand 0 "" "=rf")
9044         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9045               (match_operand 2 "" "")))
9046    (clobber (reg:DI PR_MEDIA_REG))]
9047   "TARGET_SHMEDIA"
9048   "blink        %1, r18"
9049   [(set_attr "type" "jump_media")])
9050
9051 (define_expand "call"
9052   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9053                             (match_operand 1 "" ""))
9054               (match_operand 2 "" "")
9055               (use (reg:PSI FPSCR_REG))
9056               (clobber (reg:SI PR_REG))])]
9057   ""
9058 {
9059   if (TARGET_SHMEDIA)
9060     {
9061       operands[0] = shmedia_prepare_call_address (operands[0], 0);
9062       emit_call_insn (gen_call_media (operands[0], operands[1]));
9063       DONE;
9064     }
9065   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9066     {
9067       rtx cookie_rtx = operands[2];
9068       long cookie = INTVAL (cookie_rtx);
9069       rtx func = XEXP (operands[0], 0);
9070       rtx r0, r1;
9071
9072       if (flag_pic)
9073         {
9074           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9075             {
9076               rtx reg = gen_reg_rtx (Pmode);
9077
9078               emit_insn (gen_symGOTPLT2reg (reg, func));
9079               func = reg;
9080             }
9081           else
9082             func = legitimize_pic_address (func, Pmode, 0);
9083         }
9084
9085       r0 = gen_rtx_REG (SImode, R0_REG);
9086       r1 = gen_rtx_REG (SImode, R1_REG);
9087
9088       /* Since such a call function may use all call-clobbered
9089          registers, we force a mode switch earlier, so that we don't
9090          run out of registers when adjusting fpscr for the call.  */
9091       emit_insn (gen_force_mode_for_call ());
9092
9093       operands[0]
9094         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9095       operands[0] = force_reg (SImode, operands[0]);
9096
9097       emit_move_insn (r0, func);
9098       emit_move_insn (r1, cookie_rtx);
9099
9100       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9101         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9102                                                    operands[2]));
9103       else
9104         emit_call_insn (gen_call_compact (operands[0], operands[1],
9105                                           operands[2]));
9106
9107       DONE;
9108     }
9109   else if (TARGET_SHCOMPACT && flag_pic
9110            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9111            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9112     {
9113       rtx reg = gen_reg_rtx (Pmode);
9114
9115       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9116       XEXP (operands[0], 0) = reg;
9117     }
9118   if (!flag_pic && TARGET_SH2A
9119       && MEM_P (operands[0])
9120       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9121     {
9122       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9123         {
9124           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9125                                              operands[1]));
9126           DONE;
9127         }
9128     }
9129   if (flag_pic && TARGET_SH2
9130       && MEM_P (operands[0])
9131       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9132     {
9133       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9134       DONE;
9135     }
9136   else
9137   {
9138     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9139     operands[1] = operands[2];
9140   }
9141
9142   emit_call_insn (gen_calli (operands[0], operands[1]));
9143   DONE;
9144 })
9145
9146 (define_insn "call_pop_compact"
9147   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9148          (match_operand 1 "" ""))
9149    (match_operand 2 "immediate_operand" "n")
9150    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9151                                  (match_operand 3 "immediate_operand" "n")))
9152    (use (reg:SI R0_REG))
9153    (use (reg:SI R1_REG))
9154    (use (reg:PSI FPSCR_REG))
9155    (clobber (reg:SI PR_REG))]
9156   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9157   "jsr  @%0%#"
9158   [(set_attr "type" "call")
9159    (set (attr "fp_mode")
9160         (if_then_else (eq_attr "fpu_single" "yes")
9161                       (const_string "single") (const_string "double")))
9162    (set_attr "needs_delay_slot" "yes")])
9163
9164 (define_insn "call_pop_compact_rettramp"
9165   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9166          (match_operand 1 "" ""))
9167    (match_operand 2 "immediate_operand" "n")
9168    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9169                                  (match_operand 3 "immediate_operand" "n")))
9170    (use (reg:SI R0_REG))
9171    (use (reg:SI R1_REG))
9172    (use (reg:PSI FPSCR_REG))
9173    (clobber (reg:SI R10_REG))
9174    (clobber (reg:SI PR_REG))]
9175   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9176   "jsr  @%0%#"
9177   [(set_attr "type" "call")
9178    (set (attr "fp_mode")
9179         (if_then_else (eq_attr "fpu_single" "yes")
9180                       (const_string "single") (const_string "double")))
9181    (set_attr "needs_delay_slot" "yes")])
9182
9183 (define_expand "call_pop"
9184   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9185                     (match_operand 1 "" ""))
9186              (match_operand 2 "" "")
9187              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9188                                            (match_operand 3 "" "")))])]
9189   "TARGET_SHCOMPACT"
9190 {
9191   rtx cookie_rtx;
9192   long cookie;
9193   rtx func;
9194   rtx r0, r1;
9195
9196   gcc_assert (operands[2] && INTVAL (operands[2]));
9197   cookie_rtx = operands[2];
9198   cookie = INTVAL (cookie_rtx);
9199   func = XEXP (operands[0], 0);
9200
9201   if (flag_pic)
9202     {
9203       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9204         {
9205           rtx reg = gen_reg_rtx (Pmode);
9206           emit_insn (gen_symGOTPLT2reg (reg, func));
9207           func = reg;
9208         }
9209       else
9210         func = legitimize_pic_address (func, Pmode, 0);
9211     }
9212
9213   r0 = gen_rtx_REG (SImode, R0_REG);
9214   r1 = gen_rtx_REG (SImode, R1_REG);
9215
9216   /* Since such a call function may use all call-clobbered
9217      registers, we force a mode switch earlier, so that we don't
9218      run out of registers when adjusting fpscr for the call.  */
9219   emit_insn (gen_force_mode_for_call ());
9220
9221   operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9222                                  SFUNC_GOT);
9223   operands[0] = force_reg (SImode, operands[0]);
9224
9225   emit_move_insn (r0, func);
9226   emit_move_insn (r1, cookie_rtx);
9227
9228   if (cookie & CALL_COOKIE_RET_TRAMP (1))
9229     emit_call_insn (gen_call_pop_compact_rettramp
9230                      (operands[0], operands[1], operands[2], operands[3]));
9231   else
9232     emit_call_insn (gen_call_pop_compact
9233                      (operands[0], operands[1], operands[2], operands[3]));
9234
9235   DONE;
9236 })
9237
9238 (define_expand "call_value"
9239   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9240                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9241                                  (match_operand 2 "" "")))
9242               (match_operand 3 "" "")
9243               (use (reg:PSI FPSCR_REG))
9244               (clobber (reg:SI PR_REG))])]
9245   ""
9246 {
9247   if (TARGET_SHMEDIA)
9248     {
9249       operands[1] = shmedia_prepare_call_address (operands[1], 0);
9250       emit_call_insn (gen_call_value_media (operands[0], operands[1],
9251                                             operands[2]));
9252       DONE;
9253     }
9254   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9255     {
9256       rtx cookie_rtx = operands[3];
9257       long cookie = INTVAL (cookie_rtx);
9258       rtx func = XEXP (operands[1], 0);
9259       rtx r0, r1;
9260
9261       if (flag_pic)
9262         {
9263           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9264             {
9265               rtx reg = gen_reg_rtx (Pmode);
9266
9267               emit_insn (gen_symGOTPLT2reg (reg, func));
9268               func = reg;
9269             }
9270           else
9271             func = legitimize_pic_address (func, Pmode, 0);
9272         }
9273
9274       r0 = gen_rtx_REG (SImode, R0_REG);
9275       r1 = gen_rtx_REG (SImode, R1_REG);
9276
9277       /* Since such a call function may use all call-clobbered
9278          registers, we force a mode switch earlier, so that we don't
9279          run out of registers when adjusting fpscr for the call.  */
9280       emit_insn (gen_force_mode_for_call ());
9281
9282       operands[1]
9283         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9284       operands[1] = force_reg (SImode, operands[1]);
9285
9286       emit_move_insn (r0, func);
9287       emit_move_insn (r1, cookie_rtx);
9288
9289       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9290         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9291                                                          operands[1],
9292                                                          operands[2],
9293                                                          operands[3]));
9294       else
9295         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9296                                                 operands[2], operands[3]));
9297
9298       DONE;
9299     }
9300   else if (TARGET_SHCOMPACT && flag_pic
9301            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9302            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9303     {
9304       rtx reg = gen_reg_rtx (Pmode);
9305
9306       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9307       XEXP (operands[1], 0) = reg;
9308     }
9309   if (!flag_pic && TARGET_SH2A
9310       && MEM_P (operands[1])
9311       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9312     {
9313       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9314         {
9315           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9316                                  XEXP (operands[1], 0), operands[2]));
9317           DONE;
9318         }
9319     }
9320   if (flag_pic && TARGET_SH2
9321       && MEM_P (operands[1])
9322       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9323     {
9324       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9325                                             operands[2]));
9326       DONE;
9327     }
9328   else
9329     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9330
9331   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9332   DONE;
9333 })
9334
9335 (define_insn "sibcalli"
9336   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9337          (match_operand 1 "" ""))
9338    (use (reg:PSI FPSCR_REG))
9339    (return)]
9340   "TARGET_SH1"
9341   "jmp  @%0%#"
9342   [(set_attr "needs_delay_slot" "yes")
9343    (set (attr "fp_mode")
9344         (if_then_else (eq_attr "fpu_single" "yes")
9345                       (const_string "single") (const_string "double")))
9346    (set_attr "type" "jump_ind")])
9347
9348 (define_insn "sibcalli_pcrel"
9349   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9350          (match_operand 1 "" ""))
9351    (use (match_operand 2 "" ""))
9352    (use (reg:PSI FPSCR_REG))
9353    (return)]
9354   "TARGET_SH2"
9355 {
9356   return       "braf    %0"     "\n"
9357          "%O2:%#";
9358 }
9359   [(set_attr "needs_delay_slot" "yes")
9360    (set (attr "fp_mode")
9361         (if_then_else (eq_attr "fpu_single" "yes")
9362                       (const_string "single") (const_string "double")))
9363    (set_attr "type" "jump_ind")])
9364
9365 ;; This uses an unspec to describe that the symbol_ref is very close.
9366 (define_insn "sibcalli_thunk"
9367   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9368                              UNSPEC_THUNK))
9369          (match_operand 1 "" ""))
9370    (use (reg:PSI FPSCR_REG))
9371    (return)]
9372   "TARGET_SH1"
9373   "bra  %O0"
9374   [(set_attr "needs_delay_slot" "yes")
9375    (set (attr "fp_mode")
9376         (if_then_else (eq_attr "fpu_single" "yes")
9377                       (const_string "single") (const_string "double")))
9378    (set_attr "type" "jump")
9379    (set_attr "length" "2")])
9380
9381 (define_insn_and_split "sibcall_pcrel"
9382   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9383          (match_operand 1 "" ""))
9384    (use (reg:PSI FPSCR_REG))
9385    (clobber (match_scratch:SI 2 "=k"))
9386    (return)]
9387   "TARGET_SH2"
9388   "#"
9389   "reload_completed"
9390   [(const_int 0)]
9391 {
9392   rtx lab = PATTERN (gen_call_site ());
9393   rtx call_insn;
9394
9395   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9396   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9397                                                   copy_rtx (lab)));
9398   SIBLING_CALL_P (call_insn) = 1;
9399   DONE;
9400 }
9401   [(set_attr "needs_delay_slot" "yes")
9402    (set (attr "fp_mode")
9403         (if_then_else (eq_attr "fpu_single" "yes")
9404                       (const_string "single") (const_string "double")))
9405    (set_attr "type" "jump_ind")])
9406
9407 (define_insn "sibcall_compact"
9408   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9409          (match_operand 1 "" ""))
9410    (return)
9411    (use (match_operand:SI 2 "register_operand" "z,x"))
9412    (use (reg:SI R1_REG))
9413    (use (reg:PSI FPSCR_REG))
9414    ;; We want to make sure the `x' above will only match MACH_REG
9415    ;; because sibcall_epilogue may clobber MACL_REG.
9416    (clobber (reg:SI MACL_REG))]
9417   "TARGET_SHCOMPACT"
9418 {
9419   static const char* alt[] =
9420   {
9421        "jmp     @%0%#",
9422
9423        "jmp     @%0"    "\n"
9424     "   sts     %2,r0"
9425   };
9426   return alt[which_alternative];
9427 }
9428   [(set_attr "needs_delay_slot" "yes,no")
9429    (set_attr "length" "2,4")
9430    (set (attr "fp_mode") (const_string "single"))
9431    (set_attr "type" "jump_ind")])
9432
9433 (define_insn "sibcall_media"
9434   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9435          (match_operand 1 "" ""))
9436    (use (reg:SI PR_MEDIA_REG))
9437    (return)]
9438   "TARGET_SHMEDIA"
9439   "blink        %0, r63"
9440   [(set_attr "type" "jump_media")])
9441
9442 (define_expand "sibcall"
9443   [(parallel
9444     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9445            (match_operand 1 "" ""))
9446      (match_operand 2 "" "")
9447      (use (reg:PSI FPSCR_REG))
9448      (return)])]
9449   ""
9450 {
9451   if (TARGET_SHMEDIA)
9452     {
9453       operands[0] = shmedia_prepare_call_address (operands[0], 1);
9454       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9455       DONE;
9456     }
9457   else if (TARGET_SHCOMPACT && operands[2]
9458            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9459     {
9460       rtx cookie_rtx = operands[2];
9461       long cookie = INTVAL (cookie_rtx);
9462       rtx func = XEXP (operands[0], 0);
9463       rtx mach, r1;
9464
9465       if (flag_pic)
9466         {
9467           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9468             {
9469               rtx reg = gen_reg_rtx (Pmode);
9470
9471               emit_insn (gen_symGOT2reg (reg, func));
9472               func = reg;
9473             }
9474           else
9475             func = legitimize_pic_address (func, Pmode, 0);
9476         }
9477
9478       /* FIXME: if we could tell whether all argument registers are
9479          already taken, we could decide whether to force the use of
9480          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
9481          simple way to tell.  We could use the CALL_COOKIE, but we
9482          can't currently tell a register used for regular argument
9483          passing from one that is unused.  If we leave it up to reload
9484          to decide which register to use, it seems to always choose
9485          R0_REG, which leaves no available registers in SIBCALL_REGS
9486          to hold the address of the trampoline.  */
9487       mach = gen_rtx_REG (SImode, MACH_REG);
9488       r1 = gen_rtx_REG (SImode, R1_REG);
9489
9490       /* Since such a call function may use all call-clobbered
9491          registers, we force a mode switch earlier, so that we don't
9492          run out of registers when adjusting fpscr for the call.  */
9493       emit_insn (gen_force_mode_for_call ());
9494
9495       operands[0]
9496         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9497       operands[0] = force_reg (SImode, operands[0]);
9498
9499       /* We don't need a return trampoline, since the callee will
9500          return directly to the upper caller.  */
9501       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9502         {
9503           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9504           cookie_rtx = GEN_INT (cookie);
9505         }
9506
9507       emit_move_insn (mach, func);
9508       emit_move_insn (r1, cookie_rtx);
9509
9510       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9511       DONE;
9512     }
9513   else if (TARGET_SHCOMPACT && flag_pic
9514            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9515            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9516     {
9517       rtx reg = gen_reg_rtx (Pmode);
9518
9519       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9520       XEXP (operands[0], 0) = reg;
9521     }
9522   if (flag_pic && TARGET_SH2
9523       && MEM_P (operands[0])
9524       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9525       /* The PLT needs the PIC register, but the epilogue would have
9526          to restore it, so we can only use PC-relative PIC calls for
9527          static functions.  */
9528       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9529     {
9530       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9531       DONE;
9532     }
9533   else
9534     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9535
9536   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9537   DONE;
9538 })
9539
9540 (define_insn "sibcall_valuei"
9541   [(set (match_operand 0 "" "=rf")
9542         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9543               (match_operand 2 "" "")))
9544    (use (reg:PSI FPSCR_REG))
9545    (return)]
9546   "TARGET_SH1"
9547   "jmp  @%1%#"
9548   [(set_attr "needs_delay_slot" "yes")
9549    (set (attr "fp_mode")
9550         (if_then_else (eq_attr "fpu_single" "yes")
9551                       (const_string "single") (const_string "double")))
9552    (set_attr "type" "jump_ind")])
9553
9554 (define_insn "sibcall_valuei_pcrel"
9555   [(set (match_operand 0 "" "=rf")
9556         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9557               (match_operand 2 "" "")))
9558    (use (match_operand 3 "" ""))
9559    (use (reg:PSI FPSCR_REG))
9560    (return)]
9561   "TARGET_SH2"
9562 {
9563   return       "braf    %1"     "\n"
9564          "%O3:%#";
9565 }
9566   [(set_attr "needs_delay_slot" "yes")
9567    (set (attr "fp_mode")
9568         (if_then_else (eq_attr "fpu_single" "yes")
9569                       (const_string "single") (const_string "double")))
9570    (set_attr "type" "jump_ind")])
9571
9572 (define_insn_and_split "sibcall_value_pcrel"
9573   [(set (match_operand 0 "" "=rf")
9574         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9575               (match_operand 2 "" "")))
9576    (use (reg:PSI FPSCR_REG))
9577    (clobber (match_scratch:SI 3 "=k"))
9578    (return)]
9579   "TARGET_SH2"
9580   "#"
9581   "reload_completed"
9582   [(const_int 0)]
9583 {
9584   rtx lab = PATTERN (gen_call_site ());
9585   rtx call_insn;
9586
9587   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9588   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9589                                                         operands[3],
9590                                                         operands[2],
9591                                                         copy_rtx (lab)));
9592   SIBLING_CALL_P (call_insn) = 1;
9593   DONE;
9594 }
9595   [(set_attr "needs_delay_slot" "yes")
9596    (set (attr "fp_mode")
9597         (if_then_else (eq_attr "fpu_single" "yes")
9598                       (const_string "single") (const_string "double")))
9599    (set_attr "type" "jump_ind")])
9600
9601 (define_insn "sibcall_value_compact"
9602   [(set (match_operand 0 "" "=rf,rf")
9603         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9604               (match_operand 2 "" "")))
9605    (return)
9606    (use (match_operand:SI 3 "register_operand" "z,x"))
9607    (use (reg:SI R1_REG))
9608    (use (reg:PSI FPSCR_REG))
9609    ;; We want to make sure the `x' above will only match MACH_REG
9610    ;; because sibcall_epilogue may clobber MACL_REG.
9611    (clobber (reg:SI MACL_REG))]
9612   "TARGET_SHCOMPACT"
9613 {
9614   static const char* alt[] =
9615   {
9616        "jmp     @%1%#",
9617
9618        "jmp     @%1"    "\n"
9619     "   sts     %3,r0"
9620   };
9621   return alt[which_alternative];
9622 }
9623   [(set_attr "needs_delay_slot" "yes,no")
9624    (set_attr "length" "2,4")
9625    (set (attr "fp_mode") (const_string "single"))
9626    (set_attr "type" "jump_ind")])
9627
9628 (define_insn "sibcall_value_media"
9629   [(set (match_operand 0 "" "=rf")
9630         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9631               (match_operand 2 "" "")))
9632    (use (reg:SI PR_MEDIA_REG))
9633    (return)]
9634   "TARGET_SHMEDIA"
9635   "blink        %1, r63"
9636   [(set_attr "type" "jump_media")])
9637
9638 (define_expand "sibcall_value"
9639   [(parallel
9640     [(set (match_operand 0 "arith_reg_operand" "")
9641           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9642                 (match_operand 2 "" "")))
9643      (match_operand 3 "" "")
9644      (use (reg:PSI FPSCR_REG))
9645      (return)])]
9646   ""
9647 {
9648   if (TARGET_SHMEDIA)
9649     {
9650       operands[1] = shmedia_prepare_call_address (operands[1], 1);
9651       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9652                                                operands[2]));
9653       DONE;
9654     }
9655   else if (TARGET_SHCOMPACT && operands[3]
9656            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9657     {
9658       rtx cookie_rtx = operands[3];
9659       long cookie = INTVAL (cookie_rtx);
9660       rtx func = XEXP (operands[1], 0);
9661       rtx mach, r1;
9662
9663       if (flag_pic)
9664         {
9665           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9666             {
9667               rtx reg = gen_reg_rtx (Pmode);
9668
9669               emit_insn (gen_symGOT2reg (reg, func));
9670               func = reg;
9671             }
9672           else
9673             func = legitimize_pic_address (func, Pmode, 0);
9674         }
9675
9676       /* FIXME: if we could tell whether all argument registers are
9677          already taken, we could decide whether to force the use of
9678          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
9679          simple way to tell.  We could use the CALL_COOKIE, but we
9680          can't currently tell a register used for regular argument
9681          passing from one that is unused.  If we leave it up to reload
9682          to decide which register to use, it seems to always choose
9683          R0_REG, which leaves no available registers in SIBCALL_REGS
9684          to hold the address of the trampoline.  */
9685       mach = gen_rtx_REG (SImode, MACH_REG);
9686       r1 = gen_rtx_REG (SImode, R1_REG);
9687
9688       /* Since such a call function may use all call-clobbered
9689          registers, we force a mode switch earlier, so that we don't
9690          run out of registers when adjusting fpscr for the call.  */
9691       emit_insn (gen_force_mode_for_call ());
9692
9693       operands[1]
9694         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9695       operands[1] = force_reg (SImode, operands[1]);
9696
9697       /* We don't need a return trampoline, since the callee will
9698          return directly to the upper caller.  */
9699       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9700         {
9701           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9702           cookie_rtx = GEN_INT (cookie);
9703         }
9704
9705       emit_move_insn (mach, func);
9706       emit_move_insn (r1, cookie_rtx);
9707
9708       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9709                                                  operands[2], mach));
9710       DONE;
9711     }
9712   else if (TARGET_SHCOMPACT && flag_pic
9713            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9714            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9715     {
9716       rtx reg = gen_reg_rtx (Pmode);
9717
9718       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9719       XEXP (operands[1], 0) = reg;
9720     }
9721   if (flag_pic && TARGET_SH2
9722       && MEM_P (operands[1])
9723       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9724       /* The PLT needs the PIC register, but the epilogue would have
9725          to restore it, so we can only use PC-relative PIC calls for
9726          static functions.  */
9727       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9728     {
9729       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9730                                                XEXP (operands[1], 0),
9731                                                operands[2]));
9732       DONE;
9733     }
9734   else
9735     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9736
9737   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9738   DONE;
9739 })
9740
9741 (define_insn "call_value_pop_compact"
9742   [(set (match_operand 0 "" "=rf")
9743         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9744               (match_operand 2 "" "")))
9745    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9746                                  (match_operand 4 "immediate_operand" "n")))
9747    (match_operand 3 "immediate_operand" "n")
9748    (use (reg:SI R0_REG))
9749    (use (reg:SI R1_REG))
9750    (use (reg:PSI FPSCR_REG))
9751    (clobber (reg:SI PR_REG))]
9752   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9753   "jsr  @%1%#"
9754   [(set_attr "type" "call")
9755    (set (attr "fp_mode")
9756         (if_then_else (eq_attr "fpu_single" "yes")
9757                       (const_string "single") (const_string "double")))
9758    (set_attr "needs_delay_slot" "yes")])
9759
9760 (define_insn "call_value_pop_compact_rettramp"
9761   [(set (match_operand 0 "" "=rf")
9762         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9763               (match_operand 2 "" "")))
9764    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9765                                  (match_operand 4 "immediate_operand" "n")))
9766    (match_operand 3 "immediate_operand" "n")
9767    (use (reg:SI R0_REG))
9768    (use (reg:SI R1_REG))
9769    (use (reg:PSI FPSCR_REG))
9770    (clobber (reg:SI R10_REG))
9771    (clobber (reg:SI PR_REG))]
9772   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9773   "jsr  @%1%#"
9774   [(set_attr "type" "call")
9775    (set (attr "fp_mode")
9776         (if_then_else (eq_attr "fpu_single" "yes")
9777                       (const_string "single") (const_string "double")))
9778    (set_attr "needs_delay_slot" "yes")])
9779
9780 (define_expand "call_value_pop"
9781   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9782                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9783                                  (match_operand 2 "" "")))
9784               (match_operand 3 "" "")
9785               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9786                                             (match_operand 4 "" "")))])]
9787   "TARGET_SHCOMPACT"
9788 {
9789   rtx cookie_rtx;
9790   long cookie;
9791   rtx func;
9792   rtx r0, r1;
9793
9794   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9795   cookie_rtx = operands[3];
9796   cookie = INTVAL (cookie_rtx);
9797   func = XEXP (operands[1], 0);
9798
9799   if (flag_pic)
9800     {
9801       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9802         {
9803           rtx reg = gen_reg_rtx (Pmode);
9804
9805           emit_insn (gen_symGOTPLT2reg (reg, func));
9806           func = reg;
9807         }
9808       else
9809         func = legitimize_pic_address (func, Pmode, 0);
9810     }
9811
9812   r0 = gen_rtx_REG (SImode, R0_REG);
9813   r1 = gen_rtx_REG (SImode, R1_REG);
9814
9815   /* Since such a call function may use all call-clobbered
9816      registers, we force a mode switch earlier, so that we don't
9817      run out of registers when adjusting fpscr for the call.  */
9818   emit_insn (gen_force_mode_for_call ());
9819
9820   operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9821                                  SFUNC_GOT);
9822   operands[1] = force_reg (SImode, operands[1]);
9823
9824   emit_move_insn (r0, func);
9825   emit_move_insn (r1, cookie_rtx);
9826
9827   if (cookie & CALL_COOKIE_RET_TRAMP (1))
9828     emit_call_insn (gen_call_value_pop_compact_rettramp
9829                         (operands[0], operands[1], operands[2],
9830                          operands[3], operands[4]));
9831   else
9832     emit_call_insn (gen_call_value_pop_compact
9833                         (operands[0], operands[1], operands[2],
9834                          operands[3], operands[4]));
9835
9836   DONE;
9837 })
9838
9839 (define_expand "sibcall_epilogue"
9840   [(return)]
9841   ""
9842 {
9843   sh_expand_epilogue (true);
9844   if (TARGET_SHCOMPACT)
9845     {
9846       rtx insn, set;
9847
9848       /* If epilogue clobbers r0, preserve it in macl.  */
9849       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9850         if ((set = single_set (insn))
9851             && REG_P (SET_DEST (set))
9852             && REGNO (SET_DEST (set)) == R0_REG)
9853           {
9854             rtx r0 = gen_rtx_REG (SImode, R0_REG);
9855             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
9856
9857             /* We can't tell at this point whether the sibcall is a
9858                sibcall_compact and, if it is, whether it uses r0 or
9859                mach as operand 2, so let the instructions that
9860                preserve r0 be optimized away if r0 turns out to be
9861                dead.  */
9862             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
9863             emit_move_insn (r0, tmp);
9864             break;
9865           }
9866     }
9867   DONE;
9868 })
9869
9870 (define_insn "indirect_jump_compact"
9871   [(set (pc)
9872         (match_operand:SI 0 "arith_reg_operand" "r"))]
9873   "TARGET_SH1"
9874   "jmp  @%0%#"
9875   [(set_attr "needs_delay_slot" "yes")
9876    (set_attr "type" "jump_ind")])
9877
9878 (define_expand "indirect_jump"
9879   [(set (pc)
9880         (match_operand 0 "register_operand" ""))]
9881   ""
9882 {
9883   if (GET_MODE (operands[0]) != Pmode)
9884     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
9885 })
9886
9887 ;; The use of operand 1 / 2 helps us distinguish case table jumps
9888 ;; which can be present in structured code from indirect jumps which can not
9889 ;; be present in structured code.  This allows -fprofile-arcs to work.
9890
9891 ;; For SH1 processors.
9892 (define_insn "casesi_jump_1"
9893   [(set (pc)
9894         (match_operand:SI 0 "register_operand" "r"))
9895    (use (label_ref (match_operand 1 "" "")))]
9896   "TARGET_SH1"
9897   "jmp  @%0%#"
9898   [(set_attr "needs_delay_slot" "yes")
9899    (set_attr "type" "jump_ind")])
9900
9901 ;; For all later processors.
9902 (define_insn "casesi_jump_2"
9903   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
9904                       (label_ref (match_operand 1 "" ""))))
9905    (use (label_ref (match_operand 2 "" "")))]
9906   "TARGET_SH2
9907    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
9908   "braf %0%#"
9909   [(set_attr "needs_delay_slot" "yes")
9910    (set_attr "type" "jump_ind")])
9911
9912 (define_insn "casesi_jump_media"
9913   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
9914    (use (label_ref (match_operand 1 "" "")))]
9915   "TARGET_SHMEDIA"
9916   "blink        %0, r63"
9917   [(set_attr "type" "jump_media")])
9918
9919 ;; Call subroutine returning any type.
9920 ;; ??? This probably doesn't work.
9921 (define_expand "untyped_call"
9922   [(parallel [(call (match_operand 0 "" "")
9923                     (const_int 0))
9924               (match_operand 1 "" "")
9925               (match_operand 2 "" "")])]
9926   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
9927 {
9928   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9929
9930   for (int i = 0; i < XVECLEN (operands[2], 0); i++)
9931     {
9932       rtx set = XVECEXP (operands[2], 0, i);
9933       emit_move_insn (SET_DEST (set), SET_SRC (set));
9934     }
9935
9936   /* The optimizer does not know that the call sets the function value
9937      registers we stored in the result block.  We avoid problems by
9938      claiming that all hard registers are used and clobbered at this
9939      point.  */
9940   emit_insn (gen_blockage ());
9941
9942   DONE;
9943 })
9944 \f
9945 ;; ------------------------------------------------------------------------
9946 ;; Misc insns
9947 ;; ------------------------------------------------------------------------
9948
9949 (define_insn "dect"
9950   [(set (reg:SI T_REG)
9951         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
9952    (set (match_operand:SI 0 "arith_reg_dest" "=r")
9953         (plus:SI (match_dup 1) (const_int -1)))]
9954   "TARGET_SH2"
9955   "dt   %0"
9956   [(set_attr "type" "arith")])
9957
9958 (define_insn "nop"
9959   [(const_int 0)]
9960   ""
9961   "nop")
9962
9963 ;; Load address of a label. This is only generated by the casesi expand,
9964 ;; and by machine_dependent_reorg (fixing up fp moves).
9965 ;; This must use unspec, because this only works for labels that are
9966 ;; within range.
9967 (define_insn "mova"
9968   [(set (reg:SI R0_REG)
9969         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
9970   "TARGET_SH1"
9971   "mova %O0,r0"
9972   [(set_attr "in_delay_slot" "no")
9973    (set_attr "type" "arith")])
9974
9975 ;; machine_dependent_reorg will make this a `mova'.
9976 (define_insn "mova_const"
9977   [(set (reg:SI R0_REG)
9978         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
9979   "TARGET_SH1"
9980   "#"
9981   [(set_attr "in_delay_slot" "no")
9982    (set_attr "type" "arith")])
9983
9984 (define_expand "GOTaddr2picreg"
9985   [(set (reg:SI R0_REG)
9986         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
9987                    UNSPEC_MOVA))
9988    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
9989    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9990   ""
9991 {
9992   if (TARGET_VXWORKS_RTP)
9993     {
9994       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
9995       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
9996       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
9997       DONE;
9998     }
9999
10000   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10001   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10002
10003   if (TARGET_SHMEDIA)
10004     {
10005       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10006       rtx pic = operands[0];
10007       rtx lab = PATTERN (gen_call_site ());
10008       rtx insn, equiv;
10009
10010       equiv = operands[1];
10011       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10012                                     UNSPEC_PCREL_SYMOFF);
10013       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10014
10015       if (Pmode == SImode)
10016         {
10017           emit_insn (gen_movsi_const (pic, operands[1]));
10018           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10019         }
10020       else
10021         {
10022           emit_insn (gen_movdi_const (pic, operands[1]));
10023           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10024         }
10025
10026       insn = emit_move_insn (operands[0], tr);
10027
10028       set_unique_reg_note (insn, REG_EQUAL, equiv);
10029
10030       DONE;
10031     }
10032 })
10033
10034 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10035 ;; PIC register.
10036 (define_expand "vxworks_picreg"
10037   [(set (reg:SI PIC_REG)
10038         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10039    (set (reg:SI R0_REG)
10040         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10041    (set (reg:SI PIC_REG)
10042         (mem:SI (reg:SI PIC_REG)))
10043    (set (reg:SI PIC_REG)
10044         (mem:SI (plus:SI (reg:SI PIC_REG)
10045                          (reg:SI R0_REG))))]
10046   "TARGET_VXWORKS_RTP")
10047
10048 (define_insn "*ptb"
10049   [(set (match_operand 0 "target_reg_operand" "=b")
10050         (const (unspec [(match_operand 1 "" "Csy")]
10051                              UNSPEC_DATALABEL)))]
10052   "TARGET_SHMEDIA && flag_pic
10053    && satisfies_constraint_Csy (operands[1])"
10054   "ptb/u        datalabel %1, %0"
10055   [(set_attr "type" "ptabs_media")
10056    (set_attr "length" "*")])
10057
10058 (define_insn "ptrel_si"
10059   [(set (match_operand:SI 0 "target_reg_operand" "=b")
10060         (plus:SI (match_operand:SI 1 "register_operand" "r")
10061               (pc)))
10062    (match_operand:SI 2 "" "")]
10063   "TARGET_SHMEDIA"
10064   "%O2: ptrel/u %1, %0"
10065   [(set_attr "type" "ptabs_media")])
10066
10067 (define_insn "ptrel_di"
10068   [(set (match_operand:DI 0 "target_reg_operand" "=b")
10069         (plus:DI (match_operand:DI 1 "register_operand" "r")
10070               (pc)))
10071    (match_operand:DI 2 "" "")]
10072   "TARGET_SHMEDIA"
10073   "%O2: ptrel/u %1, %0"
10074   [(set_attr "type" "ptabs_media")])
10075
10076 (define_expand "builtin_setjmp_receiver"
10077   [(match_operand 0 "" "")]
10078   "flag_pic"
10079 {
10080   emit_insn (gen_GOTaddr2picreg ());
10081   DONE;
10082 })
10083
10084 (define_expand "call_site"
10085   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10086   "TARGET_SH1"
10087 {
10088   static HOST_WIDE_INT i = 0;
10089   operands[0] = GEN_INT (i);
10090   i++;
10091 })
10092
10093 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
10094 ;; in symGOT_load expand.
10095 (define_insn_and_split "chk_guard_add"
10096   [(set (match_operand:SI 0 "register_operand" "=&r")
10097         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10098                     (reg:SI PIC_REG)]
10099                    UNSPEC_CHKADD))]
10100   "TARGET_SH1"
10101   "#"
10102   "TARGET_SH1 && reload_completed"
10103   [(set (match_dup 0) (reg:SI PIC_REG))
10104    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10105   ""
10106   [(set_attr "type" "arith")])
10107
10108 (define_expand "sym_label2reg"
10109   [(set (match_operand:SI 0 "" "")
10110         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10111                               (const (plus:SI (match_operand:SI 2 "" "")
10112                                               (const_int 2)))]
10113                              UNSPEC_SYMOFF)))]
10114   "TARGET_SH1" "")
10115
10116 (define_expand "symGOT_load"
10117   [(set (match_dup 2) (match_operand 1 "" ""))
10118    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10119    (set (match_operand 0 "" "") (mem (match_dup 3)))]
10120   ""
10121 {
10122   rtx mem;
10123
10124   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10125   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10126
10127   if (TARGET_SHMEDIA)
10128     {
10129       rtx reg = operands[2];
10130
10131       if (Pmode == DImode)
10132         {      
10133           if (flag_pic > 1)
10134             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10135           else
10136             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10137         }
10138       else
10139         {
10140           if (flag_pic > 1)
10141             emit_insn (gen_movsi_const (reg, operands[1]));
10142           else
10143             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10144         }
10145     }
10146   else
10147     emit_move_insn (operands[2], operands[1]);
10148
10149   /* When stack protector inserts codes after the result is set to
10150      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
10151      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10152      when rX is a GOT address for the guard symbol.  Ugly but doesn't
10153      matter because this is a rare situation.  */
10154   if (!TARGET_SHMEDIA
10155       && flag_stack_protect
10156       && GET_CODE (operands[1]) == CONST
10157       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10158       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10159       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10160                  "__stack_chk_guard") == 0)
10161     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10162   else
10163     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10164                                                gen_rtx_REG (Pmode, PIC_REG)));
10165
10166   /* N.B. This is not constant for a GOTPLT relocation.  */
10167   mem = gen_rtx_MEM (Pmode, operands[3]);
10168   MEM_NOTRAP_P (mem) = 1;
10169   /* ??? Should we have a special alias set for the GOT?  */
10170   emit_move_insn (operands[0], mem);
10171
10172   DONE;
10173 })
10174
10175 (define_expand "sym2GOT"
10176   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10177   ""
10178   "")
10179
10180 (define_expand "symGOT2reg"
10181   [(match_operand 0 "" "") (match_operand 1 "" "")]
10182   ""
10183 {
10184   rtx gotsym, insn;
10185
10186   gotsym = gen_sym2GOT (operands[1]);
10187   PUT_MODE (gotsym, Pmode);
10188   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10189
10190   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10191
10192   DONE;
10193 })
10194
10195 (define_expand "symGOTPLT2reg"
10196   [(match_operand 0 "" "") (match_operand 1 "" "")]
10197   ""
10198 {
10199   rtx pltsym = gen_rtx_CONST (Pmode,
10200                               gen_rtx_UNSPEC (Pmode,
10201                                               gen_rtvec (1, operands[1]),
10202                                               UNSPEC_GOTPLT));
10203   emit_insn (gen_symGOT_load (operands[0], pltsym));
10204   DONE;
10205 })
10206
10207 (define_expand "sym2GOTOFF"
10208   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10209   ""
10210   "")
10211
10212 (define_expand "symGOTOFF2reg"
10213   [(match_operand 0 "" "") (match_operand 1 "" "")]
10214   ""
10215 {
10216   rtx gotoffsym, insn;
10217   rtx t = (!can_create_pseudo_p ()
10218            ? operands[0]
10219            : gen_reg_rtx (GET_MODE (operands[0])));
10220
10221   gotoffsym = gen_sym2GOTOFF (operands[1]);
10222   PUT_MODE (gotoffsym, Pmode);
10223   emit_move_insn (t, gotoffsym);
10224   insn = emit_move_insn (operands[0],
10225                          gen_rtx_PLUS (Pmode, t,
10226                                        gen_rtx_REG (Pmode, PIC_REG)));
10227
10228   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10229
10230   DONE;
10231 })
10232
10233 (define_expand "symPLT_label2reg"
10234   [(set (match_operand:SI 0 "" "")
10235         (const:SI
10236          (unspec:SI
10237           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10238            (const:SI (plus:SI (match_operand:SI 2 "" "")
10239                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10240    ;; Even though the PIC register is not really used by the call
10241    ;; sequence in which this is expanded, the PLT code assumes the PIC
10242    ;; register is set, so we must not skip its initialization.  Since
10243    ;; we only use this expand as part of calling sequences, and never
10244    ;; to take the address of a function, this is the best point to
10245    ;; insert the (use).  Using the PLT to take the address of a
10246    ;; function would be wrong, not only because the PLT entry could
10247    ;; then be called from a function that doesn't initialize the PIC
10248    ;; register to the proper GOT, but also because pointers to the
10249    ;; same function might not compare equal, should they be set by
10250    ;; different shared libraries.
10251    (use (reg:SI PIC_REG))]
10252   "TARGET_SH1"
10253   "")
10254
10255 (define_expand "sym2PIC"
10256   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10257   ""
10258   "")
10259
10260 ;; -------------------------------------------------------------------------
10261 ;; TLS code generation.
10262
10263 ;; FIXME: The multi-insn asm blocks should be converted to use
10264 ;; define_insn_and_split.
10265 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10266 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10267 ;; for details.
10268
10269 (define_insn "tls_global_dynamic"
10270   [(set (match_operand:SI 0 "register_operand" "=&z")
10271         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10272                                   UNSPEC_TLSGD))
10273               (const_int 0)))
10274    (use (reg:PSI FPSCR_REG))
10275    (use (reg:SI PIC_REG))
10276    (clobber (reg:SI PR_REG))
10277    (clobber (scratch:SI))]
10278   "TARGET_SH1"
10279 {
10280   return       "mov.l   1f,r4"                  "\n"
10281          "      mova    2f,r0"                  "\n"
10282          "      mov.l   2f,r1"                  "\n"
10283          "      add     r0,r1"                  "\n"
10284          "      jsr     @r1"                    "\n"
10285          "      add     r12,r4"                 "\n"
10286          "      bra     3f"                     "\n"
10287          "      nop"                            "\n"
10288          "      .align  2"                      "\n"
10289          "1:    .long   %a1@TLSGD"              "\n"
10290          "2:    .long   __tls_get_addr@PLT"     "\n"
10291          "3:";
10292 }
10293   [(set_attr "type" "tls_load")
10294    (set_attr "length" "26")])
10295
10296 (define_insn "tls_local_dynamic"
10297   [(set (match_operand:SI 0 "register_operand" "=&z")
10298         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10299                                   UNSPEC_TLSLDM))
10300               (const_int 0)))
10301    (use (reg:PSI FPSCR_REG))
10302    (use (reg:SI PIC_REG))
10303    (clobber (reg:SI PR_REG))
10304    (clobber (scratch:SI))]
10305   "TARGET_SH1"
10306 {
10307   return       "mov.l   1f,r4"                  "\n"
10308          "      mova    2f,r0"                  "\n"
10309          "      mov.l   2f,r1"                  "\n"
10310          "      add     r0,r1"                  "\n"
10311          "      jsr     @r1"                    "\n"
10312          "      add     r12,r4"                 "\n"
10313          "      bra     3f"                     "\n"
10314          "      nop"                            "\n"
10315          "      .align  2"                      "\n"
10316          "1:    .long   %a1@TLSLDM"             "\n"
10317          "2:    .long   __tls_get_addr@PLT"     "\n"
10318          "3:";
10319 }
10320   [(set_attr "type" "tls_load")
10321    (set_attr "length" "26")])
10322
10323 (define_expand "sym2DTPOFF"
10324   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10325   ""
10326   "")
10327
10328 (define_expand "symDTPOFF2reg"
10329   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10330   ""
10331 {
10332   rtx dtpoffsym;
10333   rtx t = (!can_create_pseudo_p ()
10334            ? operands[0]
10335            : gen_reg_rtx (GET_MODE (operands[0])));
10336
10337   dtpoffsym = gen_sym2DTPOFF (operands[1]);
10338   PUT_MODE (dtpoffsym, Pmode);
10339   emit_move_insn (t, dtpoffsym);
10340   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10341   DONE;
10342 })
10343
10344 (define_expand "sym2GOTTPOFF"
10345   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10346   ""
10347   "")
10348
10349 (define_insn "tls_initial_exec"
10350   [(set (match_operand:SI 0 "register_operand" "=&r")
10351         (unspec:SI [(match_operand:SI 1 "" "")]
10352                     UNSPEC_TLSIE))
10353    (use (reg:SI GBR_REG))
10354    (use (reg:SI PIC_REG))
10355    (clobber (reg:SI R0_REG))]
10356   ""
10357 {
10358   return       "mov.l   1f,r0"          "\n"
10359          "      stc     gbr,%0"         "\n"
10360          "      mov.l   @(r0,r12),r0"   "\n"
10361          "      bra     2f"             "\n"
10362          "      add     r0,%0"          "\n"
10363          "      .align  2"              "\n"
10364          "1:    .long   %a1"            "\n"
10365          "2:";
10366 }
10367   [(set_attr "type" "tls_load")
10368    (set_attr "length" "16")])
10369
10370 (define_expand "sym2TPOFF"
10371   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10372   ""
10373   "")
10374
10375 (define_expand "symTPOFF2reg"
10376   [(match_operand 0 "" "") (match_operand 1 "" "")]
10377   ""
10378 {
10379   rtx tpoffsym;
10380
10381   tpoffsym = gen_sym2TPOFF (operands[1]);
10382   PUT_MODE (tpoffsym, Pmode);
10383   emit_move_insn (operands[0], tpoffsym);
10384   DONE;
10385 })
10386
10387 ;;------------------------------------------------------------------------------
10388 ;; Thread pointer getter and setter.
10389 ;;
10390 ;; On SH the thread pointer is kept in the GBR.
10391 ;; These patterns are usually expanded from the respective built-in functions.
10392 (define_expand "get_thread_pointersi"
10393   [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10394   "TARGET_SH1")
10395
10396 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10397 (define_insn "store_gbr"
10398   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10399   ""
10400   "stc  gbr,%0"
10401   [(set_attr "type" "tls_load")])
10402
10403 (define_expand "set_thread_pointersi"
10404   [(set (reg:SI GBR_REG)
10405         (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10406          UNSPECV_GBR))]
10407   "TARGET_SH1")
10408
10409 (define_insn "load_gbr"
10410   [(set (reg:SI GBR_REG)
10411         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10412          UNSPECV_GBR))]
10413   "TARGET_SH1"
10414   "ldc  %0,gbr"
10415   [(set_attr "type" "move")])
10416
10417 ;;------------------------------------------------------------------------------
10418 ;; Thread pointer relative memory loads and stores.
10419 ;;
10420 ;; On SH there are GBR displacement address modes which can be utilized to
10421 ;; access memory behind the thread pointer.
10422 ;; Since we do not allow using GBR for general purpose memory accesses, these
10423 ;; GBR addressing modes are formed by the combine pass.
10424 ;; This could be done with fewer patterns than below by using a mem predicate
10425 ;; for the GBR mem, but then reload would try to reload addresses with a
10426 ;; zero displacement for some strange reason.
10427
10428 (define_insn "*mov<mode>_gbr_load"
10429   [(set (match_operand:QIHISI 0 "register_operand" "=z")
10430         (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10431                              (match_operand:QIHISI 1 "gbr_displacement"))))]
10432   "TARGET_SH1"
10433   "mov.<bwl>    @(%O1,gbr),%0"
10434   [(set_attr "type" "load")])
10435
10436 (define_insn "*mov<mode>_gbr_load"
10437   [(set (match_operand:QIHISI 0 "register_operand" "=z")
10438         (mem:QIHISI (reg:SI GBR_REG)))]
10439   "TARGET_SH1"
10440   "mov.<bwl>    @(0,gbr),%0"
10441   [(set_attr "type" "load")])
10442
10443 (define_insn "*mov<mode>_gbr_load"
10444   [(set (match_operand:SI 0 "register_operand" "=z")
10445         (sign_extend:SI
10446           (mem:QIHI (plus:SI (reg:SI GBR_REG)
10447                              (match_operand:QIHI 1 "gbr_displacement")))))]
10448   "TARGET_SH1"
10449   "mov.<bw>     @(%O1,gbr),%0"
10450   [(set_attr "type" "load")])
10451
10452 (define_insn "*mov<mode>_gbr_load"
10453   [(set (match_operand:SI 0 "register_operand" "=z")
10454         (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10455   "TARGET_SH1"
10456   "mov.<bw>     @(0,gbr),%0"
10457   [(set_attr "type" "load")])
10458
10459 (define_insn "*mov<mode>_gbr_store"
10460   [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10461                              (match_operand:QIHISI 0 "gbr_displacement")))
10462         (match_operand:QIHISI 1 "register_operand" "z"))]
10463   "TARGET_SH1"
10464   "mov.<bwl>    %1,@(%O0,gbr)"
10465   [(set_attr "type" "store")])
10466
10467 (define_insn "*mov<mode>_gbr_store"
10468   [(set (mem:QIHISI (reg:SI GBR_REG))
10469         (match_operand:QIHISI 0 "register_operand" "z"))]
10470   "TARGET_SH1"
10471   "mov.<bwl>    %0,@(0,gbr)"
10472   [(set_attr "type" "store")])
10473
10474 ;; DImode memory accesses have to be split in two SImode accesses.
10475 ;; Split them before reload, so that it gets a better chance to figure out
10476 ;; how to deal with the R0 restriction for the individual SImode accesses.
10477 ;; Do not match this insn during or after reload because it can't be split
10478 ;; afterwards.
10479 (define_insn_and_split "*movdi_gbr_load"
10480   [(set (match_operand:DI 0 "register_operand")
10481         (match_operand:DI 1 "gbr_address_mem"))]
10482   "TARGET_SH1 && can_create_pseudo_p ()"
10483   "#"
10484   "&& 1"
10485   [(set (match_dup 3) (match_dup 5))
10486    (set (match_dup 4) (match_dup 6))]
10487 {
10488   /* Swap low/high part load order on little endian, so that the result reg
10489      of the second load can be used better.  */
10490   int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10491   operands[3 + off] = gen_lowpart (SImode, operands[0]);
10492   operands[5 + off] = gen_lowpart (SImode, operands[1]);
10493   operands[4 - off] = gen_highpart (SImode, operands[0]);
10494   operands[6 - off] = gen_highpart (SImode, operands[1]);
10495 })
10496
10497 (define_insn_and_split "*movdi_gbr_store"
10498   [(set (match_operand:DI 0 "gbr_address_mem")
10499         (match_operand:DI 1 "register_operand"))]
10500   "TARGET_SH1 && can_create_pseudo_p ()"
10501   "#"
10502   "&& 1"
10503   [(set (match_dup 3) (match_dup 5))
10504    (set (match_dup 4) (match_dup 6))]
10505 {
10506   /* Swap low/high part store order on big endian, so that stores of function
10507      call results can save a reg copy.  */
10508   int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10509   operands[3 + off] = gen_lowpart (SImode, operands[0]);
10510   operands[5 + off] = gen_lowpart (SImode, operands[1]);
10511   operands[4 - off] = gen_highpart (SImode, operands[0]);
10512   operands[6 - off] = gen_highpart (SImode, operands[1]);
10513 })
10514
10515 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10516 ;; in particular when the displacements are in the range of the regular move
10517 ;; insns.  Thus, in the first split pass after the combine pass we search
10518 ;; for missed opportunities and try to fix them up ourselves.
10519 ;; If an equivalent GBR address can be determined the load / store is split
10520 ;; into one of the GBR load / store patterns.
10521 ;; All of that must happen before reload (GBR address modes use R0 as the
10522 ;; other operand) and there's no point of doing it if the GBR is not
10523 ;; referenced in a function at all.
10524 (define_split
10525   [(set (match_operand:QIHISIDI 0 "register_operand")
10526         (match_operand:QIHISIDI 1 "memory_operand"))]
10527   "TARGET_SH1 && !reload_in_progress && !reload_completed
10528    && df_regs_ever_live_p (GBR_REG)"
10529   [(set (match_dup 0) (match_dup 1))]
10530 {
10531   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10532   if (gbr_mem != NULL_RTX)
10533     operands[1] = replace_equiv_address (operands[1], gbr_mem);
10534   else
10535     FAIL;
10536 })
10537
10538 (define_split
10539   [(set (match_operand:SI 0 "register_operand")
10540         (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10541   "TARGET_SH1 && !reload_in_progress && !reload_completed
10542    && df_regs_ever_live_p (GBR_REG)"
10543   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10544 {
10545   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10546   if (gbr_mem != NULL_RTX)
10547     operands[1] = replace_equiv_address (operands[1], gbr_mem);
10548   else
10549     FAIL;
10550 })
10551
10552 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10553 ;; Split those so that a GBR load can be used.
10554 (define_split
10555   [(set (match_operand:SI 0 "register_operand")
10556         (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10557   "TARGET_SH2A && !reload_in_progress && !reload_completed
10558    && df_regs_ever_live_p (GBR_REG)"
10559   [(set (match_dup 2) (match_dup 1))
10560    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10561 {
10562   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10563   if (gbr_mem != NULL_RTX)
10564     {
10565       operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10566       operands[1] = replace_equiv_address (operands[1], gbr_mem);
10567     }
10568   else
10569     FAIL;
10570 })
10571
10572 (define_split
10573   [(set (match_operand:QIHISIDI 0 "memory_operand")
10574         (match_operand:QIHISIDI 1 "register_operand"))]
10575   "TARGET_SH1 && !reload_in_progress && !reload_completed
10576    && df_regs_ever_live_p (GBR_REG)"
10577   [(set (match_dup 0) (match_dup 1))]
10578 {
10579   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10580   if (gbr_mem != NULL_RTX)
10581     operands[0] = replace_equiv_address (operands[0], gbr_mem);
10582   else
10583     FAIL;
10584 })
10585
10586 ;;------------------------------------------------------------------------------
10587 ;; case instruction for switch statements.
10588
10589 ;; operand 0 is index
10590 ;; operand 1 is the minimum bound
10591 ;; operand 2 is the maximum bound - minimum bound + 1
10592 ;; operand 3 is CODE_LABEL for the table;
10593 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10594 (define_expand "casesi"
10595   [(match_operand:SI 0 "arith_reg_operand" "")
10596    (match_operand:SI 1 "arith_reg_operand" "")
10597    (match_operand:SI 2 "arith_reg_operand" "")
10598    (match_operand 3 "" "") (match_operand 4 "" "")]
10599   ""
10600 {
10601   rtx reg = gen_reg_rtx (SImode);
10602   rtx reg2 = gen_reg_rtx (SImode);
10603   if (TARGET_SHMEDIA)
10604     {
10605       rtx reg = gen_reg_rtx (DImode);
10606       rtx reg2 = gen_reg_rtx (DImode);
10607       rtx reg3 = gen_reg_rtx (Pmode);
10608       rtx reg4 = gen_reg_rtx (Pmode);
10609       rtx reg5 = gen_reg_rtx (Pmode);
10610       rtx load, test;
10611
10612       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10613       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10614       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10615
10616       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10617       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
10618                                       operands[4]));
10619       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10620       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10621       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10622       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10623       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10624                                                (Pmode, operands[3])));
10625       /* Messy: can we subreg to clean this up? */
10626       if (Pmode == DImode)
10627         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10628       else
10629         load = gen_casesi_load_media (reg4,
10630                                       gen_rtx_SUBREG (DImode, reg3, 0),
10631                                       reg2, operands[3]);
10632       PUT_MODE (SET_SRC (load), Pmode);
10633       emit_insn (load);
10634       /* ??? The following add could be eliminated if we used ptrel.  */
10635       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10636       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10637       emit_barrier ();
10638       DONE;
10639     }
10640   operands[1] = copy_to_mode_reg (SImode, operands[1]);
10641   operands[2] = copy_to_mode_reg (SImode, operands[2]);
10642   /* If optimizing, casesi_worker depends on the mode of the instruction
10643      before label it 'uses' - operands[3].  */
10644   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10645                            reg));
10646   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10647   if (TARGET_SH2)
10648     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10649   else
10650     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10651   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10652      operands[3], but to lab.  We will fix this up in
10653      machine_dependent_reorg.  */
10654   emit_barrier ();
10655   DONE;
10656 })
10657
10658 (define_expand "casesi_0"
10659   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10660    (set (match_dup 4) (minus:SI (match_dup 4)
10661                                 (match_operand:SI 1 "arith_operand" "")))
10662    (set (reg:SI T_REG)
10663         (gtu:SI (match_dup 4)
10664                 (match_operand:SI 2 "arith_reg_operand" "")))
10665    (set (pc)
10666         (if_then_else (ne (reg:SI T_REG)
10667                           (const_int 0))
10668                       (label_ref (match_operand 3 "" ""))
10669                       (pc)))]
10670   "TARGET_SH1"
10671   "")
10672
10673 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10674 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10675 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10676 (define_insn "casesi_worker_0"
10677   [(set (match_operand:SI 0 "register_operand" "=r,r")
10678         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10679                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10680    (clobber (match_scratch:SI 3 "=X,1"))
10681    (clobber (match_scratch:SI 4 "=&z,z"))]
10682   "TARGET_SH1"
10683   "#")
10684
10685 (define_split
10686   [(set (match_operand:SI 0 "register_operand" "")
10687         (unspec:SI [(match_operand:SI 1 "register_operand" "")
10688                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10689    (clobber (match_scratch:SI 3 ""))
10690    (clobber (match_scratch:SI 4 ""))]
10691   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10692   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10693    (parallel [(set (match_dup 0)
10694               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10695                           (label_ref (match_dup 2))] UNSPEC_CASESI))
10696               (clobber (match_dup 3))])
10697    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10698 {
10699   if (GET_CODE (operands[2]) == CODE_LABEL)
10700     LABEL_NUSES (operands[2])++;
10701 })
10702
10703 (define_split
10704   [(set (match_operand:SI 0 "register_operand" "")
10705         (unspec:SI [(match_operand:SI 1 "register_operand" "")
10706                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10707    (clobber (match_scratch:SI 3 ""))
10708    (clobber (match_scratch:SI 4 ""))]
10709   "TARGET_SH2 && reload_completed"
10710   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10711    (parallel [(set (match_dup 0)
10712               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10713                           (label_ref (match_dup 2))] UNSPEC_CASESI))
10714               (clobber (match_dup 3))])]
10715 {
10716   if (GET_CODE (operands[2]) == CODE_LABEL)
10717     LABEL_NUSES (operands[2])++;
10718 })
10719
10720 (define_insn "casesi_worker_1"
10721   [(set (match_operand:SI 0 "register_operand" "=r,r")
10722         (unspec:SI [(reg:SI R0_REG)
10723                     (match_operand:SI 1 "register_operand" "0,r")
10724                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10725    (clobber (match_scratch:SI 3 "=X,1"))]
10726   "TARGET_SH1"
10727 {
10728   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10729
10730   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10731
10732   switch (GET_MODE (diff_vec))
10733     {
10734     case SImode:
10735       return   "shll2   %1"     "\n"
10736              "  mov.l   @(r0,%1),%0";
10737     case HImode:
10738       return   "add     %1,%1"  "\n"
10739              "  mov.w   @(r0,%1),%0";
10740     case QImode:
10741       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10742         return         "mov.b   @(r0,%1),%0"    "\n"
10743                "        extu.b  %0,%0";
10744       else
10745         return "mov.b   @(r0,%1),%0";
10746
10747     default:
10748       gcc_unreachable ();
10749     }
10750 }
10751   [(set_attr "length" "4")])
10752
10753 (define_insn "casesi_worker_2"
10754   [(set (match_operand:SI 0 "register_operand" "=r,r")
10755         (unspec:SI [(reg:SI R0_REG)
10756                     (match_operand:SI 1 "register_operand" "0,r")
10757                     (label_ref (match_operand 2 "" ""))
10758                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10759    (clobber (match_operand:SI 4 "" "=X,1"))]
10760   "TARGET_SH2 && reload_completed && flag_pic"
10761 {
10762   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10763   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10764
10765   switch (GET_MODE (diff_vec))
10766     {
10767     case SImode:
10768       return   "shll2   %1"             "\n"
10769              "  add     r0,%1"          "\n"
10770              "  mova    %O3,r0"         "\n"
10771              "  mov.l   @(r0,%1),%0";
10772     case HImode:
10773       return   "add     %1,%1"          "\n"
10774              "  add     r0,%1"          "\n"
10775              "  mova    %O3,r0"         "\n"
10776              "  mov.w   @(r0,%1),%0";
10777     case QImode:
10778       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10779         return         "add     r0,%1"          "\n"
10780                 "       mova    %O3,r0"         "\n"
10781                 "       mov.b   @(r0,%1),%0"    "\n"
10782                 "       extu.b  %0,%0";
10783       else
10784         return         "add     r0,%1"          "\n"
10785                 "       mova    %O3,r0"         "\n"
10786                 "       mov.b   @(r0,%1),%0";
10787     default:
10788       gcc_unreachable ();
10789     }
10790 }
10791   [(set_attr "length" "8")])
10792
10793 (define_insn "casesi_shift_media"
10794   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10795         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10796                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10797                     UNSPEC_CASESI)))]
10798   "TARGET_SHMEDIA"
10799 {
10800   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10801
10802   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10803
10804   switch (GET_MODE (diff_vec))
10805     {
10806     case SImode:
10807       return "shlli     %1, 2, %0";
10808     case HImode:
10809       return "shlli     %1, 1, %0";
10810     case QImode:
10811       if (rtx_equal_p (operands[0], operands[1]))
10812         return "";
10813       return "add       %1, r63, %0";
10814     default:
10815       gcc_unreachable ();
10816     }
10817 }
10818   [(set_attr "type" "arith_media")])
10819
10820 (define_insn "casesi_load_media"
10821   [(set (match_operand 0 "any_arith_reg_dest" "=r")
10822         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
10823                       (match_operand:DI 2 "arith_reg_operand" "r")
10824                       (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
10825   "TARGET_SHMEDIA"
10826 {
10827   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
10828
10829   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10830
10831   switch (GET_MODE (diff_vec))
10832     {
10833     case SImode:
10834       return "ldx.l     %1, %2, %0";
10835     case HImode:
10836 #if 0
10837       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10838         return "ldx.uw  %1, %2, %0";
10839 #endif
10840       return "ldx.w     %1, %2, %0";
10841     case QImode:
10842       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10843         return "ldx.ub  %1, %2, %0";
10844       return "ldx.b     %1, %2, %0";
10845     default:
10846       gcc_unreachable ();
10847     }
10848 }
10849   [(set_attr "type" "load_media")])
10850
10851 (define_expand "simple_return"
10852   [(simple_return)]
10853  "sh_can_use_simple_return_p ()")
10854
10855 (define_expand "return"
10856   [(return)]
10857  "reload_completed && epilogue_completed"
10858 {
10859   if (TARGET_SHMEDIA)
10860     {
10861       emit_jump_insn (gen_return_media ());
10862       DONE;
10863     }
10864
10865   if (TARGET_SHCOMPACT
10866       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
10867     {
10868       emit_jump_insn (gen_shcompact_return_tramp ());
10869       DONE;
10870     }
10871 })
10872
10873 (define_insn "*<code>_i"
10874   [(any_return)]
10875   "TARGET_SH1 && ! (TARGET_SHCOMPACT
10876                     && (crtl->args.info.call_cookie
10877                         & CALL_COOKIE_RET_TRAMP (1)))
10878    && reload_completed
10879    && ! sh_cfun_trap_exit_p ()"
10880 {
10881   if (TARGET_SH2A && (dbr_sequence_length () == 0)
10882       && !current_function_interrupt)
10883     return "rts/n";
10884   else
10885     return "%@  %#";
10886 }
10887   [(set_attr "type" "return")
10888    (set_attr "needs_delay_slot" "yes")])
10889
10890 ;; trapa has no delay slot.
10891 (define_insn "*return_trapa"
10892   [(return)]
10893   "TARGET_SH1 && !TARGET_SHCOMPACT
10894    && reload_completed"
10895   "%@"
10896   [(set_attr "type" "return")])
10897
10898 (define_expand "shcompact_return_tramp"
10899   [(return)]
10900   "TARGET_SHCOMPACT
10901    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10902 {
10903   rtx reg = gen_rtx_REG (Pmode, R0_REG);
10904
10905   function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
10906   emit_jump_insn (gen_shcompact_return_tramp_i ());
10907   DONE;
10908 })
10909
10910 (define_insn "shcompact_return_tramp_i"
10911   [(parallel [(return) (use (reg:SI R0_REG))])]
10912   "TARGET_SHCOMPACT
10913    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10914   "jmp  @r0%#"
10915   [(set_attr "type" "jump_ind")
10916    (set_attr "needs_delay_slot" "yes")])
10917
10918 (define_insn "return_media_i"
10919   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
10920   "TARGET_SHMEDIA && reload_completed"
10921   "blink        %0, r63"
10922   [(set_attr "type" "jump_media")])
10923
10924 (define_insn "return_media_rte"
10925   [(return)]
10926   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
10927   "rte"
10928   [(set_attr "type" "jump_media")])
10929
10930 (define_expand "return_media"
10931   [(return)]
10932   "TARGET_SHMEDIA && reload_completed"
10933 {
10934   int tr_regno = sh_media_register_for_return ();
10935   rtx tr;
10936
10937   if (current_function_interrupt)
10938     {
10939       emit_jump_insn (gen_return_media_rte ());
10940       DONE;
10941     }
10942   if (tr_regno < 0)
10943     {
10944       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
10945
10946       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
10947       tr_regno = TR0_REG;
10948       tr = gen_rtx_REG (Pmode, tr_regno);
10949       emit_move_insn (tr, r18);
10950     }
10951   else
10952     tr = gen_rtx_REG (Pmode, tr_regno);
10953
10954   emit_jump_insn (gen_return_media_i (tr));
10955   DONE;
10956 })
10957
10958 (define_insn "shcompact_preserve_incoming_args"
10959   [(set (match_operand:SI 0 "register_operand" "+r")
10960         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
10961   "TARGET_SHCOMPACT"
10962   ""
10963   [(set_attr "length" "0")])
10964
10965 (define_insn "shcompact_incoming_args"
10966   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
10967    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
10968    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
10969    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
10970    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
10971    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
10972    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
10973    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
10974    (set (mem:BLK (reg:SI MACL_REG))
10975         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
10976    (use (reg:SI R0_REG))
10977    (clobber (reg:SI R0_REG))
10978    (clobber (reg:SI MACL_REG))
10979    (clobber (reg:SI MACH_REG))
10980    (clobber (reg:SI PR_REG))]
10981   "TARGET_SHCOMPACT"
10982   "jsr  @r0%#"
10983   [(set_attr "needs_delay_slot" "yes")])
10984
10985 (define_insn "shmedia_save_restore_regs_compact"
10986   [(set (reg:SI SP_REG)
10987         (plus:SI (reg:SI SP_REG)
10988                  (match_operand:SI 0 "immediate_operand" "i")))
10989    (use (reg:SI R0_REG))
10990    (clobber (reg:SI PR_REG))]
10991   "TARGET_SHCOMPACT
10992    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
10993        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
10994   "jsr @r0%#"
10995   [(set_attr "needs_delay_slot" "yes")])
10996
10997 (define_expand "prologue"
10998   [(const_int 0)]
10999   ""
11000 {
11001   sh_expand_prologue ();
11002   DONE;
11003 })
11004
11005 (define_expand "epilogue"
11006   [(return)]
11007   ""
11008 {
11009   sh_expand_epilogue (false);
11010   if (TARGET_SHMEDIA
11011       || (TARGET_SHCOMPACT
11012           && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11013     {
11014       emit_jump_insn (gen_return ());
11015       DONE;
11016     }
11017 })
11018
11019 (define_expand "eh_return"
11020   [(use (match_operand 0 "register_operand" ""))]
11021   ""
11022 {
11023   rtx ra = operands[0];
11024
11025   if (TARGET_SHMEDIA64)
11026     emit_insn (gen_eh_set_ra_di (ra));
11027   else
11028     emit_insn (gen_eh_set_ra_si (ra));
11029
11030   DONE;
11031 })
11032
11033 ;; Clobber the return address on the stack.  We can't expand this
11034 ;; until we know where it will be put in the stack frame.
11035
11036 (define_insn "eh_set_ra_si"
11037   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11038       UNSPECV_EH_RETURN)
11039    (clobber (match_scratch:SI 1 "=&r"))]
11040   "! TARGET_SHMEDIA64"
11041   "#")
11042
11043 (define_insn "eh_set_ra_di"
11044   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11045       UNSPECV_EH_RETURN)
11046    (clobber (match_scratch:DI 1 "=&r"))]
11047   "TARGET_SHMEDIA64"
11048   "#")
11049
11050 (define_split
11051   [(unspec_volatile [(match_operand 0 "register_operand" "")]
11052       UNSPECV_EH_RETURN)
11053    (clobber (match_scratch 1 ""))]
11054   "reload_completed"
11055   [(const_int 0)]
11056 {
11057   sh_set_return_address (operands[0], operands[1]);
11058   DONE;
11059 })
11060
11061 (define_insn "blockage"
11062   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11063   ""
11064   ""
11065   [(set_attr "length" "0")])
11066 \f
11067 ;; Define movml instructions for SH2A target.  Currently they are
11068 ;; used to push and pop all banked registers only.
11069
11070 (define_insn "movml_push_banked"
11071   [(set (match_operand:SI 0 "register_operand" "=r")
11072           (plus (match_dup 0) (const_int -32)))
11073    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11074    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11075    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11076    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11077    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11078    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11079    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11080    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11081   "TARGET_SH2A && REGNO (operands[0]) == 15"
11082   "movml.l      r7,@-r15"
11083   [(set_attr "in_delay_slot" "no")])
11084
11085 (define_insn "movml_pop_banked"
11086   [(set (match_operand:SI 0 "register_operand" "=r")
11087           (plus (match_dup 0) (const_int 32)))
11088    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11089    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11090    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11091    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11092    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11093    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11094    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11095    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11096   "TARGET_SH2A && REGNO (operands[0]) == 15"
11097   "movml.l      @r15+,r7"
11098   [(set_attr "in_delay_slot" "no")])
11099 \f
11100 ;; ------------------------------------------------------------------------
11101 ;; Scc instructions
11102 ;; ------------------------------------------------------------------------
11103
11104 (define_insn "movt"
11105   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11106         (match_operand:SI 1 "t_reg_operand"))]
11107   "TARGET_SH1"
11108   "movt %0"
11109   [(set_attr "type" "arith")])
11110
11111 (define_insn "movrt"
11112   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11113         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11114   "TARGET_SH2A"
11115   "movrt        %0"
11116   [(set_attr "type" "arith")])
11117
11118 (define_expand "cstore4_media"
11119   [(set (match_operand:SI 0 "register_operand" "=r")
11120         (match_operator:SI 1 "sh_float_comparison_operator"
11121          [(match_operand 2 "logical_operand" "")
11122           (match_operand 3 "cmp_operand" "")]))]
11123   "TARGET_SHMEDIA"
11124 {
11125   enum machine_mode mode = GET_MODE (operands[2]);
11126   enum rtx_code code = GET_CODE (operands[1]);
11127   bool invert, swap;
11128   if (mode == VOIDmode)
11129     mode = GET_MODE (operands[3]);
11130   if (operands[2] == const0_rtx)
11131     {
11132       if (code == EQ || code == NE)
11133         operands[2] = operands[3], operands[3] = const0_rtx;
11134     }
11135   else
11136     operands[2] = force_reg (mode, operands[2]);
11137   if (operands[3] != const0_rtx)
11138     operands[3] = force_reg (mode, operands[3]);
11139
11140   switch (code)
11141     {
11142     case GEU:
11143     case GE:
11144       swap = invert = !FLOAT_MODE_P (mode);
11145       break;
11146
11147     case LEU:
11148     case LE:
11149       swap = FLOAT_MODE_P (mode), invert = !swap;
11150       break;
11151
11152     case LTU:
11153     case LT:
11154       swap = true, invert = false;
11155       break;
11156
11157     case GTU:
11158     case GT:
11159     case EQ:
11160     case UNORDERED:
11161       swap = invert = false;
11162       break;
11163
11164     case NE:
11165       swap = invert = true;
11166       break;
11167
11168     default:
11169       gcc_unreachable ();
11170   }
11171
11172   if (swap)
11173     {
11174       rtx tem = operands[2];
11175       operands[2] = operands[3];
11176       operands[3] = tem;
11177       code = swap_condition (code);
11178     }
11179
11180   if (invert)
11181     {
11182       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11183       code = reverse_condition (code);
11184       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11185       emit_insn (gen_cstore4_media (tem, operands[1],
11186                                     operands[2], operands[3]));
11187       code = EQ;
11188       operands[2] = tem;
11189       operands[3] = const0_rtx;
11190     }
11191
11192   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11193 })
11194
11195 (define_expand "cstoresi4"
11196   [(set (match_operand:SI 0 "register_operand" "=r")
11197         (match_operator:SI 1 "comparison_operator"
11198          [(match_operand:SI 2 "cmpsi_operand" "")
11199           (match_operand:SI 3 "arith_operand" "")]))]
11200   "TARGET_SH1 || TARGET_SHMEDIA"
11201 {
11202   if (TARGET_SHMEDIA)
11203     {
11204       emit_insn (gen_cstore4_media (operands[0], operands[1],
11205                                     operands[2], operands[3]));
11206       DONE;
11207     }
11208
11209    if (sh_expand_t_scc (operands))
11210      DONE;
11211
11212    if (! currently_expanding_to_rtl)
11213      FAIL;
11214    
11215    sh_emit_compare_and_set (operands, SImode);
11216    DONE;
11217 })
11218
11219 (define_expand "cstoredi4"
11220   [(set (match_operand:SI 0 "register_operand" "=r")
11221         (match_operator:SI 1 "comparison_operator"
11222          [(match_operand:DI 2 "arith_operand" "")
11223           (match_operand:DI 3 "arith_operand" "")]))]
11224   "TARGET_SH2 || TARGET_SHMEDIA"
11225 {
11226   if (TARGET_SHMEDIA)
11227     {
11228       emit_insn (gen_cstore4_media (operands[0], operands[1],
11229                                     operands[2], operands[3]));
11230       DONE;
11231     }
11232
11233    if (sh_expand_t_scc (operands))
11234      DONE;
11235
11236    if (! currently_expanding_to_rtl)
11237      FAIL;
11238    
11239    sh_emit_compare_and_set (operands, DImode);
11240    DONE;
11241 })
11242
11243 ;; Move the complement of the T reg to a reg.
11244 ;; On SH2A the movrt insn can be used.
11245 ;; On anything else than SH2A this has to be done with multiple instructions.
11246 ;; One obvious way would be:
11247 ;;      cmp/eq  ...
11248 ;;      movt    r0
11249 ;;      xor     #1,r0
11250 ;;
11251 ;; However, this puts pressure on r0 in most cases and thus the following is
11252 ;; more appealing:
11253 ;;      cmp/eq  ...
11254 ;;      mov     #-1,temp
11255 ;;      negc    temp,dest
11256 ;;
11257 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11258 ;; becomes a one instruction operation.  Moreover, care must be taken that
11259 ;; the insn can still be combined with inverted compare and branch code
11260 ;; around it.  On the other hand, if a function returns the complement of
11261 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11262 ;; lead to better code.
11263 (define_expand "movnegt"
11264   [(set (match_operand:SI 0 "arith_reg_dest" "")
11265         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11266   "TARGET_SH1"
11267 {
11268   if (TARGET_SH2A)
11269     emit_insn (gen_movrt (operands[0], operands[1]));
11270   else
11271     {
11272       rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11273       emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11274     }
11275   DONE;
11276 })
11277
11278 (define_insn "movrt_negc"
11279   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11280         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11281    (set (reg:SI T_REG) (const_int 1))
11282    (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11283   "TARGET_SH1"
11284   "negc %2,%0"
11285   [(set_attr "type" "arith")])
11286
11287 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11288 ;; pattern can be used by the combine pass.  Using a scratch reg for the
11289 ;; -1 constant results in slightly better register allocations compared to
11290 ;; generating a pseudo reg before reload.
11291 (define_insn_and_split "*movrt_negc"
11292   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11293         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11294    (clobber (match_scratch:SI 2 "=r"))
11295    (clobber (reg:SI T_REG))]
11296   "TARGET_SH1 && ! TARGET_SH2A"
11297   "#"
11298   "&& reload_completed"
11299   [(set (match_dup 2) (const_int -1))
11300    (parallel
11301        [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11302         (set (reg:SI T_REG) (const_int 1))
11303         (use (match_dup 2))])])
11304
11305 ;; Store the negated T bit in a reg using r0 and xor.  This one doesn't
11306 ;; clobber the T bit, which is useful when storing the T bit and the
11307 ;; negated T bit in parallel.  On SH2A the movrt insn can be used for that.
11308 ;; Usually we don't want this insn to be matched, except for cases where the
11309 ;; T bit clobber is really not appreciated.  Hence the extra use on T_REG.
11310 (define_insn_and_split "movrt_xor"
11311   [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11312         (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11313    (use (reg:SI T_REG))]
11314   "TARGET_SH1 && !TARGET_SH2A"
11315   "#"
11316   "&& reload_completed"
11317   [(set (match_dup 0) (reg:SI T_REG))
11318    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11319
11320 ;; Store the T bit and the negated T bit in two regs in parallel.  There is
11321 ;; no real insn to do that, but specifying this pattern will give combine
11322 ;; some opportunities.
11323 (define_insn_and_split "*movt_movrt"
11324   [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11325                    (match_operand:SI 1 "negt_reg_operand"))
11326               (set (match_operand:SI 2 "arith_reg_dest")
11327                    (match_operand:SI 3 "t_reg_operand"))])]
11328   "TARGET_SH1"
11329   "#"
11330   "&& 1"
11331   [(const_int 0)]
11332 {
11333   rtx i = TARGET_SH2A
11334           ? gen_movrt (operands[0], get_t_reg_rtx ())
11335           : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11336   
11337   emit_insn (i);
11338   emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11339   DONE;
11340 })
11341
11342 (define_insn_and_split "*movt_movrt"
11343   [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11344                    (match_operand:SI 1 "t_reg_operand"))
11345               (set (match_operand:SI 2 "arith_reg_dest")
11346                    (match_operand:SI 3 "negt_reg_operand"))])]
11347   "TARGET_SH1"
11348   "#"
11349   "&& 1"
11350   [(parallel [(set (match_dup 2) (match_dup 3))
11351               (set (match_dup 0) (match_dup 1))])])
11352
11353 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11354 ;;      T = 1: 0x80000000 -> reg
11355 ;;      T = 0: 0x7FFFFFFF -> reg
11356 ;; This works because 0 - 0x80000000 = 0x80000000.
11357 (define_insn_and_split "*mov_t_msb_neg"
11358   [(set (match_operand:SI 0 "arith_reg_dest")
11359         (minus:SI (const_int -2147483648)  ;; 0x80000000
11360                   (match_operand 1 "t_reg_operand")))
11361    (clobber (reg:SI T_REG))]
11362   "TARGET_SH1"
11363   "#"
11364   "&& can_create_pseudo_p ()"
11365   [(set (match_dup 2) (const_int -2147483648))
11366    (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11367                                  (reg:SI T_REG)))
11368               (clobber (reg:SI T_REG))])]
11369 {
11370   operands[2] = gen_reg_rtx (SImode);
11371 })
11372
11373 ;; These are essentially the same as above, but with the inverted T bit.
11374 ;; Combine recognizes the split patterns, but does not take them sometimes
11375 ;; if the T_REG clobber is specified.  Instead it tries to split out the
11376 ;; T bit negation.  Since these splits are supposed to be taken only by
11377 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11378 ;; should be fine.
11379 (define_split
11380   [(set (match_operand:SI 0 "arith_reg_dest")
11381         (plus:SI (match_operand 1 "negt_reg_operand")
11382                  (const_int 2147483647)))]  ;; 0x7fffffff
11383   "TARGET_SH1 && can_create_pseudo_p ()"
11384   [(parallel [(set (match_dup 0)
11385                    (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11386               (clobber (reg:SI T_REG))])])
11387
11388 (define_split
11389   [(set (match_operand:SI 0 "arith_reg_dest")
11390         (if_then_else:SI (match_operand 1 "t_reg_operand")
11391                          (const_int 2147483647)  ;; 0x7fffffff
11392                          (const_int -2147483648)))]  ;; 0x80000000
11393   "TARGET_SH1 && can_create_pseudo_p ()"
11394   [(parallel [(set (match_dup 0)
11395                    (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11396               (clobber (reg:SI T_REG))])])
11397
11398 ;; The *negnegt pattern helps the combine pass to figure out how to fold 
11399 ;; an explicit double T bit negation.
11400 (define_insn_and_split "*negnegt"
11401   [(set (reg:SI T_REG)
11402         (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11403   "TARGET_SH1"
11404   "#"
11405   ""
11406   [(const_int 0)])
11407
11408 ;; Store T bit as all zeros or ones in a reg.
11409 (define_insn "mov_neg_si_t"
11410   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11411         (neg:SI (match_operand 1 "t_reg_operand" "")))]
11412   "TARGET_SH1"
11413   "subc %0,%0"
11414   [(set_attr "type" "arith")])
11415
11416 ;; Store negated T bit as all zeros or ones in a reg.
11417 ;; Use the following sequence:
11418 ;;      subc    Rn,Rn   ! Rn = Rn - Rn - T; T = T
11419 ;;      not     Rn,Rn   ! Rn = 0 - Rn
11420 (define_split
11421   [(set (match_operand:SI 0 "arith_reg_dest" "")
11422         (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11423   "TARGET_SH1"
11424   [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11425    (set (match_dup 0) (not:SI (match_dup 0)))])
11426
11427 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11428 (define_insn_and_split "*movtt"
11429   [(set (reg:SI T_REG)
11430         (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11431   "TARGET_SH1"
11432   "#"
11433   ""
11434   [(const_int 0)])
11435
11436 ;; Invert the T bit.
11437 ;; On SH2A we can use the nott insn.  On anything else this must be done with
11438 ;; multiple insns like:
11439 ;;      movt    Rn
11440 ;;      tst     Rn,Rn
11441 (define_insn_and_split "nott"
11442   [(set (reg:SI T_REG)
11443         (xor:SI (match_operand:SI 0 "t_reg_operand" "") (const_int 1)))]
11444   "TARGET_SH1"
11445 {
11446   gcc_assert (TARGET_SH2A);
11447   return "nott";
11448 }
11449   "! TARGET_SH2A && can_create_pseudo_p ()"
11450   [(set (match_dup 0) (reg:SI T_REG))
11451    (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11452 {
11453   operands[0] = gen_reg_rtx (SImode);
11454 })
11455
11456 ;; Store T bit as MSB in a reg.
11457 ;; T = 0: 0x00000000 -> reg
11458 ;; T = 1: 0x80000000 -> reg
11459 (define_insn_and_split "*movt_msb"
11460   [(set (match_operand:SI 0 "arith_reg_dest")
11461         (mult:SI (match_operand:SI 1 "t_reg_operand")
11462                  (const_int -2147483648)))  ;; 0xffffffff80000000
11463    (clobber (reg:SI T_REG))]
11464   "TARGET_SH1"
11465   "#"
11466   "&& 1"
11467   [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11468
11469 ;; Store inverted T bit as MSB in a reg.
11470 ;; T = 0: 0x80000000 -> reg
11471 ;; T = 1: 0x00000000 -> reg
11472 ;; On SH2A we can get away without clobbering the T_REG.
11473 (define_insn_and_split "*negt_msb"
11474   [(set (match_operand:SI 0 "arith_reg_dest")
11475         (match_operand:SI 1 "negt_reg_shl31_operand"))]
11476   "TARGET_SH2A"
11477   "#"
11478   "&& can_create_pseudo_p ()"
11479   [(const_int 0)]
11480 {
11481   rtx tmp = gen_reg_rtx (SImode);
11482   emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11483   emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11484   DONE;
11485 })
11486
11487 (define_insn_and_split "*negt_msb"
11488   [(set (match_operand:SI 0 "arith_reg_dest")
11489         (match_operand:SI 1 "negt_reg_shl31_operand"))
11490    (clobber (reg:SI T_REG))]
11491   "TARGET_SH1 && !TARGET_SH2A"
11492   "#"
11493   "&& can_create_pseudo_p ()"
11494   [(const_int 0)]
11495 {
11496   rtx tmp = gen_reg_rtx (SImode);
11497   emit_move_insn (tmp, get_t_reg_rtx ());
11498   emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11499   emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11500   DONE;
11501 })
11502
11503 ;; The *cset_zero patterns convert optimizations such as
11504 ;;      "if (test) x = 0;"
11505 ;; to
11506 ;;      "x &= -(test == 0);"
11507 ;; back to conditional branch sequences if zero-displacement branches
11508 ;; are enabled.
11509 ;; FIXME: These patterns can be removed when conditional execution patterns
11510 ;; are implemented, since ifcvt will not perform these optimizations if
11511 ;; conditional execution is supported.
11512 (define_insn "*cset_zero"
11513   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11514         (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11515                          (const_int -1))
11516                 (match_operand:SI 2 "arith_reg_operand" "0")))]
11517   "TARGET_SH1 && TARGET_ZDCBRANCH"
11518 {
11519   return       "bf      0f"     "\n"
11520          "      mov     #0,%0"  "\n"
11521          "0:";
11522 }
11523   [(set_attr "type" "arith") ;; poor approximation
11524    (set_attr "length" "4")])
11525
11526 (define_insn "*cset_zero"
11527   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11528         (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
11529                          (match_operand:SI 2 "arith_reg_operand" "0")
11530                          (const_int 0)))]
11531   "TARGET_SH1 && TARGET_ZDCBRANCH"
11532 {
11533   return       "bt      0f"     "\n"
11534          "      mov     #0,%0"  "\n"
11535          "0:";
11536 }
11537   [(set_attr "type" "arith") ;; poor approximation
11538    (set_attr "length" "4")])
11539
11540 (define_expand "cstoresf4"
11541   [(set (match_operand:SI 0 "register_operand" "=r")
11542         (match_operator:SI 1 "sh_float_comparison_operator"
11543          [(match_operand:SF 2 "arith_operand" "")
11544           (match_operand:SF 3 "arith_operand" "")]))]
11545   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11546 {
11547   if (TARGET_SHMEDIA)
11548     {
11549       emit_insn (gen_cstore4_media (operands[0], operands[1],
11550                                     operands[2], operands[3]));
11551       DONE;
11552     }
11553
11554   if (! currently_expanding_to_rtl)
11555     FAIL;
11556    
11557   sh_emit_compare_and_set (operands, SFmode);
11558   DONE;
11559 })
11560
11561 (define_expand "cstoredf4"
11562   [(set (match_operand:SI 0 "register_operand" "=r")
11563         (match_operator:SI 1 "sh_float_comparison_operator"
11564          [(match_operand:DF 2 "arith_operand" "")
11565           (match_operand:DF 3 "arith_operand" "")]))]
11566   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11567 {
11568   if (TARGET_SHMEDIA)
11569     {
11570       emit_insn (gen_cstore4_media (operands[0], operands[1],
11571                                     operands[2], operands[3]));
11572       DONE;
11573     }
11574
11575   if (! currently_expanding_to_rtl)
11576     FAIL;
11577    
11578   sh_emit_compare_and_set (operands, DFmode);
11579   DONE;
11580 })
11581
11582 ;; -------------------------------------------------------------------------
11583 ;; Instructions to cope with inline literal tables
11584 ;; -------------------------------------------------------------------------
11585
11586 ;; 2 byte integer in line
11587 (define_insn "consttable_2"
11588  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11589                     (match_operand 1 "" "")]
11590                    UNSPECV_CONST2)]
11591  ""
11592 {
11593   if (operands[1] != const0_rtx)
11594     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11595   return "";
11596 }
11597  [(set_attr "length" "2")
11598  (set_attr "in_delay_slot" "no")])
11599
11600 ;; 4 byte integer in line
11601 (define_insn "consttable_4"
11602  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11603                     (match_operand 1 "" "")]
11604                    UNSPECV_CONST4)]
11605  ""
11606 {
11607   if (operands[1] != const0_rtx)
11608     {
11609       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11610       mark_symbol_refs_as_used (operands[0]);
11611     }
11612   return "";
11613 }
11614  [(set_attr "length" "4")
11615   (set_attr "in_delay_slot" "no")])
11616
11617 ;; 8 byte integer in line
11618 (define_insn "consttable_8"
11619  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11620                     (match_operand 1 "" "")]
11621                    UNSPECV_CONST8)]
11622  ""
11623 {
11624   if (operands[1] != const0_rtx)
11625     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11626   return "";
11627 }
11628  [(set_attr "length" "8")
11629   (set_attr "in_delay_slot" "no")])
11630
11631 ;; 4 byte floating point
11632 (define_insn "consttable_sf"
11633  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11634                     (match_operand 1 "" "")]
11635                    UNSPECV_CONST4)]
11636  ""
11637 {
11638   if (operands[1] != const0_rtx)
11639     {
11640       REAL_VALUE_TYPE d;
11641       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11642       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11643     }
11644   return "";
11645 }
11646  [(set_attr "length" "4")
11647   (set_attr "in_delay_slot" "no")])
11648
11649 ;; 8 byte floating point
11650 (define_insn "consttable_df"
11651  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11652                     (match_operand 1 "" "")]
11653                    UNSPECV_CONST8)]
11654  ""
11655 {
11656   if (operands[1] != const0_rtx)
11657     {
11658       REAL_VALUE_TYPE d;
11659       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11660       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11661     }
11662   return "";
11663 }
11664  [(set_attr "length" "8")
11665   (set_attr "in_delay_slot" "no")])
11666
11667 ;; Alignment is needed for some constant tables; it may also be added for
11668 ;; Instructions at the start of loops, or after unconditional branches.
11669 ;; ??? We would get more accurate lengths if we did instruction
11670 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11671 ;; here is too conservative.
11672
11673 ;; align to a two byte boundary
11674 (define_expand "align_2"
11675  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11676  ""
11677  "")
11678
11679 ;; Align to a four byte boundary.
11680 ;; align_4 and align_log are instructions for the starts of loops, or
11681 ;; after unconditional branches, which may take up extra room.
11682 (define_expand "align_4"
11683  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11684  ""
11685  "")
11686
11687 ;; Align to a cache line boundary.
11688 (define_insn "align_log"
11689  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11690  ""
11691  ""
11692  [(set_attr "length" "0")
11693   (set_attr "in_delay_slot" "no")])
11694
11695 ;; Emitted at the end of the literal table, used to emit the
11696 ;; 32bit branch labels if needed.
11697 (define_insn "consttable_end"
11698   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11699   ""
11700 {
11701   return output_jump_label_table ();
11702 }
11703   [(set_attr "in_delay_slot" "no")])
11704
11705 ;; Emitted at the end of the window in the literal table.
11706 (define_insn "consttable_window_end"
11707   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11708   ""
11709   ""
11710   [(set_attr "length" "0")
11711    (set_attr "in_delay_slot" "no")])
11712
11713 ;; -------------------------------------------------------------------------
11714 ;; Misc
11715 ;; -------------------------------------------------------------------------
11716
11717 ;; String/block move insn.
11718
11719 (define_expand "movmemsi"
11720   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
11721                    (mem:BLK (match_operand:BLK 1 "" "")))
11722               (use (match_operand:SI 2 "nonmemory_operand" ""))
11723               (use (match_operand:SI 3 "immediate_operand" ""))
11724               (clobber (reg:SI PR_REG))
11725               (clobber (reg:SI R4_REG))
11726               (clobber (reg:SI R5_REG))
11727               (clobber (reg:SI R0_REG))])]
11728   "TARGET_SH1 && ! TARGET_SH5"
11729 {
11730   if(expand_block_move (operands))
11731      DONE;
11732   else FAIL;
11733 })
11734
11735 (define_insn "block_move_real"
11736   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11737                    (mem:BLK (reg:SI R5_REG)))
11738               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11739               (clobber (reg:SI PR_REG))
11740               (clobber (reg:SI R0_REG))])]
11741   "TARGET_SH1 && ! TARGET_HARD_SH4"
11742   "jsr  @%0%#"
11743   [(set_attr "type" "sfunc")
11744    (set_attr "needs_delay_slot" "yes")])
11745
11746 (define_insn "block_lump_real"
11747   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11748                    (mem:BLK (reg:SI R5_REG)))
11749               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11750               (use (reg:SI R6_REG))
11751               (clobber (reg:SI PR_REG))
11752               (clobber (reg:SI T_REG))
11753               (clobber (reg:SI R4_REG))
11754               (clobber (reg:SI R5_REG))
11755               (clobber (reg:SI R6_REG))
11756               (clobber (reg:SI R0_REG))])]
11757   "TARGET_SH1 && ! TARGET_HARD_SH4"
11758   "jsr  @%0%#"
11759   [(set_attr "type" "sfunc")
11760    (set_attr "needs_delay_slot" "yes")])
11761
11762 (define_insn "block_move_real_i4"
11763   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11764                    (mem:BLK (reg:SI R5_REG)))
11765               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11766               (clobber (reg:SI PR_REG))
11767               (clobber (reg:SI R0_REG))
11768               (clobber (reg:SI R1_REG))
11769               (clobber (reg:SI R2_REG))])]
11770   "TARGET_HARD_SH4"
11771   "jsr  @%0%#"
11772   [(set_attr "type" "sfunc")
11773    (set_attr "needs_delay_slot" "yes")])
11774
11775 (define_insn "block_lump_real_i4"
11776   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11777                    (mem:BLK (reg:SI R5_REG)))
11778               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11779               (use (reg:SI R6_REG))
11780               (clobber (reg:SI PR_REG))
11781               (clobber (reg:SI T_REG))
11782               (clobber (reg:SI R4_REG))
11783               (clobber (reg:SI R5_REG))
11784               (clobber (reg:SI R6_REG))
11785               (clobber (reg:SI R0_REG))
11786               (clobber (reg:SI R1_REG))
11787               (clobber (reg:SI R2_REG))
11788               (clobber (reg:SI R3_REG))])]
11789   "TARGET_HARD_SH4"
11790   "jsr  @%0%#"
11791   [(set_attr "type" "sfunc")
11792    (set_attr "needs_delay_slot" "yes")])
11793 \f
11794 ;; -------------------------------------------------------------------------
11795 ;; Floating point instructions.
11796 ;; -------------------------------------------------------------------------
11797
11798 ;; ??? All patterns should have a type attribute.
11799
11800 (define_expand "movpsi"
11801   [(set (match_operand:PSI 0 "register_operand" "")
11802         (match_operand:PSI 1 "general_movsrc_operand" ""))]
11803   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11804   "")
11805
11806 ;; The c / m alternative is a fake to guide reload to load directly into
11807 ;; fpscr, since reload doesn't know how to use post-increment.
11808 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
11809 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
11810 ;; predicate after reload.
11811 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
11812 ;; like a mac -> gpr move.
11813 (define_insn "fpu_switch"
11814   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
11815         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
11816   "TARGET_SH2E
11817    && (! reload_completed
11818        || true_regnum (operands[0]) != FPSCR_REG
11819        || !MEM_P (operands[1])
11820        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
11821   "@
11822         ! precision stays the same
11823         lds.l   %1,fpscr
11824         mov.l   %1,%0
11825         #
11826         lds     %1,fpscr
11827         mov     %1,%0
11828         mov.l   %1,%0
11829         sts     fpscr,%0
11830         sts.l   fpscr,%0"
11831   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
11832    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,
11833                      mac_gp,fstore")])
11834
11835 (define_peephole2
11836   [(set (reg:PSI FPSCR_REG)
11837         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
11839   [(const_int 0)]
11840 {
11841   rtx fpscr, mem, new_insn;
11842
11843   fpscr = SET_DEST (PATTERN (curr_insn));
11844   mem = SET_SRC (PATTERN (curr_insn));
11845   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11846
11847   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11848   add_reg_note (new_insn, REG_INC, operands[0]);
11849   DONE;
11850 })
11851
11852 (define_split
11853   [(set (reg:PSI FPSCR_REG)
11854         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11855   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
11856    && (flag_peephole2 ? epilogue_completed : reload_completed)"
11857   [(const_int 0)]
11858 {
11859   rtx fpscr, mem, new_insn;
11860
11861   fpscr = SET_DEST (PATTERN (curr_insn));
11862   mem = SET_SRC (PATTERN (curr_insn));
11863   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11864
11865   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11866   add_reg_note (new_insn, REG_INC, operands[0]);
11867
11868   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
11869     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
11870   DONE;
11871 })
11872
11873 ;; ??? This uses the fp unit, but has no type indicating that.
11874 ;; If we did that, this would either give a bogus latency or introduce
11875 ;; a bogus FIFO constraint.
11876 ;; Since this insn is currently only used for prologues/epilogues,
11877 ;; it is probably best to claim no function unit, which matches the
11878 ;; current setting.
11879 (define_insn "toggle_sz"
11880   [(set (reg:PSI FPSCR_REG)
11881         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
11882   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11883   "fschg"
11884   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
11885
11886 ;; There's no way we can use it today, since optimize mode switching
11887 ;; doesn't enable us to know from which mode we're switching to the
11888 ;; mode it requests, to tell whether we can use a relative mode switch
11889 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
11890 ;; memory).
11891 (define_insn "toggle_pr"
11892   [(set (reg:PSI FPSCR_REG)
11893         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
11894   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
11895   "fpchg"
11896   [(set_attr "type" "fpscr_toggle")])
11897
11898 (define_expand "addsf3"
11899   [(set (match_operand:SF 0 "arith_reg_operand" "")
11900         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
11901                  (match_operand:SF 2 "arith_reg_operand" "")))]
11902   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11903 {
11904   if (TARGET_SH2E)
11905     {
11906       expand_sf_binop (&gen_addsf3_i, operands);
11907       DONE;
11908     }
11909 })
11910
11911 (define_insn "*addsf3_media"
11912   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11913         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
11914                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11915   "TARGET_SHMEDIA_FPU"
11916   "fadd.s       %1, %2, %0"
11917   [(set_attr "type" "fparith_media")])
11918
11919 (define_insn_and_split "unary_sf_op"
11920   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11921         (vec_select:V2SF
11922          (vec_concat:V2SF
11923           (vec_select:SF
11924            (match_dup 0)
11925            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
11926           (match_operator:SF 2 "unary_float_operator"
11927             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11928                             (parallel [(match_operand 4
11929                                         "const_int_operand" "n")]))]))
11930          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
11931   "TARGET_SHMEDIA_FPU"
11932   "#"
11933   "TARGET_SHMEDIA_FPU && reload_completed"
11934   [(set (match_dup 5) (match_dup 6))]
11935 {
11936   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11937   rtx op1 = gen_rtx_REG (SFmode,
11938                          (true_regnum (operands[1])
11939                           + (INTVAL (operands[4]) ^ endian)));
11940
11941   operands[7] = gen_rtx_REG (SFmode,
11942                              (true_regnum (operands[0])
11943                               + (INTVAL (operands[3]) ^ endian)));
11944   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
11945 }
11946   [(set_attr "type" "fparith_media")])
11947
11948 (define_insn_and_split "binary_sf_op0"
11949   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11950         (vec_concat:V2SF
11951           (match_operator:SF 3 "binary_float_operator"
11952             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11953                             (parallel [(const_int 0)]))
11954              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11955                             (parallel [(const_int 0)]))])
11956           (vec_select:SF
11957            (match_dup 0)
11958            (parallel [(const_int 1)]))))]
11959   "TARGET_SHMEDIA_FPU"
11960   "#"
11961   "&& reload_completed"
11962   [(set (match_dup 4) (match_dup 5))]
11963 {
11964   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11965   rtx op1 = gen_rtx_REG (SFmode,
11966                          true_regnum (operands[1]) + endian);
11967   rtx op2 = gen_rtx_REG (SFmode,
11968                          true_regnum (operands[2]) + endian);
11969
11970   operands[4] = gen_rtx_REG (SFmode,
11971                              true_regnum (operands[0]) + endian);
11972   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11973 }
11974   [(set_attr "type" "fparith_media")])
11975
11976 (define_insn_and_split "binary_sf_op1"
11977   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11978         (vec_concat:V2SF
11979           (vec_select:SF
11980            (match_dup 0)
11981            (parallel [(const_int 0)]))
11982           (match_operator:SF 3 "binary_float_operator"
11983             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11984                             (parallel [(const_int 1)]))
11985              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11986                             (parallel [(const_int 1)]))])))]
11987   "TARGET_SHMEDIA_FPU"
11988   "#"
11989   "&& reload_completed"
11990   [(set (match_dup 4) (match_dup 5))]
11991 {
11992   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11993   rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
11994   rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
11995
11996   operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
11997   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11998 }
11999   [(set_attr "type" "fparith_media")])
12000
12001 (define_insn "addsf3_i"
12002   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12003         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12004                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12005    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12006   "TARGET_SH2E"
12007   "fadd %2,%0"
12008   [(set_attr "type" "fp")
12009    (set_attr "fp_mode" "single")])
12010
12011 (define_expand "subsf3"
12012   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12013         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12014                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12015   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12016 {
12017   if (TARGET_SH2E)
12018     {
12019       expand_sf_binop (&gen_subsf3_i, operands);
12020       DONE;
12021     }
12022 })
12023
12024 (define_insn "*subsf3_media"
12025   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12026         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12027                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12028   "TARGET_SHMEDIA_FPU"
12029   "fsub.s       %1, %2, %0"
12030   [(set_attr "type" "fparith_media")])
12031
12032 (define_insn "subsf3_i"
12033   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12034         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12035                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12036    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12037   "TARGET_SH2E"
12038   "fsub %2,%0"
12039   [(set_attr "type" "fp")
12040    (set_attr "fp_mode" "single")])
12041
12042 (define_expand "mulsf3"
12043   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12044         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12045                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12046   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12047 {
12048   if (TARGET_SH2E)
12049     {
12050       emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2],
12051                  get_fpscr_rtx ()));
12052       DONE;
12053     }
12054 })
12055
12056 (define_insn "*mulsf3_media"
12057   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12058         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12059                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12060   "TARGET_SHMEDIA_FPU"
12061   "fmul.s       %1, %2, %0"
12062   [(set_attr "type" "fparith_media")])
12063
12064 (define_insn "mulsf3_i"
12065   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12066         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12067                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12068    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12069   "TARGET_SH2E"
12070   "fmul %2,%0"
12071   [(set_attr "type" "fp")
12072    (set_attr "fp_mode" "single")])
12073
12074 ;; FMA (fused multiply-add) patterns
12075 (define_expand "fmasf4"
12076   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12077         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12078                 (match_operand:SF 2 "fp_arith_reg_operand" "")
12079                 (match_operand:SF 3 "fp_arith_reg_operand" "")))]
12080   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12081 {
12082   if (TARGET_SH2E)
12083     {
12084       emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12085                                   operands[3], get_fpscr_rtx ()));
12086       DONE;
12087     }
12088 })
12089
12090 (define_insn "fmasf4_i"
12091   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12092         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12093                 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12094                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12095    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
12096   "TARGET_SH2E"
12097   "fmac %1,%2,%0"
12098   [(set_attr "type" "fp")
12099    (set_attr "fp_mode" "single")])
12100
12101 (define_insn "fmasf4_media"
12102   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12103         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12104                 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12105                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12106   "TARGET_SHMEDIA_FPU"
12107   "fmac.s %1, %2, %0"
12108   [(set_attr "type" "fparith_media")])
12109
12110 (define_expand "divsf3"
12111   [(set (match_operand:SF 0 "arith_reg_operand" "")
12112         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
12113                 (match_operand:SF 2 "arith_reg_operand" "")))]
12114   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12115 {
12116   if (TARGET_SH2E)
12117     {
12118       expand_sf_binop (&gen_divsf3_i, operands);
12119       DONE;
12120     }
12121 })
12122
12123 (define_insn "*divsf3_media"
12124   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12125         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12126                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12127   "TARGET_SHMEDIA_FPU"
12128   "fdiv.s       %1, %2, %0"
12129   [(set_attr "type" "fdiv_media")])
12130
12131 (define_insn "divsf3_i"
12132   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
12133         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
12134                  (match_operand:SF 2 "arith_reg_operand" "f")))
12135    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12136   "TARGET_SH2E"
12137   "fdiv %2,%0"
12138   [(set_attr "type" "fdiv")
12139    (set_attr "fp_mode" "single")])
12140
12141 (define_insn "floatdisf2"
12142   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12143         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12144   "TARGET_SHMEDIA_FPU"
12145   "float.qs %1, %0"
12146   [(set_attr "type" "fpconv_media")])
12147
12148 (define_expand "floatsisf2"
12149   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12150         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12151   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12152 {
12153   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12154     {
12155       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1],
12156                                        get_fpscr_rtx ()));
12157       DONE;
12158     }
12159 })
12160
12161 (define_insn "*floatsisf2_media"
12162   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12163         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12164   "TARGET_SHMEDIA_FPU"
12165   "float.ls     %1, %0"
12166   [(set_attr "type" "fpconv_media")])
12167
12168 (define_insn "floatsisf2_i4"
12169   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12170         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12171    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12172   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12173   "float        %1,%0"
12174   [(set_attr "type" "fp")
12175    (set_attr "fp_mode" "single")])
12176
12177 (define_insn "*floatsisf2_ie"
12178   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12179         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
12180   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12181   "float        %1,%0"
12182   [(set_attr "type" "fp")])
12183
12184 (define_insn "fix_truncsfdi2"
12185   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12186         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12187   "TARGET_SHMEDIA_FPU"
12188   "ftrc.sq %1, %0"
12189   [(set_attr "type" "fpconv_media")])
12190
12191 (define_expand "fix_truncsfsi2"
12192   [(set (match_operand:SI 0 "fpul_operand" "=y")
12193         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12194   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12195 {
12196   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12197     {
12198       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1],
12199                                            get_fpscr_rtx ()));
12200       DONE;
12201     }
12202 })
12203
12204 (define_insn "*fix_truncsfsi2_media"
12205   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12206         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12207   "TARGET_SHMEDIA_FPU"
12208   "ftrc.sl      %1, %0"
12209   [(set_attr "type" "fpconv_media")])
12210
12211 (define_insn "fix_truncsfsi2_i4"
12212   [(set (match_operand:SI 0 "fpul_operand" "=y")
12213         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12214    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12215   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12216   "ftrc %1,%0"
12217   [(set_attr "type" "ftrc_s")
12218    (set_attr "fp_mode" "single")])
12219
12220 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
12221 ;; fix_truncsfsi2_i4.
12222 ;; (define_insn "fix_truncsfsi2_i4_2"
12223 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12224 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12225 ;;   (use (reg:PSI FPSCR_REG))
12226 ;;   (clobber (reg:SI FPUL_REG))]
12227 ;;  "TARGET_SH4"
12228 ;;  "#"
12229 ;;  [(set_attr "length" "4")
12230 ;;   (set_attr "fp_mode" "single")])
12231
12232 ;;(define_split
12233 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12234 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12235 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
12236 ;;   (clobber (reg:SI FPUL_REG))]
12237 ;;  "TARGET_SH4"
12238 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12239 ;;            (use (match_dup 2))])
12240 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
12241
12242 (define_insn "*fixsfsi"
12243   [(set (match_operand:SI 0 "fpul_operand" "=y")
12244         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12245   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12246   "ftrc %1,%0"
12247   [(set_attr "type" "fp")])
12248
12249 (define_insn "cmpgtsf_t"
12250   [(set (reg:SI T_REG)
12251         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12252                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12253   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12254   "fcmp/gt      %1,%0"
12255   [(set_attr "type" "fp_cmp")
12256    (set_attr "fp_mode" "single")])
12257
12258 (define_insn "cmpeqsf_t"
12259   [(set (reg:SI T_REG)
12260         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12261                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12262   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12263   "fcmp/eq      %1,%0"
12264   [(set_attr "type" "fp_cmp")
12265    (set_attr "fp_mode" "single")])
12266
12267 (define_insn "ieee_ccmpeqsf_t"
12268   [(set (reg:SI T_REG)
12269         (ior:SI (reg:SI T_REG)
12270                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12271                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
12272   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12273 {
12274   return output_ieee_ccmpeq (insn, operands);
12275 }
12276   [(set_attr "length" "4")])
12277
12278
12279 (define_insn "cmpgtsf_t_i4"
12280   [(set (reg:SI T_REG)
12281         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12282                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12283    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12284   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12285   "fcmp/gt      %1,%0"
12286   [(set_attr "type" "fp_cmp")
12287    (set_attr "fp_mode" "single")])
12288
12289 (define_insn "cmpeqsf_t_i4"
12290   [(set (reg:SI T_REG)
12291         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12292                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12293    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12294   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12295   "fcmp/eq      %1,%0"
12296   [(set_attr "type" "fp_cmp")
12297    (set_attr "fp_mode" "single")])
12298
12299 (define_insn "*ieee_ccmpeqsf_t_4"
12300   [(set (reg:SI T_REG)
12301         (ior:SI (reg:SI T_REG)
12302                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12303                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12304    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12305   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12306 {
12307   return output_ieee_ccmpeq (insn, operands);
12308 }
12309   [(set_attr "length" "4")
12310    (set_attr "fp_mode" "single")])
12311
12312 (define_insn "cmpeqsf_media"
12313   [(set (match_operand:SI 0 "register_operand" "=r")
12314         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12315                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12316   "TARGET_SHMEDIA_FPU"
12317   "fcmpeq.s     %1, %2, %0"
12318   [(set_attr "type" "fcmp_media")])
12319
12320 (define_insn "cmpgtsf_media"
12321   [(set (match_operand:SI 0 "register_operand" "=r")
12322         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12323                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12324   "TARGET_SHMEDIA_FPU"
12325   "fcmpgt.s     %1, %2, %0"
12326   [(set_attr "type" "fcmp_media")])
12327
12328 (define_insn "cmpgesf_media"
12329   [(set (match_operand:SI 0 "register_operand" "=r")
12330         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12331                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12332   "TARGET_SHMEDIA_FPU"
12333   "fcmpge.s     %1, %2, %0"
12334   [(set_attr "type" "fcmp_media")])
12335
12336 (define_insn "cmpunsf_media"
12337   [(set (match_operand:SI 0 "register_operand" "=r")
12338         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12339                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12340   "TARGET_SHMEDIA_FPU"
12341   "fcmpun.s     %1, %2, %0"
12342   [(set_attr "type" "fcmp_media")])
12343
12344 (define_expand "cbranchsf4"
12345   [(set (pc)
12346         (if_then_else (match_operator 0 "sh_float_comparison_operator"
12347                        [(match_operand:SF 1 "arith_operand" "")
12348                         (match_operand:SF 2 "arith_operand" "")])
12349                       (match_operand 3 "" "")
12350                       (pc)))]
12351   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12352 {
12353   if (TARGET_SHMEDIA)
12354     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12355                                           operands[3]));
12356   else
12357     sh_emit_compare_and_branch (operands, SFmode);
12358   DONE;
12359 })
12360
12361 (define_expand "negsf2"
12362   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12363         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12364   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12365 {
12366   if (TARGET_SH2E)
12367     {
12368       expand_sf_unop (&gen_negsf2_i, operands);
12369       DONE;
12370     }
12371 })
12372
12373 (define_insn "*negsf2_media"
12374   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12375         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12376   "TARGET_SHMEDIA_FPU"
12377   "fneg.s       %1, %0"
12378   [(set_attr "type" "fmove_media")])
12379
12380 (define_insn "negsf2_i"
12381   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12382         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12383    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12384   "TARGET_SH2E"
12385   "fneg %0"
12386   [(set_attr "type" "fmove")
12387    (set_attr "fp_mode" "single")])
12388
12389 (define_expand "sqrtsf2"
12390   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12391         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12392   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12393 {
12394   if (TARGET_SH3E)
12395     {
12396       expand_sf_unop (&gen_sqrtsf2_i, operands);
12397       DONE;
12398     }
12399 })
12400
12401 (define_insn "*sqrtsf2_media"
12402   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12403         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12404   "TARGET_SHMEDIA_FPU"
12405   "fsqrt.s      %1, %0"
12406   [(set_attr "type" "fdiv_media")])
12407
12408 (define_insn "sqrtsf2_i"
12409   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12410         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12411    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12412   "TARGET_SH3E"
12413   "fsqrt        %0"
12414   [(set_attr "type" "fdiv")
12415    (set_attr "fp_mode" "single")])
12416
12417 (define_insn "rsqrtsf2"
12418   [(set (match_operand:SF 0 "register_operand" "=f")
12419         (div:SF (match_operand:SF 1 "immediate_operand" "i")
12420                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
12421    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12422   "TARGET_FPU_ANY && TARGET_FSRRA
12423    && operands[1] == CONST1_RTX (SFmode)"
12424   "fsrra        %0"
12425   [(set_attr "type" "fsrra")
12426    (set_attr "fp_mode" "single")])
12427
12428 ;; When the sincos pattern is defined, the builtin functions sin and cos
12429 ;; will be expanded to the sincos pattern and one of the output values will
12430 ;; remain unused.
12431 (define_expand "sincossf3"
12432   [(set (match_operand:SF 0 "nonimmediate_operand")
12433         (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12434    (set (match_operand:SF 1 "nonimmediate_operand")
12435         (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12436   "TARGET_FPU_ANY && TARGET_FSCA"
12437 {
12438   rtx scaled = gen_reg_rtx (SFmode);
12439   rtx truncated = gen_reg_rtx (SImode);
12440   rtx fsca = gen_reg_rtx (V2SFmode);
12441   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12442
12443   emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12444   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
12445   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
12446                           get_fpscr_rtx ()));
12447
12448   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12449   emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12450   DONE;
12451 })
12452
12453 (define_insn_and_split "fsca"
12454   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12455         (vec_concat:V2SF
12456          (unspec:SF [(mult:SF
12457                       (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12458                       (match_operand:SF 2 "fsca_scale_factor" "i"))
12459                     ] UNSPEC_FSINA)
12460          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12461                     ] UNSPEC_FCOSA)))
12462    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12463   "TARGET_FPU_ANY && TARGET_FSCA"
12464   "fsca fpul,%d0"
12465   "&& !fpul_operand (operands[1], SImode)"
12466   [(const_int 0)]
12467 {
12468   /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12469      to a simple reg, otherwise reload will have trouble reloading the
12470      pseudo into fpul.  */
12471   rtx x = XEXP (operands[1], 0);
12472   while (x != NULL_RTX && !fpul_operand (x, SImode))
12473     {
12474       gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12475       x = XEXP (x, 0);
12476     }
12477
12478   gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12479   emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
12480   DONE;
12481 }
12482   [(set_attr "type" "fsca")
12483    (set_attr "fp_mode" "single")])
12484
12485 (define_expand "abssf2"
12486   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12487         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12488   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12489 {
12490   if (TARGET_SH2E)
12491     {
12492       expand_sf_unop (&gen_abssf2_i, operands);
12493       DONE;
12494     }
12495 })
12496
12497 (define_insn "*abssf2_media"
12498   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12499         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12500   "TARGET_SHMEDIA_FPU"
12501   "fabs.s       %1, %0"
12502   [(set_attr "type" "fmove_media")])
12503
12504 (define_insn "abssf2_i"
12505   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12506         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12507    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12508   "TARGET_SH2E"
12509   "fabs %0"
12510   [(set_attr "type" "fmove")
12511    (set_attr "fp_mode" "single")])
12512
12513 (define_expand "adddf3"
12514   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12515         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12516                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12517   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12518 {
12519   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12520     {
12521       expand_df_binop (&gen_adddf3_i, operands);
12522       DONE;
12523     }
12524 })
12525
12526 (define_insn "*adddf3_media"
12527   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12528         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12529                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12530   "TARGET_SHMEDIA_FPU"
12531   "fadd.d       %1, %2, %0"
12532   [(set_attr "type" "dfparith_media")])
12533
12534 (define_insn "adddf3_i"
12535   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12536         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12537                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12538    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12539   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12540   "fadd %2,%0"
12541   [(set_attr "type" "dfp_arith")
12542    (set_attr "fp_mode" "double")])
12543
12544 (define_expand "subdf3"
12545   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12546         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12547                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12548   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12549 {
12550   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12551     {
12552       expand_df_binop (&gen_subdf3_i, operands);
12553       DONE;
12554     }
12555 })
12556
12557 (define_insn "*subdf3_media"
12558   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12559         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12560                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12561   "TARGET_SHMEDIA_FPU"
12562   "fsub.d       %1, %2, %0"
12563   [(set_attr "type" "dfparith_media")])
12564
12565 (define_insn "subdf3_i"
12566   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12567         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12568                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12569    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12570   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12571   "fsub %2,%0"
12572   [(set_attr "type" "dfp_arith")
12573    (set_attr "fp_mode" "double")])
12574
12575 (define_expand "muldf3"
12576   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12577         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12578                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12579   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12580 {
12581   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12582     {
12583       expand_df_binop (&gen_muldf3_i, operands);
12584       DONE;
12585     }
12586 })
12587
12588 (define_insn "*muldf3_media"
12589   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12590         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12591                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12592   "TARGET_SHMEDIA_FPU"
12593   "fmul.d       %1, %2, %0"
12594   [(set_attr "type" "dfmul_media")])
12595
12596 (define_insn "muldf3_i"
12597   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12598         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12599                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12600    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12601   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12602   "fmul %2,%0"
12603   [(set_attr "type" "dfp_mul")
12604    (set_attr "fp_mode" "double")])
12605
12606 (define_expand "divdf3"
12607   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12608         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12609                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12610   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12611 {
12612   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12613     {
12614       expand_df_binop (&gen_divdf3_i, operands);
12615       DONE;
12616     }
12617 })
12618
12619 (define_insn "*divdf3_media"
12620   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12621         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12622                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12623   "TARGET_SHMEDIA_FPU"
12624   "fdiv.d       %1, %2, %0"
12625   [(set_attr "type" "dfdiv_media")])
12626
12627 (define_insn "divdf3_i"
12628   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12629         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12630                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12631    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12632   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12633   "fdiv %2,%0"
12634   [(set_attr "type" "dfdiv")
12635    (set_attr "fp_mode" "double")])
12636
12637 (define_insn "floatdidf2"
12638   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12639         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12640   "TARGET_SHMEDIA_FPU"
12641   "float.qd     %1, %0"
12642   [(set_attr "type" "dfpconv_media")])
12643
12644 (define_expand "floatsidf2"
12645   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12646         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
12647   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12648 {
12649   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12650     {
12651       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
12652                                       get_fpscr_rtx ()));
12653       DONE;
12654     }
12655 })
12656
12657 (define_insn "*floatsidf2_media"
12658   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12659         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12660   "TARGET_SHMEDIA_FPU"
12661   "float.ld     %1, %0"
12662   [(set_attr "type" "dfpconv_media")])
12663
12664 (define_insn "floatsidf2_i"
12665   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12666         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
12667    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12668   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12669   "float        %1,%0"
12670   [(set_attr "type" "dfp_conv")
12671    (set_attr "fp_mode" "double")])
12672
12673 (define_insn "fix_truncdfdi2"
12674   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12675         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12676   "TARGET_SHMEDIA_FPU"
12677   "ftrc.dq      %1, %0"
12678   [(set_attr "type" "dfpconv_media")])
12679
12680 (define_expand "fix_truncdfsi2"
12681   [(set (match_operand:SI 0 "fpul_operand" "")
12682         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12683   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12684 {
12685   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12686     {
12687       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
12688                                           get_fpscr_rtx ()));
12689       DONE;
12690     }
12691 })
12692
12693 (define_insn "*fix_truncdfsi2_media"
12694   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12695         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12696   "TARGET_SHMEDIA_FPU"
12697   "ftrc.dl      %1, %0"
12698   [(set_attr "type" "dfpconv_media")])
12699
12700 (define_insn "fix_truncdfsi2_i"
12701   [(set (match_operand:SI 0 "fpul_operand" "=y")
12702         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12703    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12704   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12705   "ftrc %1,%0"
12706   [(set_attr "type" "dfp_conv")
12707    (set_attr "dfp_comp" "no")
12708    (set_attr "fp_mode" "double")])
12709
12710 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
12711 ;; fix_truncdfsi2_i.
12712 ;; (define_insn "fix_truncdfsi2_i4"
12713 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12714 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12715 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
12716 ;;    (clobber (reg:SI FPUL_REG))]
12717 ;;   "TARGET_SH4"
12718 ;;   "#"
12719 ;;   [(set_attr "length" "4")
12720 ;;    (set_attr "fp_mode" "double")])
12721 ;;
12722 ;; (define_split
12723 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12724 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12725 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
12726 ;;    (clobber (reg:SI FPUL_REG))]
12727 ;;   "TARGET_SH4"
12728 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12729 ;;            (use (match_dup 2))])
12730 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
12731
12732 (define_insn "cmpgtdf_t"
12733   [(set (reg:SI T_REG)
12734         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
12735                (match_operand:DF 1 "arith_reg_operand" "f")))
12736    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12737   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12738   "fcmp/gt      %1,%0"
12739   [(set_attr "type" "dfp_cmp")
12740    (set_attr "fp_mode" "double")])
12741
12742 (define_insn "cmpeqdf_t"
12743   [(set (reg:SI T_REG)
12744         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12745                (match_operand:DF 1 "arith_reg_operand" "f")))
12746    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12747   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12748   "fcmp/eq      %1,%0"
12749   [(set_attr "type" "dfp_cmp")
12750    (set_attr "fp_mode" "double")])
12751
12752 (define_insn "*ieee_ccmpeqdf_t"
12753   [(set (reg:SI T_REG)
12754         (ior:SI (reg:SI T_REG)
12755                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12756                        (match_operand:DF 1 "arith_reg_operand" "f"))))
12757    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12758   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12759 {
12760   return output_ieee_ccmpeq (insn, operands);
12761 }
12762   [(set_attr "length" "4")
12763    (set_attr "fp_mode" "double")])
12764
12765 (define_insn "cmpeqdf_media"
12766   [(set (match_operand:SI 0 "register_operand" "=r")
12767         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12768                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12769   "TARGET_SHMEDIA_FPU"
12770   "fcmpeq.d     %1,%2,%0"
12771   [(set_attr "type" "fcmp_media")])
12772
12773 (define_insn "cmpgtdf_media"
12774   [(set (match_operand:SI 0 "register_operand" "=r")
12775         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12776                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12777   "TARGET_SHMEDIA_FPU"
12778   "fcmpgt.d     %1,%2,%0"
12779   [(set_attr "type" "fcmp_media")])
12780
12781 (define_insn "cmpgedf_media"
12782   [(set (match_operand:SI 0 "register_operand" "=r")
12783         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12784                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12785   "TARGET_SHMEDIA_FPU"
12786   "fcmpge.d     %1,%2,%0"
12787   [(set_attr "type" "fcmp_media")])
12788
12789 (define_insn "cmpundf_media"
12790   [(set (match_operand:SI 0 "register_operand" "=r")
12791         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12792                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12793   "TARGET_SHMEDIA_FPU"
12794   "fcmpun.d     %1,%2,%0"
12795   [(set_attr "type" "fcmp_media")])
12796
12797 (define_expand "cbranchdf4"
12798   [(set (pc)
12799         (if_then_else (match_operator 0 "sh_float_comparison_operator"
12800                        [(match_operand:DF 1 "arith_operand" "")
12801                         (match_operand:DF 2 "arith_operand" "")])
12802                       (match_operand 3 "" "")
12803                       (pc)))]
12804   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12805 {
12806   if (TARGET_SHMEDIA)
12807     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12808                                           operands[3]));
12809   else
12810     sh_emit_compare_and_branch (operands, DFmode);
12811   DONE;
12812 })
12813
12814
12815 (define_expand "negdf2"
12816   [(set (match_operand:DF 0 "arith_reg_operand" "")
12817         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12818   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12819 {
12820   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12821     {
12822       expand_df_unop (&gen_negdf2_i, operands);
12823       DONE;
12824     }
12825 })
12826
12827 (define_insn "*negdf2_media"
12828   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12829         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12830   "TARGET_SHMEDIA_FPU"
12831   "fneg.d       %1, %0"
12832   [(set_attr "type" "fmove_media")])
12833
12834 (define_insn "negdf2_i"
12835   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12836         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12837    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12839   "fneg %0"
12840   [(set_attr "type" "fmove")
12841    (set_attr "fp_mode" "double")])
12842
12843 (define_expand "sqrtdf2"
12844   [(set (match_operand:DF 0 "arith_reg_operand" "")
12845         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12846   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12847 {
12848   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12849     {
12850       expand_df_unop (&gen_sqrtdf2_i, operands);
12851       DONE;
12852     }
12853 })
12854
12855 (define_insn "*sqrtdf2_media"
12856   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12857         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12858   "TARGET_SHMEDIA_FPU"
12859   "fsqrt.d      %1, %0"
12860   [(set_attr "type" "dfdiv_media")])
12861
12862 (define_insn "sqrtdf2_i"
12863   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12864         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12865    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12866   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12867   "fsqrt        %0"
12868   [(set_attr "type" "dfdiv")
12869    (set_attr "fp_mode" "double")])
12870
12871 (define_expand "absdf2"
12872   [(set (match_operand:DF 0 "arith_reg_operand" "")
12873         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12874   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12875 {
12876   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12877     {
12878       expand_df_unop (&gen_absdf2_i, operands);
12879       DONE;
12880     }
12881 })
12882
12883 (define_insn "*absdf2_media"
12884   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12885         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12886   "TARGET_SHMEDIA_FPU"
12887   "fabs.d       %1, %0"
12888   [(set_attr "type" "fmove_media")])
12889
12890 (define_insn "absdf2_i"
12891   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12892         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12893    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12894   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12895   "fabs %0"
12896   [(set_attr "type" "fmove")
12897    (set_attr "fp_mode" "double")])
12898
12899 (define_expand "extendsfdf2"
12900   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12901         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
12902   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12903 {
12904   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12905     {
12906       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
12907                                         get_fpscr_rtx ()));
12908       DONE;
12909     }
12910 })
12911
12912 (define_insn "*extendsfdf2_media"
12913   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12914         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12915   "TARGET_SHMEDIA_FPU"
12916   "fcnv.sd      %1, %0"
12917   [(set_attr "type" "dfpconv_media")])
12918
12919 (define_insn "extendsfdf2_i4"
12920   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12921         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
12922    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12924   "fcnvsd  %1,%0"
12925   [(set_attr "type" "fp")
12926    (set_attr "fp_mode" "double")])
12927
12928 (define_expand "truncdfsf2"
12929   [(set (match_operand:SF 0 "fpul_operand" "")
12930         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12931   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12932 {
12933   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12934     {
12935       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
12936                                        get_fpscr_rtx ()));
12937       DONE;
12938     }
12939 })
12940
12941 (define_insn "*truncdfsf2_media"
12942   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12943         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12944   "TARGET_SHMEDIA_FPU"
12945   "fcnv.ds      %1, %0"
12946   [(set_attr "type" "dfpconv_media")])
12947
12948 (define_insn "truncdfsf2_i4"
12949   [(set (match_operand:SF 0 "fpul_operand" "=y")
12950         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12951    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12952   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12953   "fcnvds  %1,%0"
12954   [(set_attr "type" "fp")
12955    (set_attr "fp_mode" "double")])
12956 \f
12957 ;; -------------------------------------------------------------------------
12958 ;; Bit field extract patterns.
12959 ;; -------------------------------------------------------------------------
12960
12961 ;; These give better code for packed bitfields,  because they allow
12962 ;; auto-increment addresses to be generated.
12963
12964 (define_expand "insv"
12965   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
12966                          (match_operand:SI 1 "immediate_operand" "")
12967                          (match_operand:SI 2 "immediate_operand" ""))
12968         (match_operand:SI 3 "general_operand" ""))]
12969   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
12970 {
12971   rtx addr_target, orig_address, shift_reg, qi_val;
12972   HOST_WIDE_INT bitsize, size, v = 0;
12973   rtx x = operands[3];
12974
12975   if (TARGET_SH2A && TARGET_BITOPS
12976       && (satisfies_constraint_Sbw (operands[0])
12977           || satisfies_constraint_Sbv (operands[0]))
12978       && satisfies_constraint_M (operands[1])
12979       && satisfies_constraint_K03 (operands[2]))
12980     {
12981       if (satisfies_constraint_N (operands[3]))
12982         {
12983           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
12984           DONE;
12985         }
12986       else if (satisfies_constraint_M (operands[3]))
12987         {
12988           emit_insn (gen_bset_m2a (operands[0], operands[2]));
12989           DONE;
12990         }
12991       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
12992                 && satisfies_constraint_M (operands[1]))
12993         {
12994           emit_insn (gen_bst_m2a (operands[0], operands[2]));
12995           DONE;
12996         }
12997       else if (REG_P (operands[3])
12998                && satisfies_constraint_M (operands[1]))
12999         {
13000           emit_insn (gen_bld_reg (operands[3], const0_rtx));
13001           emit_insn (gen_bst_m2a (operands[0], operands[2]));
13002           DONE;
13003         }
13004     }
13005   /* ??? expmed doesn't care for non-register predicates.  */
13006   if (! memory_operand (operands[0], VOIDmode)
13007       || ! immediate_operand (operands[1], VOIDmode)
13008       || ! immediate_operand (operands[2], VOIDmode)
13009       || ! general_operand (x, VOIDmode))
13010     FAIL;
13011   /* If this isn't a 16 / 24 / 32 bit field, or if
13012      it doesn't start on a byte boundary, then fail.  */
13013   bitsize = INTVAL (operands[1]);
13014   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13015       || (INTVAL (operands[2]) % 8) != 0)
13016     FAIL;
13017
13018   size = bitsize / 8;
13019   orig_address = XEXP (operands[0], 0);
13020   shift_reg = gen_reg_rtx (SImode);
13021   if (CONST_INT_P (x))
13022     {
13023       v = INTVAL (x);
13024       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13025     }
13026   else
13027     {
13028       emit_insn (gen_movsi (shift_reg, operands[3]));
13029       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13030     }
13031   addr_target = copy_addr_to_reg (plus_constant (Pmode,
13032                                                  orig_address, size - 1));
13033
13034   operands[0] = replace_equiv_address (operands[0], addr_target);
13035   emit_insn (gen_movqi (operands[0], qi_val));
13036
13037   while (size -= 1)
13038     {
13039       if (CONST_INT_P (x))
13040         qi_val
13041           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13042       else
13043         {
13044           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13045           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13046         }
13047       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13048       emit_insn (gen_movqi (operands[0], qi_val));
13049     }
13050
13051   DONE;
13052 })
13053
13054 (define_insn "movua"
13055   [(set (match_operand:SI 0 "register_operand" "=z")
13056         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13057                    UNSPEC_MOVUA))]
13058   "TARGET_SH4A_ARCH"
13059   "movua.l      %1,%0"
13060   [(set_attr "type" "movua")])
13061
13062 ;; We shouldn't need this, but cse replaces increments with references
13063 ;; to other regs before flow has a chance to create post_inc
13064 ;; addressing modes, and only postreload's cse_move2add brings the
13065 ;; increments back to a usable form.
13066 (define_peephole2
13067   [(set (match_operand:SI 0 "register_operand" "")
13068         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13069                          (const_int 32) (const_int 0)))
13070    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13071   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
13072   [(set (match_operand:SI 0 "register_operand" "")
13073         (sign_extract:SI (mem:SI (post_inc:SI
13074                                   (match_operand:SI 1 "register_operand" "")))
13075                          (const_int 32) (const_int 0)))]
13076   "")
13077
13078 (define_expand "extv"
13079   [(set (match_operand:SI 0 "register_operand" "")
13080         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13081                          (match_operand 2 "const_int_operand" "")
13082                          (match_operand 3 "const_int_operand" "")))]
13083   "TARGET_SH4A_ARCH || TARGET_SH2A"
13084 {
13085   if (TARGET_SH2A && TARGET_BITOPS
13086       && (satisfies_constraint_Sbw (operands[1])
13087           || satisfies_constraint_Sbv (operands[1]))
13088       && satisfies_constraint_M (operands[2])
13089       && satisfies_constraint_K03 (operands[3]))
13090    {
13091       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13092       if (REGNO (operands[0]) != T_REG)
13093         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13094       DONE;
13095    }
13096   if (TARGET_SH4A_ARCH
13097       && INTVAL (operands[2]) == 32
13098       && INTVAL (operands[3]) == 0
13099       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13100     {
13101       rtx src = adjust_address (operands[1], BLKmode, 0);
13102       set_mem_size (src, 4);
13103       emit_insn (gen_movua (operands[0], src));
13104       DONE;
13105     }
13106
13107   FAIL;
13108 })
13109
13110 (define_expand "extzv"
13111   [(set (match_operand:SI 0 "register_operand" "")
13112         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13113                          (match_operand 2 "const_int_operand" "")
13114                          (match_operand 3 "const_int_operand" "")))]
13115   "TARGET_SH4A_ARCH || TARGET_SH2A"
13116 {
13117   if (TARGET_SH2A && TARGET_BITOPS
13118       && (satisfies_constraint_Sbw (operands[1])
13119           || satisfies_constraint_Sbv (operands[1]))
13120       && satisfies_constraint_M (operands[2])
13121       && satisfies_constraint_K03 (operands[3]))
13122     {
13123       emit_insn (gen_bld_m2a (operands[1], operands[3]));
13124       if (REGNO (operands[0]) != T_REG)
13125         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13126       DONE;
13127     }
13128   if (TARGET_SH4A_ARCH
13129       && INTVAL (operands[2]) == 32
13130       && INTVAL (operands[3]) == 0
13131       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13132     {
13133       rtx src = adjust_address (operands[1], BLKmode, 0);
13134       set_mem_size (src, 4);
13135       emit_insn (gen_movua (operands[0], src));
13136       DONE;
13137     }
13138
13139   FAIL;
13140 })
13141
13142 ;; SH2A instructions for bitwise operations.
13143 ;; FIXME: Convert multiple instruction insns to insn_and_split.
13144 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
13145
13146 ;; Clear a bit in a memory location.
13147 (define_insn "bclr_m2a"
13148   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13149         (and:QI
13150             (not:QI (ashift:QI (const_int 1)
13151                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
13152             (match_dup 0)))]
13153   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13154   "@
13155         bclr.b  %1,%0
13156         bclr.b  %1,@(0,%t0)"
13157 [(set_attr "length" "4,4")])
13158
13159 (define_insn "bclrmem_m2a"
13160   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13161         (and:QI (match_dup 0)
13162                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13163   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13164   "@
13165         bclr.b  %W1,%0
13166         bclr.b  %W1,@(0,%t0)"
13167   [(set_attr "length" "4,4")])
13168
13169 ;; Set a bit in a memory location.
13170 (define_insn "bset_m2a"
13171   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13172         (ior:QI
13173             (ashift:QI (const_int 1)
13174                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
13175             (match_dup 0)))]
13176   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13177   "@
13178         bset.b  %1,%0
13179         bset.b  %1,@(0,%t0)"
13180   [(set_attr "length" "4,4")])
13181
13182 (define_insn "bsetmem_m2a"
13183   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13184         (ior:QI (match_dup 0)
13185                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13186   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13187   "@
13188         bset.b  %V1,%0
13189         bset.b  %V1,@(0,%t0)"
13190   [(set_attr "length" "4,4")])
13191
13192 ;;; Transfer the contents of the T bit to a specified bit of memory.
13193 (define_insn "bst_m2a"
13194   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13195         (if_then_else (eq (reg:SI T_REG) (const_int 0))
13196             (and:QI
13197                 (not:QI (ashift:QI (const_int 1)
13198                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
13199                 (match_dup 0))
13200             (ior:QI
13201                 (ashift:QI (const_int 1) (match_dup 1))
13202                 (match_dup 0))))]
13203   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13204   "@
13205         bst.b   %1,%0
13206         bst.b   %1,@(0,%t0)"
13207   [(set_attr "length" "4")])
13208
13209 ;; Store a specified bit of memory in the T bit.
13210 (define_insn "bld_m2a"
13211   [(set (reg:SI T_REG)
13212         (zero_extract:SI
13213             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13214             (const_int 1)
13215             (match_operand 1 "const_int_operand" "K03,K03")))]
13216   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13217   "@
13218         bld.b   %1,%0
13219         bld.b   %1,@(0,%t0)"
13220   [(set_attr "length" "4,4")])
13221
13222 ;; Store a specified bit of memory in the T bit.
13223 (define_insn "bldsign_m2a"
13224   [(set (reg:SI T_REG)
13225         (sign_extract:SI
13226             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13227             (const_int 1)
13228             (match_operand 1 "const_int_operand" "K03,K03")))]
13229   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13230   "@
13231         bld.b   %1,%0
13232         bld.b   %1,@(0,%t0)"
13233   [(set_attr "length" "4,4")])
13234
13235 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13236 (define_insn "bld_reg"
13237   [(set (reg:SI T_REG)
13238         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13239                          (const_int 1)
13240                          (match_operand 1 "const_int_operand" "K03")))]
13241   "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13242   "bld  %1,%0")
13243
13244 (define_insn "*bld_regqi"
13245   [(set (reg:SI T_REG)
13246         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13247                          (const_int 1)
13248                          (match_operand 1 "const_int_operand" "K03")))]
13249   "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13250   "bld  %1,%0")
13251
13252 ;; Take logical and of a specified bit of memory with the T bit and
13253 ;; store its result in the T bit.
13254 (define_insn "band_m2a"
13255   [(set (reg:SI T_REG)
13256         (and:SI (reg:SI T_REG)
13257                 (zero_extract:SI
13258                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13259                     (const_int 1)
13260                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13261   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13262   "@
13263         band.b  %1,%0
13264         band.b  %1,@(0,%t0)"
13265   [(set_attr "length" "4,4")])
13266
13267 (define_insn "bandreg_m2a"
13268   [(set (match_operand:SI 0 "register_operand" "=r,r")
13269         (and:SI (zero_extract:SI
13270                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13271                     (const_int 1)
13272                     (match_operand 2 "const_int_operand" "K03,K03"))
13273                 (match_operand:SI 3 "register_operand" "r,r")))]
13274   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13275 {
13276   static const char* alt[] =
13277   {
13278        "band.b  %2,%1"          "\n"
13279     "   movt    %0",
13280
13281        "band.b  %2,@(0,%t1)"    "\n"
13282     "   movt    %0"
13283   };
13284   return alt[which_alternative];
13285 }
13286   [(set_attr "length" "6,6")])
13287
13288 ;; Take logical or of a specified bit of memory with the T bit and
13289 ;; store its result in the T bit.
13290 (define_insn "bor_m2a"
13291   [(set (reg:SI T_REG)
13292         (ior:SI (reg:SI T_REG)
13293                 (zero_extract:SI
13294                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13295                     (const_int 1)
13296                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13297   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13298   "@
13299         bor.b   %1,%0
13300         bor.b   %1,@(0,%t0)"
13301   [(set_attr "length" "4,4")])
13302
13303 (define_insn "borreg_m2a"
13304   [(set (match_operand:SI 0 "register_operand" "=r,r")
13305         (ior:SI (zero_extract:SI
13306                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13307                     (const_int 1)
13308                     (match_operand 2 "const_int_operand" "K03,K03"))
13309                 (match_operand:SI 3 "register_operand" "=r,r")))]
13310   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13311 {
13312   static const char* alt[] =
13313   {
13314        "bor.b   %2,%1"          "\n"
13315     "   movt    %0",
13316
13317        "bor.b   %2,@(0,%t1)"    "\n"
13318     "   movt    %0"
13319   };
13320   return alt[which_alternative];
13321 }
13322   [(set_attr "length" "6,6")])
13323
13324 ;; Take exclusive or of a specified bit of memory with the T bit and
13325 ;; store its result in the T bit.
13326 (define_insn "bxor_m2a"
13327   [(set (reg:SI T_REG)
13328         (xor:SI (reg:SI T_REG)
13329                 (zero_extract:SI
13330                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13331                     (const_int 1)
13332                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13333   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13334   "@
13335         bxor.b  %1,%0
13336         bxor.b  %1,@(0,%t0)"
13337   [(set_attr "length" "4,4")])
13338
13339 (define_insn "bxorreg_m2a"
13340   [(set (match_operand:SI 0 "register_operand" "=r,r")
13341         (xor:SI (zero_extract:SI
13342                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13343                     (const_int 1)
13344                     (match_operand 2 "const_int_operand" "K03,K03"))
13345                 (match_operand:SI 3 "register_operand" "=r,r")))]
13346   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13347 {
13348   static const char* alt[] =
13349   {
13350        "bxor.b  %2,%1"          "\n"
13351     "   movt    %0",
13352
13353        "bxor.b  %2,@(0,%t1)"    "\n"
13354     "   movt    %0"
13355   };
13356   return alt[which_alternative];
13357 }
13358   [(set_attr "length" "6,6")])
13359 \f
13360 ;; -------------------------------------------------------------------------
13361 ;; Peepholes
13362 ;; -------------------------------------------------------------------------
13363 ;; This matches cases where the bit in a memory location is set.
13364 (define_peephole2
13365   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13366         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13367    (set (match_dup 0)
13368         (ior:SI (match_dup 0)
13369         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
13370    (set (match_dup 1)
13371         (match_operand 3 "arith_reg_operand" "r,r"))]
13372   "TARGET_SH2A && TARGET_BITOPS
13373    && satisfies_constraint_Pso (operands[2])
13374    && REGNO (operands[0]) == REGNO (operands[3])"
13375   [(set (match_dup 1)
13376         (ior:QI (match_dup 1) (match_dup 2)))]
13377   "")
13378
13379 ;; This matches cases where the bit in a memory location is cleared.
13380 (define_peephole2
13381   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13382         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13383    (set (match_dup 0)
13384         (and:SI (match_dup 0)
13385         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
13386    (set (match_dup 1)
13387         (match_operand 3 "arith_reg_operand" "r,r"))]
13388   "TARGET_SH2A && TARGET_BITOPS
13389    && satisfies_constraint_Psz (operands[2])
13390    && REGNO (operands[0]) == REGNO (operands[3])"
13391   [(set (match_dup 1)
13392         (and:QI (match_dup 1) (match_dup 2)))]
13393   "")
13394
13395 ;; This matches cases where a stack pointer increment at the start of the
13396 ;; epilogue combines with a stack slot read loading the return value.
13397 (define_peephole
13398   [(set (match_operand:SI 0 "arith_reg_operand" "")
13399         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13400    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13401   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13402   "mov.l        @%1+,%0")
13403
13404 ;; See the comment on the dt combiner pattern above.
13405 (define_peephole
13406   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13407         (plus:SI (match_dup 0)
13408                  (const_int -1)))
13409    (set (reg:SI T_REG)
13410         (eq:SI (match_dup 0) (const_int 0)))]
13411   "TARGET_SH2"
13412   "dt   %0")
13413
13414 ;; The following peepholes fold load sequences for which reload was not
13415 ;; able to generate a displacement addressing move insn.
13416 ;; This can happen when reload has to transform a move insn 
13417 ;; without displacement into one with displacement.  Or when reload can't
13418 ;; fit a displacement into the insn's constraints.  In the latter case, the
13419 ;; load destination reg remains at r0, which reload compensates by inserting
13420 ;; another mov insn.
13421
13422 ;; Fold sequence:
13423 ;;      mov #54,r0
13424 ;;      mov.{b,w} @(r0,r15),r0
13425 ;;      mov r0,r3
13426 ;; into:
13427 ;;      mov.{b,w} @(54,r15),r3
13428 ;;
13429 (define_peephole2
13430   [(set (match_operand:SI 0 "arith_reg_dest" "")
13431         (match_operand:SI 1 "const_int_operand" ""))
13432    (set (match_operand:SI 2 "arith_reg_dest" "")
13433         (sign_extend:SI
13434          (mem:QI (plus:SI (match_dup 0)
13435                           (match_operand:SI 3 "arith_reg_operand" "")))))
13436    (set (match_operand:QI 4 "arith_reg_dest" "")
13437         (match_operand:QI 5 "arith_reg_operand" ""))]
13438   "TARGET_SH2A
13439    && sh_legitimate_index_p (QImode, operands[1], true, true)
13440    && REGNO (operands[2]) == REGNO (operands[5])
13441    && peep2_reg_dead_p (3, operands[5])"
13442   [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13443   "")
13444
13445 (define_peephole2
13446   [(set (match_operand:SI 0 "arith_reg_dest" "")
13447         (match_operand:SI 1 "const_int_operand" ""))
13448    (set (match_operand:SI 2 "arith_reg_dest" "")
13449         (sign_extend:SI
13450          (mem:HI (plus:SI (match_dup 0)
13451                           (match_operand:SI 3 "arith_reg_operand" "")))))
13452    (set (match_operand:HI 4 "arith_reg_dest" "")
13453         (match_operand:HI 5 "arith_reg_operand" ""))]
13454   "TARGET_SH2A
13455    && sh_legitimate_index_p (HImode, operands[1], true, true)
13456    && REGNO (operands[2]) == REGNO (operands[5])
13457    && peep2_reg_dead_p (3, operands[5])"
13458   [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13459   "")
13460
13461 ;; Fold sequence:
13462 ;;      mov #54,r0
13463 ;;      mov.{b,w} @(r0,r15),r1
13464 ;; into:
13465 ;;      mov.{b,w} @(54,r15),r1
13466 ;;
13467 (define_peephole2
13468   [(set (match_operand:SI 0 "arith_reg_dest" "")
13469         (match_operand:SI 1 "const_int_operand" ""))
13470    (set (match_operand:SI 2 "arith_reg_dest" "")
13471          (sign_extend:SI
13472          (mem:QI (plus:SI (match_dup 0)
13473                           (match_operand:SI 3 "arith_reg_operand" "")))))]
13474   "TARGET_SH2A
13475    && sh_legitimate_index_p (QImode, operands[1], true, true)
13476    && (peep2_reg_dead_p (2, operands[0])
13477        || REGNO (operands[0]) == REGNO (operands[2]))"
13478   [(set (match_dup 2)
13479         (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13480   "")
13481
13482 (define_peephole2
13483   [(set (match_operand:SI 0 "arith_reg_dest" "")
13484         (match_operand:SI 1 "const_int_operand" ""))
13485    (set (match_operand:SI 2 "arith_reg_dest" "")
13486          (sign_extend:SI
13487          (mem:HI (plus:SI (match_dup 0)
13488                           (match_operand:SI 3 "arith_reg_operand" "")))))]
13489   "TARGET_SH2A
13490    && sh_legitimate_index_p (HImode, operands[1], true, true)
13491    && (peep2_reg_dead_p (2, operands[0])
13492        || REGNO (operands[0]) == REGNO (operands[2]))"
13493   [(set (match_dup 2)
13494         (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13495   "")
13496
13497 ;; Fold sequence:
13498 ;;      mov.{b,w} @(r0,r15),r0
13499 ;;      mov r0,r3
13500 ;; into:
13501 ;;      mov.{b,w} @(r0,r15),r3
13502 ;;
13503 ;; This can happen when initially a displacement address is picked, where
13504 ;; the destination reg is fixed to r0, and then the address is transformed
13505 ;; into 'r0 + reg'.
13506 (define_peephole2
13507   [(set (match_operand:SI 0 "arith_reg_dest" "")
13508         (sign_extend:SI
13509          (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13510                           (match_operand:SI 2 "arith_reg_operand" "")))))
13511    (set (match_operand:QI 3 "arith_reg_dest" "")
13512         (match_operand:QI 4 "arith_reg_operand" ""))]
13513   "TARGET_SH1
13514    && REGNO (operands[0]) == REGNO (operands[4])
13515    && peep2_reg_dead_p (2, operands[0])"
13516   [(set (match_dup 3)
13517         (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13518   "")
13519
13520 (define_peephole2
13521   [(set (match_operand:SI 0 "arith_reg_dest" "")
13522         (sign_extend:SI
13523          (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13524                           (match_operand:SI 2 "arith_reg_operand" "")))))
13525    (set (match_operand:HI 3 "arith_reg_dest" "")
13526         (match_operand:HI 4 "arith_reg_operand" ""))]
13527   "TARGET_SH1
13528    && REGNO (operands[0]) == REGNO (operands[4])
13529    && peep2_reg_dead_p (2, operands[0])"
13530   [(set (match_dup 3)
13531         (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13532   "")
13533
13534 (define_peephole
13535   [(set (match_operand:SI 0 "register_operand" "=r")
13536         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13537    (set (mem:SF (match_dup 0))
13538         (match_operand:SF 2 "general_movsrc_operand" ""))]
13539   "TARGET_SH1 && REGNO (operands[0]) == 0
13540    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13541        || (GET_CODE (operands[2]) == SUBREG
13542            && REGNO (SUBREG_REG (operands[2])) < 16))
13543    && reg_unused_after (operands[0], insn)"
13544   "mov.l        %2,@(%0,%1)")
13545
13546 (define_peephole
13547   [(set (match_operand:SI 0 "register_operand" "=r")
13548         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13549    (set (match_operand:SF 2 "general_movdst_operand" "")
13550
13551         (mem:SF (match_dup 0)))]
13552   "TARGET_SH1 && REGNO (operands[0]) == 0
13553    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13554        || (GET_CODE (operands[2]) == SUBREG
13555            && REGNO (SUBREG_REG (operands[2])) < 16))
13556    && reg_unused_after (operands[0], insn)"
13557   "mov.l        @(%0,%1),%2")
13558
13559 (define_peephole
13560   [(set (match_operand:SI 0 "register_operand" "=r")
13561         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13562    (set (mem:SF (match_dup 0))
13563         (match_operand:SF 2 "general_movsrc_operand" ""))]
13564   "TARGET_SH2E && REGNO (operands[0]) == 0
13565    && ((REG_P (operands[2])
13566         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13567        || (GET_CODE (operands[2]) == SUBREG
13568            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13569    && reg_unused_after (operands[0], insn)"
13570   "fmov{.s|}    %2,@(%0,%1)")
13571
13572 (define_peephole
13573   [(set (match_operand:SI 0 "register_operand" "=r")
13574         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13575    (set (match_operand:SF 2 "general_movdst_operand" "")
13576
13577         (mem:SF (match_dup 0)))]
13578   "TARGET_SH2E && REGNO (operands[0]) == 0
13579    && ((REG_P (operands[2])
13580         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13581        || (GET_CODE (operands[2]) == SUBREG
13582            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13583    && reg_unused_after (operands[0], insn)"
13584   "fmov{.s|}    @(%0,%1),%2")
13585
13586 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13587 (define_insn "sp_switch_1"
13588   [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
13589     UNSPECV_SP_SWITCH_B))]
13590   "TARGET_SH1"
13591 {
13592   return       "mov.l   r0,@-r15"       "\n"
13593          "      mov.l   %0,r0"          "\n"
13594          "      mov.l   @r0,r0"         "\n"
13595          "      mov.l   r15,@-r0"       "\n"
13596          "      mov     r0,r15";
13597 }
13598   [(set_attr "length" "10")])
13599
13600 ;; Switch back to the original stack for interrupt functions with the
13601 ;; sp_switch attribute.
13602 (define_insn "sp_switch_2"
13603   [(unspec_volatile [(const_int 0)]
13604     UNSPECV_SP_SWITCH_E)]
13605   "TARGET_SH1"
13606 {
13607   return       "mov.l   @r15,r15"       "\n"
13608          "      mov.l   @r15+,r0";
13609 }
13610   [(set_attr "length" "4")])
13611
13612 ;; -------------------------------------------------------------------------
13613 ;; Integer vector moves
13614 ;; -------------------------------------------------------------------------
13615
13616 (define_expand "movv8qi"
13617   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13618         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13619   "TARGET_SHMEDIA"
13620 {
13621   prepare_move_operands (operands, V8QImode);
13622 })
13623
13624 (define_insn "movv8qi_i"
13625   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13626         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13627   "TARGET_SHMEDIA
13628    && (register_operand (operands[0], V8QImode)
13629        || sh_register_operand (operands[1], V8QImode))"
13630   "@
13631         add     %1, r63, %0
13632         movi    %1, %0
13633         #
13634         ld%M1.q %m1, %0
13635         st%M0.q %m0, %N1"
13636   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13637    (set_attr "length" "4,4,16,4,4")])
13638
13639 (define_split
13640   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13641         (subreg:V8QI (const_int 0) 0))]
13642   "TARGET_SHMEDIA"
13643   [(set (match_dup 0)
13644         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13645                             (const_int 0) (const_int 0) (const_int 0)
13646                             (const_int 0) (const_int 0)]))])
13647
13648 (define_split
13649   [(set (match_operand 0 "arith_reg_dest" "")
13650         (match_operand 1 "sh_rep_vec" ""))]
13651   "TARGET_SHMEDIA && reload_completed
13652    && GET_MODE (operands[0]) == GET_MODE (operands[1])
13653    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13654    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13655    && (XVECEXP (operands[1], 0, 0) != const0_rtx
13656        || XVECEXP (operands[1], 0, 1) != const0_rtx)
13657    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13658        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13659   [(set (match_dup 0) (match_dup 1))
13660    (match_dup 2)]
13661 {
13662   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
13663   rtx elt1 = XVECEXP (operands[1], 0, 1);
13664
13665   if (unit_size > 2)
13666     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
13667   else
13668     {
13669       if (unit_size < 2)
13670         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
13671       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
13672     }
13673   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
13674   operands[1] = XVECEXP (operands[1], 0, 0);
13675   if (unit_size < 2)
13676     {
13677       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
13678         operands[1]
13679           = GEN_INT (TARGET_LITTLE_ENDIAN
13680                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
13681                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
13682       else
13683         {
13684           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
13685           operands[1]
13686             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
13687         }
13688     }
13689 })
13690
13691 (define_split
13692   [(set (match_operand 0 "arith_reg_dest" "")
13693         (match_operand 1 "sh_const_vec" ""))]
13694   "TARGET_SHMEDIA && reload_completed
13695    && GET_MODE (operands[0]) == GET_MODE (operands[1])
13696    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
13697   [(set (match_dup 0) (match_dup 1))]
13698 {
13699   rtx v = operands[1];
13700   enum machine_mode new_mode
13701     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
13702
13703   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
13704   operands[1]
13705     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
13706 })
13707
13708 (define_expand "movv2hi"
13709   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
13710         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
13711   "TARGET_SHMEDIA"
13712 {
13713   prepare_move_operands (operands, V2HImode);
13714 })
13715
13716 (define_insn "movv2hi_i"
13717   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13718         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13719   "TARGET_SHMEDIA
13720    && (register_operand (operands[0], V2HImode)
13721        || sh_register_operand (operands[1], V2HImode))"
13722   "@
13723         add.l   %1, r63, %0
13724         movi    %1, %0
13725         #
13726         ld%M1.l %m1, %0
13727         st%M0.l %m0, %N1"
13728   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13729    (set_attr "length" "4,4,16,4,4")
13730    (set (attr "highpart")
13731         (cond [(match_test "sh_contains_memref_p (insn)")
13732                (const_string "user")]
13733               (const_string "ignore")))])
13734
13735 (define_expand "movv4hi"
13736   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
13737         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
13738   "TARGET_SHMEDIA"
13739 {
13740   prepare_move_operands (operands, V4HImode);
13741 })
13742
13743 (define_insn "movv4hi_i"
13744   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13745         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13746   "TARGET_SHMEDIA
13747    && (register_operand (operands[0], V4HImode)
13748        || sh_register_operand (operands[1], V4HImode))"
13749   "@
13750         add     %1, r63, %0
13751         movi    %1, %0
13752         #
13753         ld%M1.q %m1, %0
13754         st%M0.q %m0, %N1"
13755   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13756    (set_attr "length" "4,4,16,4,4")
13757    (set_attr "highpart" "depend")])
13758
13759 (define_expand "movv2si"
13760   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
13761         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
13762   "TARGET_SHMEDIA"
13763 {
13764   prepare_move_operands (operands, V2SImode);
13765 })
13766
13767 (define_insn "movv2si_i"
13768   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
13769         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13770   "TARGET_SHMEDIA
13771    && (register_operand (operands[0], V2SImode)
13772        || sh_register_operand (operands[1], V2SImode))"
13773   "@
13774         add     %1, r63, %0
13775         #
13776         #
13777         ld%M1.q %m1, %0
13778         st%M0.q %m0, %N1"
13779   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13780    (set_attr "length" "4,4,16,4,4")
13781    (set_attr "highpart" "depend")])
13782
13783 ;; -------------------------------------------------------------------------
13784 ;; Multimedia Intrinsics
13785 ;; -------------------------------------------------------------------------
13786
13787 (define_insn "absv2si2"
13788   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13789         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
13790   "TARGET_SHMEDIA"
13791   "mabs.l       %1, %0"
13792   [(set_attr "type" "mcmp_media")
13793    (set_attr "highpart" "depend")])
13794
13795 (define_insn "absv4hi2"
13796   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13797         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
13798   "TARGET_SHMEDIA"
13799   "mabs.w       %1, %0"
13800   [(set_attr "type" "mcmp_media")
13801    (set_attr "highpart" "depend")])
13802
13803 (define_insn "addv2si3"
13804   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13805         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13806                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13807   "TARGET_SHMEDIA"
13808   "madd.l       %1, %2, %0"
13809   [(set_attr "type" "arith_media")
13810    (set_attr "highpart" "depend")])
13811
13812 (define_insn "addv4hi3"
13813   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13814         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13815                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13816   "TARGET_SHMEDIA"
13817   "madd.w       %1, %2, %0"
13818   [(set_attr "type" "arith_media")
13819    (set_attr "highpart" "depend")])
13820
13821 (define_insn_and_split "addv2hi3"
13822   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13823         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
13824                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
13825   "TARGET_SHMEDIA"
13826   "#"
13827   "TARGET_SHMEDIA"
13828   [(const_int 0)]
13829 {
13830   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13831   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13832   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13833   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13834   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13835
13836   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
13837   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13838   DONE;
13839 }
13840   [(set_attr "highpart" "must_split")])
13841
13842 (define_insn "ssaddv2si3"
13843   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13844         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13845                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13846   "TARGET_SHMEDIA"
13847   "madds.l      %1, %2, %0"
13848   [(set_attr "type" "mcmp_media")
13849    (set_attr "highpart" "depend")])
13850
13851 (define_insn "usaddv8qi3"
13852   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13853         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
13854                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13855   "TARGET_SHMEDIA"
13856   "madds.ub     %1, %2, %0"
13857   [(set_attr "type" "mcmp_media")
13858    (set_attr "highpart" "depend")])
13859
13860 (define_insn "ssaddv4hi3"
13861   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13862         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13863                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13864   "TARGET_SHMEDIA"
13865   "madds.w      %1, %2, %0"
13866   [(set_attr "type" "mcmp_media")
13867    (set_attr "highpart" "depend")])
13868
13869 (define_insn "negcmpeqv8qi"
13870   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13871         (neg:V8QI (eq:V8QI
13872                     (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13873                     (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13874   "TARGET_SHMEDIA"
13875   "mcmpeq.b     %N1, %N2, %0"
13876   [(set_attr "type" "mcmp_media")
13877    (set_attr "highpart" "depend")])
13878
13879 (define_insn "negcmpeqv2si"
13880   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13881         (neg:V2SI (eq:V2SI
13882                     (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13883                     (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13884   "TARGET_SHMEDIA"
13885   "mcmpeq.l     %N1, %N2, %0"
13886   [(set_attr "type" "mcmp_media")
13887    (set_attr "highpart" "depend")])
13888
13889 (define_insn "negcmpeqv4hi"
13890   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13891         (neg:V4HI (eq:V4HI
13892                     (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13893                     (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13894   "TARGET_SHMEDIA"
13895   "mcmpeq.w     %N1, %N2, %0"
13896   [(set_attr "type" "mcmp_media")
13897    (set_attr "highpart" "depend")])
13898
13899 (define_insn "negcmpgtuv8qi"
13900   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13901         (neg:V8QI (gtu:V8QI
13902                     (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13903                     (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13904   "TARGET_SHMEDIA"
13905   "mcmpgt.ub    %N1, %N2, %0"
13906   [(set_attr "type" "mcmp_media")
13907    (set_attr "highpart" "depend")])
13908
13909 (define_insn "negcmpgtv2si"
13910   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13911         (neg:V2SI (gt:V2SI
13912                     (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13913                     (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13914   "TARGET_SHMEDIA"
13915   "mcmpgt.l     %N1, %N2, %0"
13916   [(set_attr "type" "mcmp_media")
13917    (set_attr "highpart" "depend")])
13918
13919 (define_insn "negcmpgtv4hi"
13920   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13921         (neg:V4HI (gt:V4HI
13922                     (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13923                     (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13924   "TARGET_SHMEDIA"
13925   "mcmpgt.w     %N1, %N2, %0"
13926   [(set_attr "type" "mcmp_media")
13927    (set_attr "highpart" "depend")])
13928
13929 (define_insn "mcmv"
13930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13931         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13932                         (match_operand:DI 2 "arith_reg_operand" "r"))
13933                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
13934                         (not:DI (match_dup 2)))))]
13935   "TARGET_SHMEDIA"
13936   "mcmv %N1, %2, %0"
13937   [(set_attr "type" "arith_media")
13938    (set_attr "highpart" "depend")])
13939
13940 (define_insn "mcnvs_lw"
13941   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13942         (vec_concat:V4HI
13943          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
13944          (ss_truncate:V2HI
13945            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13946   "TARGET_SHMEDIA"
13947   "mcnvs.lw     %N1, %N2, %0"
13948   [(set_attr "type" "mcmp_media")])
13949
13950 (define_insn "mcnvs_wb"
13951   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13952         (vec_concat:V8QI
13953          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13954          (ss_truncate:V4QI
13955            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13956   "TARGET_SHMEDIA"
13957   "mcnvs.wb     %N1, %N2, %0"
13958   [(set_attr "type" "mcmp_media")])
13959
13960 (define_insn "mcnvs_wub"
13961   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13962         (vec_concat:V8QI
13963          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13964          (us_truncate:V4QI
13965            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13966   "TARGET_SHMEDIA"
13967   "mcnvs.wub    %N1, %N2, %0"
13968   [(set_attr "type" "mcmp_media")])
13969
13970 (define_insn "mextr_rl"
13971   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13972         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13973                              (match_operand:HI 3 "mextr_bit_offset" "i"))
13974                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13975                            (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13976   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13977 {
13978   static char templ[21];
13979   sprintf (templ, "mextr%d      %%N1, %%N2, %%0",
13980            (int) INTVAL (operands[3]) >> 3);
13981   return templ;
13982 }
13983   [(set_attr "type" "arith_media")])
13984
13985 (define_insn "*mextr_lr"
13986   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13987         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13988                            (match_operand:HI 3 "mextr_bit_offset" "i"))
13989                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13990                              (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13991   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13992 {
13993   static char templ[21];
13994   sprintf (templ, "mextr%d      %%N2, %%N1, %%0",
13995            (int) INTVAL (operands[4]) >> 3);
13996   return templ;
13997 }
13998   [(set_attr "type" "arith_media")])
13999
14000 ; mextrN can be modelled with vec_select / vec_concat, but the selection
14001 ; vector then varies depending on endianness.
14002 (define_expand "mextr1"
14003   [(match_operand:DI 0 "arith_reg_dest" "")
14004    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14005    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14006   "TARGET_SHMEDIA"
14007 {
14008   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14009                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
14010   DONE;
14011 })
14012
14013 (define_expand "mextr2"
14014   [(match_operand:DI 0 "arith_reg_dest" "")
14015    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14016    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14017   "TARGET_SHMEDIA"
14018 {
14019   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14020                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
14021   DONE;
14022 })
14023
14024 (define_expand "mextr3"
14025   [(match_operand:DI 0 "arith_reg_dest" "")
14026    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14027    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14028   "TARGET_SHMEDIA"
14029 {
14030   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14031                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
14032   DONE;
14033 })
14034
14035 (define_expand "mextr4"
14036   [(match_operand:DI 0 "arith_reg_dest" "")
14037    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14038    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14039   "TARGET_SHMEDIA"
14040 {
14041   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14042                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
14043   DONE;
14044 })
14045
14046 (define_expand "mextr5"
14047   [(match_operand:DI 0 "arith_reg_dest" "")
14048    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14049    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14050   "TARGET_SHMEDIA"
14051 {
14052   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14053                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
14054   DONE;
14055 })
14056
14057 (define_expand "mextr6"
14058   [(match_operand:DI 0 "arith_reg_dest" "")
14059    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14060    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14061   "TARGET_SHMEDIA"
14062 {
14063   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14064                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
14065   DONE;
14066 })
14067
14068 (define_expand "mextr7"
14069   [(match_operand:DI 0 "arith_reg_dest" "")
14070    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14071    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14072   "TARGET_SHMEDIA"
14073 {
14074   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14075                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
14076   DONE;
14077 })
14078
14079 (define_expand "mmacfx_wl"
14080   [(match_operand:V2SI 0 "arith_reg_dest" "")
14081    (match_operand:V2HI 1 "extend_reg_operand" "")
14082    (match_operand:V2HI 2 "extend_reg_operand" "")
14083    (match_operand:V2SI 3 "arith_reg_operand" "")]
14084   "TARGET_SHMEDIA"
14085 {
14086   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14087                               operands[1], operands[2]));
14088   DONE;
14089 })
14090
14091 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14092 ;; is depend
14093 (define_insn "mmacfx_wl_i"
14094   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14095         (ss_plus:V2SI
14096          (match_operand:V2SI 1 "arith_reg_operand" "0")
14097          (ss_truncate:V2SI
14098           (ashift:V2DI
14099            (sign_extend:V2DI
14100             (mult:V2SI
14101              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14102              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14103            (const_int 1)))))]
14104   "TARGET_SHMEDIA"
14105   "mmacfx.wl    %2, %3, %0"
14106   [(set_attr "type" "mac_media")
14107    (set_attr "highpart" "depend")])
14108
14109 (define_expand "mmacnfx_wl"
14110   [(match_operand:V2SI 0 "arith_reg_dest" "")
14111    (match_operand:V2HI 1 "extend_reg_operand" "")
14112    (match_operand:V2HI 2 "extend_reg_operand" "")
14113    (match_operand:V2SI 3 "arith_reg_operand" "")]
14114   "TARGET_SHMEDIA"
14115 {
14116   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14117                                operands[1], operands[2]));
14118   DONE;
14119 })
14120
14121 (define_insn "mmacnfx_wl_i"
14122   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14123         (ss_minus:V2SI
14124          (match_operand:V2SI 1 "arith_reg_operand" "0")
14125          (ss_truncate:V2SI
14126           (ashift:V2DI
14127            (sign_extend:V2DI
14128             (mult:V2SI
14129              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14130              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14131            (const_int 1)))))]
14132   "TARGET_SHMEDIA"
14133   "mmacnfx.wl   %2, %3, %0"
14134   [(set_attr "type" "mac_media")
14135    (set_attr "highpart" "depend")])
14136
14137 (define_insn "mulv2si3"
14138   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14139         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14140                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14141   "TARGET_SHMEDIA"
14142   "mmul.l       %1, %2, %0"
14143   [(set_attr "type" "d2mpy_media")
14144    (set_attr "highpart" "depend")])
14145
14146 (define_insn "mulv4hi3"
14147   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14148         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14149                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14150   "TARGET_SHMEDIA"
14151   "mmul.w       %1, %2, %0"
14152   [(set_attr "type" "dmpy_media")
14153    (set_attr "highpart" "depend")])
14154
14155 (define_insn "mmulfx_l"
14156   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14157         (ss_truncate:V2SI
14158          (ashiftrt:V2DI
14159           (mult:V2DI
14160            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14161            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14162           (const_int 31))))]
14163   "TARGET_SHMEDIA"
14164   "mmulfx.l     %1, %2, %0"
14165   [(set_attr "type" "d2mpy_media")
14166    (set_attr "highpart" "depend")])
14167
14168 (define_insn "mmulfx_w"
14169   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14170         (ss_truncate:V4HI
14171          (ashiftrt:V4SI
14172           (mult:V4SI
14173            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14174            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14175           (const_int 15))))]
14176   "TARGET_SHMEDIA"
14177   "mmulfx.w     %1, %2, %0"
14178   [(set_attr "type" "dmpy_media")
14179    (set_attr "highpart" "depend")])
14180
14181 (define_insn "mmulfxrp_w"
14182   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14183         (ss_truncate:V4HI
14184          (ashiftrt:V4SI
14185           (plus:V4SI
14186            (mult:V4SI
14187             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14188             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14189            (const_int 16384))
14190           (const_int 15))))]
14191   "TARGET_SHMEDIA"
14192   "mmulfxrp.w   %1, %2, %0"
14193   [(set_attr "type" "dmpy_media")
14194    (set_attr "highpart" "depend")])
14195
14196
14197 (define_expand "mmulhi_wl"
14198   [(match_operand:V2SI 0 "arith_reg_dest" "")
14199    (match_operand:V4HI 1 "arith_reg_operand" "")
14200    (match_operand:V4HI 2 "arith_reg_operand" "")]
14201   "TARGET_SHMEDIA"
14202 {
14203   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14204              (operands[0], operands[1], operands[2]));
14205   DONE;
14206 })
14207
14208 (define_expand "mmullo_wl"
14209   [(match_operand:V2SI 0 "arith_reg_dest" "")
14210    (match_operand:V4HI 1 "arith_reg_operand" "")
14211    (match_operand:V4HI 2 "arith_reg_operand" "")]
14212   "TARGET_SHMEDIA"
14213 {
14214   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14215              (operands[0], operands[1], operands[2]));
14216   DONE;
14217 })
14218
14219 (define_insn "mmul23_wl"
14220   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14221         (vec_select:V2SI
14222          (mult:V4SI
14223           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14224           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14225          (parallel [(const_int 2) (const_int 3)])))]
14226   "TARGET_SHMEDIA"
14227 {
14228   return (TARGET_LITTLE_ENDIAN
14229           ? "mmulhi.wl  %1, %2, %0"
14230           : "mmullo.wl  %1, %2, %0");
14231 }
14232   [(set_attr "type" "dmpy_media")
14233    (set (attr "highpart")
14234         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14235          (const_string "user")))])
14236
14237 (define_insn "mmul01_wl"
14238   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14239         (vec_select:V2SI
14240          (mult:V4SI
14241           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14242           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14243          (parallel [(const_int 0) (const_int 1)])))]
14244   "TARGET_SHMEDIA"
14245 {
14246   return (TARGET_LITTLE_ENDIAN
14247           ? "mmullo.wl  %1, %2, %0"
14248           : "mmulhi.wl  %1, %2, %0");
14249 }
14250   [(set_attr "type" "dmpy_media")
14251    (set (attr "highpart")
14252         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14253          (const_string "user")))])
14254
14255
14256 (define_expand "mmulsum_wq"
14257   [(match_operand:DI 0 "arith_reg_dest" "")
14258    (match_operand:V4HI 1 "arith_reg_operand" "")
14259    (match_operand:V4HI 2 "arith_reg_operand" "")
14260    (match_operand:DI 3 "arith_reg_operand" "")]
14261   "TARGET_SHMEDIA"
14262 {
14263   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14264                                operands[1], operands[2]));
14265   DONE;
14266 })
14267
14268 (define_insn "mmulsum_wq_i"
14269   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14270         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14271          (plus:DI
14272           (plus:DI
14273            (vec_select:DI
14274             (mult:V4DI
14275              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14276              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14277             (parallel [(const_int 0)]))
14278            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14279                                      (sign_extend:V4DI (match_dup 3)))
14280                           (parallel [(const_int 1)])))
14281           (plus:DI
14282            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14283                                      (sign_extend:V4DI (match_dup 3)))
14284                           (parallel [(const_int 2)]))
14285            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14286                                      (sign_extend:V4DI (match_dup 3)))
14287                           (parallel [(const_int 3)]))))))]
14288   "TARGET_SHMEDIA"
14289   "mmulsum.wq   %2, %3, %0"
14290   [(set_attr "type" "mac_media")])
14291
14292 (define_expand "mperm_w"
14293   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14294    (match_operand:V4HI 1 "arith_reg_operand" "r")
14295    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14296   "TARGET_SHMEDIA"
14297 {
14298   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14299              (operands[0], operands[1], operands[2]));
14300   DONE;
14301 })
14302
14303 ; This use of vec_select isn't exactly correct according to rtl.texi
14304 ; (because not constant), but it seems a straightforward extension.
14305 (define_insn "mperm_w_little"
14306   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14307         (vec_select:V4HI
14308          (match_operand:V4HI 1 "arith_reg_operand" "r")
14309          (parallel
14310           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14311                             (const_int 2) (const_int 0))
14312            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14313            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14314            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14315   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14316   "mperm.w      %1, %N2, %0"
14317   [(set_attr "type" "arith_media")])
14318
14319 (define_insn "mperm_w_big"
14320   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14321         (vec_select:V4HI
14322          (match_operand:V4HI 1 "arith_reg_operand" "r")
14323          (parallel
14324           [(zero_extract:QI (not:QI (match_operand:QI 2
14325                                      "extend_reg_or_0_operand" "rZ"))
14326                             (const_int 2) (const_int 0))
14327            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14328            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14329            (zero_extract:QI (not:QI (match_dup 2))
14330                             (const_int 2) (const_int 6))])))]
14331   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
14332   "mperm.w      %1, %N2, %0"
14333   [(set_attr "type" "arith_media")])
14334
14335 (define_insn "mperm_w0"
14336   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14337         (vec_duplicate:V4HI (truncate:HI (match_operand 1
14338                                           "trunc_hi_operand" "r"))))]
14339   "TARGET_SHMEDIA"
14340   "mperm.w      %1, r63, %0"
14341   [(set_attr "type" "arith_media")
14342    (set_attr "highpart" "ignore")])
14343
14344 (define_expand "msad_ubq"
14345   [(match_operand:DI 0 "arith_reg_dest" "")
14346    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14347    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14348    (match_operand:DI 3 "arith_reg_operand" "")]
14349   "TARGET_SHMEDIA"
14350 {
14351   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14352                              operands[1], operands[2]));
14353   DONE;
14354 })
14355
14356 (define_insn "msad_ubq_i"
14357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14358         (plus:DI
14359          (plus:DI
14360           (plus:DI
14361            (plus:DI
14362             (match_operand:DI 1 "arith_reg_operand" "0")
14363             (abs:DI (vec_select:DI
14364                      (minus:V8DI
14365                       (zero_extend:V8DI
14366                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14367                       (zero_extend:V8DI
14368                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14369                      (parallel [(const_int 0)]))))
14370            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14371                                               (zero_extend:V8DI (match_dup 3)))
14372                                   (parallel [(const_int 1)]))))
14373           (plus:DI
14374            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14375                                               (zero_extend:V8DI (match_dup 3)))
14376                                   (parallel [(const_int 2)])))
14377            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14378                                               (zero_extend:V8DI (match_dup 3)))
14379                                   (parallel [(const_int 3)])))))
14380          (plus:DI
14381           (plus:DI
14382            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14383                                               (zero_extend:V8DI (match_dup 3)))
14384                                   (parallel [(const_int 4)])))
14385            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14386                                               (zero_extend:V8DI (match_dup 3)))
14387                                   (parallel [(const_int 5)]))))
14388           (plus:DI
14389            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14390                                               (zero_extend:V8DI (match_dup 3)))
14391                                   (parallel [(const_int 6)])))
14392            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14393                                               (zero_extend:V8DI (match_dup 3)))
14394                                   (parallel [(const_int 7)])))))))]
14395   "TARGET_SHMEDIA"
14396   "msad.ubq     %N2, %N3, %0"
14397   [(set_attr "type" "mac_media")])
14398
14399 (define_insn "mshalds_l"
14400   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14401         (ss_truncate:V2SI
14402          (ashift:V2DI
14403           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14404           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14405                   (const_int 31)))))]
14406   "TARGET_SHMEDIA"
14407   "mshalds.l    %1, %2, %0"
14408   [(set_attr "type" "mcmp_media")
14409    (set_attr "highpart" "depend")])
14410
14411 (define_insn "mshalds_w"
14412   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14413         (ss_truncate:V4HI
14414          (ashift:V4SI
14415           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14416           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14417                   (const_int 15)))))]
14418   "TARGET_SHMEDIA"
14419   "mshalds.w    %1, %2, %0"
14420   [(set_attr "type" "mcmp_media")
14421    (set_attr "highpart" "depend")])
14422
14423 (define_insn "ashrv2si3"
14424   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14425         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14426                        (match_operand:DI 2 "arith_reg_operand" "r")))]
14427   "TARGET_SHMEDIA"
14428   "mshard.l     %1, %2, %0"
14429   [(set_attr "type" "arith_media")
14430    (set_attr "highpart" "depend")])
14431
14432 (define_insn "ashrv4hi3"
14433   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14434         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14435                        (match_operand:DI 2 "arith_reg_operand" "r")))]
14436   "TARGET_SHMEDIA"
14437   "mshard.w     %1, %2, %0"
14438   [(set_attr "type" "arith_media")
14439    (set_attr "highpart" "depend")])
14440
14441 (define_insn "mshards_q"
14442   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14443         (ss_truncate:HI
14444          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14445                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14446   "TARGET_SHMEDIA"
14447   "mshards.q    %1, %N2, %0"
14448   [(set_attr "type" "mcmp_media")])
14449
14450 (define_expand "mshfhi_b"
14451   [(match_operand:V8QI 0 "arith_reg_dest" "")
14452    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14453    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14454   "TARGET_SHMEDIA"
14455 {
14456   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14457              (operands[0], operands[1], operands[2]));
14458   DONE;
14459 })
14460
14461 (define_expand "mshflo_b"
14462   [(match_operand:V8QI 0 "arith_reg_dest" "")
14463    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14464    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14465   "TARGET_SHMEDIA"
14466 {
14467   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14468              (operands[0], operands[1], operands[2]));
14469   DONE;
14470 })
14471
14472 (define_insn "mshf4_b"
14473   [(set
14474     (match_operand:V8QI 0 "arith_reg_dest" "=r")
14475     (vec_select:V8QI
14476      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14477                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14478      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14479                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14480   "TARGET_SHMEDIA"
14481 {
14482   return (TARGET_LITTLE_ENDIAN
14483           ? "mshfhi.b   %N1, %N2, %0"
14484           : "mshflo.b   %N1, %N2, %0");
14485 }
14486   [(set_attr "type" "arith_media")
14487    (set (attr "highpart")
14488         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14489          (const_string "user")))])
14490
14491 (define_insn "mshf0_b"
14492   [(set
14493     (match_operand:V8QI 0 "arith_reg_dest" "=r")
14494     (vec_select:V8QI
14495      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14496                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14497      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14498                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14499   "TARGET_SHMEDIA"
14500 {
14501   return (TARGET_LITTLE_ENDIAN
14502           ? "mshflo.b   %N1, %N2, %0"
14503           : "mshfhi.b   %N1, %N2, %0");
14504 }
14505   [(set_attr "type" "arith_media")
14506    (set (attr "highpart")
14507         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14508          (const_string "user")))])
14509
14510 (define_expand "mshfhi_l"
14511   [(match_operand:V2SI 0 "arith_reg_dest" "")
14512    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14513    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14514   "TARGET_SHMEDIA"
14515 {
14516   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14517              (operands[0], operands[1], operands[2]));
14518   DONE;
14519 })
14520
14521 (define_expand "mshflo_l"
14522   [(match_operand:V2SI 0 "arith_reg_dest" "")
14523    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14524    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14525   "TARGET_SHMEDIA"
14526 {
14527   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14528              (operands[0], operands[1], operands[2]));
14529   DONE;
14530 })
14531
14532 (define_insn "mshf4_l"
14533   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14534         (vec_select:V2SI
14535          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14536                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14537          (parallel [(const_int 1) (const_int 3)])))]
14538   "TARGET_SHMEDIA"
14539 {
14540   return (TARGET_LITTLE_ENDIAN
14541           ? "mshfhi.l   %N1, %N2, %0"
14542           : "mshflo.l   %N1, %N2, %0");
14543 }
14544   [(set_attr "type" "arith_media")
14545    (set (attr "highpart")
14546         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14547          (const_string "user")))])
14548
14549 (define_insn "mshf0_l"
14550   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14551         (vec_select:V2SI
14552          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14553                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14554          (parallel [(const_int 0) (const_int 2)])))]
14555   "TARGET_SHMEDIA"
14556 {
14557   return (TARGET_LITTLE_ENDIAN
14558           ? "mshflo.l   %N1, %N2, %0"
14559           : "mshfhi.l   %N1, %N2, %0");
14560 }
14561   [(set_attr "type" "arith_media")
14562    (set (attr "highpart")
14563         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14564          (const_string "user")))])
14565
14566 (define_expand "mshfhi_w"
14567   [(match_operand:V4HI 0 "arith_reg_dest" "")
14568    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14569    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14570   "TARGET_SHMEDIA"
14571 {
14572   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14573              (operands[0], operands[1], operands[2]));
14574   DONE;
14575 })
14576
14577 (define_expand "mshflo_w"
14578   [(match_operand:V4HI 0 "arith_reg_dest" "")
14579    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14580    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14581   "TARGET_SHMEDIA"
14582 {
14583   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14584              (operands[0], operands[1], operands[2]));
14585   DONE;
14586 })
14587
14588 (define_insn "mshf4_w"
14589   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14590         (vec_select:V4HI
14591          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14592                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14593          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14594   "TARGET_SHMEDIA"
14595 {
14596   return (TARGET_LITTLE_ENDIAN
14597           ? "mshfhi.w   %N1, %N2, %0"
14598           : "mshflo.w   %N1, %N2, %0");
14599 }
14600   [(set_attr "type" "arith_media")
14601    (set (attr "highpart")
14602         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14603          (const_string "user")))])
14604
14605 (define_insn "mshf0_w"
14606   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14607         (vec_select:V4HI
14608          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14609                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14610          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14611   "TARGET_SHMEDIA"
14612 {
14613   return (TARGET_LITTLE_ENDIAN
14614           ? "mshflo.w   %N1, %N2, %0"
14615           : "mshfhi.w   %N1, %N2, %0");
14616 }
14617   [(set_attr "type" "arith_media")
14618    (set (attr "highpart")
14619         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14620          (const_string "user")))])
14621
14622 (define_insn "mshflo_w_x"
14623   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14624         (vec_select:V4HI
14625          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14626                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14627          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14628   "TARGET_SHMEDIA"
14629   "mshflo.w     %N1, %N2, %0"
14630   [(set_attr "type" "arith_media")
14631    (set_attr "highpart" "ignore")])
14632
14633 ;; These are useful to expand ANDs and as combiner patterns.
14634 (define_insn_and_split "mshfhi_l_di"
14635   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14636         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14637                              (const_int 32))
14638                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14639                         (const_int -4294967296))))]
14640   "TARGET_SHMEDIA"
14641   "@
14642         mshfhi.l        %N1, %N2, %0
14643         #"
14644   "TARGET_SHMEDIA && reload_completed
14645    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14646   [(set (match_dup 3) (match_dup 4))
14647    (set (match_dup 5) (match_dup 6))]
14648 {
14649   operands[3] = gen_lowpart (SImode, operands[0]);
14650   operands[4] = gen_highpart (SImode, operands[1]);
14651   operands[5] = gen_highpart (SImode, operands[0]);
14652   operands[6] = gen_highpart (SImode, operands[2]);
14653 }
14654   [(set_attr "type" "arith_media")])
14655
14656 (define_insn "*mshfhi_l_di_rev"
14657   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14658         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14659                         (const_int -4294967296))
14660                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14661                              (const_int 32))))]
14662   "TARGET_SHMEDIA"
14663   "mshfhi.l     %N2, %N1, %0"
14664   [(set_attr "type" "arith_media")])
14665
14666 (define_split
14667   [(set (match_operand:DI 0 "arith_reg_dest" "")
14668         (ior:DI (zero_extend:DI (match_operand:SI 1
14669                                               "extend_reg_or_0_operand" ""))
14670                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
14671                         (const_int -4294967296))))
14672    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
14673   "TARGET_SHMEDIA"
14674   [(const_int 0)]
14675 {
14676   emit_insn (gen_ashldi3_media (operands[3],
14677                                 simplify_gen_subreg (DImode, operands[1],
14678                                                      SImode, 0),
14679                                 GEN_INT (32)));
14680   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
14681   DONE;
14682 })
14683
14684 (define_insn "mshflo_l_di"
14685   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14686         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14687                         (const_int 4294967295))
14688                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14689                            (const_int 32))))]
14690
14691   "TARGET_SHMEDIA"
14692   "mshflo.l     %N1, %N2, %0"
14693   [(set_attr "type" "arith_media")
14694    (set_attr "highpart" "ignore")])
14695
14696 (define_insn "*mshflo_l_di_rev"
14697   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14698         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14699                            (const_int 32))
14700                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14701                         (const_int 4294967295))))]
14702
14703   "TARGET_SHMEDIA"
14704   "mshflo.l     %N2, %N1, %0"
14705   [(set_attr "type" "arith_media")
14706    (set_attr "highpart" "ignore")])
14707
14708 ;; Combiner pattern for trampoline initialization.
14709 (define_insn_and_split "*double_shori"
14710   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14711         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
14712                            (const_int 32))
14713                 (match_operand:DI 2 "const_int_operand" "n")))]
14714   "TARGET_SHMEDIA
14715    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
14716   "#"
14717   "rtx_equal_p (operands[0], operands[1])"
14718   [(const_int 0)]
14719 {
14720   HOST_WIDE_INT v = INTVAL (operands[2]);
14721
14722   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
14723   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
14724   DONE;
14725 }
14726   [(set_attr "highpart" "ignore")])
14727
14728 (define_insn "*mshflo_l_di_x"
14729   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14730         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
14731                                  "rZ"))
14732                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14733                            (const_int 32))))]
14734   "TARGET_SHMEDIA"
14735   "mshflo.l     %N1, %N2, %0"
14736   [(set_attr "type" "arith_media")
14737    (set_attr "highpart" "ignore")])
14738
14739 (define_insn_and_split "concat_v2sf"
14740   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
14741 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
14742         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
14743                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
14744   "TARGET_SHMEDIA"
14745   "@
14746         mshflo.l        %N1, %N2, %0
14747         #
14748         #"
14749   "TARGET_SHMEDIA && reload_completed
14750    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14751   [(set (match_dup 3) (match_dup 1))
14752    (set (match_dup 4) (match_dup 2))]
14753 {
14754   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
14755   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
14756 }
14757   [(set_attr "type" "arith_media")
14758    (set_attr "highpart" "ignore")])
14759
14760 (define_insn "*mshflo_l_di_x_rev"
14761   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14762         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14763                            (const_int 32))
14764                 (zero_extend:DI
14765                   (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
14766   "TARGET_SHMEDIA"
14767   "mshflo.l     %N2, %N1, %0"
14768   [(set_attr "type" "arith_media")
14769    (set_attr "highpart" "ignore")])
14770
14771 (define_insn "ashlv2si3"
14772   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14773         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14774                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14775   "TARGET_SHMEDIA"
14776   "mshlld.l     %1, %2, %0"
14777   [(set_attr "type" "arith_media")
14778    (set_attr "highpart" "depend")])
14779
14780 (define_split
14781   [(set (match_operand 0 "any_register_operand" "")
14782         (match_operator 3 "shift_operator"
14783           [(match_operand 1 "any_register_operand" "")
14784            (match_operand 2 "shift_count_reg_operand" "")]))]
14785   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
14786   [(set (match_dup 0) (match_dup 3))]
14787 {
14788   rtx count = operands[2];
14789   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
14790
14791   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
14792          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
14793          || GET_CODE (count) == TRUNCATE)
14794     count = XEXP (count, 0);
14795   inner_mode = GET_MODE (count);
14796   count = simplify_gen_subreg (outer_mode, count, inner_mode,
14797                                subreg_lowpart_offset (outer_mode, inner_mode));
14798   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
14799                                 operands[1], count);
14800 })
14801
14802 (define_insn "ashlv4hi3"
14803   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14804         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14805                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14806   "TARGET_SHMEDIA"
14807   "mshlld.w     %1, %2, %0"
14808   [(set_attr "type" "arith_media")
14809    (set_attr "highpart" "depend")])
14810
14811 (define_insn "lshrv2si3"
14812   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14813         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14814                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14815   "TARGET_SHMEDIA"
14816   "mshlrd.l     %1, %2, %0"
14817   [(set_attr "type" "arith_media")
14818    (set_attr "highpart" "depend")])
14819
14820 (define_insn "lshrv4hi3"
14821   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14822         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14823                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14824   "TARGET_SHMEDIA"
14825   "mshlrd.w     %1, %2, %0"
14826   [(set_attr "type" "arith_media")
14827    (set_attr "highpart" "depend")])
14828
14829 (define_insn "subv2si3"
14830   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14831         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14832                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14833   "TARGET_SHMEDIA"
14834   "msub.l       %N1, %2, %0"
14835   [(set_attr "type" "arith_media")
14836    (set_attr "highpart" "depend")])
14837
14838 (define_insn "subv4hi3"
14839   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14840         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14841                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14842   "TARGET_SHMEDIA"
14843   "msub.w       %N1, %2, %0"
14844   [(set_attr "type" "arith_media")
14845    (set_attr "highpart" "depend")])
14846
14847 (define_insn_and_split "subv2hi3"
14848   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14849         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
14850                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
14851   "TARGET_SHMEDIA"
14852   "#"
14853   "TARGET_SHMEDIA"
14854   [(const_int 0)]
14855 {
14856   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14857   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14858   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14859   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14860   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14861
14862   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
14863   emit_insn (gen_truncdisi2 (si_dst, di_dst));
14864   DONE;
14865 }
14866   [(set_attr "highpart" "must_split")])
14867
14868 (define_insn "sssubv2si3"
14869   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14870         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14871                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14872   "TARGET_SHMEDIA"
14873   "msubs.l      %N1, %2, %0"
14874   [(set_attr "type" "mcmp_media")
14875    (set_attr "highpart" "depend")])
14876
14877 (define_insn "ussubv8qi3"
14878   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14879         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14880                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14881   "TARGET_SHMEDIA"
14882   "msubs.ub     %N1, %2, %0"
14883   [(set_attr "type" "mcmp_media")
14884    (set_attr "highpart" "depend")])
14885
14886 (define_insn "sssubv4hi3"
14887   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14888         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14889                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14890   "TARGET_SHMEDIA"
14891   "msubs.w      %N1, %2, %0"
14892   [(set_attr "type" "mcmp_media")
14893    (set_attr "highpart" "depend")])
14894
14895 ;; -------------------------------------------------------------------------
14896 ;; Floating Point Intrinsics
14897 ;; -------------------------------------------------------------------------
14898
14899 (define_insn "fcosa_s"
14900   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14901         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14902                    UNSPEC_FCOSA))]
14903   "TARGET_SHMEDIA"
14904   "fcosa.s      %1, %0"
14905   [(set_attr "type" "atrans_media")])
14906
14907 (define_insn "fsina_s"
14908   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14909         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14910                    UNSPEC_FSINA))]
14911   "TARGET_SHMEDIA"
14912   "fsina.s      %1, %0"
14913   [(set_attr "type" "atrans_media")])
14914
14915 (define_insn "fipr"
14916   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14917         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
14918                                                     "fp_arith_reg_operand" "f")
14919                                                    (match_operand:V4SF 2
14920                                                     "fp_arith_reg_operand" "f"))
14921                                          (parallel [(const_int 0)]))
14922                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14923                                          (parallel [(const_int 1)])))
14924                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14925                                          (parallel [(const_int 2)]))
14926                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14927                                          (parallel [(const_int 3)])))))]
14928   "TARGET_SHMEDIA"
14929   "fipr.s       %1, %2, %0"
14930   [(set_attr "type" "fparith_media")])
14931
14932 (define_insn "fsrra_s"
14933   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14934         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
14935                    UNSPEC_FSRRA))]
14936   "TARGET_SHMEDIA"
14937   "fsrra.s      %1, %0"
14938   [(set_attr "type" "atrans_media")])
14939
14940 (define_insn "ftrv"
14941   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
14942         (plus:V4SF
14943          (plus:V4SF
14944           (mult:V4SF
14945            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
14946                             (parallel [(const_int 0) (const_int 5)
14947                                        (const_int 10) (const_int 15)]))
14948            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
14949           (mult:V4SF
14950            (vec_select:V4SF (match_dup 1)
14951                             (parallel [(const_int 4) (const_int 9)
14952                                        (const_int 14) (const_int 3)]))
14953            (vec_select:V4SF (match_dup 2)
14954                             (parallel [(const_int 1) (const_int 2)
14955                                        (const_int 3) (const_int 0)]))))
14956          (plus:V4SF
14957           (mult:V4SF
14958            (vec_select:V4SF (match_dup 1)
14959                             (parallel [(const_int 8) (const_int 13)
14960                                        (const_int 2) (const_int 7)]))
14961            (vec_select:V4SF (match_dup 2)
14962                             (parallel [(const_int 2) (const_int 3)
14963                                        (const_int 0) (const_int 1)])))
14964           (mult:V4SF
14965            (vec_select:V4SF (match_dup 1)
14966                             (parallel [(const_int 12) (const_int 1)
14967                                        (const_int 6) (const_int 11)]))
14968            (vec_select:V4SF (match_dup 2)
14969                             (parallel [(const_int 3) (const_int 0)
14970                                        (const_int 1) (const_int 2)]))))))]
14971   "TARGET_SHMEDIA"
14972   "ftrv.s %1, %2, %0"
14973   [(set_attr "type" "fparith_media")])
14974
14975 (define_insn "ldhi_l"
14976   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
14977         (zero_extract:SI
14978          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14979                                   (const_int 3))
14980                           (const_int -3)))
14981          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
14982          (const_int 0)))]
14983   "TARGET_SHMEDIA32"
14984   "ldhi.l       %U1, %0"
14985   [(set_attr "type" "load_media")])
14986
14987 (define_insn "ldhi_q"
14988   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14989         (zero_extract:DI
14990          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14991                                   (const_int 7))
14992                           (const_int -7)))
14993          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
14994          (const_int 0)))]
14995   "TARGET_SHMEDIA32"
14996   "ldhi.q       %U1, %0"
14997   [(set_attr "type" "load_media")])
14998
14999 (define_insn_and_split "*ldhi_q_comb0"
15000   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15001         (zero_extract:DI
15002          (mem:DI (plus:SI (ior:SI (plus:SI
15003                                     (match_operand:SI 1 "register_operand" "r")
15004                                     (match_operand:SI 2 "ua_offset" "I06"))
15005                                   (const_int 7))
15006                           (const_int -7)))
15007          (plus:SI (and:SI (match_dup 1) (const_int 7))
15008                   (const_int 1))
15009          (const_int 0)))]
15010   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15011   "#"
15012   ""
15013   [(pc)]
15014 {
15015   emit_insn (gen_ldhi_q (operands[0],
15016                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15017   DONE;
15018 })
15019
15020 (define_insn_and_split "*ldhi_q_comb1"
15021   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15022         (zero_extract:DI
15023          (mem:DI (plus:SI (ior:SI (plus:SI
15024                                     (match_operand:SI 1 "register_operand" "r")
15025                                     (match_operand:SI 2 "ua_offset" "I06"))
15026                                   (const_int 7))
15027                           (const_int -7)))
15028          (plus:SI (and:SI (plus:SI (match_dup 1)
15029                                    (match_operand:SI 3 "ua_offset" "I06"))
15030                           (const_int 7))
15031                   (const_int 1))
15032          (const_int 0)))]
15033   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15034    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15035   "#"
15036   ""
15037   [(pc)]
15038 {
15039   emit_insn (gen_ldhi_q (operands[0],
15040                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15041   DONE;
15042 })
15043
15044 (define_insn "ldlo_l"
15045   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15046         (zero_extract:SI
15047          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15048                          (const_int -4)))
15049          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15050          (and:SI (match_dup 1) (const_int 3))))]
15051   "TARGET_SHMEDIA32"
15052   "ldlo.l       %U1, %0"
15053   [(set_attr "type" "load_media")])
15054
15055 (define_insn "ldlo_q"
15056   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15057         (zero_extract:DI
15058          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15059                          (const_int -8)))
15060          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15061          (and:SI (match_dup 1) (const_int 7))))]
15062   "TARGET_SHMEDIA32"
15063   "ldlo.q       %U1, %0"
15064   [(set_attr "type" "load_media")])
15065
15066 (define_insn_and_split "*ldlo_q_comb0"
15067   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15068         (zero_extract:DI
15069          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15070                                   (match_operand:SI 2 "ua_offset" "I06"))
15071                          (const_int -8)))
15072          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15073          (and:SI (match_dup 1) (const_int 7))))]
15074   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15075   "#"
15076   ""
15077   [(pc)]
15078 {
15079   emit_insn (gen_ldlo_q (operands[0],
15080                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15081   DONE;
15082 })
15083
15084 (define_insn_and_split "*ldlo_q_comb1"
15085   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15086         (zero_extract:DI
15087          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15088                                   (match_operand:SI 2 "ua_offset" "I06"))
15089                          (const_int -8)))
15090          (minus:SI (const_int 8)
15091                    (and:SI (plus:SI (match_dup 1)
15092                                     (match_operand:SI 3 "ua_offset" "I06"))
15093                            (const_int 7)))
15094          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15095   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15096    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15097   "#"
15098   ""
15099   [(pc)]
15100 {
15101   emit_insn (gen_ldlo_q (operands[0],
15102                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15103   DONE;
15104 })
15105
15106 (define_insn "sthi_l"
15107   [(set (zero_extract:SI
15108          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15109                                   (const_int 3))
15110                           (const_int -3)))
15111          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15112          (const_int 0))
15113         (match_operand:SI 1 "arith_reg_operand" "r"))]
15114   "TARGET_SHMEDIA32"
15115   "sthi.l       %U0, %1"
15116   [(set_attr "type" "ustore_media")])
15117
15118 ;; All unaligned stores are considered to be 'narrow' because they typically
15119 ;; operate on less that a quadword, and when they operate on a full quadword,
15120 ;; the vanilla store high / store low sequence will cause a stall if not
15121 ;; scheduled apart.
15122 (define_insn "sthi_q"
15123   [(set (zero_extract:DI
15124          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15125                                   (const_int 7))
15126                           (const_int -7)))
15127          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15128          (const_int 0))
15129         (match_operand:DI 1 "arith_reg_operand" "r"))]
15130   "TARGET_SHMEDIA32"
15131   "sthi.q       %U0, %1"
15132   [(set_attr "type" "ustore_media")])
15133
15134 (define_insn_and_split "*sthi_q_comb0"
15135   [(set (zero_extract:DI
15136          (mem:DI (plus:SI (ior:SI (plus:SI
15137                                     (match_operand:SI 0 "register_operand" "r")
15138                                     (match_operand:SI 1 "ua_offset" "I06"))
15139                                   (const_int 7))
15140                           (const_int -7)))
15141          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15142          (const_int 0))
15143         (match_operand:DI 2 "arith_reg_operand" "r"))]
15144   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15145   "#"
15146   ""
15147   [(pc)]
15148 {
15149   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15150                          operands[2]));
15151   DONE;
15152 })
15153
15154 (define_insn_and_split "*sthi_q_comb1"
15155   [(set (zero_extract:DI
15156          (mem:DI (plus:SI (ior:SI (plus:SI
15157                                     (match_operand:SI 0 "register_operand" "r")
15158                                     (match_operand:SI 1 "ua_offset" "I06"))
15159                                   (const_int 7))
15160                           (const_int -7)))
15161          (plus:SI (and:SI (plus:SI (match_dup 0)
15162                                    (match_operand:SI 2 "ua_offset" "I06"))
15163                           (const_int 7))
15164                   (const_int 1))
15165          (const_int 0))
15166         (match_operand:DI 3 "arith_reg_operand" "r"))]
15167   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15168    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15169   "#"
15170   ""
15171   [(pc)]
15172 {
15173   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15174                          operands[3]));
15175   DONE;
15176 })
15177
15178 ;; This is highpart user because the address is used as full 64 bit.
15179 (define_insn "stlo_l"
15180   [(set (zero_extract:SI
15181          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15182                          (const_int -4)))
15183          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15184          (and:SI (match_dup 0) (const_int 3)))
15185         (match_operand:SI 1 "arith_reg_operand" "r"))]
15186   "TARGET_SHMEDIA32"
15187   "stlo.l       %U0, %1"
15188   [(set_attr "type" "ustore_media")])
15189
15190 (define_insn "stlo_q"
15191   [(set (zero_extract:DI
15192          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15193                          (const_int -8)))
15194          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15195          (and:SI (match_dup 0) (const_int 7)))
15196         (match_operand:DI 1 "arith_reg_operand" "r"))]
15197   "TARGET_SHMEDIA32"
15198   "stlo.q       %U0, %1"
15199   [(set_attr "type" "ustore_media")])
15200
15201 (define_insn_and_split "*stlo_q_comb0"
15202   [(set (zero_extract:DI
15203          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15204                                   (match_operand:SI 1 "ua_offset" "I06"))
15205                          (const_int -8)))
15206          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15207          (and:SI (match_dup 0) (const_int 7)))
15208         (match_operand:DI 2 "arith_reg_operand" "r"))]
15209   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15210   "#"
15211   ""
15212   [(pc)]
15213 {
15214   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15215                          operands[2]));
15216   DONE;
15217 })
15218
15219 (define_insn_and_split "*stlo_q_comb1"
15220   [(set (zero_extract:DI
15221          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15222                                   (match_operand:SI 1 "ua_offset" "I06"))
15223                          (const_int -8)))
15224          (minus:SI (const_int 8)
15225                    (and:SI (plus:SI (match_dup 0)
15226                                     (match_operand:SI 2 "ua_offset" "I06"))
15227                            (const_int 7)))
15228          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15229         (match_operand:DI 3 "arith_reg_operand" "r"))]
15230   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15231   "#"
15232   ""
15233   [(pc)]
15234 {
15235   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15236                          operands[3]));
15237    DONE;
15238 })
15239
15240 (define_insn "ldhi_l64"
15241   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15242         (zero_extract:SI
15243          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15244                                   (const_int 3))
15245                           (const_int -3)))
15246          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15247          (const_int 0)))]
15248   "TARGET_SHMEDIA64"
15249   "ldhi.l       %U1, %0"
15250   [(set_attr "type" "load_media")])
15251
15252 (define_insn "ldhi_q64"
15253   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15254         (zero_extract:DI
15255          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15256                                   (const_int 7))
15257                           (const_int -7)))
15258          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15259          (const_int 0)))]
15260   "TARGET_SHMEDIA64"
15261   "ldhi.q       %U1, %0"
15262   [(set_attr "type" "load_media")])
15263
15264 (define_insn "ldlo_l64"
15265   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15266         (zero_extract:SI
15267          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15268                          (const_int -4)))
15269          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15270          (and:DI (match_dup 1) (const_int 3))))]
15271   "TARGET_SHMEDIA64"
15272   "ldlo.l       %U1, %0"
15273   [(set_attr "type" "load_media")])
15274
15275 (define_insn "ldlo_q64"
15276   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15277         (zero_extract:DI
15278          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15279                          (const_int -8)))
15280          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15281          (and:DI (match_dup 1) (const_int 7))))]
15282   "TARGET_SHMEDIA64"
15283   "ldlo.q       %U1, %0"
15284   [(set_attr "type" "load_media")])
15285
15286 (define_insn "sthi_l64"
15287   [(set (zero_extract:SI
15288          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15289                                   (const_int 3))
15290                           (const_int -3)))
15291          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15292          (const_int 0))
15293         (match_operand:SI 1 "arith_reg_operand" "r"))]
15294   "TARGET_SHMEDIA64"
15295   "sthi.l       %U0, %1"
15296   [(set_attr "type" "ustore_media")])
15297
15298 (define_insn "sthi_q64"
15299   [(set (zero_extract:DI
15300          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15301                                   (const_int 7))
15302                           (const_int -7)))
15303          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15304          (const_int 0))
15305         (match_operand:DI 1 "arith_reg_operand" "r"))]
15306   "TARGET_SHMEDIA64"
15307   "sthi.q       %U0, %1"
15308   [(set_attr "type" "ustore_media")])
15309
15310 (define_insn "stlo_l64"
15311   [(set (zero_extract:SI
15312          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15313                          (const_int -4)))
15314          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15315          (and:DI (match_dup 0) (const_int 3)))
15316         (match_operand:SI 1 "arith_reg_operand" "r"))]
15317   "TARGET_SHMEDIA64"
15318   "stlo.l       %U0, %1"
15319   [(set_attr "type" "ustore_media")])
15320
15321 (define_insn "stlo_q64"
15322   [(set (zero_extract:DI
15323          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15324                          (const_int -8)))
15325          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15326          (and:DI (match_dup 0) (const_int 7)))
15327         (match_operand:DI 1 "arith_reg_operand" "r"))]
15328   "TARGET_SHMEDIA64"
15329   "stlo.q       %U0, %1"
15330   [(set_attr "type" "ustore_media")])
15331
15332 (define_insn "nsb"
15333   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15334         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15335                    UNSPEC_NSB))]
15336   "TARGET_SHMEDIA"
15337   "nsb  %1, %0"
15338   [(set_attr "type" "arith_media")])
15339
15340 (define_insn "nsbsi"
15341   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15342         (zero_extend:SI
15343          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15344                     UNSPEC_NSB)))]
15345   "TARGET_SHMEDIA"
15346   "nsb  %1, %0"
15347   [(set_attr "type" "arith_media")])
15348
15349 (define_insn "nsbdi"
15350   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15351         (zero_extend:DI
15352          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15353                     UNSPEC_NSB)))]
15354   "TARGET_SHMEDIA"
15355   "nsb  %1, %0"
15356   [(set_attr "type" "arith_media")])
15357
15358 (define_expand "ffsdi2"
15359   [(set (match_operand:DI 0 "arith_reg_dest" "")
15360         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15361   "TARGET_SHMEDIA"
15362 {
15363   rtx scratch = gen_reg_rtx (DImode);
15364   rtx last;
15365
15366   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15367   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15368   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15369   emit_insn (gen_nsbdi (scratch, scratch));
15370   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15371   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15372   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15373   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15374
15375   DONE;
15376 })
15377
15378 (define_expand "ffssi2"
15379   [(set (match_operand:SI 0 "arith_reg_dest" "")
15380         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15381   "TARGET_SHMEDIA"
15382 {
15383   rtx scratch = gen_reg_rtx (SImode);
15384   rtx discratch = gen_reg_rtx (DImode);
15385   rtx last;
15386
15387   emit_insn (gen_adddi3 (discratch,
15388                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
15389                          constm1_rtx));
15390   emit_insn (gen_andcdi3 (discratch,
15391                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
15392                           discratch));
15393   emit_insn (gen_nsbsi (scratch, discratch));
15394   last = emit_insn (gen_subsi3 (operands[0],
15395                                 force_reg (SImode, GEN_INT (63)), scratch));
15396   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15397
15398   DONE;
15399 })
15400
15401 (define_insn "byterev"
15402   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15403         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15404                          (parallel [(const_int 7) (const_int 6) (const_int 5)
15405                                     (const_int 4) (const_int 3) (const_int 2)
15406                                     (const_int 1) (const_int 0)])))]
15407   "TARGET_SHMEDIA"
15408   "byterev      %1, %0"
15409   [(set_attr "type" "arith_media")])
15410
15411 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15412 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
15413 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15414 (define_expand "prefetch"
15415   [(prefetch (match_operand 0 "address_operand" "")
15416              (match_operand:SI 1 "const_int_operand" "")
15417              (match_operand:SI 2 "const_int_operand" ""))]
15418   "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15419    && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15420
15421 (define_insn "*prefetch"
15422   [(prefetch (match_operand:SI 0 "register_operand" "r")
15423              (match_operand:SI 1 "const_int_operand" "n")
15424              (match_operand:SI 2 "const_int_operand" "n"))]
15425   "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15426   "pref @%0"
15427   [(set_attr "type" "other")])
15428
15429 (define_insn "*prefetch_media"
15430   [(prefetch (match_operand:QI 0 "address_operand" "p")
15431              (match_operand:SI 1 "const_int_operand" "n")
15432              (match_operand:SI 2 "const_int_operand" "n"))]
15433   "TARGET_SHMEDIA"
15434 {
15435   operands[0] = gen_rtx_MEM (QImode, operands[0]);
15436   output_asm_insn ("ld%M0.b     %m0,r63", operands);
15437   return "";
15438 }
15439   [(set_attr "type" "other")])
15440
15441 (define_insn "alloco_i"
15442   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15443         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15444   "TARGET_SHMEDIA32"
15445 {
15446   rtx xops[2];
15447
15448   if (GET_CODE (operands[0]) == PLUS)
15449     {
15450       xops[0] = XEXP (operands[0], 0);
15451       xops[1] = XEXP (operands[0], 1);
15452     }
15453   else
15454     {
15455       xops[0] = operands[0];
15456       xops[1] = const0_rtx;
15457     }
15458   output_asm_insn ("alloco      %0, %1", xops);
15459   return "";
15460 }
15461   [(set_attr "type" "other")])
15462
15463 (define_split
15464   [(set (match_operand 0 "any_register_operand" "")
15465         (match_operand 1 "" ""))]
15466   "TARGET_SHMEDIA && reload_completed"
15467   [(set (match_dup 0) (match_dup 1))]
15468 {
15469   int n_changes = 0;
15470
15471   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
15472   if (!n_changes)
15473     FAIL;
15474 })
15475
15476 ;; -------------------------------------------------------------------------
15477 ;; Stack Protector Patterns
15478 ;; -------------------------------------------------------------------------
15479
15480 (define_expand "stack_protect_set"
15481   [(set (match_operand 0 "memory_operand" "")
15482         (match_operand 1 "memory_operand" ""))]
15483   ""
15484 {
15485   if (TARGET_SHMEDIA)
15486     {
15487       if (TARGET_SHMEDIA64)
15488         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15489       else
15490         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15491     }
15492   else
15493     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15494
15495   DONE;
15496 })
15497
15498 (define_insn "stack_protect_set_si"
15499   [(set (match_operand:SI 0 "memory_operand" "=m")
15500         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15501    (set (match_scratch:SI 2 "=&r") (const_int 0))]
15502   "!TARGET_SHMEDIA"
15503 {
15504   return       "mov.l   %1,%2"  "\n"
15505          "      mov.l   %2,%0"  "\n"
15506          "      mov     #0,%2";
15507 }
15508   [(set_attr "type" "other")
15509    (set_attr "length" "6")])
15510
15511 (define_insn "stack_protect_set_si_media"
15512   [(set (match_operand:SI 0 "memory_operand" "=m")
15513         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15514    (set (match_scratch:SI 2 "=&r") (const_int 0))]
15515   "TARGET_SHMEDIA"
15516 {
15517   return       "ld%M1.l %m1,%2" "\n"
15518          "      st%M0.l %m0,%2" "\n"
15519          "      movi    0,%2";
15520 }
15521   [(set_attr "type" "other")
15522    (set_attr "length" "12")])
15523
15524 (define_insn "stack_protect_set_di_media"
15525   [(set (match_operand:DI 0 "memory_operand" "=m")
15526         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15527    (set (match_scratch:DI 2 "=&r") (const_int 0))]
15528   "TARGET_SHMEDIA64"
15529 {
15530   return       "ld%M1.q %m1,%2" "\n"
15531          "      st%M0.q %m0,%2" "\n"
15532          "      movi    0,%2";
15533 }
15534   [(set_attr "type" "other")
15535    (set_attr "length" "12")])
15536
15537 (define_expand "stack_protect_test"
15538   [(match_operand 0 "memory_operand" "")
15539    (match_operand 1 "memory_operand" "")
15540    (match_operand 2 "" "")]
15541   ""
15542 {
15543   if (TARGET_SHMEDIA)
15544     {
15545       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15546       rtx test;
15547
15548       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15549       if (TARGET_SHMEDIA64)
15550         {
15551           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15552                                                       operands[1]));
15553           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15554         }
15555       else
15556         {
15557           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15558                                                       operands[1]));
15559           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15560         }
15561     }
15562   else
15563     {
15564       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15565       emit_jump_insn (gen_branch_true (operands[2]));
15566     }
15567
15568   DONE;
15569 })
15570
15571 (define_insn "stack_protect_test_si"
15572   [(set (reg:SI T_REG)
15573         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15574                     (match_operand:SI 1 "memory_operand" "m")]
15575                    UNSPEC_SP_TEST))
15576   (set (match_scratch:SI 2 "=&r") (const_int 0))
15577   (set (match_scratch:SI 3 "=&r") (const_int 0))]
15578   "!TARGET_SHMEDIA"
15579 {
15580   return       "mov.l   %0,%2"  "\n"
15581          "      mov.l   %1,%3"  "\n"
15582          "      cmp/eq  %2,%3"  "\n"
15583          "      mov     #0,%2"  "\n"
15584          "      mov     #0,%3";
15585 }
15586   [(set_attr "type" "other")
15587    (set_attr "length" "10")])
15588
15589 (define_insn "stack_protect_test_si_media"
15590   [(set (match_operand:SI 0 "register_operand" "=&r")
15591         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15592                     (match_operand:SI 2 "memory_operand" "m")]
15593                    UNSPEC_SP_TEST))
15594   (set (match_scratch:SI 3 "=&r") (const_int 0))]
15595   "TARGET_SHMEDIA"
15596 {
15597   return       "ld%M1.l %m1,%0"         "\n"
15598          "      ld%M2.l %m2,%3"         "\n"
15599          "      cmpeq   %0,%3,%0"       "\n"
15600          "      movi    0,%3";
15601 }
15602   [(set_attr "type" "other")
15603    (set_attr "length" "16")])
15604
15605 (define_insn "stack_protect_test_di_media"
15606   [(set (match_operand:DI 0 "register_operand" "=&r")
15607         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15608                     (match_operand:DI 2 "memory_operand" "m")]
15609                    UNSPEC_SP_TEST))
15610   (set (match_scratch:DI 3 "=&r") (const_int 0))]
15611   "TARGET_SHMEDIA64"
15612 {
15613   return       "ld%M1.q %m1,%0"         "\n"
15614          "      ld%M2.q %m2,%3"         "\n"
15615          "      cmpeq   %0,%3,%0"       "\n"
15616          "      movi    0,%3";
15617 }
15618   [(set_attr "type" "other")
15619    (set_attr "length" "16")])
15620
15621 ;; -------------------------------------------------------------------------
15622 ;; Atomic operations
15623 ;; -------------------------------------------------------------------------
15624
15625 (include "sync.md")