remove unused files
[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
6840 ;; try other insns and not stick to movqi_reg_reg, unless there were spilled
6841 ;; pseudos in which case 'm' constraints pertain.
6842 ;; The same applies to the movhi variants.
6843 ;;
6844 ;; Notice, that T bit is not allowed as a mov src operand here.  This is to
6845 ;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
6846 ;; introduces zero extensions after T bit stores and redundant reg copies.
6847 ;;
6848 ;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
6849 ;; predicate for the mov src operand because reload will have trouble
6850 ;; reloading MAC subregs otherwise.  For that probably special patterns
6851 ;; would be required.
6852 (define_insn "*mov<mode>_reg_reg"
6853   [(set (match_operand:QIHI 0 "arith_reg_dest" "=r,m,*z")
6854         (match_operand:QIHI 1 "register_operand" "r,*z,m"))]
6855   "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
6856   "@
6857     mov         %1,%0
6858     mov.<bw>    %1,%0
6859     mov.<bw>    %1,%0"
6860   [(set_attr "type" "move,store,load")])
6861
6862 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
6863 ;; "enabled" attribute as it is done in other targets.
6864 (define_insn "*mov<mode>_store_mem_disp04"
6865   [(set (mem:QIHI
6866           (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
6867                    (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
6868         (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
6869   "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
6870   "@
6871         mov.<bw>        %2,@(%O1,%0)
6872         mov.<bw>        %2,@%0"
6873   [(set_attr "type" "store")])
6874
6875 (define_insn "*mov<mode>_store_mem_disp12"
6876   [(set (mem:QIHI
6877           (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
6878                    (match_operand:SI 1 "const_int_operand" "<disp12>")))
6879         (match_operand:QIHI 2 "arith_reg_operand" "r"))]
6880   "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
6881   "mov.<bw>     %2,@(%O1,%0)"
6882   [(set_attr "type" "store")
6883    (set_attr "length" "4")])
6884
6885 (define_insn "*mov<mode>_load_mem_disp04"
6886   [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
6887         (mem:QIHI
6888           (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
6889                    (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
6890   "TARGET_SH1 && ! TARGET_SH2A
6891    && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6892   "@
6893         mov.<bw>        @(%O2,%1),%0
6894         mov.<bw>        @%1,%0"
6895   [(set_attr "type" "load")])
6896
6897 (define_insn "*mov<mode>_load_mem_disp12"
6898   [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
6899         (mem:QIHI
6900           (plus:SI
6901             (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6902             (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
6903   "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6904   "@
6905         mov.<bw>        @(%O2,%1),%0
6906         mov.<bw>        @%1,%0
6907         mov.<bw>        @(%O2,%1),%0"
6908   [(set_attr "type" "load")
6909    (set_attr "length" "2,2,4")])
6910
6911 ;; The m constraints basically allow any kind of addresses to be used with any
6912 ;; source/target register as the other operand.  This is not true for 
6913 ;; displacement addressing modes on anything but SH2A.  That's why the
6914 ;; specialized load/store insns are specified above.
6915 (define_insn "*movqi"
6916   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
6917         (match_operand:QI 1 "general_movsrc_operand"  "i,m,r,l,r"))]
6918   "TARGET_SH1
6919    && (arith_reg_operand (operands[0], QImode)
6920        || arith_reg_operand (operands[1], QImode))"
6921   "@
6922         mov     %1,%0
6923         mov.b   %1,%0
6924         mov.b   %1,%0
6925         sts     %1,%0
6926         lds     %1,%0"
6927  [(set_attr "type" "movi8,load,store,prget,prset")])
6928
6929 (define_insn "*movhi"
6930   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
6931         (match_operand:HI 1 "general_movsrc_operand"  "Q,i,m,r,l,r"))]
6932   "TARGET_SH1
6933    && (arith_reg_operand (operands[0], HImode)
6934        || arith_reg_operand (operands[1], HImode))"
6935   "@
6936         mov.w   %1,%0
6937         mov     %1,%0
6938         mov.w   %1,%0
6939         mov.w   %1,%0
6940         sts     %1,%0
6941         lds     %1,%0"
6942  [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
6943
6944 (define_insn "*movqi_media"
6945   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
6946         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
6947   "TARGET_SHMEDIA
6948    && (arith_reg_operand (operands[0], QImode)
6949        || extend_reg_or_0_operand (operands[1], QImode))"
6950   "@
6951         add.l   %1, r63, %0
6952         movi    %1, %0
6953         ld%M1.ub        %m1, %0
6954         st%M0.b %m0, %N1"
6955   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
6956    (set (attr "highpart")
6957         (cond [(match_test "sh_contains_memref_p (insn)")
6958                (const_string "user")]
6959               (const_string "ignore")))])
6960
6961 (define_expand "reload_inqi"
6962   [(set (match_operand:SI 2 "" "=&r")
6963         (match_operand:QI 1 "inqhi_operand" ""))
6964    (set (match_operand:QI 0 "arith_reg_operand" "=r")
6965         (truncate:QI (match_dup 3)))]
6966   "TARGET_SHMEDIA"
6967 {
6968   rtx inner = XEXP (operands[1], 0);
6969   int regno = REGNO (inner);
6970
6971   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6972   operands[1] = gen_rtx_REG (SImode, regno);
6973   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
6974 })
6975
6976 (define_insn "*movhi_media"
6977   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
6978         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
6979   "TARGET_SHMEDIA
6980    && (arith_reg_operand (operands[0], HImode)
6981        || arith_reg_or_0_operand (operands[1], HImode))"
6982   "@
6983         add.l   %1, r63, %0
6984         movi    %1, %0
6985         #
6986         ld%M1.w %m1, %0
6987         st%M0.w %m0, %N1"
6988   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
6989    (set (attr "highpart")
6990         (cond [(match_test "sh_contains_memref_p (insn)")
6991                (const_string "user")]
6992               (const_string "ignore")))])
6993
6994 (define_split
6995   [(set (match_operand:HI 0 "register_operand" "")
6996         (match_operand:HI 1 "immediate_operand" ""))]
6997   "TARGET_SHMEDIA && reload_completed
6998    && ! satisfies_constraint_I16 (operands[1])"
6999   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7000
7001 (define_expand "reload_inhi"
7002   [(set (match_operand:SI 2 "" "=&r")
7003         (match_operand:HI 1 "inqhi_operand" ""))
7004    (set (match_operand:HI 0 "arith_reg_operand" "=r")
7005         (truncate:HI (match_dup 3)))]
7006   "TARGET_SHMEDIA"
7007 {
7008   rtx inner = XEXP (operands[1], 0);
7009   int regno = REGNO (inner);
7010
7011   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7012   operands[1] = gen_rtx_REG (SImode, regno);
7013   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7014 })
7015
7016 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7017 ;; compiled with -m2 -ml -O3 -funroll-loops
7018 (define_insn "*movdi_i"
7019   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7020         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7021   "TARGET_SH1
7022    && (arith_reg_operand (operands[0], DImode)
7023        || arith_reg_operand (operands[1], DImode))"
7024 {
7025   return output_movedouble (insn, operands, DImode);
7026 }
7027   [(set_attr "length" "4")
7028    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7029
7030 ;; If the output is a register and the input is memory or a register, we have
7031 ;; to be careful and see which word needs to be loaded first.
7032 (define_split
7033   [(set (match_operand:DI 0 "general_movdst_operand" "")
7034         (match_operand:DI 1 "general_movsrc_operand" ""))]
7035   "TARGET_SH1 && reload_completed"
7036   [(set (match_dup 2) (match_dup 3))
7037    (set (match_dup 4) (match_dup 5))]
7038 {
7039   int regno;
7040
7041   if ((MEM_P (operands[0])
7042        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7043       || (MEM_P (operands[1])
7044           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7045     FAIL;
7046
7047   switch (GET_CODE (operands[0]))
7048     {
7049     case REG:
7050       regno = REGNO (operands[0]);
7051       break;
7052     case SUBREG:
7053       regno = subreg_regno (operands[0]);
7054       break;
7055     case MEM:
7056       regno = -1;
7057       break;
7058     default:
7059       gcc_unreachable ();
7060     }
7061
7062   if (regno == -1
7063       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7064     {
7065       operands[2] = operand_subword (operands[0], 0, 0, DImode);
7066       operands[3] = operand_subword (operands[1], 0, 0, DImode);
7067       operands[4] = operand_subword (operands[0], 1, 0, DImode);
7068       operands[5] = operand_subword (operands[1], 1, 0, DImode);
7069     }
7070   else
7071     {
7072       operands[2] = operand_subword (operands[0], 1, 0, DImode);
7073       operands[3] = operand_subword (operands[1], 1, 0, DImode);
7074       operands[4] = operand_subword (operands[0], 0, 0, DImode);
7075       operands[5] = operand_subword (operands[1], 0, 0, DImode);
7076     }
7077
7078   if (operands[2] == 0 || operands[3] == 0
7079       || operands[4] == 0 || operands[5] == 0)
7080     FAIL;
7081 })
7082
7083 ;; The '?'s in the following constraints may not reflect the time taken
7084 ;; to perform the move. They are there to discourage the use of floating-
7085 ;; point registers for storing integer values.
7086 (define_insn "*movdi_media"
7087   [(set (match_operand:DI 0 "general_movdst_operand"
7088                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7089         (match_operand:DI 1 "general_movsrc_operand"
7090          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7091   "TARGET_SHMEDIA_FPU
7092    && (register_operand (operands[0], DImode)
7093        || sh_register_operand (operands[1], DImode))"
7094   "@
7095         add     %1, r63, %0
7096         movi    %1, %0
7097         #
7098         ld%M1.q %m1, %0
7099         st%M0.q %m0, %N1
7100         fld%M1.d        %m1, %0
7101         fst%M0.d        %m0, %1
7102         fmov.qd %N1, %0
7103         fmov.dq %1, %0
7104         fmov.d  %1, %0
7105         ptabs   %1, %0
7106         gettr   %1, %0
7107         pt      %1, %0"
7108   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7109                      fload_media,fstore_media,fload_media,dfpconv_media,
7110                      fmove_media,ptabs_media,gettr_media,pt_media")
7111    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7112
7113 (define_insn "*movdi_media_nofpu"
7114   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7115         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7116   "TARGET_SHMEDIA
7117    && (register_operand (operands[0], DImode)
7118        || sh_register_operand (operands[1], DImode))"
7119   "@
7120         add     %1, r63, %0
7121         movi    %1, %0
7122         #
7123         ld%M1.q %m1, %0
7124         st%M0.q %m0, %N1
7125         ptabs   %1, %0
7126         gettr   %1, %0
7127         pt      %1, %0"
7128   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7129                      ptabs_media,gettr_media,pt_media")
7130    (set_attr "length" "4,4,16,4,4,4,4,*")])
7131
7132 (define_insn "*movdi_media_I16"
7133   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7134         (match_operand:DI 1 "const_int_operand" "I16"))]
7135   "TARGET_SHMEDIA && reload_completed"
7136   "movi %1, %0"
7137   [(set_attr "type" "arith_media")
7138    (set_attr "length" "4")])
7139
7140 (define_split
7141   [(set (match_operand:DI 0 "arith_reg_dest" "")
7142         (match_operand:DI 1 "immediate_operand" ""))]
7143   "TARGET_SHMEDIA && reload_completed
7144    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7145   [(set (match_dup 0) (match_dup 1))]
7146 {
7147   rtx insn;
7148
7149   if (TARGET_SHMEDIA64)
7150     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7151   else
7152     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7153
7154   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7155
7156   DONE;
7157 })
7158
7159 (define_expand "movdi_const"
7160   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7161         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7162                               (const_int 48)] UNSPEC_EXTRACT_S16)))
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 32)] 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 16)] UNSPEC_EXTRACT_U16))))
7171    (set (match_dup 0)
7172         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7173                 (const:DI (unspec:DI [(match_dup 1)
7174                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
7175   "TARGET_SHMEDIA64 && reload_completed
7176    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7177 {
7178   sh_mark_label (operands[1], 4);
7179 })
7180
7181 (define_expand "movdi_const_32bit"
7182   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7183         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7184                               (const_int 16)] UNSPEC_EXTRACT_S16)))
7185    (set (match_dup 0)
7186         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7187                 (const:DI (unspec:DI [(match_dup 1)
7188                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
7189   "TARGET_SHMEDIA32 && reload_completed
7190    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7191 {
7192   sh_mark_label (operands[1], 2);
7193 })
7194
7195 (define_expand "movdi_const_16bit"
7196   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7197         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7198                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
7199   "TARGET_SHMEDIA && flag_pic && reload_completed
7200    && GET_CODE (operands[1]) == SYMBOL_REF"
7201   "")
7202
7203 (define_split
7204   [(set (match_operand:DI 0 "ext_dest_operand" "")
7205         (match_operand:DI 1 "immediate_operand" ""))]
7206   "TARGET_SHMEDIA && reload_completed
7207    && CONST_INT_P (operands[1])
7208    && ! satisfies_constraint_I16 (operands[1])"
7209   [(set (match_dup 0) (match_dup 2))
7210    (match_dup 1)]
7211 {
7212   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7213   unsigned HOST_WIDE_INT low = val;
7214   unsigned HOST_WIDE_INT high = val;
7215   unsigned HOST_WIDE_INT sign;
7216   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7217
7218   /* Zero-extend the 16 least-significant bits.  */
7219   low &= 0xffff;
7220
7221   /* Arithmetic shift right the word by 16 bits.  */
7222   high >>= 16;
7223   if (GET_CODE (operands[0]) == SUBREG
7224       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7225     {
7226       high &= 0xffff;
7227       high ^= 0x8000;
7228       high -= 0x8000;
7229     }
7230   else
7231     {
7232       sign = 1;
7233       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7234       high ^= sign;
7235       high -= sign;
7236     }
7237   do
7238     {
7239       /* If we can't generate the constant with a two-insn movi / shori
7240          sequence, try some other strategies.  */
7241       if (! CONST_OK_FOR_I16 (high))
7242         {
7243           /* Try constant load / left shift.  We know VAL != 0.  */
7244           val2 = val ^ (val-1);
7245           if (val2 > 0x1ffff)
7246             {
7247               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7248
7249               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7250                   || (! CONST_OK_FOR_I16 (high >> 16)
7251                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7252                 {
7253                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7254                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
7255                                                    GEN_INT (trailing_zeroes));
7256                   break;
7257                 }
7258             }
7259           /* Try constant load / right shift.  */
7260           val2 = (val >> 15) + 1;
7261           if (val2 == (val2 & -val2))
7262             {
7263               int shift = 49 - exact_log2 (val2);
7264
7265               val2 = trunc_int_for_mode (val << shift, DImode);
7266               if (CONST_OK_FOR_I16 (val2))
7267                 {
7268                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7269                                                    GEN_INT (shift));
7270                   break;
7271                 }
7272             }
7273           /* Try mperm.w .  */
7274           val2 = val & 0xffff;
7275           if ((val >> 16 & 0xffff) == val2
7276               && (val >> 32 & 0xffff) == val2
7277               && (val >> 48 & 0xffff) == val2)
7278             {
7279               val2 = (HOST_WIDE_INT) val >> 48;
7280               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7281               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7282               break;
7283             }
7284           /* Try movi / mshflo.l  */
7285           val2 = (HOST_WIDE_INT) val >> 32;
7286           if (val2 == ((unsigned HOST_WIDE_INT)
7287                         trunc_int_for_mode (val, SImode)))
7288             {
7289               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7290                                              operands[0]);
7291               break;
7292             }
7293           /* Try movi / mshflo.l w/ r63.  */
7294           val2 = val + ((HOST_WIDE_INT) -1 << 32);
7295           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7296             {
7297               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7298                                              const0_rtx);
7299               break;
7300             }
7301         }
7302       val2 = high;
7303       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7304     }
7305   while (0);
7306   operands[2] = GEN_INT (val2);
7307 })
7308
7309 (define_split
7310   [(set (match_operand:DI 0 "ext_dest_operand" "")
7311         (match_operand:DI 1 "immediate_operand" ""))]
7312   "TARGET_SHMEDIA && reload_completed
7313    && GET_CODE (operands[1]) == CONST_DOUBLE"
7314   [(set (match_dup 0) (match_dup 2))
7315   (set (match_dup 0)
7316        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7317 {
7318   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7319   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7320   unsigned HOST_WIDE_INT val = low;
7321   unsigned HOST_WIDE_INT sign;
7322
7323   /* Zero-extend the 16 least-significant bits.  */
7324   val &= 0xffff;
7325   operands[1] = GEN_INT (val);
7326
7327   /* Arithmetic shift right the double-word by 16 bits.  */
7328   low >>= 16;
7329   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7330   high >>= 16;
7331   sign = 1;
7332   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7333   high ^= sign;
7334   high -= sign;
7335
7336   /* This will only be true if high is a sign-extension of low, i.e.,
7337      it must be either 0 or (unsigned)-1, and be zero iff the
7338      most-significant bit of low is set.  */
7339   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7340     operands[2] = GEN_INT (low);
7341   else
7342     operands[2] = immed_double_const (low, high, DImode);
7343 })
7344
7345 (define_insn "shori_media"
7346   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7347         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7348                            (const_int 16))
7349                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7350   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7351   "@
7352         shori   %u2, %0
7353         #"
7354   [(set_attr "type" "arith_media,*")])
7355
7356 (define_insn "*shori_media_si"
7357   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7358         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7359                            (const_int 16))
7360                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7361   "TARGET_SHMEDIA"
7362   "shori        %u2, %0")
7363
7364 (define_expand "movdi"
7365   [(set (match_operand:DI 0 "general_movdst_operand" "")
7366         (match_operand:DI 1 "general_movsrc_operand" ""))]
7367   ""
7368 {
7369   prepare_move_operands (operands, DImode);
7370 })
7371
7372 (define_insn "movdf_media"
7373   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7374         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7375   "TARGET_SHMEDIA_FPU
7376    && (register_operand (operands[0], DFmode)
7377        || sh_register_operand (operands[1], DFmode))"
7378   "@
7379         fmov.d  %1, %0
7380         fmov.qd %N1, %0
7381         fmov.dq %1, %0
7382         add     %1, r63, %0
7383         #
7384         fld%M1.d        %m1, %0
7385         fst%M0.d        %m0, %1
7386         ld%M1.q %m1, %0
7387         st%M0.q %m0, %N1"
7388   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7389                      fload_media,fstore_media,load_media,store_media")])
7390
7391 (define_insn "movdf_media_nofpu"
7392   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7393         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7394   "TARGET_SHMEDIA
7395    && (register_operand (operands[0], DFmode)
7396        || sh_register_operand (operands[1], DFmode))"
7397   "@
7398         add     %1, r63, %0
7399         #
7400         ld%M1.q %m1, %0
7401         st%M0.q %m0, %N1"
7402   [(set_attr "type" "arith_media,*,load_media,store_media")])
7403
7404 (define_split
7405   [(set (match_operand:DF 0 "arith_reg_dest" "")
7406         (match_operand:DF 1 "immediate_operand" ""))]
7407   "TARGET_SHMEDIA && reload_completed"
7408   [(set (match_dup 3) (match_dup 2))]
7409 {
7410   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7411   long values[2];
7412   REAL_VALUE_TYPE value;
7413
7414   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7415   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7416
7417   if (HOST_BITS_PER_WIDE_INT >= 64)
7418     operands[2] = immed_double_const ((unsigned long) values[endian]
7419                                       | ((HOST_WIDE_INT) values[1 - endian]
7420                                          << 32), 0, DImode);
7421   else
7422     {
7423       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7424       operands[2] = immed_double_const (values[endian], values[1 - endian],
7425                                         DImode);
7426     }
7427
7428   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7429 })
7430
7431 ;; FIXME: This should be a define_insn_and_split.
7432 (define_insn "movdf_k"
7433   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7434         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7435   "TARGET_SH1
7436    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7437        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7438        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7439        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7440    && (arith_reg_operand (operands[0], DFmode)
7441        || arith_reg_operand (operands[1], DFmode))"
7442 {
7443   return output_movedouble (insn, operands, DFmode);
7444 }
7445   [(set_attr "length" "4")
7446    (set_attr "type" "move,pcload,load,store")])
7447
7448 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7449 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7450 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7451 ;; the d/m/c/X alternative, which is split later into single-precision
7452 ;; instructions.  And when not optimizing, no splits are done before fixing
7453 ;; up pcloads, so we need usable length information for that.
7454 (define_insn "movdf_i4"
7455   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7456         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
7457    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
7458    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
7459   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7460    && (arith_reg_operand (operands[0], DFmode)
7461        || arith_reg_operand (operands[1], DFmode))"
7462   {
7463     switch (which_alternative)
7464     {
7465     case 0:
7466       if (TARGET_FMOVD)
7467         return "fmov    %1,%0";
7468       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7469         return         "fmov    %R1,%R0"        "\n"
7470                "        fmov    %S1,%S0";
7471       else
7472         return         "fmov    %S1,%S0"        "\n"
7473                "        fmov    %R1,%R0";
7474     case 3:
7475     case 4:
7476       return "fmov.d    %1,%0";
7477     default:
7478       return "#";
7479     }
7480   }
7481   [(set_attr_alternative "length"
7482      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7483       (const_int 4)
7484       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7485       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7486       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7487       (const_int 4)
7488       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7489       ;; We can't use 4-byte push/pop on SHcompact, so we have to
7490       ;; increment or decrement r15 explicitly.
7491       (if_then_else
7492        (match_test "TARGET_SHCOMPACT")
7493        (const_int 10) (const_int 8))
7494       (if_then_else
7495        (match_test "TARGET_SHCOMPACT")
7496        (const_int 10) (const_int 8))])
7497    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7498    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7499    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7500                                            (const_string "double")
7501                                            (const_string "none")))])
7502
7503 ;; Moving DFmode between fp/general registers through memory
7504 ;; (the top of the stack) is faster than moving through fpul even for
7505 ;; little endian.  Because the type of an instruction is important for its
7506 ;; scheduling,  it is beneficial to split these operations, rather than
7507 ;; emitting them in one single chunk, even if this will expose a stack
7508 ;; use that will prevent scheduling of other stack accesses beyond this
7509 ;; instruction.
7510 (define_split
7511   [(set (match_operand:DF 0 "register_operand" "")
7512         (match_operand:DF 1 "register_operand" ""))
7513    (use (match_operand:PSI 2 "fpscr_operand" ""))
7514    (clobber (match_scratch:SI 3 "=X"))]
7515   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7516    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7517   [(const_int 0)]
7518 {
7519   rtx insn, tos;
7520
7521   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7522     {
7523       emit_move_insn (stack_pointer_rtx,
7524                       plus_constant (Pmode, stack_pointer_rtx, -8));
7525       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7526     }
7527   else
7528     tos = gen_tmp_stack_mem (DFmode,
7529                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7530   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
7531   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7532     add_reg_note (insn, REG_INC, stack_pointer_rtx);
7533   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7534     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7535   else
7536     tos = gen_tmp_stack_mem (DFmode,
7537                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7538   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
7539   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7540     emit_move_insn (stack_pointer_rtx,
7541                     plus_constant (Pmode, stack_pointer_rtx, 8));
7542   else
7543     add_reg_note (insn, REG_INC, stack_pointer_rtx);
7544   DONE;
7545 })
7546
7547 ;; local-alloc sometimes allocates scratch registers even when not required,
7548 ;; so we must be prepared to handle these.
7549
7550 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7551 (define_split
7552   [(set (match_operand:DF 0 "general_movdst_operand" "")
7553         (match_operand:DF 1 "general_movsrc_operand"  ""))
7554    (use (match_operand:PSI 2 "fpscr_operand" ""))
7555    (clobber (match_scratch:SI 3 ""))]
7556   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7557    && reload_completed
7558    && true_regnum (operands[0]) < 16
7559    && true_regnum (operands[1]) < 16"
7560   [(set (match_dup 0) (match_dup 1))]
7561 {
7562   /* If this was a reg <-> mem operation with base + index reg addressing,
7563      we have to handle this in a special way.  */
7564   rtx mem = operands[0];
7565   int store_p = 1;
7566   if (! memory_operand (mem, DFmode))
7567     {
7568       mem = operands[1];
7569       store_p = 0;
7570     }
7571   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7572     mem = SUBREG_REG (mem);
7573   if (MEM_P (mem))
7574     {
7575       rtx addr = XEXP (mem, 0);
7576       if (GET_CODE (addr) == PLUS
7577           && REG_P (XEXP (addr, 0))
7578           && REG_P (XEXP (addr, 1)))
7579         {
7580           int offset;
7581           rtx reg0 = gen_rtx_REG (Pmode, 0);
7582           rtx regop = operands[store_p], word0 ,word1;
7583
7584           if (GET_CODE (regop) == SUBREG)
7585             alter_subreg (&regop, true);
7586           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7587             offset = 2;
7588           else
7589             offset = 4;
7590           mem = copy_rtx (mem);
7591           PUT_MODE (mem, SImode);
7592           word0 = gen_rtx_SUBREG (SImode, regop, 0);
7593           alter_subreg (&word0, true);
7594           word1 = gen_rtx_SUBREG (SImode, regop, 4);
7595           alter_subreg (&word1, true);
7596           if (store_p || ! refers_to_regno_p (REGNO (word0),
7597                                               REGNO (word0) + 1, addr, 0))
7598             {
7599               emit_insn (store_p
7600                          ? gen_movsi_ie (mem, word0)
7601                          : gen_movsi_ie (word0, mem));
7602               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7603               mem = copy_rtx (mem);
7604               emit_insn (store_p
7605                          ? gen_movsi_ie (mem, word1)
7606                          : gen_movsi_ie (word1, mem));
7607               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7608             }
7609           else
7610             {
7611               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7612               emit_insn (gen_movsi_ie (word1, mem));
7613               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7614               mem = copy_rtx (mem);
7615               emit_insn (gen_movsi_ie (word0, mem));
7616             }
7617           DONE;
7618         }
7619     }
7620 })
7621
7622 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7623 (define_split
7624   [(set (match_operand:DF 0 "register_operand" "")
7625         (match_operand:DF 1 "memory_operand"  ""))
7626    (use (match_operand:PSI 2 "fpscr_operand" ""))
7627    (clobber (reg:SI R0_REG))]
7628   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7629   [(parallel [(set (match_dup 0) (match_dup 1))
7630               (use (match_dup 2))
7631               (clobber (scratch:SI))])]
7632   "")
7633
7634 (define_expand "reload_indf__frn"
7635   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7636                    (match_operand:DF 1 "immediate_operand" "FQ"))
7637               (use (reg:PSI FPSCR_REG))
7638               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7639   "TARGET_SH1"
7640   "")
7641
7642 (define_expand "reload_outdf__RnFRm"
7643   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7644                    (match_operand:DF 1 "register_operand" "af,r"))
7645               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7646   "TARGET_SH1"
7647   "")
7648
7649 ;; Simplify no-op moves.
7650 (define_split
7651   [(set (match_operand:SF 0 "register_operand" "")
7652         (match_operand:SF 1 "register_operand" ""))
7653    (use (match_operand:PSI 2 "fpscr_operand" ""))
7654    (clobber (match_scratch:SI 3 ""))]
7655   "TARGET_SH2E && reload_completed
7656    && true_regnum (operands[0]) == true_regnum (operands[1])"
7657   [(set (match_dup 0) (match_dup 0))]
7658   "")
7659
7660 ;; fmovd substitute post-reload splits
7661 (define_split
7662   [(set (match_operand:DF 0 "register_operand" "")
7663         (match_operand:DF 1 "register_operand" ""))
7664    (use (match_operand:PSI 2 "fpscr_operand" ""))
7665    (clobber (match_scratch:SI 3 ""))]
7666   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7667    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7668    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7669   [(const_int 0)]
7670 {
7671   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7672   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7673                            gen_rtx_REG (SFmode, src), operands[2]));
7674   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7675                            gen_rtx_REG (SFmode, src + 1), operands[2]));
7676   DONE;
7677 })
7678
7679 (define_split
7680   [(set (match_operand:DF 0 "register_operand" "")
7681         (mem:DF (match_operand:SI 1 "register_operand" "")))
7682    (use (match_operand:PSI 2 "fpscr_operand" ""))
7683    (clobber (match_scratch:SI 3 ""))]
7684   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7685    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7686    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7687   [(const_int 0)]
7688 {
7689   int regno = true_regnum (operands[0]);
7690   rtx insn;
7691   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7692   rtx mem2
7693     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7694   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7695                                            regno + !! TARGET_LITTLE_ENDIAN),
7696                                   mem2, operands[2]));
7697   add_reg_note (insn, REG_INC, operands[1]);
7698   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7699                                                regno + ! TARGET_LITTLE_ENDIAN),
7700                                   change_address (mem, SFmode, NULL_RTX),
7701                                   operands[2]));
7702   DONE;
7703 })
7704
7705 (define_split
7706   [(set (match_operand:DF 0 "register_operand" "")
7707         (match_operand:DF 1 "memory_operand" ""))
7708    (use (match_operand:PSI 2 "fpscr_operand" ""))
7709    (clobber (match_scratch:SI 3 ""))]
7710   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7711    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7712   [(const_int 0)]
7713 {
7714   int regno = true_regnum (operands[0]);
7715   rtx addr, insn;
7716   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7717   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7718   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7719
7720   operands[1] = copy_rtx (mem2);
7721   addr = XEXP (mem2, 0);
7722
7723   switch (GET_CODE (addr))
7724     {
7725     case REG:
7726       /* This is complicated.  If the register is an arithmetic register
7727          we can just fall through to the REG+DISP case below.  Otherwise
7728          we have to use a combination of POST_INC and REG addressing...  */
7729       if (! arith_reg_operand (operands[1], SFmode))
7730         {
7731           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7732           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
7733           add_reg_note (insn, REG_INC, XEXP (addr, 0));
7734           
7735           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7736
7737           /* If we have modified the stack pointer, the value that we have
7738              read with post-increment might be modified by an interrupt,
7739              so write it back.  */
7740           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7741             emit_insn (gen_push_e (reg0));
7742           else
7743             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
7744                                    GEN_INT (-4)));
7745           break;
7746         }
7747       /* Fall through.  */
7748
7749     case PLUS:
7750       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7751       operands[1] = copy_rtx (operands[1]);
7752       XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7753       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7754       break;
7755
7756     case POST_INC:
7757       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7758       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7759
7760       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7761       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7762       break;
7763
7764     default:
7765       debug_rtx (addr);
7766       gcc_unreachable ();
7767     }
7768
7769   DONE;
7770 })
7771
7772 (define_split
7773   [(set (match_operand:DF 0 "memory_operand" "")
7774         (match_operand:DF 1 "register_operand" ""))
7775    (use (match_operand:PSI 2 "fpscr_operand" ""))
7776    (clobber (match_scratch:SI 3 ""))]
7777   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7778    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7779   [(const_int 0)]
7780 {
7781   int regno = true_regnum (operands[1]);
7782   rtx insn, addr;
7783   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7784   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7785
7786   operands[0] = copy_rtx (operands[0]);
7787   PUT_MODE (operands[0], SFmode);
7788   addr = XEXP (operands[0], 0);
7789
7790   switch (GET_CODE (addr))
7791     {
7792     case REG:
7793       /* This is complicated.  If the register is an arithmetic register
7794          we can just fall through to the REG+DISP case below.  Otherwise
7795          we have to use a combination of REG and PRE_DEC addressing...  */
7796       if (! arith_reg_operand (operands[0], SFmode))
7797         {
7798           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7799           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7800
7801           operands[0] = copy_rtx (operands[0]);
7802           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7803           
7804           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7805           add_reg_note (insn, REG_INC, XEXP (addr, 0));
7806           break;
7807         }
7808       /* Fall through.  */
7809
7810     case PLUS:
7811       /* Since REG+DISP addressing has already been decided upon by gcc
7812          we can rely upon it having chosen an arithmetic register as the
7813          register component of the address.  Just emit the lower numbered
7814          register first, to the lower address, then the higher numbered
7815          register to the higher address.  */
7816       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7817
7818       operands[0] = copy_rtx (operands[0]);
7819       XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
7820
7821       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7822       break;
7823
7824     case PRE_DEC:
7825       /* This is easy.  Output the word to go to the higher address
7826          first (ie the word in the higher numbered register) then the
7827          word to go to the lower address.  */
7828
7829       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7830       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7831
7832       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7833       add_reg_note (insn, REG_INC, XEXP (addr, 0));
7834       break;
7835
7836     default:
7837       /* FAIL; */
7838       debug_rtx (addr);
7839       gcc_unreachable ();
7840     }
7841
7842   DONE;
7843 })
7844
7845 ;; If the output is a register and the input is memory or a register, we have
7846 ;; to be careful and see which word needs to be loaded first.
7847 (define_split
7848   [(set (match_operand:DF 0 "general_movdst_operand" "")
7849         (match_operand:DF 1 "general_movsrc_operand" ""))]
7850   "TARGET_SH1 && reload_completed"
7851   [(set (match_dup 2) (match_dup 3))
7852    (set (match_dup 4) (match_dup 5))]
7853 {
7854   int regno;
7855
7856   if ((MEM_P (operands[0])
7857        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7858       || (MEM_P (operands[1])
7859           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7860     FAIL;
7861
7862   switch (GET_CODE (operands[0]))
7863     {
7864     case REG:
7865       regno = REGNO (operands[0]);
7866       break;
7867     case SUBREG:
7868       regno = subreg_regno (operands[0]);
7869       break;
7870     case MEM:
7871       regno = -1;
7872       break;
7873     default:
7874       gcc_unreachable ();
7875     }
7876
7877   if (regno == -1
7878       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7879     {
7880       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
7881       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
7882       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
7883       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
7884     }
7885   else
7886     {
7887       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
7888       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
7889       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
7890       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
7891     }
7892
7893   if (operands[2] == 0 || operands[3] == 0
7894       || operands[4] == 0 || operands[5] == 0)
7895     FAIL;
7896 })
7897
7898 (define_expand "movdf"
7899   [(set (match_operand:DF 0 "general_movdst_operand" "")
7900         (match_operand:DF 1 "general_movsrc_operand" ""))]
7901   ""
7902 {
7903   prepare_move_operands (operands, DFmode);
7904   if (TARGET_SHMEDIA)
7905     {
7906       if (TARGET_SHMEDIA_FPU)
7907         emit_insn (gen_movdf_media (operands[0], operands[1]));
7908       else
7909         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
7910       DONE;
7911     }
7912   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
7913     {
7914       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7915       DONE;
7916     }
7917 })
7918
7919 ;;This is incompatible with the way gcc uses subregs.
7920 ;;(define_insn "movv2sf_i"
7921 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
7922 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
7923 ;;  "TARGET_SHMEDIA_FPU
7924 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
7925 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
7926 ;;  "@
7927 ;;      #
7928 ;;      fld%M1.p        %m1, %0
7929 ;;      fst%M0.p        %m0, %1"
7930 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
7931 (define_insn_and_split "movv2sf_i"
7932   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7933         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7934   "TARGET_SHMEDIA_FPU"
7935   "#"
7936   "TARGET_SHMEDIA_FPU && reload_completed"
7937   [(set (match_dup 0) (match_dup 1))]
7938 {
7939   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
7940   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
7941 })
7942
7943 (define_expand "movv2sf"
7944   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
7945         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
7946   "TARGET_SHMEDIA_FPU"
7947 {
7948   prepare_move_operands (operands, V2SFmode);
7949 })
7950
7951 (define_expand "addv2sf3"
7952   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7953    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7954    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7955   "TARGET_SHMEDIA_FPU"
7956 {
7957   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
7958   DONE;
7959 })
7960
7961 (define_expand "subv2sf3"
7962   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7963    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7964    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7965   "TARGET_SHMEDIA_FPU"
7966 {
7967   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
7968   DONE;
7969 })
7970
7971 (define_expand "mulv2sf3"
7972   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7973    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7974    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7975   "TARGET_SHMEDIA_FPU"
7976 {
7977   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
7978   DONE;
7979 })
7980
7981 (define_expand "divv2sf3"
7982   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7983    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7984    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7985   "TARGET_SHMEDIA_FPU"
7986 {
7987   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
7988   DONE;
7989 })
7990
7991 (define_insn_and_split "*movv4sf_i"
7992   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7993         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7994   "TARGET_SHMEDIA_FPU"
7995   "#"
7996   "&& reload_completed"
7997   [(const_int 0)]
7998 {
7999   for (int i = 0; i < 4/2; i++)
8000     {
8001       rtx x, y;
8002
8003       if (MEM_P (operands[0]))
8004         x = adjust_address (operands[0], V2SFmode,
8005                             i * GET_MODE_SIZE (V2SFmode));
8006       else
8007         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8008
8009       if (MEM_P (operands[1]))
8010         y = adjust_address (operands[1], V2SFmode,
8011                             i * GET_MODE_SIZE (V2SFmode));
8012       else
8013         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8014
8015       emit_insn (gen_movv2sf_i (x, y));
8016     }
8017
8018   DONE;
8019 }
8020   [(set_attr "length" "8")])
8021
8022 (define_expand "movv4sf"
8023   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8024         (match_operand:V4SF 1 "general_operand" ""))]
8025   "TARGET_SHMEDIA_FPU"
8026 {
8027   prepare_move_operands (operands, V4SFmode);
8028 })
8029
8030 (define_insn_and_split "*movv16sf_i"
8031   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8032         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8033   "TARGET_SHMEDIA_FPU"
8034   "#"
8035   "&& reload_completed"
8036   [(const_int 0)]
8037 {
8038   for (int i = 0; i < 16/2; i++)
8039     {
8040       rtx x, y;
8041
8042       if (MEM_P (operands[0]))
8043         x = adjust_address (operands[0], V2SFmode,
8044                             i * GET_MODE_SIZE (V2SFmode));
8045       else
8046         {
8047           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8048           alter_subreg (&x, true);
8049         }
8050
8051       if (MEM_P (operands[1]))
8052         y = adjust_address (operands[1], V2SFmode,
8053                             i * GET_MODE_SIZE (V2SFmode));
8054       else
8055         {
8056           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8057           alter_subreg (&y, true);
8058         }
8059
8060       emit_insn (gen_movv2sf_i (x, y));
8061     }
8062
8063   DONE;
8064 }
8065   [(set_attr "length" "32")])
8066
8067 (define_expand "movv16sf"
8068   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8069         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8070   "TARGET_SHMEDIA_FPU"
8071 {
8072   prepare_move_operands (operands, V16SFmode);
8073 })
8074
8075 (define_insn "movsf_media"
8076   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8077         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8078   "TARGET_SHMEDIA_FPU
8079    && (register_operand (operands[0], SFmode)
8080        || sh_register_operand (operands[1], SFmode))"
8081   "@
8082         fmov.s  %1, %0
8083         fmov.ls %N1, %0
8084         fmov.sl %1, %0
8085         add.l   %1, r63, %0
8086         #
8087         fld%M1.s        %m1, %0
8088         fst%M0.s        %m0, %1
8089         ld%M1.l %m1, %0
8090         st%M0.l %m0, %N1"
8091   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8092    (set (attr "highpart")
8093         (cond [(match_test "sh_contains_memref_p (insn)")
8094                (const_string "user")]
8095               (const_string "ignore")))])
8096
8097 (define_insn "movsf_media_nofpu"
8098   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8099         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8100   "TARGET_SHMEDIA
8101    && (register_operand (operands[0], SFmode)
8102        || sh_register_operand (operands[1], SFmode))"
8103   "@
8104         add.l   %1, r63, %0
8105         #
8106         ld%M1.l %m1, %0
8107         st%M0.l %m0, %N1"
8108   [(set_attr "type" "arith_media,*,load_media,store_media")
8109    (set (attr "highpart")
8110         (cond [(match_test "sh_contains_memref_p (insn)")
8111                (const_string "user")]
8112               (const_string "ignore")))])
8113
8114 (define_split
8115   [(set (match_operand:SF 0 "arith_reg_dest" "")
8116         (match_operand:SF 1 "immediate_operand" ""))]
8117   "TARGET_SHMEDIA && reload_completed
8118    && ! FP_REGISTER_P (true_regnum (operands[0]))"
8119   [(set (match_dup 3) (match_dup 2))]
8120 {
8121   long values;
8122   REAL_VALUE_TYPE value;
8123
8124   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8125   REAL_VALUE_TO_TARGET_SINGLE (value, values);
8126   operands[2] = GEN_INT (values);
8127
8128   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8129 })
8130
8131 (define_insn "movsf_i"
8132   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8133         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
8134   "TARGET_SH1
8135    && (! TARGET_SH2E
8136        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8137        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8138        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8139    && (arith_reg_operand (operands[0], SFmode)
8140        || arith_reg_operand (operands[1], SFmode))"
8141   "@
8142         mov     %1,%0
8143         mov     #0,%0
8144         mov.l   %1,%0
8145         mov.l   %1,%0
8146         mov.l   %1,%0
8147         lds     %1,%0
8148         sts     %1,%0"
8149   [(set_attr "type" "move,move,pcload,load,store,move,move")])
8150
8151 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8152 ;; update_flow_info would not know where to put REG_EQUAL notes
8153 ;; when the destination changes mode.
8154 (define_insn "movsf_ie"
8155   [(set (match_operand:SF 0 "general_movdst_operand"
8156          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8157         (match_operand:SF 1 "general_movsrc_operand"
8158           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8159    (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"))
8160    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8161   "TARGET_SH2E
8162    && (arith_reg_operand (operands[0], SFmode)
8163        || arith_reg_operand (operands[1], SFmode)
8164        || arith_reg_operand (operands[3], SImode)
8165        || (fpul_operand (operands[0], SFmode)
8166            && memory_operand (operands[1], SFmode)
8167            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
8168        || (fpul_operand (operands[1], SFmode)
8169            && memory_operand (operands[0], SFmode)
8170            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
8171   "@
8172         fmov    %1,%0
8173         mov     %1,%0
8174         fldi0   %0
8175         fldi1   %0
8176         #
8177         fmov.s  %1,%0
8178         fmov.s  %1,%0
8179         mov.l   %1,%0
8180         mov.l   %1,%0
8181         mov.l   %1,%0
8182         fsts    fpul,%0
8183         flds    %1,fpul
8184         lds.l   %1,%0
8185         #
8186         sts     %1,%0
8187         lds     %1,%0
8188         sts.l   %1,%0
8189         lds.l   %1,%0
8190         ! move optimized away"
8191   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8192                      store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8193    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8194    (set_attr_alternative "length"
8195      [(const_int 2)
8196       (const_int 2)
8197       (const_int 2)
8198       (const_int 2)
8199       (const_int 4)
8200       (if_then_else
8201         (match_test "TARGET_SH2A")
8202         (const_int 4) (const_int 2))
8203       (if_then_else
8204         (match_test "TARGET_SH2A")
8205         (const_int 4) (const_int 2))
8206       (const_int 2)
8207       (if_then_else
8208         (match_test "TARGET_SH2A")
8209         (const_int 4) (const_int 2))
8210       (if_then_else
8211         (match_test "TARGET_SH2A")
8212         (const_int 4) (const_int 2))
8213       (const_int 2)
8214       (const_int 2)
8215       (const_int 2)
8216       (const_int 4)
8217       (const_int 2)
8218       (const_int 2)
8219       (const_int 2)
8220       (const_int 2)
8221       (const_int 0)])
8222    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8223                                            (const_string "single")
8224                                            (const_string "single")))])
8225
8226 (define_split
8227   [(set (match_operand:SF 0 "register_operand" "")
8228         (match_operand:SF 1 "register_operand" ""))
8229    (use (match_operand:PSI 2 "fpscr_operand" ""))
8230    (clobber (reg:SI FPUL_REG))]
8231   "TARGET_SH1"
8232   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8233               (use (match_dup 2))
8234               (clobber (scratch:SI))])
8235    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8236               (use (match_dup 2))
8237               (clobber (scratch:SI))])]
8238   "")
8239
8240 (define_expand "movsf"
8241   [(set (match_operand:SF 0 "general_movdst_operand" "")
8242         (match_operand:SF 1 "general_movsrc_operand" ""))]
8243   ""
8244 {
8245   prepare_move_operands (operands, SFmode);
8246   if (TARGET_SHMEDIA)
8247     {
8248       if (TARGET_SHMEDIA_FPU)
8249         emit_insn (gen_movsf_media (operands[0], operands[1]));
8250       else
8251         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8252       DONE;
8253     }
8254   if (TARGET_SH2E)
8255     {
8256       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
8257       DONE;
8258     }
8259 })
8260
8261 (define_insn "mov_nop"
8262   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8263   "TARGET_SH2E"
8264   ""
8265   [(set_attr "length" "0")
8266    (set_attr "type" "nil")])
8267
8268 (define_expand "reload_insf__frn"
8269   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8270                    (match_operand:SF 1 "immediate_operand" "FQ"))
8271               (use (reg:PSI FPSCR_REG))
8272               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8273   "TARGET_SH1"
8274   "")
8275
8276 (define_expand "reload_insi__i_fpul"
8277   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8278                    (match_operand:SI 1 "immediate_operand" "i"))
8279               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8280   "TARGET_SH1"
8281   "")
8282
8283 (define_expand "ptabs"
8284   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8285   "TARGET_SHMEDIA"
8286 {
8287   if (!TARGET_PT_FIXED)
8288     {
8289       rtx eq = operands[1];
8290
8291       /* ??? For canonical RTL we really should remove any CONST from EQ
8292          before wrapping it in the AND, and finally wrap the EQ into a
8293          const if is constant.  However, for reload we must expose the
8294          input register or symbolic constant, and we can't have
8295          different insn structures outside of the operands for different
8296          alternatives of the same pattern.  */
8297       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8298                        GEN_INT (3));
8299       operands[1]
8300         = (gen_rtx_IF_THEN_ELSE
8301             (PDImode,
8302              eq,
8303              gen_rtx_MEM (PDImode, operands[1]),
8304              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8305                             PDImode, operands[1])));
8306     }
8307 })
8308
8309 ;; expanded by ptabs expander.
8310 (define_insn "*extendsipdi_media"
8311   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8312         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8313                                                           "r,Csy")
8314                                       (const_int 3))
8315                               (const_int 3))
8316                           (mem:PDI (match_dup 1))
8317                           (sign_extend:PDI (match_dup 1))))]
8318   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8319   "@
8320         ptabs   %1, %0
8321         pt      %1, %0"
8322   [(set_attr "type"   "ptabs_media,pt_media")
8323    (set_attr "length" "4,*")])
8324
8325 (define_insn "*truncdipdi_media"
8326   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8327         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8328                                                           "r,Csy")
8329                                       (const_int 3))
8330                               (const_int 3))
8331                           (mem:PDI (match_dup 1))
8332                           (truncate:PDI (match_dup 1))))]
8333   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8334   "@
8335         ptabs   %1, %0
8336         pt      %1, %0"
8337   [(set_attr "type"   "ptabs_media,pt_media")
8338    (set_attr "length" "4,*")])
8339
8340 (define_insn "*movsi_y"
8341   [(set (match_operand:SI 0 "register_operand" "=y,y")
8342         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8343    (clobber (match_scratch:SI 2 "=&z,r"))]
8344   "TARGET_SH2E
8345    && (reload_in_progress || reload_completed)"
8346   "#"
8347   [(set_attr "length" "4")
8348    (set_attr "type" "pcload,move")])
8349
8350 (define_split
8351   [(set (match_operand:SI 0 "register_operand" "")
8352         (match_operand:SI 1 "immediate_operand" ""))
8353    (clobber (match_operand:SI 2 "register_operand" ""))]
8354   "TARGET_SH1"
8355   [(set (match_dup 2) (match_dup 1))
8356    (set (match_dup 0) (match_dup 2))]
8357   "")
8358 \f
8359 ;; ------------------------------------------------------------------------
8360 ;; Define the real conditional branch instructions.
8361 ;; ------------------------------------------------------------------------
8362
8363 (define_expand "branch_true"
8364   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8365                            (label_ref (match_operand 0))
8366                            (pc)))]
8367   "TARGET_SH1")
8368
8369 (define_expand "branch_false"
8370   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8371                            (label_ref (match_operand 0))
8372                            (pc)))]
8373   "TARGET_SH1")
8374
8375 (define_insn_and_split "*cbranch_t"
8376   [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8377                            (label_ref (match_operand 0))
8378                            (pc)))]
8379   "TARGET_SH1"
8380 {
8381   return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8382 }
8383   "&& 1"
8384   [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
8385                            (label_ref (match_dup 0))
8386                            (pc)))]
8387 {
8388   /* Try to find missed test and branch combine opportunities which result
8389      in redundant T bit tests before conditional branches.
8390      This is done not only after combine (and before reload) but in every
8391      split pass, because some opportunities are formed also after combine.
8392      FIXME: Probably this would not be needed if CCmode was used
8393      together with TARGET_FIXED_CONDITION_CODE_REGS.  */
8394
8395   const int treg_value = sh_eval_treg_value (operands[1]);
8396   operands[2] = NULL_RTX;
8397
8398   /* Scan the insns backwards for an insn that sets the T bit by testing a
8399      reg against zero like:
8400         (set (reg T_REG) (eq (reg) (const_int 0)))  */
8401   rtx testing_insn = NULL_RTX;
8402   rtx tested_reg = NULL_RTX;
8403
8404   set_of_reg s0 = sh_find_set_of_reg (get_t_reg_rtx (), curr_insn,
8405                                       prev_nonnote_insn_bb);
8406   if (s0.set_src != NULL_RTX
8407       && GET_CODE (s0.set_src) == EQ
8408       && REG_P (XEXP (s0.set_src, 0))
8409       && satisfies_constraint_Z (XEXP (s0.set_src, 1)))
8410     {
8411       testing_insn = s0.insn;
8412       tested_reg = XEXP (s0.set_src, 0);
8413     }
8414   else
8415     FAIL;
8416
8417   /* Continue scanning the insns backwards and try to find the insn that
8418      sets the tested reg which we found above.  If the reg is set by storing
8419      the T bit or the negated T bit we can eliminate the test insn before
8420      the branch.  Notice that the branch condition has to be inverted if the
8421      test is eliminated.  */
8422
8423   /* If the T bit is used between the testing insn and the brach insn
8424      leave it alone.  */
8425   if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
8426     FAIL;
8427
8428   while (true)
8429     {
8430       /* It's not safe to go beyond the current basic block after reload.  */
8431       set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
8432                                           reload_completed
8433                                           ? prev_nonnote_insn_bb
8434                                           : prev_nonnote_insn);
8435       if (s1.set_src == NULL_RTX)
8436         break;
8437
8438       if (t_reg_operand (s1.set_src, VOIDmode))
8439         operands[2] = GEN_INT (treg_value ^ 1);
8440       else if (negt_reg_operand (s1.set_src, VOIDmode))
8441         operands[2] = GEN_INT (treg_value);
8442       else if (REG_P (s1.set_src))
8443         {
8444            /* If it's a reg-reg copy follow the copied reg.  This can
8445               happen e.g. when T bit store zero-extensions are
8446               eliminated.  */
8447           tested_reg = s1.set_src;
8448           s0.insn = s1.insn;
8449           continue;
8450         }
8451
8452         /* It's only safe to remove the testing insn if the T bit is not
8453            modified between the testing insn and the insn that stores the
8454            T bit.  Notice that some T bit stores such as negc also modify
8455            the T bit.  */
8456         if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
8457             || modified_in_p (get_t_reg_rtx (), s1.insn))
8458           operands[2] = NULL_RTX;
8459
8460         break;
8461     }
8462
8463   if (operands[2] == NULL_RTX)
8464     FAIL;
8465
8466   set_insn_deleted (testing_insn);
8467 }
8468   [(set_attr "type" "cbranch")])
8469
8470 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8471 ;; which destination is too far away.
8472 ;; The const_int_operand is distinct for each branch target; it avoids
8473 ;; unwanted matches with redundant_insn.
8474 (define_insn "block_branch_redirect"
8475   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8476   "TARGET_SH1"
8477   ""
8478   [(set_attr "length" "0")])
8479
8480 ;; This one has the additional purpose to record a possible scratch register
8481 ;; for the following branch.
8482 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8483 ;; because the insn then might be deemed dead and deleted.  And we can't
8484 ;; make the use in the jump insn explicit because that would disable
8485 ;; delay slot scheduling from the target.
8486 (define_insn "indirect_jump_scratch"
8487   [(set (match_operand:SI 0 "register_operand" "=r")
8488         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8489    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8490   "TARGET_SH1"
8491   ""
8492   [(set_attr "length" "0")])
8493
8494 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8495 ;; being pulled into the delay slot of a condbranch that has been made to
8496 ;; jump around the unconditional jump because it was out of range.
8497 (define_insn "stuff_delay_slot"
8498   [(set (pc)
8499         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8500                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8501   "TARGET_SH1"
8502   ""
8503   [(set_attr "length" "0")
8504    (set_attr "cond_delay_slot" "yes")])
8505 \f
8506 ;; Conditional branch insns
8507
8508 (define_expand "cbranchint4_media"
8509   [(set (pc)
8510         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8511                        [(match_operand 1 "" "")
8512                         (match_operand 2 "" "")])
8513                       (match_operand 3 "" "")
8514                       (pc)))]
8515   "TARGET_SHMEDIA"
8516 {
8517   enum machine_mode mode = GET_MODE (operands[1]);
8518   if (mode == VOIDmode)
8519     mode = GET_MODE (operands[2]);
8520   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8521     {
8522       operands[1] = force_reg (mode, operands[1]);
8523       if (CONSTANT_P (operands[2])
8524           && (! satisfies_constraint_I06 (operands[2])))
8525         operands[2] = force_reg (mode, operands[2]);
8526     }
8527   else
8528     {
8529       if (operands[1] != const0_rtx)
8530         operands[1] = force_reg (mode, operands[1]);
8531       if (operands[2] != const0_rtx)
8532         operands[2] = force_reg (mode, operands[2]);
8533     }
8534   switch (GET_CODE (operands[0]))
8535     {
8536     case LEU:
8537     case LE:
8538     case LTU:
8539     case LT:
8540       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8541                                     VOIDmode, operands[2], operands[1]);
8542       operands[1] = XEXP (operands[0], 0);
8543       operands[2] = XEXP (operands[0], 1);
8544       break;
8545     default:
8546       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8547                                     VOIDmode, operands[1], operands[2]);
8548       break;
8549     }
8550   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8551 })
8552
8553 (define_expand "cbranchfp4_media"
8554   [(set (pc)
8555         (if_then_else (match_operator 0 "sh_float_comparison_operator"
8556                        [(match_operand 1 "" "")
8557                         (match_operand 2 "" "")])
8558                       (match_operand 3 "" "")
8559                       (pc)))]
8560   "TARGET_SHMEDIA"
8561 {
8562   rtx tmp = gen_reg_rtx (SImode);
8563   rtx cmp;
8564   if (GET_CODE (operands[0]) == NE)
8565     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8566   else
8567     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8568                           operands[1], operands[2]);
8569
8570   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8571
8572   if (GET_CODE (cmp) == GET_CODE (operands[0]))
8573     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8574   else
8575     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8576   operands[1] = tmp;
8577   operands[2] = const0_rtx;
8578   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8579 })
8580
8581 (define_insn "*beq_media_i"
8582   [(set (pc)
8583         (if_then_else (match_operator 3 "equality_comparison_operator"
8584                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
8585                          (match_operand:DI 2 "arith_operand" "r,I06")])
8586                       (match_operand 0 "target_operand" "b,b")
8587                       (pc)))]
8588   "TARGET_SHMEDIA"
8589   "@
8590         b%o3%'  %1, %2, %0%>
8591         b%o3i%' %1, %2, %0%>"
8592   [(set_attr "type" "cbranch_media")])
8593
8594 (define_insn "*beq_media_i32"
8595   [(set (pc)
8596         (if_then_else (match_operator 3 "equality_comparison_operator"
8597                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
8598                          (match_operand:SI 2 "arith_operand" "r,I06")])
8599                       (match_operand 0 "target_operand" "b,b")
8600                       (pc)))]
8601   "TARGET_SHMEDIA"
8602   "@
8603         b%o3%'  %1, %2, %0%>
8604         b%o3i%' %1, %2, %0%>"
8605   [(set_attr "type" "cbranch_media")])
8606
8607 (define_insn "*bgt_media_i"
8608   [(set (pc)
8609         (if_then_else (match_operator 3 "greater_comparison_operator"
8610                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8611                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8612                       (match_operand 0 "target_operand" "b")
8613                       (pc)))]
8614   "TARGET_SHMEDIA"
8615   "b%o3%'       %N1, %N2, %0%>"
8616   [(set_attr "type" "cbranch_media")])
8617
8618 (define_insn "*bgt_media_i32"
8619   [(set (pc)
8620         (if_then_else (match_operator 3 "greater_comparison_operator"
8621                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8622                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8623                       (match_operand 0 "target_operand" "b")
8624                       (pc)))]
8625   "TARGET_SHMEDIA"
8626   "b%o3%'       %N1, %N2, %0%>"
8627   [(set_attr "type" "cbranch_media")])
8628
8629 ;; These are only needed to make invert_jump() happy - otherwise, jump
8630 ;; optimization will be silently disabled.
8631 (define_insn "*blt_media_i"
8632   [(set (pc)
8633         (if_then_else (match_operator 3 "less_comparison_operator"
8634                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8635                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8636                       (match_operand 0 "target_operand" "b")
8637                       (pc)))]
8638   "TARGET_SHMEDIA"
8639   "b%o3%'       %N2, %N1, %0%>"
8640   [(set_attr "type" "cbranch_media")])
8641
8642 (define_insn "*blt_media_i32"
8643   [(set (pc)
8644         (if_then_else (match_operator 3 "less_comparison_operator"
8645                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8646                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8647                       (match_operand 0 "target_operand" "b")
8648                       (pc)))]
8649   "TARGET_SHMEDIA"
8650   "b%o3%'       %N2, %N1, %0%>"
8651   [(set_attr "type" "cbranch_media")])
8652
8653 ;; combiner splitter for test-and-branch on single bit in register.  This
8654 ;; is endian dependent because the non-paradoxical subreg looks different
8655 ;; on big endian.
8656 (define_split
8657   [(set (pc)
8658         (if_then_else
8659           (match_operator 3 "equality_comparison_operator"
8660             [(subreg:SI
8661                (zero_extract:DI
8662                  (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
8663                  (const_int 1)
8664                  (match_operand 2 "const_int_operand" "")) 0)
8665              (const_int 0)])
8666           (match_operand 0 "target_operand" "")
8667           (pc)))
8668    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8669   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8670   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8671    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8672 {
8673   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8674   operands[6] = (GET_CODE (operands[3]) == EQ
8675                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8676                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8677 })
8678
8679 ; operand 0 is the loop count pseudo register
8680 ; operand 1 is the number of loop iterations or 0 if it is unknown
8681 ; operand 2 is the maximum number of loop iterations
8682 ; operand 3 is the number of levels of enclosed loops
8683 ; operand 4 is the label to jump to at the top of the loop
8684 (define_expand "doloop_end"
8685   [(parallel [(set (pc)
8686                    (if_then_else (ne:SI (match_operand:SI 0 "" "")
8687                                         (const_int 1))
8688                                  (label_ref (match_operand 4 "" ""))
8689                                  (pc)))
8690               (set (match_dup 0)
8691                    (plus:SI (match_dup 0) (const_int -1)))
8692               (clobber (reg:SI T_REG))])
8693    (match_operand 5 "" "")]
8694   "TARGET_SH2"
8695 {
8696   if (GET_MODE (operands[0]) != SImode)
8697     FAIL;
8698   emit_jump_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
8699   DONE;
8700 })
8701
8702 (define_insn_and_split "doloop_end_split"
8703   [(set (pc)
8704         (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8705                              (const_int 1))
8706                       (label_ref (match_operand 1 "" ""))
8707                       (pc)))
8708    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8709         (plus (match_dup 2) (const_int -1)))
8710    (clobber (reg:SI T_REG))]
8711   "TARGET_SH2"
8712   "#"
8713   ""
8714   [(parallel [(set (reg:SI T_REG)
8715                    (eq:SI (match_dup 2) (const_int 1)))
8716               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8717    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8718                            (label_ref (match_dup 1))
8719                            (pc)))]
8720   ""
8721   [(set_attr "type" "cbranch")])
8722 \f
8723 ;; ------------------------------------------------------------------------
8724 ;; Jump and linkage insns
8725 ;; ------------------------------------------------------------------------
8726
8727 (define_insn "jump_compact"
8728   [(set (pc)
8729         (label_ref (match_operand 0 "" "")))]
8730   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
8731 {
8732   /* The length is 16 if the delay slot is unfilled.  */
8733   if (get_attr_length(insn) > 4)
8734     return output_far_jump(insn, operands[0]);
8735   else
8736     return "bra %l0%#";
8737 }
8738   [(set_attr "type" "jump")
8739    (set_attr "needs_delay_slot" "yes")])
8740
8741 ;; ??? It would be much saner to explicitly use the scratch register
8742 ;; in the jump insn, and have indirect_jump_scratch only set it,
8743 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8744 ;; from the target then, as it uses simplejump_p.
8745 ;;(define_insn "jump_compact_far"
8746 ;;  [(set (pc)
8747 ;;      (label_ref (match_operand 0 "" "")))
8748 ;;   (use (match_operand 1 "register_operand" "r")]
8749 ;;  "TARGET_SH1"
8750 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
8751 ;;  [(set_attr "type" "jump")
8752 ;;   (set_attr "needs_delay_slot" "yes")])
8753
8754 (define_insn "jump_media"
8755   [(set (pc)
8756         (match_operand 0 "target_operand" "b"))]
8757   "TARGET_SHMEDIA"
8758   "blink        %0, r63%>"
8759   [(set_attr "type" "jump_media")])
8760
8761 (define_expand "jump"
8762   [(set (pc)
8763         (label_ref (match_operand 0 "" "")))]
8764   ""
8765 {
8766   if (TARGET_SH1)
8767     emit_jump_insn (gen_jump_compact (operands[0]));
8768   else if (TARGET_SHMEDIA)
8769     {
8770       if (reload_in_progress || reload_completed)
8771         FAIL;
8772       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
8773     }
8774   DONE;
8775 })
8776
8777 (define_insn "force_mode_for_call"
8778   [(use (reg:PSI FPSCR_REG))]
8779   "TARGET_SHCOMPACT"
8780   ""
8781   [(set_attr "length" "0")
8782    (set (attr "fp_mode")
8783         (if_then_else (eq_attr "fpu_single" "yes")
8784                       (const_string "single") (const_string "double")))])
8785
8786 (define_insn "calli"
8787   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8788          (match_operand 1 "" ""))
8789    (use (reg:PSI FPSCR_REG))
8790    (clobber (reg:SI PR_REG))]
8791   "TARGET_SH1"
8792 {
8793   if (TARGET_SH2A && (dbr_sequence_length () == 0))
8794     return "jsr/n       @%0";
8795   else
8796     return "jsr @%0%#";
8797 }
8798   [(set_attr "type" "call")
8799    (set (attr "fp_mode")
8800         (if_then_else (eq_attr "fpu_single" "yes")
8801                       (const_string "single") (const_string "double")))
8802    (set_attr "needs_delay_slot" "yes")
8803    (set_attr "fp_set" "unknown")])
8804
8805 ;; This is TBR relative jump instruction for SH2A architecture.
8806 ;; Its use is enabled by assigning an attribute "function_vector"
8807 ;; and the vector number to a function during its declaration.
8808 (define_insn "calli_tbr_rel"
8809   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8810          (match_operand 1 "" ""))
8811    (use (reg:PSI FPSCR_REG))
8812    (clobber (reg:SI PR_REG))]
8813   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8814 {
8815   unsigned HOST_WIDE_INT vect_num;
8816   vect_num = sh2a_get_function_vector_number (operands[0]);
8817   operands[2] = GEN_INT (vect_num * 4);
8818
8819   return "jsr/n @@(%O2,tbr)";
8820 }
8821   [(set_attr "type" "call")
8822    (set (attr "fp_mode")
8823         (if_then_else (eq_attr "fpu_single" "yes")
8824                       (const_string "single") (const_string "double")))
8825    (set_attr "needs_delay_slot" "no")
8826    (set_attr "fp_set" "unknown")])
8827
8828 ;; This is a pc-rel call, using bsrf, for use with PIC.
8829 (define_insn "calli_pcrel"
8830   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8831          (match_operand 1 "" ""))
8832    (use (reg:PSI FPSCR_REG))
8833    (use (reg:SI PIC_REG))
8834    (use (match_operand 2 "" ""))
8835    (clobber (reg:SI PR_REG))]
8836   "TARGET_SH2"
8837 {
8838   return       "bsrf    %0"     "\n"
8839          "%O2:%#";
8840 }
8841   [(set_attr "type" "call")
8842    (set (attr "fp_mode")
8843         (if_then_else (eq_attr "fpu_single" "yes")
8844                       (const_string "single") (const_string "double")))
8845    (set_attr "needs_delay_slot" "yes")
8846    (set_attr "fp_set" "unknown")])
8847
8848 (define_insn_and_split "call_pcrel"
8849   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8850          (match_operand 1 "" ""))
8851    (use (reg:PSI FPSCR_REG))
8852    (use (reg:SI PIC_REG))
8853    (clobber (reg:SI PR_REG))
8854    (clobber (match_scratch:SI 2 "=r"))]
8855   "TARGET_SH2"
8856   "#"
8857   "reload_completed"
8858   [(const_int 0)]
8859 {
8860   rtx lab = PATTERN (gen_call_site ());
8861
8862   if (SYMBOL_REF_LOCAL_P (operands[0]))
8863     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8864   else
8865     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
8866   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
8867   DONE;
8868 }
8869   [(set_attr "type" "call")
8870    (set (attr "fp_mode")
8871         (if_then_else (eq_attr "fpu_single" "yes")
8872                       (const_string "single") (const_string "double")))
8873    (set_attr "needs_delay_slot" "yes")
8874    (set_attr "fp_set" "unknown")])
8875
8876 (define_insn "call_compact"
8877   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8878          (match_operand 1 "" ""))
8879    (match_operand 2 "immediate_operand" "n")
8880    (use (reg:SI R0_REG))
8881    (use (reg:SI R1_REG))
8882    (use (reg:PSI FPSCR_REG))
8883    (clobber (reg:SI PR_REG))]
8884   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8885   "jsr  @%0%#"
8886   [(set_attr "type" "call")
8887    (set (attr "fp_mode")
8888         (if_then_else (eq_attr "fpu_single" "yes")
8889                       (const_string "single") (const_string "double")))
8890    (set_attr "needs_delay_slot" "yes")])
8891
8892 (define_insn "call_compact_rettramp"
8893   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8894          (match_operand 1 "" ""))
8895    (match_operand 2 "immediate_operand" "n")
8896    (use (reg:SI R0_REG))
8897    (use (reg:SI R1_REG))
8898    (use (reg:PSI FPSCR_REG))
8899    (clobber (reg:SI R10_REG))
8900    (clobber (reg:SI PR_REG))]
8901   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8902   "jsr  @%0%#"
8903   [(set_attr "type" "call")
8904    (set (attr "fp_mode")
8905         (if_then_else (eq_attr "fpu_single" "yes")
8906                       (const_string "single") (const_string "double")))
8907    (set_attr "needs_delay_slot" "yes")])
8908
8909 (define_insn "call_media"
8910   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
8911          (match_operand 1 "" ""))
8912    (clobber (reg:DI PR_MEDIA_REG))]
8913   "TARGET_SHMEDIA"
8914   "blink        %0, r18"
8915   [(set_attr "type" "jump_media")])
8916
8917 (define_insn "call_valuei"
8918   [(set (match_operand 0 "" "=rf")
8919         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8920               (match_operand 2 "" "")))
8921    (use (reg:PSI FPSCR_REG))
8922    (clobber (reg:SI PR_REG))]
8923   "TARGET_SH1"
8924 {
8925   if (TARGET_SH2A && (dbr_sequence_length () == 0))
8926     return "jsr/n       @%1";
8927   else
8928     return "jsr @%1%#";
8929 }
8930   [(set_attr "type" "call")
8931    (set (attr "fp_mode")
8932         (if_then_else (eq_attr "fpu_single" "yes")
8933                       (const_string "single") (const_string "double")))
8934    (set_attr "needs_delay_slot" "yes")
8935    (set_attr "fp_set" "unknown")])
8936
8937 ;; This is TBR relative jump instruction for SH2A architecture.
8938 ;; Its use is enabled by assigning an attribute "function_vector"
8939 ;; and the vector number to a function during its declaration.
8940 (define_insn "call_valuei_tbr_rel"
8941   [(set (match_operand 0 "" "=rf")
8942         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8943               (match_operand 2 "" "")))
8944    (use (reg:PSI FPSCR_REG))
8945    (clobber (reg:SI PR_REG))]
8946   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
8947 {
8948   unsigned HOST_WIDE_INT vect_num;
8949   vect_num = sh2a_get_function_vector_number (operands[1]);
8950   operands[3] = GEN_INT (vect_num * 4);
8951
8952   return "jsr/n @@(%O3,tbr)";
8953 }
8954   [(set_attr "type" "call")
8955    (set (attr "fp_mode")
8956         (if_then_else (eq_attr "fpu_single" "yes")
8957                       (const_string "single") (const_string "double")))
8958    (set_attr "needs_delay_slot" "no")
8959    (set_attr "fp_set" "unknown")])
8960
8961 (define_insn "call_valuei_pcrel"
8962   [(set (match_operand 0 "" "=rf")
8963         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8964               (match_operand 2 "" "")))
8965    (use (reg:PSI FPSCR_REG))
8966    (use (reg:SI PIC_REG))
8967    (use (match_operand 3 "" ""))
8968    (clobber (reg:SI PR_REG))]
8969   "TARGET_SH2"
8970 {
8971   return       "bsrf    %1"     "\n"
8972          "%O3:%#";
8973 }
8974   [(set_attr "type" "call")
8975    (set (attr "fp_mode")
8976         (if_then_else (eq_attr "fpu_single" "yes")
8977                       (const_string "single") (const_string "double")))
8978    (set_attr "needs_delay_slot" "yes")
8979    (set_attr "fp_set" "unknown")])
8980
8981 (define_insn_and_split "call_value_pcrel"
8982   [(set (match_operand 0 "" "=rf")
8983         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8984               (match_operand 2 "" "")))
8985    (use (reg:PSI FPSCR_REG))
8986    (use (reg:SI PIC_REG))
8987    (clobber (reg:SI PR_REG))
8988    (clobber (match_scratch:SI 3 "=r"))]
8989   "TARGET_SH2"
8990   "#"
8991   "reload_completed"
8992   [(const_int 0)]
8993 {
8994   rtx lab = PATTERN (gen_call_site ());
8995
8996   if (SYMBOL_REF_LOCAL_P (operands[1]))
8997     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8998   else
8999     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
9000   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
9001                                          operands[2], copy_rtx (lab)));
9002   DONE;
9003 }
9004   [(set_attr "type" "call")
9005    (set (attr "fp_mode")
9006         (if_then_else (eq_attr "fpu_single" "yes")
9007                       (const_string "single") (const_string "double")))
9008    (set_attr "needs_delay_slot" "yes")
9009    (set_attr "fp_set" "unknown")])
9010
9011 (define_insn "call_value_compact"
9012   [(set (match_operand 0 "" "=rf")
9013         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9014               (match_operand 2 "" "")))
9015    (match_operand 3 "immediate_operand" "n")
9016    (use (reg:SI R0_REG))
9017    (use (reg:SI R1_REG))
9018    (use (reg:PSI FPSCR_REG))
9019    (clobber (reg:SI PR_REG))]
9020   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9021   "jsr  @%1%#"
9022   [(set_attr "type" "call")
9023    (set (attr "fp_mode")
9024         (if_then_else (eq_attr "fpu_single" "yes")
9025                       (const_string "single") (const_string "double")))
9026    (set_attr "needs_delay_slot" "yes")])
9027
9028 (define_insn "call_value_compact_rettramp"
9029   [(set (match_operand 0 "" "=rf")
9030         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9031               (match_operand 2 "" "")))
9032    (match_operand 3 "immediate_operand" "n")
9033    (use (reg:SI R0_REG))
9034    (use (reg:SI R1_REG))
9035    (use (reg:PSI FPSCR_REG))
9036    (clobber (reg:SI R10_REG))
9037    (clobber (reg:SI PR_REG))]
9038   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9039   "jsr  @%1%#"
9040   [(set_attr "type" "call")
9041    (set (attr "fp_mode")
9042         (if_then_else (eq_attr "fpu_single" "yes")
9043                       (const_string "single") (const_string "double")))
9044    (set_attr "needs_delay_slot" "yes")])
9045
9046 (define_insn "call_value_media"
9047   [(set (match_operand 0 "" "=rf")
9048         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9049               (match_operand 2 "" "")))
9050    (clobber (reg:DI PR_MEDIA_REG))]
9051   "TARGET_SHMEDIA"
9052   "blink        %1, r18"
9053   [(set_attr "type" "jump_media")])
9054
9055 (define_expand "call"
9056   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9057                             (match_operand 1 "" ""))
9058               (match_operand 2 "" "")
9059               (use (reg:PSI FPSCR_REG))
9060               (clobber (reg:SI PR_REG))])]
9061   ""
9062 {
9063   if (TARGET_SHMEDIA)
9064     {
9065       operands[0] = shmedia_prepare_call_address (operands[0], 0);
9066       emit_call_insn (gen_call_media (operands[0], operands[1]));
9067       DONE;
9068     }
9069   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9070     {
9071       rtx cookie_rtx = operands[2];
9072       long cookie = INTVAL (cookie_rtx);
9073       rtx func = XEXP (operands[0], 0);
9074       rtx r0, r1;
9075
9076       if (flag_pic)
9077         {
9078           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9079             {
9080               rtx reg = gen_reg_rtx (Pmode);
9081
9082               emit_insn (gen_symGOTPLT2reg (reg, func));
9083               func = reg;
9084             }
9085           else
9086             func = legitimize_pic_address (func, Pmode, 0);
9087         }
9088
9089       r0 = gen_rtx_REG (SImode, R0_REG);
9090       r1 = gen_rtx_REG (SImode, R1_REG);
9091
9092       /* Since such a call function may use all call-clobbered
9093          registers, we force a mode switch earlier, so that we don't
9094          run out of registers when adjusting fpscr for the call.  */
9095       emit_insn (gen_force_mode_for_call ());
9096
9097       operands[0]
9098         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9099       operands[0] = force_reg (SImode, operands[0]);
9100
9101       emit_move_insn (r0, func);
9102       emit_move_insn (r1, cookie_rtx);
9103
9104       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9105         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9106                                                    operands[2]));
9107       else
9108         emit_call_insn (gen_call_compact (operands[0], operands[1],
9109                                           operands[2]));
9110
9111       DONE;
9112     }
9113   else if (TARGET_SHCOMPACT && flag_pic
9114            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9115            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9116     {
9117       rtx reg = gen_reg_rtx (Pmode);
9118
9119       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9120       XEXP (operands[0], 0) = reg;
9121     }
9122   if (!flag_pic && TARGET_SH2A
9123       && MEM_P (operands[0])
9124       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9125     {
9126       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9127         {
9128           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9129                                              operands[1]));
9130           DONE;
9131         }
9132     }
9133   if (flag_pic && TARGET_SH2
9134       && MEM_P (operands[0])
9135       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9136     {
9137       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9138       DONE;
9139     }
9140   else
9141   {
9142     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9143     operands[1] = operands[2];
9144   }
9145
9146   emit_call_insn (gen_calli (operands[0], operands[1]));
9147   DONE;
9148 })
9149
9150 (define_insn "call_pop_compact"
9151   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9152          (match_operand 1 "" ""))
9153    (match_operand 2 "immediate_operand" "n")
9154    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9155                                  (match_operand 3 "immediate_operand" "n")))
9156    (use (reg:SI R0_REG))
9157    (use (reg:SI R1_REG))
9158    (use (reg:PSI FPSCR_REG))
9159    (clobber (reg:SI PR_REG))]
9160   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9161   "jsr  @%0%#"
9162   [(set_attr "type" "call")
9163    (set (attr "fp_mode")
9164         (if_then_else (eq_attr "fpu_single" "yes")
9165                       (const_string "single") (const_string "double")))
9166    (set_attr "needs_delay_slot" "yes")])
9167
9168 (define_insn "call_pop_compact_rettramp"
9169   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9170          (match_operand 1 "" ""))
9171    (match_operand 2 "immediate_operand" "n")
9172    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9173                                  (match_operand 3 "immediate_operand" "n")))
9174    (use (reg:SI R0_REG))
9175    (use (reg:SI R1_REG))
9176    (use (reg:PSI FPSCR_REG))
9177    (clobber (reg:SI R10_REG))
9178    (clobber (reg:SI PR_REG))]
9179   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9180   "jsr  @%0%#"
9181   [(set_attr "type" "call")
9182    (set (attr "fp_mode")
9183         (if_then_else (eq_attr "fpu_single" "yes")
9184                       (const_string "single") (const_string "double")))
9185    (set_attr "needs_delay_slot" "yes")])
9186
9187 (define_expand "call_pop"
9188   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9189                     (match_operand 1 "" ""))
9190              (match_operand 2 "" "")
9191              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9192                                            (match_operand 3 "" "")))])]
9193   "TARGET_SHCOMPACT"
9194 {
9195   rtx cookie_rtx;
9196   long cookie;
9197   rtx func;
9198   rtx r0, r1;
9199
9200   gcc_assert (operands[2] && INTVAL (operands[2]));
9201   cookie_rtx = operands[2];
9202   cookie = INTVAL (cookie_rtx);
9203   func = XEXP (operands[0], 0);
9204
9205   if (flag_pic)
9206     {
9207       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9208         {
9209           rtx reg = gen_reg_rtx (Pmode);
9210           emit_insn (gen_symGOTPLT2reg (reg, func));
9211           func = reg;
9212         }
9213       else
9214         func = legitimize_pic_address (func, Pmode, 0);
9215     }
9216
9217   r0 = gen_rtx_REG (SImode, R0_REG);
9218   r1 = gen_rtx_REG (SImode, R1_REG);
9219
9220   /* Since such a call function may use all call-clobbered
9221      registers, we force a mode switch earlier, so that we don't
9222      run out of registers when adjusting fpscr for the call.  */
9223   emit_insn (gen_force_mode_for_call ());
9224
9225   operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9226                                  SFUNC_GOT);
9227   operands[0] = force_reg (SImode, operands[0]);
9228
9229   emit_move_insn (r0, func);
9230   emit_move_insn (r1, cookie_rtx);
9231
9232   if (cookie & CALL_COOKIE_RET_TRAMP (1))
9233     emit_call_insn (gen_call_pop_compact_rettramp
9234                      (operands[0], operands[1], operands[2], operands[3]));
9235   else
9236     emit_call_insn (gen_call_pop_compact
9237                      (operands[0], operands[1], operands[2], operands[3]));
9238
9239   DONE;
9240 })
9241
9242 (define_expand "call_value"
9243   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9244                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9245                                  (match_operand 2 "" "")))
9246               (match_operand 3 "" "")
9247               (use (reg:PSI FPSCR_REG))
9248               (clobber (reg:SI PR_REG))])]
9249   ""
9250 {
9251   if (TARGET_SHMEDIA)
9252     {
9253       operands[1] = shmedia_prepare_call_address (operands[1], 0);
9254       emit_call_insn (gen_call_value_media (operands[0], operands[1],
9255                                             operands[2]));
9256       DONE;
9257     }
9258   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9259     {
9260       rtx cookie_rtx = operands[3];
9261       long cookie = INTVAL (cookie_rtx);
9262       rtx func = XEXP (operands[1], 0);
9263       rtx r0, r1;
9264
9265       if (flag_pic)
9266         {
9267           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9268             {
9269               rtx reg = gen_reg_rtx (Pmode);
9270
9271               emit_insn (gen_symGOTPLT2reg (reg, func));
9272               func = reg;
9273             }
9274           else
9275             func = legitimize_pic_address (func, Pmode, 0);
9276         }
9277
9278       r0 = gen_rtx_REG (SImode, R0_REG);
9279       r1 = gen_rtx_REG (SImode, R1_REG);
9280
9281       /* Since such a call function may use all call-clobbered
9282          registers, we force a mode switch earlier, so that we don't
9283          run out of registers when adjusting fpscr for the call.  */
9284       emit_insn (gen_force_mode_for_call ());
9285
9286       operands[1]
9287         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9288       operands[1] = force_reg (SImode, operands[1]);
9289
9290       emit_move_insn (r0, func);
9291       emit_move_insn (r1, cookie_rtx);
9292
9293       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9294         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9295                                                          operands[1],
9296                                                          operands[2],
9297                                                          operands[3]));
9298       else
9299         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9300                                                 operands[2], operands[3]));
9301
9302       DONE;
9303     }
9304   else if (TARGET_SHCOMPACT && flag_pic
9305            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9306            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9307     {
9308       rtx reg = gen_reg_rtx (Pmode);
9309
9310       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9311       XEXP (operands[1], 0) = reg;
9312     }
9313   if (!flag_pic && TARGET_SH2A
9314       && MEM_P (operands[1])
9315       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9316     {
9317       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9318         {
9319           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9320                                  XEXP (operands[1], 0), operands[2]));
9321           DONE;
9322         }
9323     }
9324   if (flag_pic && TARGET_SH2
9325       && MEM_P (operands[1])
9326       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9327     {
9328       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9329                                             operands[2]));
9330       DONE;
9331     }
9332   else
9333     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9334
9335   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9336   DONE;
9337 })
9338
9339 (define_insn "sibcalli"
9340   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9341          (match_operand 1 "" ""))
9342    (use (reg:PSI FPSCR_REG))
9343    (return)]
9344   "TARGET_SH1"
9345   "jmp  @%0%#"
9346   [(set_attr "needs_delay_slot" "yes")
9347    (set (attr "fp_mode")
9348         (if_then_else (eq_attr "fpu_single" "yes")
9349                       (const_string "single") (const_string "double")))
9350    (set_attr "type" "jump_ind")])
9351
9352 (define_insn "sibcalli_pcrel"
9353   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9354          (match_operand 1 "" ""))
9355    (use (match_operand 2 "" ""))
9356    (use (reg:PSI FPSCR_REG))
9357    (return)]
9358   "TARGET_SH2"
9359 {
9360   return       "braf    %0"     "\n"
9361          "%O2:%#";
9362 }
9363   [(set_attr "needs_delay_slot" "yes")
9364    (set (attr "fp_mode")
9365         (if_then_else (eq_attr "fpu_single" "yes")
9366                       (const_string "single") (const_string "double")))
9367    (set_attr "type" "jump_ind")])
9368
9369 ;; This uses an unspec to describe that the symbol_ref is very close.
9370 (define_insn "sibcalli_thunk"
9371   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9372                              UNSPEC_THUNK))
9373          (match_operand 1 "" ""))
9374    (use (reg:PSI FPSCR_REG))
9375    (return)]
9376   "TARGET_SH1"
9377   "bra  %O0"
9378   [(set_attr "needs_delay_slot" "yes")
9379    (set (attr "fp_mode")
9380         (if_then_else (eq_attr "fpu_single" "yes")
9381                       (const_string "single") (const_string "double")))
9382    (set_attr "type" "jump")
9383    (set_attr "length" "2")])
9384
9385 (define_insn_and_split "sibcall_pcrel"
9386   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9387          (match_operand 1 "" ""))
9388    (use (reg:PSI FPSCR_REG))
9389    (clobber (match_scratch:SI 2 "=k"))
9390    (return)]
9391   "TARGET_SH2"
9392   "#"
9393   "reload_completed"
9394   [(const_int 0)]
9395 {
9396   rtx lab = PATTERN (gen_call_site ());
9397   rtx call_insn;
9398
9399   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9400   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9401                                                   copy_rtx (lab)));
9402   SIBLING_CALL_P (call_insn) = 1;
9403   DONE;
9404 }
9405   [(set_attr "needs_delay_slot" "yes")
9406    (set (attr "fp_mode")
9407         (if_then_else (eq_attr "fpu_single" "yes")
9408                       (const_string "single") (const_string "double")))
9409    (set_attr "type" "jump_ind")])
9410
9411 (define_insn "sibcall_compact"
9412   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9413          (match_operand 1 "" ""))
9414    (return)
9415    (use (match_operand:SI 2 "register_operand" "z,x"))
9416    (use (reg:SI R1_REG))
9417    (use (reg:PSI FPSCR_REG))
9418    ;; We want to make sure the `x' above will only match MACH_REG
9419    ;; because sibcall_epilogue may clobber MACL_REG.
9420    (clobber (reg:SI MACL_REG))]
9421   "TARGET_SHCOMPACT"
9422 {
9423   static const char* alt[] =
9424   {
9425        "jmp     @%0%#",
9426
9427        "jmp     @%0"    "\n"
9428     "   sts     %2,r0"
9429   };
9430   return alt[which_alternative];
9431 }
9432   [(set_attr "needs_delay_slot" "yes,no")
9433    (set_attr "length" "2,4")
9434    (set (attr "fp_mode") (const_string "single"))
9435    (set_attr "type" "jump_ind")])
9436
9437 (define_insn "sibcall_media"
9438   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9439          (match_operand 1 "" ""))
9440    (use (reg:SI PR_MEDIA_REG))
9441    (return)]
9442   "TARGET_SHMEDIA"
9443   "blink        %0, r63"
9444   [(set_attr "type" "jump_media")])
9445
9446 (define_expand "sibcall"
9447   [(parallel
9448     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9449            (match_operand 1 "" ""))
9450      (match_operand 2 "" "")
9451      (use (reg:PSI FPSCR_REG))
9452      (return)])]
9453   ""
9454 {
9455   if (TARGET_SHMEDIA)
9456     {
9457       operands[0] = shmedia_prepare_call_address (operands[0], 1);
9458       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9459       DONE;
9460     }
9461   else if (TARGET_SHCOMPACT && operands[2]
9462            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9463     {
9464       rtx cookie_rtx = operands[2];
9465       long cookie = INTVAL (cookie_rtx);
9466       rtx func = XEXP (operands[0], 0);
9467       rtx mach, r1;
9468
9469       if (flag_pic)
9470         {
9471           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9472             {
9473               rtx reg = gen_reg_rtx (Pmode);
9474
9475               emit_insn (gen_symGOT2reg (reg, func));
9476               func = reg;
9477             }
9478           else
9479             func = legitimize_pic_address (func, Pmode, 0);
9480         }
9481
9482       /* FIXME: if we could tell whether all argument registers are
9483          already taken, we could decide whether to force the use of
9484          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
9485          simple way to tell.  We could use the CALL_COOKIE, but we
9486          can't currently tell a register used for regular argument
9487          passing from one that is unused.  If we leave it up to reload
9488          to decide which register to use, it seems to always choose
9489          R0_REG, which leaves no available registers in SIBCALL_REGS
9490          to hold the address of the trampoline.  */
9491       mach = gen_rtx_REG (SImode, MACH_REG);
9492       r1 = gen_rtx_REG (SImode, R1_REG);
9493
9494       /* Since such a call function may use all call-clobbered
9495          registers, we force a mode switch earlier, so that we don't
9496          run out of registers when adjusting fpscr for the call.  */
9497       emit_insn (gen_force_mode_for_call ());
9498
9499       operands[0]
9500         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9501       operands[0] = force_reg (SImode, operands[0]);
9502
9503       /* We don't need a return trampoline, since the callee will
9504          return directly to the upper caller.  */
9505       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9506         {
9507           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9508           cookie_rtx = GEN_INT (cookie);
9509         }
9510
9511       emit_move_insn (mach, func);
9512       emit_move_insn (r1, cookie_rtx);
9513
9514       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9515       DONE;
9516     }
9517   else if (TARGET_SHCOMPACT && flag_pic
9518            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9519            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9520     {
9521       rtx reg = gen_reg_rtx (Pmode);
9522
9523       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9524       XEXP (operands[0], 0) = reg;
9525     }
9526   if (flag_pic && TARGET_SH2
9527       && MEM_P (operands[0])
9528       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9529       /* The PLT needs the PIC register, but the epilogue would have
9530          to restore it, so we can only use PC-relative PIC calls for
9531          static functions.  */
9532       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9533     {
9534       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9535       DONE;
9536     }
9537   else
9538     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9539
9540   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9541   DONE;
9542 })
9543
9544 (define_insn "sibcall_valuei"
9545   [(set (match_operand 0 "" "=rf")
9546         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9547               (match_operand 2 "" "")))
9548    (use (reg:PSI FPSCR_REG))
9549    (return)]
9550   "TARGET_SH1"
9551   "jmp  @%1%#"
9552   [(set_attr "needs_delay_slot" "yes")
9553    (set (attr "fp_mode")
9554         (if_then_else (eq_attr "fpu_single" "yes")
9555                       (const_string "single") (const_string "double")))
9556    (set_attr "type" "jump_ind")])
9557
9558 (define_insn "sibcall_valuei_pcrel"
9559   [(set (match_operand 0 "" "=rf")
9560         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9561               (match_operand 2 "" "")))
9562    (use (match_operand 3 "" ""))
9563    (use (reg:PSI FPSCR_REG))
9564    (return)]
9565   "TARGET_SH2"
9566 {
9567   return       "braf    %1"     "\n"
9568          "%O3:%#";
9569 }
9570   [(set_attr "needs_delay_slot" "yes")
9571    (set (attr "fp_mode")
9572         (if_then_else (eq_attr "fpu_single" "yes")
9573                       (const_string "single") (const_string "double")))
9574    (set_attr "type" "jump_ind")])
9575
9576 (define_insn_and_split "sibcall_value_pcrel"
9577   [(set (match_operand 0 "" "=rf")
9578         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9579               (match_operand 2 "" "")))
9580    (use (reg:PSI FPSCR_REG))
9581    (clobber (match_scratch:SI 3 "=k"))
9582    (return)]
9583   "TARGET_SH2"
9584   "#"
9585   "reload_completed"
9586   [(const_int 0)]
9587 {
9588   rtx lab = PATTERN (gen_call_site ());
9589   rtx call_insn;
9590
9591   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9592   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9593                                                         operands[3],
9594                                                         operands[2],
9595                                                         copy_rtx (lab)));
9596   SIBLING_CALL_P (call_insn) = 1;
9597   DONE;
9598 }
9599   [(set_attr "needs_delay_slot" "yes")
9600    (set (attr "fp_mode")
9601         (if_then_else (eq_attr "fpu_single" "yes")
9602                       (const_string "single") (const_string "double")))
9603    (set_attr "type" "jump_ind")])
9604
9605 (define_insn "sibcall_value_compact"
9606   [(set (match_operand 0 "" "=rf,rf")
9607         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9608               (match_operand 2 "" "")))
9609    (return)
9610    (use (match_operand:SI 3 "register_operand" "z,x"))
9611    (use (reg:SI R1_REG))
9612    (use (reg:PSI FPSCR_REG))
9613    ;; We want to make sure the `x' above will only match MACH_REG
9614    ;; because sibcall_epilogue may clobber MACL_REG.
9615    (clobber (reg:SI MACL_REG))]
9616   "TARGET_SHCOMPACT"
9617 {
9618   static const char* alt[] =
9619   {
9620        "jmp     @%1%#",
9621
9622        "jmp     @%1"    "\n"
9623     "   sts     %3,r0"
9624   };
9625   return alt[which_alternative];
9626 }
9627   [(set_attr "needs_delay_slot" "yes,no")
9628    (set_attr "length" "2,4")
9629    (set (attr "fp_mode") (const_string "single"))
9630    (set_attr "type" "jump_ind")])
9631
9632 (define_insn "sibcall_value_media"
9633   [(set (match_operand 0 "" "=rf")
9634         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9635               (match_operand 2 "" "")))
9636    (use (reg:SI PR_MEDIA_REG))
9637    (return)]
9638   "TARGET_SHMEDIA"
9639   "blink        %1, r63"
9640   [(set_attr "type" "jump_media")])
9641
9642 (define_expand "sibcall_value"
9643   [(parallel
9644     [(set (match_operand 0 "arith_reg_operand" "")
9645           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9646                 (match_operand 2 "" "")))
9647      (match_operand 3 "" "")
9648      (use (reg:PSI FPSCR_REG))
9649      (return)])]
9650   ""
9651 {
9652   if (TARGET_SHMEDIA)
9653     {
9654       operands[1] = shmedia_prepare_call_address (operands[1], 1);
9655       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9656                                                operands[2]));
9657       DONE;
9658     }
9659   else if (TARGET_SHCOMPACT && operands[3]
9660            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9661     {
9662       rtx cookie_rtx = operands[3];
9663       long cookie = INTVAL (cookie_rtx);
9664       rtx func = XEXP (operands[1], 0);
9665       rtx mach, r1;
9666
9667       if (flag_pic)
9668         {
9669           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9670             {
9671               rtx reg = gen_reg_rtx (Pmode);
9672
9673               emit_insn (gen_symGOT2reg (reg, func));
9674               func = reg;
9675             }
9676           else
9677             func = legitimize_pic_address (func, Pmode, 0);
9678         }
9679
9680       /* FIXME: if we could tell whether all argument registers are
9681          already taken, we could decide whether to force the use of
9682          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
9683          simple way to tell.  We could use the CALL_COOKIE, but we
9684          can't currently tell a register used for regular argument
9685          passing from one that is unused.  If we leave it up to reload
9686          to decide which register to use, it seems to always choose
9687          R0_REG, which leaves no available registers in SIBCALL_REGS
9688          to hold the address of the trampoline.  */
9689       mach = gen_rtx_REG (SImode, MACH_REG);
9690       r1 = gen_rtx_REG (SImode, R1_REG);
9691
9692       /* Since such a call function may use all call-clobbered
9693          registers, we force a mode switch earlier, so that we don't
9694          run out of registers when adjusting fpscr for the call.  */
9695       emit_insn (gen_force_mode_for_call ());
9696
9697       operands[1]
9698         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9699       operands[1] = force_reg (SImode, operands[1]);
9700
9701       /* We don't need a return trampoline, since the callee will
9702          return directly to the upper caller.  */
9703       if (cookie & CALL_COOKIE_RET_TRAMP (1))
9704         {
9705           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9706           cookie_rtx = GEN_INT (cookie);
9707         }
9708
9709       emit_move_insn (mach, func);
9710       emit_move_insn (r1, cookie_rtx);
9711
9712       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9713                                                  operands[2], mach));
9714       DONE;
9715     }
9716   else if (TARGET_SHCOMPACT && flag_pic
9717            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9718            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9719     {
9720       rtx reg = gen_reg_rtx (Pmode);
9721
9722       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9723       XEXP (operands[1], 0) = reg;
9724     }
9725   if (flag_pic && TARGET_SH2
9726       && MEM_P (operands[1])
9727       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9728       /* The PLT needs the PIC register, but the epilogue would have
9729          to restore it, so we can only use PC-relative PIC calls for
9730          static functions.  */
9731       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9732     {
9733       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9734                                                XEXP (operands[1], 0),
9735                                                operands[2]));
9736       DONE;
9737     }
9738   else
9739     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9740
9741   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9742   DONE;
9743 })
9744
9745 (define_insn "call_value_pop_compact"
9746   [(set (match_operand 0 "" "=rf")
9747         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9748               (match_operand 2 "" "")))
9749    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9750                                  (match_operand 4 "immediate_operand" "n")))
9751    (match_operand 3 "immediate_operand" "n")
9752    (use (reg:SI R0_REG))
9753    (use (reg:SI R1_REG))
9754    (use (reg:PSI FPSCR_REG))
9755    (clobber (reg:SI PR_REG))]
9756   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9757   "jsr  @%1%#"
9758   [(set_attr "type" "call")
9759    (set (attr "fp_mode")
9760         (if_then_else (eq_attr "fpu_single" "yes")
9761                       (const_string "single") (const_string "double")))
9762    (set_attr "needs_delay_slot" "yes")])
9763
9764 (define_insn "call_value_pop_compact_rettramp"
9765   [(set (match_operand 0 "" "=rf")
9766         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9767               (match_operand 2 "" "")))
9768    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9769                                  (match_operand 4 "immediate_operand" "n")))
9770    (match_operand 3 "immediate_operand" "n")
9771    (use (reg:SI R0_REG))
9772    (use (reg:SI R1_REG))
9773    (use (reg:PSI FPSCR_REG))
9774    (clobber (reg:SI R10_REG))
9775    (clobber (reg:SI PR_REG))]
9776   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9777   "jsr  @%1%#"
9778   [(set_attr "type" "call")
9779    (set (attr "fp_mode")
9780         (if_then_else (eq_attr "fpu_single" "yes")
9781                       (const_string "single") (const_string "double")))
9782    (set_attr "needs_delay_slot" "yes")])
9783
9784 (define_expand "call_value_pop"
9785   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9786                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9787                                  (match_operand 2 "" "")))
9788               (match_operand 3 "" "")
9789               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9790                                             (match_operand 4 "" "")))])]
9791   "TARGET_SHCOMPACT"
9792 {
9793   rtx cookie_rtx;
9794   long cookie;
9795   rtx func;
9796   rtx r0, r1;
9797
9798   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9799   cookie_rtx = operands[3];
9800   cookie = INTVAL (cookie_rtx);
9801   func = XEXP (operands[1], 0);
9802
9803   if (flag_pic)
9804     {
9805       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9806         {
9807           rtx reg = gen_reg_rtx (Pmode);
9808
9809           emit_insn (gen_symGOTPLT2reg (reg, func));
9810           func = reg;
9811         }
9812       else
9813         func = legitimize_pic_address (func, Pmode, 0);
9814     }
9815
9816   r0 = gen_rtx_REG (SImode, R0_REG);
9817   r1 = gen_rtx_REG (SImode, R1_REG);
9818
9819   /* Since such a call function may use all call-clobbered
9820      registers, we force a mode switch earlier, so that we don't
9821      run out of registers when adjusting fpscr for the call.  */
9822   emit_insn (gen_force_mode_for_call ());
9823
9824   operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9825                                  SFUNC_GOT);
9826   operands[1] = force_reg (SImode, operands[1]);
9827
9828   emit_move_insn (r0, func);
9829   emit_move_insn (r1, cookie_rtx);
9830
9831   if (cookie & CALL_COOKIE_RET_TRAMP (1))
9832     emit_call_insn (gen_call_value_pop_compact_rettramp
9833                         (operands[0], operands[1], operands[2],
9834                          operands[3], operands[4]));
9835   else
9836     emit_call_insn (gen_call_value_pop_compact
9837                         (operands[0], operands[1], operands[2],
9838                          operands[3], operands[4]));
9839
9840   DONE;
9841 })
9842
9843 (define_expand "sibcall_epilogue"
9844   [(return)]
9845   ""
9846 {
9847   sh_expand_epilogue (true);
9848   if (TARGET_SHCOMPACT)
9849     {
9850       rtx insn, set;
9851
9852       /* If epilogue clobbers r0, preserve it in macl.  */
9853       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9854         if ((set = single_set (insn))
9855             && REG_P (SET_DEST (set))
9856             && REGNO (SET_DEST (set)) == R0_REG)
9857           {
9858             rtx r0 = gen_rtx_REG (SImode, R0_REG);
9859             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
9860
9861             /* We can't tell at this point whether the sibcall is a
9862                sibcall_compact and, if it is, whether it uses r0 or
9863                mach as operand 2, so let the instructions that
9864                preserve r0 be optimized away if r0 turns out to be
9865                dead.  */
9866             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
9867             emit_move_insn (r0, tmp);
9868             break;
9869           }
9870     }
9871   DONE;
9872 })
9873
9874 (define_insn "indirect_jump_compact"
9875   [(set (pc)
9876         (match_operand:SI 0 "arith_reg_operand" "r"))]
9877   "TARGET_SH1"
9878   "jmp  @%0%#"
9879   [(set_attr "needs_delay_slot" "yes")
9880    (set_attr "type" "jump_ind")])
9881
9882 (define_expand "indirect_jump"
9883   [(set (pc)
9884         (match_operand 0 "register_operand" ""))]
9885   ""
9886 {
9887   if (GET_MODE (operands[0]) != Pmode)
9888     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
9889 })
9890
9891 ;; The use of operand 1 / 2 helps us distinguish case table jumps
9892 ;; which can be present in structured code from indirect jumps which can not
9893 ;; be present in structured code.  This allows -fprofile-arcs to work.
9894
9895 ;; For SH1 processors.
9896 (define_insn "casesi_jump_1"
9897   [(set (pc)
9898         (match_operand:SI 0 "register_operand" "r"))
9899    (use (label_ref (match_operand 1 "" "")))]
9900   "TARGET_SH1"
9901   "jmp  @%0%#"
9902   [(set_attr "needs_delay_slot" "yes")
9903    (set_attr "type" "jump_ind")])
9904
9905 ;; For all later processors.
9906 (define_insn "casesi_jump_2"
9907   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
9908                       (label_ref (match_operand 1 "" ""))))
9909    (use (label_ref (match_operand 2 "" "")))]
9910   "TARGET_SH2
9911    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
9912   "braf %0%#"
9913   [(set_attr "needs_delay_slot" "yes")
9914    (set_attr "type" "jump_ind")])
9915
9916 (define_insn "casesi_jump_media"
9917   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
9918    (use (label_ref (match_operand 1 "" "")))]
9919   "TARGET_SHMEDIA"
9920   "blink        %0, r63"
9921   [(set_attr "type" "jump_media")])
9922
9923 ;; Call subroutine returning any type.
9924 ;; ??? This probably doesn't work.
9925 (define_expand "untyped_call"
9926   [(parallel [(call (match_operand 0 "" "")
9927                     (const_int 0))
9928               (match_operand 1 "" "")
9929               (match_operand 2 "" "")])]
9930   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
9931 {
9932   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9933
9934   for (int i = 0; i < XVECLEN (operands[2], 0); i++)
9935     {
9936       rtx set = XVECEXP (operands[2], 0, i);
9937       emit_move_insn (SET_DEST (set), SET_SRC (set));
9938     }
9939
9940   /* The optimizer does not know that the call sets the function value
9941      registers we stored in the result block.  We avoid problems by
9942      claiming that all hard registers are used and clobbered at this
9943      point.  */
9944   emit_insn (gen_blockage ());
9945
9946   DONE;
9947 })
9948 \f
9949 ;; ------------------------------------------------------------------------
9950 ;; Misc insns
9951 ;; ------------------------------------------------------------------------
9952
9953 (define_insn "dect"
9954   [(set (reg:SI T_REG)
9955         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
9956    (set (match_operand:SI 0 "arith_reg_dest" "=r")
9957         (plus:SI (match_dup 1) (const_int -1)))]
9958   "TARGET_SH2"
9959   "dt   %0"
9960   [(set_attr "type" "arith")])
9961
9962 (define_insn "nop"
9963   [(const_int 0)]
9964   ""
9965   "nop")
9966
9967 ;; Load address of a label. This is only generated by the casesi expand,
9968 ;; and by machine_dependent_reorg (fixing up fp moves).
9969 ;; This must use unspec, because this only works for labels that are
9970 ;; within range.
9971 (define_insn "mova"
9972   [(set (reg:SI R0_REG)
9973         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
9974   "TARGET_SH1"
9975   "mova %O0,r0"
9976   [(set_attr "in_delay_slot" "no")
9977    (set_attr "type" "arith")])
9978
9979 ;; machine_dependent_reorg will make this a `mova'.
9980 (define_insn "mova_const"
9981   [(set (reg:SI R0_REG)
9982         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
9983   "TARGET_SH1"
9984   "#"
9985   [(set_attr "in_delay_slot" "no")
9986    (set_attr "type" "arith")])
9987
9988 (define_expand "GOTaddr2picreg"
9989   [(set (reg:SI R0_REG)
9990         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
9991                    UNSPEC_MOVA))
9992    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
9993    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9994   ""
9995 {
9996   if (TARGET_VXWORKS_RTP)
9997     {
9998       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
9999       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
10000       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10001       DONE;
10002     }
10003
10004   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10005   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10006
10007   if (TARGET_SHMEDIA)
10008     {
10009       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10010       rtx pic = operands[0];
10011       rtx lab = PATTERN (gen_call_site ());
10012       rtx insn, equiv;
10013
10014       equiv = operands[1];
10015       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10016                                     UNSPEC_PCREL_SYMOFF);
10017       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10018
10019       if (Pmode == SImode)
10020         {
10021           emit_insn (gen_movsi_const (pic, operands[1]));
10022           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10023         }
10024       else
10025         {
10026           emit_insn (gen_movdi_const (pic, operands[1]));
10027           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10028         }
10029
10030       insn = emit_move_insn (operands[0], tr);
10031
10032       set_unique_reg_note (insn, REG_EQUAL, equiv);
10033
10034       DONE;
10035     }
10036 })
10037
10038 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10039 ;; PIC register.
10040 (define_expand "vxworks_picreg"
10041   [(set (reg:SI PIC_REG)
10042         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10043    (set (reg:SI R0_REG)
10044         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10045    (set (reg:SI PIC_REG)
10046         (mem:SI (reg:SI PIC_REG)))
10047    (set (reg:SI PIC_REG)
10048         (mem:SI (plus:SI (reg:SI PIC_REG)
10049                          (reg:SI R0_REG))))]
10050   "TARGET_VXWORKS_RTP")
10051
10052 (define_insn "*ptb"
10053   [(set (match_operand 0 "target_reg_operand" "=b")
10054         (const (unspec [(match_operand 1 "" "Csy")]
10055                              UNSPEC_DATALABEL)))]
10056   "TARGET_SHMEDIA && flag_pic
10057    && satisfies_constraint_Csy (operands[1])"
10058   "ptb/u        datalabel %1, %0"
10059   [(set_attr "type" "ptabs_media")
10060    (set_attr "length" "*")])
10061
10062 (define_insn "ptrel_si"
10063   [(set (match_operand:SI 0 "target_reg_operand" "=b")
10064         (plus:SI (match_operand:SI 1 "register_operand" "r")
10065               (pc)))
10066    (match_operand:SI 2 "" "")]
10067   "TARGET_SHMEDIA"
10068   "%O2: ptrel/u %1, %0"
10069   [(set_attr "type" "ptabs_media")])
10070
10071 (define_insn "ptrel_di"
10072   [(set (match_operand:DI 0 "target_reg_operand" "=b")
10073         (plus:DI (match_operand:DI 1 "register_operand" "r")
10074               (pc)))
10075    (match_operand:DI 2 "" "")]
10076   "TARGET_SHMEDIA"
10077   "%O2: ptrel/u %1, %0"
10078   [(set_attr "type" "ptabs_media")])
10079
10080 (define_expand "builtin_setjmp_receiver"
10081   [(match_operand 0 "" "")]
10082   "flag_pic"
10083 {
10084   emit_insn (gen_GOTaddr2picreg ());
10085   DONE;
10086 })
10087
10088 (define_expand "call_site"
10089   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10090   "TARGET_SH1"
10091 {
10092   static HOST_WIDE_INT i = 0;
10093   operands[0] = GEN_INT (i);
10094   i++;
10095 })
10096
10097 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
10098 ;; in symGOT_load expand.
10099 (define_insn_and_split "chk_guard_add"
10100   [(set (match_operand:SI 0 "register_operand" "=&r")
10101         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10102                     (reg:SI PIC_REG)]
10103                    UNSPEC_CHKADD))]
10104   "TARGET_SH1"
10105   "#"
10106   "TARGET_SH1 && reload_completed"
10107   [(set (match_dup 0) (reg:SI PIC_REG))
10108    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10109   ""
10110   [(set_attr "type" "arith")])
10111
10112 (define_expand "sym_label2reg"
10113   [(set (match_operand:SI 0 "" "")
10114         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10115                               (const (plus:SI (match_operand:SI 2 "" "")
10116                                               (const_int 2)))]
10117                              UNSPEC_SYMOFF)))]
10118   "TARGET_SH1" "")
10119
10120 (define_expand "symGOT_load"
10121   [(set (match_dup 2) (match_operand 1 "" ""))
10122    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10123    (set (match_operand 0 "" "") (mem (match_dup 3)))]
10124   ""
10125 {
10126   rtx mem;
10127
10128   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10129   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10130
10131   if (TARGET_SHMEDIA)
10132     {
10133       rtx reg = operands[2];
10134
10135       if (Pmode == DImode)
10136         {      
10137           if (flag_pic > 1)
10138             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10139           else
10140             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10141         }
10142       else
10143         {
10144           if (flag_pic > 1)
10145             emit_insn (gen_movsi_const (reg, operands[1]));
10146           else
10147             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10148         }
10149     }
10150   else
10151     emit_move_insn (operands[2], operands[1]);
10152
10153   /* When stack protector inserts codes after the result is set to
10154      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
10155      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10156      when rX is a GOT address for the guard symbol.  Ugly but doesn't
10157      matter because this is a rare situation.  */
10158   if (!TARGET_SHMEDIA
10159       && flag_stack_protect
10160       && GET_CODE (operands[1]) == CONST
10161       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10162       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10163       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10164                  "__stack_chk_guard") == 0)
10165     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10166   else
10167     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10168                                                gen_rtx_REG (Pmode, PIC_REG)));
10169
10170   /* N.B. This is not constant for a GOTPLT relocation.  */
10171   mem = gen_rtx_MEM (Pmode, operands[3]);
10172   MEM_NOTRAP_P (mem) = 1;
10173   /* ??? Should we have a special alias set for the GOT?  */
10174   emit_move_insn (operands[0], mem);
10175
10176   DONE;
10177 })
10178
10179 (define_expand "sym2GOT"
10180   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10181   ""
10182   "")
10183
10184 (define_expand "symGOT2reg"
10185   [(match_operand 0 "" "") (match_operand 1 "" "")]
10186   ""
10187 {
10188   rtx gotsym, insn;
10189
10190   gotsym = gen_sym2GOT (operands[1]);
10191   PUT_MODE (gotsym, Pmode);
10192   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10193
10194   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10195
10196   DONE;
10197 })
10198
10199 (define_expand "symGOTPLT2reg"
10200   [(match_operand 0 "" "") (match_operand 1 "" "")]
10201   ""
10202 {
10203   rtx pltsym = gen_rtx_CONST (Pmode,
10204                               gen_rtx_UNSPEC (Pmode,
10205                                               gen_rtvec (1, operands[1]),
10206                                               UNSPEC_GOTPLT));
10207   emit_insn (gen_symGOT_load (operands[0], pltsym));
10208   DONE;
10209 })
10210
10211 (define_expand "sym2GOTOFF"
10212   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10213   ""
10214   "")
10215
10216 (define_expand "symGOTOFF2reg"
10217   [(match_operand 0 "" "") (match_operand 1 "" "")]
10218   ""
10219 {
10220   rtx gotoffsym, insn;
10221   rtx t = (!can_create_pseudo_p ()
10222            ? operands[0]
10223            : gen_reg_rtx (GET_MODE (operands[0])));
10224
10225   gotoffsym = gen_sym2GOTOFF (operands[1]);
10226   PUT_MODE (gotoffsym, Pmode);
10227   emit_move_insn (t, gotoffsym);
10228   insn = emit_move_insn (operands[0],
10229                          gen_rtx_PLUS (Pmode, t,
10230                                        gen_rtx_REG (Pmode, PIC_REG)));
10231
10232   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10233
10234   DONE;
10235 })
10236
10237 (define_expand "symPLT_label2reg"
10238   [(set (match_operand:SI 0 "" "")
10239         (const:SI
10240          (unspec:SI
10241           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10242            (const:SI (plus:SI (match_operand:SI 2 "" "")
10243                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10244    ;; Even though the PIC register is not really used by the call
10245    ;; sequence in which this is expanded, the PLT code assumes the PIC
10246    ;; register is set, so we must not skip its initialization.  Since
10247    ;; we only use this expand as part of calling sequences, and never
10248    ;; to take the address of a function, this is the best point to
10249    ;; insert the (use).  Using the PLT to take the address of a
10250    ;; function would be wrong, not only because the PLT entry could
10251    ;; then be called from a function that doesn't initialize the PIC
10252    ;; register to the proper GOT, but also because pointers to the
10253    ;; same function might not compare equal, should they be set by
10254    ;; different shared libraries.
10255    (use (reg:SI PIC_REG))]
10256   "TARGET_SH1"
10257   "")
10258
10259 (define_expand "sym2PIC"
10260   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10261   ""
10262   "")
10263
10264 ;; -------------------------------------------------------------------------
10265 ;; TLS code generation.
10266
10267 ;; FIXME: The multi-insn asm blocks should be converted to use
10268 ;; define_insn_and_split.
10269 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10270 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10271 ;; for details.
10272
10273 (define_insn "tls_global_dynamic"
10274   [(set (match_operand:SI 0 "register_operand" "=&z")
10275         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10276                                   UNSPEC_TLSGD))
10277               (const_int 0)))
10278    (use (reg:PSI FPSCR_REG))
10279    (use (reg:SI PIC_REG))
10280    (clobber (reg:SI PR_REG))
10281    (clobber (scratch:SI))]
10282   "TARGET_SH1"
10283 {
10284   return       "mov.l   1f,r4"                  "\n"
10285          "      mova    2f,r0"                  "\n"
10286          "      mov.l   2f,r1"                  "\n"
10287          "      add     r0,r1"                  "\n"
10288          "      jsr     @r1"                    "\n"
10289          "      add     r12,r4"                 "\n"
10290          "      bra     3f"                     "\n"
10291          "      nop"                            "\n"
10292          "      .align  2"                      "\n"
10293          "1:    .long   %a1@TLSGD"              "\n"
10294          "2:    .long   __tls_get_addr@PLT"     "\n"
10295          "3:";
10296 }
10297   [(set_attr "type" "tls_load")
10298    (set_attr "length" "26")])
10299
10300 (define_insn "tls_local_dynamic"
10301   [(set (match_operand:SI 0 "register_operand" "=&z")
10302         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10303                                   UNSPEC_TLSLDM))
10304               (const_int 0)))
10305    (use (reg:PSI FPSCR_REG))
10306    (use (reg:SI PIC_REG))
10307    (clobber (reg:SI PR_REG))
10308    (clobber (scratch:SI))]
10309   "TARGET_SH1"
10310 {
10311   return       "mov.l   1f,r4"                  "\n"
10312          "      mova    2f,r0"                  "\n"
10313          "      mov.l   2f,r1"                  "\n"
10314          "      add     r0,r1"                  "\n"
10315          "      jsr     @r1"                    "\n"
10316          "      add     r12,r4"                 "\n"
10317          "      bra     3f"                     "\n"
10318          "      nop"                            "\n"
10319          "      .align  2"                      "\n"
10320          "1:    .long   %a1@TLSLDM"             "\n"
10321          "2:    .long   __tls_get_addr@PLT"     "\n"
10322          "3:";
10323 }
10324   [(set_attr "type" "tls_load")
10325    (set_attr "length" "26")])
10326
10327 (define_expand "sym2DTPOFF"
10328   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10329   ""
10330   "")
10331
10332 (define_expand "symDTPOFF2reg"
10333   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10334   ""
10335 {
10336   rtx dtpoffsym;
10337   rtx t = (!can_create_pseudo_p ()
10338            ? operands[0]
10339            : gen_reg_rtx (GET_MODE (operands[0])));
10340
10341   dtpoffsym = gen_sym2DTPOFF (operands[1]);
10342   PUT_MODE (dtpoffsym, Pmode);
10343   emit_move_insn (t, dtpoffsym);
10344   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10345   DONE;
10346 })
10347
10348 (define_expand "sym2GOTTPOFF"
10349   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10350   ""
10351   "")
10352
10353 (define_insn "tls_initial_exec"
10354   [(set (match_operand:SI 0 "register_operand" "=&r")
10355         (unspec:SI [(match_operand:SI 1 "" "")]
10356                     UNSPEC_TLSIE))
10357    (use (reg:SI GBR_REG))
10358    (use (reg:SI PIC_REG))
10359    (clobber (reg:SI R0_REG))]
10360   ""
10361 {
10362   return       "mov.l   1f,r0"          "\n"
10363          "      stc     gbr,%0"         "\n"
10364          "      mov.l   @(r0,r12),r0"   "\n"
10365          "      bra     2f"             "\n"
10366          "      add     r0,%0"          "\n"
10367          "      .align  2"              "\n"
10368          "1:    .long   %a1"            "\n"
10369          "2:";
10370 }
10371   [(set_attr "type" "tls_load")
10372    (set_attr "length" "16")])
10373
10374 (define_expand "sym2TPOFF"
10375   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10376   ""
10377   "")
10378
10379 (define_expand "symTPOFF2reg"
10380   [(match_operand 0 "" "") (match_operand 1 "" "")]
10381   ""
10382 {
10383   rtx tpoffsym;
10384
10385   tpoffsym = gen_sym2TPOFF (operands[1]);
10386   PUT_MODE (tpoffsym, Pmode);
10387   emit_move_insn (operands[0], tpoffsym);
10388   DONE;
10389 })
10390
10391 ;;------------------------------------------------------------------------------
10392 ;; Thread pointer getter and setter.
10393 ;;
10394 ;; On SH the thread pointer is kept in the GBR.
10395 ;; These patterns are usually expanded from the respective built-in functions.
10396 (define_expand "get_thread_pointersi"
10397   [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10398   "TARGET_SH1")
10399
10400 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10401 (define_insn "store_gbr"
10402   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10403   ""
10404   "stc  gbr,%0"
10405   [(set_attr "type" "tls_load")])
10406
10407 (define_expand "set_thread_pointersi"
10408   [(set (reg:SI GBR_REG)
10409         (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10410          UNSPECV_GBR))]
10411   "TARGET_SH1")
10412
10413 (define_insn "load_gbr"
10414   [(set (reg:SI GBR_REG)
10415         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10416          UNSPECV_GBR))]
10417   "TARGET_SH1"
10418   "ldc  %0,gbr"
10419   [(set_attr "type" "move")])
10420
10421 ;;------------------------------------------------------------------------------
10422 ;; Thread pointer relative memory loads and stores.
10423 ;;
10424 ;; On SH there are GBR displacement address modes which can be utilized to
10425 ;; access memory behind the thread pointer.
10426 ;; Since we do not allow using GBR for general purpose memory accesses, these
10427 ;; GBR addressing modes are formed by the combine pass.
10428 ;; This could be done with fewer patterns than below by using a mem predicate
10429 ;; for the GBR mem, but then reload would try to reload addresses with a
10430 ;; zero displacement for some strange reason.
10431
10432 (define_insn "*mov<mode>_gbr_load"
10433   [(set (match_operand:QIHISI 0 "register_operand" "=z")
10434         (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10435                              (match_operand:QIHISI 1 "gbr_displacement"))))]
10436   "TARGET_SH1"
10437   "mov.<bwl>    @(%O1,gbr),%0"
10438   [(set_attr "type" "load")])
10439
10440 (define_insn "*mov<mode>_gbr_load"
10441   [(set (match_operand:QIHISI 0 "register_operand" "=z")
10442         (mem:QIHISI (reg:SI GBR_REG)))]
10443   "TARGET_SH1"
10444   "mov.<bwl>    @(0,gbr),%0"
10445   [(set_attr "type" "load")])
10446
10447 (define_insn "*mov<mode>_gbr_load"
10448   [(set (match_operand:SI 0 "register_operand" "=z")
10449         (sign_extend:SI
10450           (mem:QIHI (plus:SI (reg:SI GBR_REG)
10451                              (match_operand:QIHI 1 "gbr_displacement")))))]
10452   "TARGET_SH1"
10453   "mov.<bw>     @(%O1,gbr),%0"
10454   [(set_attr "type" "load")])
10455
10456 (define_insn "*mov<mode>_gbr_load"
10457   [(set (match_operand:SI 0 "register_operand" "=z")
10458         (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10459   "TARGET_SH1"
10460   "mov.<bw>     @(0,gbr),%0"
10461   [(set_attr "type" "load")])
10462
10463 (define_insn "*mov<mode>_gbr_store"
10464   [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10465                              (match_operand:QIHISI 0 "gbr_displacement")))
10466         (match_operand:QIHISI 1 "register_operand" "z"))]
10467   "TARGET_SH1"
10468   "mov.<bwl>    %1,@(%O0,gbr)"
10469   [(set_attr "type" "store")])
10470
10471 (define_insn "*mov<mode>_gbr_store"
10472   [(set (mem:QIHISI (reg:SI GBR_REG))
10473         (match_operand:QIHISI 0 "register_operand" "z"))]
10474   "TARGET_SH1"
10475   "mov.<bwl>    %0,@(0,gbr)"
10476   [(set_attr "type" "store")])
10477
10478 ;; DImode memory accesses have to be split in two SImode accesses.
10479 ;; Split them before reload, so that it gets a better chance to figure out
10480 ;; how to deal with the R0 restriction for the individual SImode accesses.
10481 ;; Do not match this insn during or after reload because it can't be split
10482 ;; afterwards.
10483 (define_insn_and_split "*movdi_gbr_load"
10484   [(set (match_operand:DI 0 "register_operand")
10485         (match_operand:DI 1 "gbr_address_mem"))]
10486   "TARGET_SH1 && can_create_pseudo_p ()"
10487   "#"
10488   "&& 1"
10489   [(set (match_dup 3) (match_dup 5))
10490    (set (match_dup 4) (match_dup 6))]
10491 {
10492   /* Swap low/high part load order on little endian, so that the result reg
10493      of the second load can be used better.  */
10494   int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10495   operands[3 + off] = gen_lowpart (SImode, operands[0]);
10496   operands[5 + off] = gen_lowpart (SImode, operands[1]);
10497   operands[4 - off] = gen_highpart (SImode, operands[0]);
10498   operands[6 - off] = gen_highpart (SImode, operands[1]);
10499 })
10500
10501 (define_insn_and_split "*movdi_gbr_store"
10502   [(set (match_operand:DI 0 "gbr_address_mem")
10503         (match_operand:DI 1 "register_operand"))]
10504   "TARGET_SH1 && can_create_pseudo_p ()"
10505   "#"
10506   "&& 1"
10507   [(set (match_dup 3) (match_dup 5))
10508    (set (match_dup 4) (match_dup 6))]
10509 {
10510   /* Swap low/high part store order on big endian, so that stores of function
10511      call results can save a reg copy.  */
10512   int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10513   operands[3 + off] = gen_lowpart (SImode, operands[0]);
10514   operands[5 + off] = gen_lowpart (SImode, operands[1]);
10515   operands[4 - off] = gen_highpart (SImode, operands[0]);
10516   operands[6 - off] = gen_highpart (SImode, operands[1]);
10517 })
10518
10519 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10520 ;; in particular when the displacements are in the range of the regular move
10521 ;; insns.  Thus, in the first split pass after the combine pass we search
10522 ;; for missed opportunities and try to fix them up ourselves.
10523 ;; If an equivalent GBR address can be determined the load / store is split
10524 ;; into one of the GBR load / store patterns.
10525 ;; All of that must happen before reload (GBR address modes use R0 as the
10526 ;; other operand) and there's no point of doing it if the GBR is not
10527 ;; referenced in a function at all.
10528 (define_split
10529   [(set (match_operand:QIHISIDI 0 "register_operand")
10530         (match_operand:QIHISIDI 1 "memory_operand"))]
10531   "TARGET_SH1 && !reload_in_progress && !reload_completed
10532    && df_regs_ever_live_p (GBR_REG)"
10533   [(set (match_dup 0) (match_dup 1))]
10534 {
10535   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10536   if (gbr_mem != NULL_RTX)
10537     operands[1] = replace_equiv_address (operands[1], gbr_mem);
10538   else
10539     FAIL;
10540 })
10541
10542 (define_split
10543   [(set (match_operand:SI 0 "register_operand")
10544         (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10545   "TARGET_SH1 && !reload_in_progress && !reload_completed
10546    && df_regs_ever_live_p (GBR_REG)"
10547   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10548 {
10549   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10550   if (gbr_mem != NULL_RTX)
10551     operands[1] = replace_equiv_address (operands[1], gbr_mem);
10552   else
10553     FAIL;
10554 })
10555
10556 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10557 ;; Split those so that a GBR load can be used.
10558 (define_split
10559   [(set (match_operand:SI 0 "register_operand")
10560         (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10561   "TARGET_SH2A && !reload_in_progress && !reload_completed
10562    && df_regs_ever_live_p (GBR_REG)"
10563   [(set (match_dup 2) (match_dup 1))
10564    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10565 {
10566   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10567   if (gbr_mem != NULL_RTX)
10568     {
10569       operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10570       operands[1] = replace_equiv_address (operands[1], gbr_mem);
10571     }
10572   else
10573     FAIL;
10574 })
10575
10576 (define_split
10577   [(set (match_operand:QIHISIDI 0 "memory_operand")
10578         (match_operand:QIHISIDI 1 "register_operand"))]
10579   "TARGET_SH1 && !reload_in_progress && !reload_completed
10580    && df_regs_ever_live_p (GBR_REG)"
10581   [(set (match_dup 0) (match_dup 1))]
10582 {
10583   rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10584   if (gbr_mem != NULL_RTX)
10585     operands[0] = replace_equiv_address (operands[0], gbr_mem);
10586   else
10587     FAIL;
10588 })
10589
10590 ;;------------------------------------------------------------------------------
10591 ;; case instruction for switch statements.
10592
10593 ;; operand 0 is index
10594 ;; operand 1 is the minimum bound
10595 ;; operand 2 is the maximum bound - minimum bound + 1
10596 ;; operand 3 is CODE_LABEL for the table;
10597 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10598 (define_expand "casesi"
10599   [(match_operand:SI 0 "arith_reg_operand" "")
10600    (match_operand:SI 1 "arith_reg_operand" "")
10601    (match_operand:SI 2 "arith_reg_operand" "")
10602    (match_operand 3 "" "") (match_operand 4 "" "")]
10603   ""
10604 {
10605   rtx reg = gen_reg_rtx (SImode);
10606   rtx reg2 = gen_reg_rtx (SImode);
10607   if (TARGET_SHMEDIA)
10608     {
10609       rtx reg = gen_reg_rtx (DImode);
10610       rtx reg2 = gen_reg_rtx (DImode);
10611       rtx reg3 = gen_reg_rtx (Pmode);
10612       rtx reg4 = gen_reg_rtx (Pmode);
10613       rtx reg5 = gen_reg_rtx (Pmode);
10614       rtx load, test;
10615
10616       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10617       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10618       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10619
10620       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10621       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
10622                                       operands[4]));
10623       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10624       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10625       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10626       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10627       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10628                                                (Pmode, operands[3])));
10629       /* Messy: can we subreg to clean this up? */
10630       if (Pmode == DImode)
10631         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10632       else
10633         load = gen_casesi_load_media (reg4,
10634                                       gen_rtx_SUBREG (DImode, reg3, 0),
10635                                       reg2, operands[3]);
10636       PUT_MODE (SET_SRC (load), Pmode);
10637       emit_insn (load);
10638       /* ??? The following add could be eliminated if we used ptrel.  */
10639       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10640       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10641       emit_barrier ();
10642       DONE;
10643     }
10644   operands[1] = copy_to_mode_reg (SImode, operands[1]);
10645   operands[2] = copy_to_mode_reg (SImode, operands[2]);
10646   /* If optimizing, casesi_worker depends on the mode of the instruction
10647      before label it 'uses' - operands[3].  */
10648   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10649                            reg));
10650   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10651   if (TARGET_SH2)
10652     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10653   else
10654     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10655   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10656      operands[3], but to lab.  We will fix this up in
10657      machine_dependent_reorg.  */
10658   emit_barrier ();
10659   DONE;
10660 })
10661
10662 (define_expand "casesi_0"
10663   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10664    (set (match_dup 4) (minus:SI (match_dup 4)
10665                                 (match_operand:SI 1 "arith_operand" "")))
10666    (set (reg:SI T_REG)
10667         (gtu:SI (match_dup 4)
10668                 (match_operand:SI 2 "arith_reg_operand" "")))
10669    (set (pc)
10670         (if_then_else (ne (reg:SI T_REG)
10671                           (const_int 0))
10672                       (label_ref (match_operand 3 "" ""))
10673                       (pc)))]
10674   "TARGET_SH1"
10675   "")
10676
10677 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10678 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10679 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10680 (define_insn "casesi_worker_0"
10681   [(set (match_operand:SI 0 "register_operand" "=r,r")
10682         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10683                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10684    (clobber (match_scratch:SI 3 "=X,1"))
10685    (clobber (match_scratch:SI 4 "=&z,z"))]
10686   "TARGET_SH1"
10687   "#")
10688
10689 (define_split
10690   [(set (match_operand:SI 0 "register_operand" "")
10691         (unspec:SI [(match_operand:SI 1 "register_operand" "")
10692                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10693    (clobber (match_scratch:SI 3 ""))
10694    (clobber (match_scratch:SI 4 ""))]
10695   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10696   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10697    (parallel [(set (match_dup 0)
10698               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10699                           (label_ref (match_dup 2))] UNSPEC_CASESI))
10700               (clobber (match_dup 3))])
10701    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10702 {
10703   if (GET_CODE (operands[2]) == CODE_LABEL)
10704     LABEL_NUSES (operands[2])++;
10705 })
10706
10707 (define_split
10708   [(set (match_operand:SI 0 "register_operand" "")
10709         (unspec:SI [(match_operand:SI 1 "register_operand" "")
10710                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10711    (clobber (match_scratch:SI 3 ""))
10712    (clobber (match_scratch:SI 4 ""))]
10713   "TARGET_SH2 && reload_completed"
10714   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10715    (parallel [(set (match_dup 0)
10716               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10717                           (label_ref (match_dup 2))] UNSPEC_CASESI))
10718               (clobber (match_dup 3))])]
10719 {
10720   if (GET_CODE (operands[2]) == CODE_LABEL)
10721     LABEL_NUSES (operands[2])++;
10722 })
10723
10724 (define_insn "casesi_worker_1"
10725   [(set (match_operand:SI 0 "register_operand" "=r,r")
10726         (unspec:SI [(reg:SI R0_REG)
10727                     (match_operand:SI 1 "register_operand" "0,r")
10728                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10729    (clobber (match_scratch:SI 3 "=X,1"))]
10730   "TARGET_SH1"
10731 {
10732   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10733
10734   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10735
10736   switch (GET_MODE (diff_vec))
10737     {
10738     case SImode:
10739       return   "shll2   %1"     "\n"
10740              "  mov.l   @(r0,%1),%0";
10741     case HImode:
10742       return   "add     %1,%1"  "\n"
10743              "  mov.w   @(r0,%1),%0";
10744     case QImode:
10745       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10746         return         "mov.b   @(r0,%1),%0"    "\n"
10747                "        extu.b  %0,%0";
10748       else
10749         return "mov.b   @(r0,%1),%0";
10750
10751     default:
10752       gcc_unreachable ();
10753     }
10754 }
10755   [(set_attr "length" "4")])
10756
10757 (define_insn "casesi_worker_2"
10758   [(set (match_operand:SI 0 "register_operand" "=r,r")
10759         (unspec:SI [(reg:SI R0_REG)
10760                     (match_operand:SI 1 "register_operand" "0,r")
10761                     (label_ref (match_operand 2 "" ""))
10762                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10763    (clobber (match_operand:SI 4 "" "=X,1"))]
10764   "TARGET_SH2 && reload_completed && flag_pic"
10765 {
10766   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10767   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10768
10769   switch (GET_MODE (diff_vec))
10770     {
10771     case SImode:
10772       return   "shll2   %1"             "\n"
10773              "  add     r0,%1"          "\n"
10774              "  mova    %O3,r0"         "\n"
10775              "  mov.l   @(r0,%1),%0";
10776     case HImode:
10777       return   "add     %1,%1"          "\n"
10778              "  add     r0,%1"          "\n"
10779              "  mova    %O3,r0"         "\n"
10780              "  mov.w   @(r0,%1),%0";
10781     case QImode:
10782       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10783         return         "add     r0,%1"          "\n"
10784                 "       mova    %O3,r0"         "\n"
10785                 "       mov.b   @(r0,%1),%0"    "\n"
10786                 "       extu.b  %0,%0";
10787       else
10788         return         "add     r0,%1"          "\n"
10789                 "       mova    %O3,r0"         "\n"
10790                 "       mov.b   @(r0,%1),%0";
10791     default:
10792       gcc_unreachable ();
10793     }
10794 }
10795   [(set_attr "length" "8")])
10796
10797 (define_insn "casesi_shift_media"
10798   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10799         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10800                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10801                     UNSPEC_CASESI)))]
10802   "TARGET_SHMEDIA"
10803 {
10804   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10805
10806   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10807
10808   switch (GET_MODE (diff_vec))
10809     {
10810     case SImode:
10811       return "shlli     %1, 2, %0";
10812     case HImode:
10813       return "shlli     %1, 1, %0";
10814     case QImode:
10815       if (rtx_equal_p (operands[0], operands[1]))
10816         return "";
10817       return "add       %1, r63, %0";
10818     default:
10819       gcc_unreachable ();
10820     }
10821 }
10822   [(set_attr "type" "arith_media")])
10823
10824 (define_insn "casesi_load_media"
10825   [(set (match_operand 0 "any_arith_reg_dest" "=r")
10826         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
10827                       (match_operand:DI 2 "arith_reg_operand" "r")
10828                       (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
10829   "TARGET_SHMEDIA"
10830 {
10831   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
10832
10833   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10834
10835   switch (GET_MODE (diff_vec))
10836     {
10837     case SImode:
10838       return "ldx.l     %1, %2, %0";
10839     case HImode:
10840 #if 0
10841       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10842         return "ldx.uw  %1, %2, %0";
10843 #endif
10844       return "ldx.w     %1, %2, %0";
10845     case QImode:
10846       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10847         return "ldx.ub  %1, %2, %0";
10848       return "ldx.b     %1, %2, %0";
10849     default:
10850       gcc_unreachable ();
10851     }
10852 }
10853   [(set_attr "type" "load_media")])
10854
10855 (define_expand "simple_return"
10856   [(simple_return)]
10857  "sh_can_use_simple_return_p ()")
10858
10859 (define_expand "return"
10860   [(return)]
10861  "reload_completed && epilogue_completed"
10862 {
10863   if (TARGET_SHMEDIA)
10864     {
10865       emit_jump_insn (gen_return_media ());
10866       DONE;
10867     }
10868
10869   if (TARGET_SHCOMPACT
10870       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
10871     {
10872       emit_jump_insn (gen_shcompact_return_tramp ());
10873       DONE;
10874     }
10875 })
10876
10877 (define_insn "*<code>_i"
10878   [(any_return)]
10879   "TARGET_SH1 && ! (TARGET_SHCOMPACT
10880                     && (crtl->args.info.call_cookie
10881                         & CALL_COOKIE_RET_TRAMP (1)))
10882    && reload_completed
10883    && ! sh_cfun_trap_exit_p ()"
10884 {
10885   if (TARGET_SH2A && (dbr_sequence_length () == 0)
10886       && !current_function_interrupt)
10887     return "rts/n";
10888   else
10889     return "%@  %#";
10890 }
10891   [(set_attr "type" "return")
10892    (set_attr "needs_delay_slot" "yes")])
10893
10894 ;; trapa has no delay slot.
10895 (define_insn "*return_trapa"
10896   [(return)]
10897   "TARGET_SH1 && !TARGET_SHCOMPACT
10898    && reload_completed"
10899   "%@"
10900   [(set_attr "type" "return")])
10901
10902 (define_expand "shcompact_return_tramp"
10903   [(return)]
10904   "TARGET_SHCOMPACT
10905    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10906 {
10907   rtx reg = gen_rtx_REG (Pmode, R0_REG);
10908
10909   function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
10910   emit_jump_insn (gen_shcompact_return_tramp_i ());
10911   DONE;
10912 })
10913
10914 (define_insn "shcompact_return_tramp_i"
10915   [(parallel [(return) (use (reg:SI R0_REG))])]
10916   "TARGET_SHCOMPACT
10917    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10918   "jmp  @r0%#"
10919   [(set_attr "type" "jump_ind")
10920    (set_attr "needs_delay_slot" "yes")])
10921
10922 (define_insn "return_media_i"
10923   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
10924   "TARGET_SHMEDIA && reload_completed"
10925   "blink        %0, r63"
10926   [(set_attr "type" "jump_media")])
10927
10928 (define_insn "return_media_rte"
10929   [(return)]
10930   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
10931   "rte"
10932   [(set_attr "type" "jump_media")])
10933
10934 (define_expand "return_media"
10935   [(return)]
10936   "TARGET_SHMEDIA && reload_completed"
10937 {
10938   int tr_regno = sh_media_register_for_return ();
10939   rtx tr;
10940
10941   if (current_function_interrupt)
10942     {
10943       emit_jump_insn (gen_return_media_rte ());
10944       DONE;
10945     }
10946   if (tr_regno < 0)
10947     {
10948       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
10949
10950       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
10951       tr_regno = TR0_REG;
10952       tr = gen_rtx_REG (Pmode, tr_regno);
10953       emit_move_insn (tr, r18);
10954     }
10955   else
10956     tr = gen_rtx_REG (Pmode, tr_regno);
10957
10958   emit_jump_insn (gen_return_media_i (tr));
10959   DONE;
10960 })
10961
10962 (define_insn "shcompact_preserve_incoming_args"
10963   [(set (match_operand:SI 0 "register_operand" "+r")
10964         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
10965   "TARGET_SHCOMPACT"
10966   ""
10967   [(set_attr "length" "0")])
10968
10969 (define_insn "shcompact_incoming_args"
10970   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
10971    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
10972    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
10973    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
10974    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
10975    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
10976    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
10977    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
10978    (set (mem:BLK (reg:SI MACL_REG))
10979         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
10980    (use (reg:SI R0_REG))
10981    (clobber (reg:SI R0_REG))
10982    (clobber (reg:SI MACL_REG))
10983    (clobber (reg:SI MACH_REG))
10984    (clobber (reg:SI PR_REG))]
10985   "TARGET_SHCOMPACT"
10986   "jsr  @r0%#"
10987   [(set_attr "needs_delay_slot" "yes")])
10988
10989 (define_insn "shmedia_save_restore_regs_compact"
10990   [(set (reg:SI SP_REG)
10991         (plus:SI (reg:SI SP_REG)
10992                  (match_operand:SI 0 "immediate_operand" "i")))
10993    (use (reg:SI R0_REG))
10994    (clobber (reg:SI PR_REG))]
10995   "TARGET_SHCOMPACT
10996    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
10997        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
10998   "jsr @r0%#"
10999   [(set_attr "needs_delay_slot" "yes")])
11000
11001 (define_expand "prologue"
11002   [(const_int 0)]
11003   ""
11004 {
11005   sh_expand_prologue ();
11006   DONE;
11007 })
11008
11009 (define_expand "epilogue"
11010   [(return)]
11011   ""
11012 {
11013   sh_expand_epilogue (false);
11014   if (TARGET_SHMEDIA
11015       || (TARGET_SHCOMPACT
11016           && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11017     {
11018       emit_jump_insn (gen_return ());
11019       DONE;
11020     }
11021 })
11022
11023 (define_expand "eh_return"
11024   [(use (match_operand 0 "register_operand" ""))]
11025   ""
11026 {
11027   rtx ra = operands[0];
11028
11029   if (TARGET_SHMEDIA64)
11030     emit_insn (gen_eh_set_ra_di (ra));
11031   else
11032     emit_insn (gen_eh_set_ra_si (ra));
11033
11034   DONE;
11035 })
11036
11037 ;; Clobber the return address on the stack.  We can't expand this
11038 ;; until we know where it will be put in the stack frame.
11039
11040 (define_insn "eh_set_ra_si"
11041   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11042       UNSPECV_EH_RETURN)
11043    (clobber (match_scratch:SI 1 "=&r"))]
11044   "! TARGET_SHMEDIA64"
11045   "#")
11046
11047 (define_insn "eh_set_ra_di"
11048   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11049       UNSPECV_EH_RETURN)
11050    (clobber (match_scratch:DI 1 "=&r"))]
11051   "TARGET_SHMEDIA64"
11052   "#")
11053
11054 (define_split
11055   [(unspec_volatile [(match_operand 0 "register_operand" "")]
11056       UNSPECV_EH_RETURN)
11057    (clobber (match_scratch 1 ""))]
11058   "reload_completed"
11059   [(const_int 0)]
11060 {
11061   sh_set_return_address (operands[0], operands[1]);
11062   DONE;
11063 })
11064
11065 (define_insn "blockage"
11066   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11067   ""
11068   ""
11069   [(set_attr "length" "0")])
11070 \f
11071 ;; Define movml instructions for SH2A target.  Currently they are
11072 ;; used to push and pop all banked registers only.
11073
11074 (define_insn "movml_push_banked"
11075   [(set (match_operand:SI 0 "register_operand" "=r")
11076           (plus (match_dup 0) (const_int -32)))
11077    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11078    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11079    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11080    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11081    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11082    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11083    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11084    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11085   "TARGET_SH2A && REGNO (operands[0]) == 15"
11086   "movml.l      r7,@-r15"
11087   [(set_attr "in_delay_slot" "no")])
11088
11089 (define_insn "movml_pop_banked"
11090   [(set (match_operand:SI 0 "register_operand" "=r")
11091           (plus (match_dup 0) (const_int 32)))
11092    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11093    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11094    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11095    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11096    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11097    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11098    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11099    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11100   "TARGET_SH2A && REGNO (operands[0]) == 15"
11101   "movml.l      @r15+,r7"
11102   [(set_attr "in_delay_slot" "no")])
11103 \f
11104 ;; ------------------------------------------------------------------------
11105 ;; Scc instructions
11106 ;; ------------------------------------------------------------------------
11107
11108 (define_insn "movt"
11109   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11110         (match_operand:SI 1 "t_reg_operand"))]
11111   "TARGET_SH1"
11112   "movt %0"
11113   [(set_attr "type" "arith")])
11114
11115 (define_insn "movrt"
11116   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11117         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11118   "TARGET_SH2A"
11119   "movrt        %0"
11120   [(set_attr "type" "arith")])
11121
11122 (define_expand "cstore4_media"
11123   [(set (match_operand:SI 0 "register_operand" "=r")
11124         (match_operator:SI 1 "sh_float_comparison_operator"
11125          [(match_operand 2 "logical_operand" "")
11126           (match_operand 3 "cmp_operand" "")]))]
11127   "TARGET_SHMEDIA"
11128 {
11129   enum machine_mode mode = GET_MODE (operands[2]);
11130   enum rtx_code code = GET_CODE (operands[1]);
11131   bool invert, swap;
11132   if (mode == VOIDmode)
11133     mode = GET_MODE (operands[3]);
11134   if (operands[2] == const0_rtx)
11135     {
11136       if (code == EQ || code == NE)
11137         operands[2] = operands[3], operands[3] = const0_rtx;
11138     }
11139   else
11140     operands[2] = force_reg (mode, operands[2]);
11141   if (operands[3] != const0_rtx)
11142     operands[3] = force_reg (mode, operands[3]);
11143
11144   switch (code)
11145     {
11146     case GEU:
11147     case GE:
11148       swap = invert = !FLOAT_MODE_P (mode);
11149       break;
11150
11151     case LEU:
11152     case LE:
11153       swap = FLOAT_MODE_P (mode), invert = !swap;
11154       break;
11155
11156     case LTU:
11157     case LT:
11158       swap = true, invert = false;
11159       break;
11160
11161     case GTU:
11162     case GT:
11163     case EQ:
11164     case UNORDERED:
11165       swap = invert = false;
11166       break;
11167
11168     case NE:
11169       swap = invert = true;
11170       break;
11171
11172     default:
11173       gcc_unreachable ();
11174   }
11175
11176   if (swap)
11177     {
11178       rtx tem = operands[2];
11179       operands[2] = operands[3];
11180       operands[3] = tem;
11181       code = swap_condition (code);
11182     }
11183
11184   if (invert)
11185     {
11186       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11187       code = reverse_condition (code);
11188       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11189       emit_insn (gen_cstore4_media (tem, operands[1],
11190                                     operands[2], operands[3]));
11191       code = EQ;
11192       operands[2] = tem;
11193       operands[3] = const0_rtx;
11194     }
11195
11196   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11197 })
11198
11199 (define_expand "cstoresi4"
11200   [(set (match_operand:SI 0 "register_operand" "=r")
11201         (match_operator:SI 1 "comparison_operator"
11202          [(match_operand:SI 2 "cmpsi_operand" "")
11203           (match_operand:SI 3 "arith_operand" "")]))]
11204   "TARGET_SH1 || TARGET_SHMEDIA"
11205 {
11206   if (TARGET_SHMEDIA)
11207     {
11208       emit_insn (gen_cstore4_media (operands[0], operands[1],
11209                                     operands[2], operands[3]));
11210       DONE;
11211     }
11212
11213    if (sh_expand_t_scc (operands))
11214      DONE;
11215
11216    if (! currently_expanding_to_rtl)
11217      FAIL;
11218    
11219    sh_emit_compare_and_set (operands, SImode);
11220    DONE;
11221 })
11222
11223 (define_expand "cstoredi4"
11224   [(set (match_operand:SI 0 "register_operand" "=r")
11225         (match_operator:SI 1 "comparison_operator"
11226          [(match_operand:DI 2 "arith_operand" "")
11227           (match_operand:DI 3 "arith_operand" "")]))]
11228   "TARGET_SH2 || TARGET_SHMEDIA"
11229 {
11230   if (TARGET_SHMEDIA)
11231     {
11232       emit_insn (gen_cstore4_media (operands[0], operands[1],
11233                                     operands[2], operands[3]));
11234       DONE;
11235     }
11236
11237    if (sh_expand_t_scc (operands))
11238      DONE;
11239
11240    if (! currently_expanding_to_rtl)
11241      FAIL;
11242    
11243    sh_emit_compare_and_set (operands, DImode);
11244    DONE;
11245 })
11246
11247 ;; Move the complement of the T reg to a reg.
11248 ;; On SH2A the movrt insn can be used.
11249 ;; On anything else than SH2A this has to be done with multiple instructions.
11250 ;; One obvious way would be:
11251 ;;      cmp/eq  ...
11252 ;;      movt    r0
11253 ;;      xor     #1,r0
11254 ;;
11255 ;; However, this puts pressure on r0 in most cases and thus the following is
11256 ;; more appealing:
11257 ;;      cmp/eq  ...
11258 ;;      mov     #-1,temp
11259 ;;      negc    temp,dest
11260 ;;
11261 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11262 ;; becomes a one instruction operation.  Moreover, care must be taken that
11263 ;; the insn can still be combined with inverted compare and branch code
11264 ;; around it.  On the other hand, if a function returns the complement of
11265 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11266 ;; lead to better code.
11267 (define_expand "movnegt"
11268   [(set (match_operand:SI 0 "arith_reg_dest" "")
11269         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11270   "TARGET_SH1"
11271 {
11272   if (TARGET_SH2A)
11273     emit_insn (gen_movrt (operands[0], operands[1]));
11274   else
11275     {
11276       rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11277       emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11278     }
11279   DONE;
11280 })
11281
11282 (define_insn "movrt_negc"
11283   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11284         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11285    (set (reg:SI T_REG) (const_int 1))
11286    (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11287   "TARGET_SH1"
11288   "negc %2,%0"
11289   [(set_attr "type" "arith")])
11290
11291 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11292 ;; pattern can be used by the combine pass.  Using a scratch reg for the
11293 ;; -1 constant results in slightly better register allocations compared to
11294 ;; generating a pseudo reg before reload.
11295 (define_insn_and_split "*movrt_negc"
11296   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11297         (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11298    (clobber (match_scratch:SI 2 "=r"))
11299    (clobber (reg:SI T_REG))]
11300   "TARGET_SH1 && ! TARGET_SH2A"
11301   "#"
11302   "&& reload_completed"
11303   [(set (match_dup 2) (const_int -1))
11304    (parallel
11305        [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11306         (set (reg:SI T_REG) (const_int 1))
11307         (use (match_dup 2))])])
11308
11309 ;; Store the negated T bit in a reg using r0 and xor.  This one doesn't
11310 ;; clobber the T bit, which is useful when storing the T bit and the
11311 ;; negated T bit in parallel.  On SH2A the movrt insn can be used for that.
11312 ;; Usually we don't want this insn to be matched, except for cases where the
11313 ;; T bit clobber is really not appreciated.  Hence the extra use on T_REG.
11314 (define_insn_and_split "movrt_xor"
11315   [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11316         (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11317    (use (reg:SI T_REG))]
11318   "TARGET_SH1 && !TARGET_SH2A"
11319   "#"
11320   "&& reload_completed"
11321   [(set (match_dup 0) (reg:SI T_REG))
11322    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11323
11324 ;; Store the T bit and the negated T bit in two regs in parallel.  There is
11325 ;; no real insn to do that, but specifying this pattern will give combine
11326 ;; some opportunities.
11327 (define_insn_and_split "*movt_movrt"
11328   [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11329                    (match_operand:SI 1 "negt_reg_operand"))
11330               (set (match_operand:SI 2 "arith_reg_dest")
11331                    (match_operand:SI 3 "t_reg_operand"))])]
11332   "TARGET_SH1"
11333   "#"
11334   "&& 1"
11335   [(const_int 0)]
11336 {
11337   rtx i = TARGET_SH2A
11338           ? gen_movrt (operands[0], get_t_reg_rtx ())
11339           : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11340   
11341   emit_insn (i);
11342   emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11343   DONE;
11344 })
11345
11346 (define_insn_and_split "*movt_movrt"
11347   [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11348                    (match_operand:SI 1 "t_reg_operand"))
11349               (set (match_operand:SI 2 "arith_reg_dest")
11350                    (match_operand:SI 3 "negt_reg_operand"))])]
11351   "TARGET_SH1"
11352   "#"
11353   "&& 1"
11354   [(parallel [(set (match_dup 2) (match_dup 3))
11355               (set (match_dup 0) (match_dup 1))])])
11356
11357 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11358 ;;      T = 1: 0x80000000 -> reg
11359 ;;      T = 0: 0x7FFFFFFF -> reg
11360 ;; This works because 0 - 0x80000000 = 0x80000000.
11361 (define_insn_and_split "*mov_t_msb_neg"
11362   [(set (match_operand:SI 0 "arith_reg_dest")
11363         (minus:SI (const_int -2147483648)  ;; 0x80000000
11364                   (match_operand 1 "t_reg_operand")))
11365    (clobber (reg:SI T_REG))]
11366   "TARGET_SH1"
11367   "#"
11368   "&& can_create_pseudo_p ()"
11369   [(set (match_dup 2) (const_int -2147483648))
11370    (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11371                                  (reg:SI T_REG)))
11372               (clobber (reg:SI T_REG))])]
11373 {
11374   operands[2] = gen_reg_rtx (SImode);
11375 })
11376
11377 ;; These are essentially the same as above, but with the inverted T bit.
11378 ;; Combine recognizes the split patterns, but does not take them sometimes
11379 ;; if the T_REG clobber is specified.  Instead it tries to split out the
11380 ;; T bit negation.  Since these splits are supposed to be taken only by
11381 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11382 ;; should be fine.
11383 (define_split
11384   [(set (match_operand:SI 0 "arith_reg_dest")
11385         (plus:SI (match_operand 1 "negt_reg_operand")
11386                  (const_int 2147483647)))]  ;; 0x7fffffff
11387   "TARGET_SH1 && can_create_pseudo_p ()"
11388   [(parallel [(set (match_dup 0)
11389                    (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11390               (clobber (reg:SI T_REG))])])
11391
11392 (define_split
11393   [(set (match_operand:SI 0 "arith_reg_dest")
11394         (if_then_else:SI (match_operand 1 "t_reg_operand")
11395                          (const_int 2147483647)  ;; 0x7fffffff
11396                          (const_int -2147483648)))]  ;; 0x80000000
11397   "TARGET_SH1 && can_create_pseudo_p ()"
11398   [(parallel [(set (match_dup 0)
11399                    (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11400               (clobber (reg:SI T_REG))])])
11401
11402 ;; The *negnegt pattern helps the combine pass to figure out how to fold 
11403 ;; an explicit double T bit negation.
11404 (define_insn_and_split "*negnegt"
11405   [(set (reg:SI T_REG)
11406         (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11407   "TARGET_SH1"
11408   "#"
11409   ""
11410   [(const_int 0)])
11411
11412 ;; Store T bit as all zeros or ones in a reg.
11413 (define_insn "mov_neg_si_t"
11414   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11415         (neg:SI (match_operand 1 "t_reg_operand" "")))]
11416   "TARGET_SH1"
11417   "subc %0,%0"
11418   [(set_attr "type" "arith")])
11419
11420 ;; Store negated T bit as all zeros or ones in a reg.
11421 ;; Use the following sequence:
11422 ;;      subc    Rn,Rn   ! Rn = Rn - Rn - T; T = T
11423 ;;      not     Rn,Rn   ! Rn = 0 - Rn
11424 (define_split
11425   [(set (match_operand:SI 0 "arith_reg_dest" "")
11426         (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11427   "TARGET_SH1"
11428   [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11429    (set (match_dup 0) (not:SI (match_dup 0)))])
11430
11431 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11432 (define_insn_and_split "*movtt"
11433   [(set (reg:SI T_REG)
11434         (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11435   "TARGET_SH1"
11436   "#"
11437   ""
11438   [(const_int 0)])
11439
11440 ;; Invert the T bit.
11441 ;; On SH2A we can use the nott insn.  On anything else this must be done with
11442 ;; multiple insns like:
11443 ;;      movt    Rn
11444 ;;      tst     Rn,Rn
11445 (define_insn_and_split "nott"
11446   [(set (reg:SI T_REG)
11447         (xor:SI (match_operand:SI 0 "t_reg_operand" "") (const_int 1)))]
11448   "TARGET_SH1"
11449 {
11450   gcc_assert (TARGET_SH2A);
11451   return "nott";
11452 }
11453   "! TARGET_SH2A && can_create_pseudo_p ()"
11454   [(set (match_dup 0) (reg:SI T_REG))
11455    (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11456 {
11457   operands[0] = gen_reg_rtx (SImode);
11458 })
11459
11460 ;; Store T bit as MSB in a reg.
11461 ;; T = 0: 0x00000000 -> reg
11462 ;; T = 1: 0x80000000 -> reg
11463 (define_insn_and_split "*movt_msb"
11464   [(set (match_operand:SI 0 "arith_reg_dest")
11465         (mult:SI (match_operand:SI 1 "t_reg_operand")
11466                  (const_int -2147483648)))  ;; 0xffffffff80000000
11467    (clobber (reg:SI T_REG))]
11468   "TARGET_SH1"
11469   "#"
11470   "&& 1"
11471   [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11472
11473 ;; Store inverted T bit as MSB in a reg.
11474 ;; T = 0: 0x80000000 -> reg
11475 ;; T = 1: 0x00000000 -> reg
11476 ;; On SH2A we can get away without clobbering the T_REG.
11477 (define_insn_and_split "*negt_msb"
11478   [(set (match_operand:SI 0 "arith_reg_dest")
11479         (match_operand:SI 1 "negt_reg_shl31_operand"))]
11480   "TARGET_SH2A"
11481   "#"
11482   "&& can_create_pseudo_p ()"
11483   [(const_int 0)]
11484 {
11485   rtx tmp = gen_reg_rtx (SImode);
11486   emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11487   emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11488   DONE;
11489 })
11490
11491 (define_insn_and_split "*negt_msb"
11492   [(set (match_operand:SI 0 "arith_reg_dest")
11493         (match_operand:SI 1 "negt_reg_shl31_operand"))
11494    (clobber (reg:SI T_REG))]
11495   "TARGET_SH1 && !TARGET_SH2A"
11496   "#"
11497   "&& can_create_pseudo_p ()"
11498   [(const_int 0)]
11499 {
11500   rtx tmp = gen_reg_rtx (SImode);
11501   emit_move_insn (tmp, get_t_reg_rtx ());
11502   emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11503   emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11504   DONE;
11505 })
11506
11507 ;; The *cset_zero patterns convert optimizations such as
11508 ;;      "if (test) x = 0;"
11509 ;; to
11510 ;;      "x &= -(test == 0);"
11511 ;; back to conditional branch sequences if zero-displacement branches
11512 ;; are enabled.
11513 ;; FIXME: These patterns can be removed when conditional execution patterns
11514 ;; are implemented, since ifcvt will not perform these optimizations if
11515 ;; conditional execution is supported.
11516 (define_insn "*cset_zero"
11517   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11518         (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11519                          (const_int -1))
11520                 (match_operand:SI 2 "arith_reg_operand" "0")))]
11521   "TARGET_SH1 && TARGET_ZDCBRANCH"
11522 {
11523   return       "bf      0f"     "\n"
11524          "      mov     #0,%0"  "\n"
11525          "0:";
11526 }
11527   [(set_attr "type" "arith") ;; poor approximation
11528    (set_attr "length" "4")])
11529
11530 (define_insn "*cset_zero"
11531   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11532         (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
11533                          (match_operand:SI 2 "arith_reg_operand" "0")
11534                          (const_int 0)))]
11535   "TARGET_SH1 && TARGET_ZDCBRANCH"
11536 {
11537   return       "bt      0f"     "\n"
11538          "      mov     #0,%0"  "\n"
11539          "0:";
11540 }
11541   [(set_attr "type" "arith") ;; poor approximation
11542    (set_attr "length" "4")])
11543
11544 (define_expand "cstoresf4"
11545   [(set (match_operand:SI 0 "register_operand" "=r")
11546         (match_operator:SI 1 "sh_float_comparison_operator"
11547          [(match_operand:SF 2 "arith_operand" "")
11548           (match_operand:SF 3 "arith_operand" "")]))]
11549   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11550 {
11551   if (TARGET_SHMEDIA)
11552     {
11553       emit_insn (gen_cstore4_media (operands[0], operands[1],
11554                                     operands[2], operands[3]));
11555       DONE;
11556     }
11557
11558   if (! currently_expanding_to_rtl)
11559     FAIL;
11560    
11561   sh_emit_compare_and_set (operands, SFmode);
11562   DONE;
11563 })
11564
11565 (define_expand "cstoredf4"
11566   [(set (match_operand:SI 0 "register_operand" "=r")
11567         (match_operator:SI 1 "sh_float_comparison_operator"
11568          [(match_operand:DF 2 "arith_operand" "")
11569           (match_operand:DF 3 "arith_operand" "")]))]
11570   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11571 {
11572   if (TARGET_SHMEDIA)
11573     {
11574       emit_insn (gen_cstore4_media (operands[0], operands[1],
11575                                     operands[2], operands[3]));
11576       DONE;
11577     }
11578
11579   if (! currently_expanding_to_rtl)
11580     FAIL;
11581    
11582   sh_emit_compare_and_set (operands, DFmode);
11583   DONE;
11584 })
11585
11586 ;; -------------------------------------------------------------------------
11587 ;; Instructions to cope with inline literal tables
11588 ;; -------------------------------------------------------------------------
11589
11590 ;; 2 byte integer in line
11591 (define_insn "consttable_2"
11592  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11593                     (match_operand 1 "" "")]
11594                    UNSPECV_CONST2)]
11595  ""
11596 {
11597   if (operands[1] != const0_rtx)
11598     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11599   return "";
11600 }
11601  [(set_attr "length" "2")
11602  (set_attr "in_delay_slot" "no")])
11603
11604 ;; 4 byte integer in line
11605 (define_insn "consttable_4"
11606  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11607                     (match_operand 1 "" "")]
11608                    UNSPECV_CONST4)]
11609  ""
11610 {
11611   if (operands[1] != const0_rtx)
11612     {
11613       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11614       mark_symbol_refs_as_used (operands[0]);
11615     }
11616   return "";
11617 }
11618  [(set_attr "length" "4")
11619   (set_attr "in_delay_slot" "no")])
11620
11621 ;; 8 byte integer in line
11622 (define_insn "consttable_8"
11623  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11624                     (match_operand 1 "" "")]
11625                    UNSPECV_CONST8)]
11626  ""
11627 {
11628   if (operands[1] != const0_rtx)
11629     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11630   return "";
11631 }
11632  [(set_attr "length" "8")
11633   (set_attr "in_delay_slot" "no")])
11634
11635 ;; 4 byte floating point
11636 (define_insn "consttable_sf"
11637  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11638                     (match_operand 1 "" "")]
11639                    UNSPECV_CONST4)]
11640  ""
11641 {
11642   if (operands[1] != const0_rtx)
11643     {
11644       REAL_VALUE_TYPE d;
11645       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11646       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11647     }
11648   return "";
11649 }
11650  [(set_attr "length" "4")
11651   (set_attr "in_delay_slot" "no")])
11652
11653 ;; 8 byte floating point
11654 (define_insn "consttable_df"
11655  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11656                     (match_operand 1 "" "")]
11657                    UNSPECV_CONST8)]
11658  ""
11659 {
11660   if (operands[1] != const0_rtx)
11661     {
11662       REAL_VALUE_TYPE d;
11663       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11664       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11665     }
11666   return "";
11667 }
11668  [(set_attr "length" "8")
11669   (set_attr "in_delay_slot" "no")])
11670
11671 ;; Alignment is needed for some constant tables; it may also be added for
11672 ;; Instructions at the start of loops, or after unconditional branches.
11673 ;; ??? We would get more accurate lengths if we did instruction
11674 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11675 ;; here is too conservative.
11676
11677 ;; align to a two byte boundary
11678 (define_expand "align_2"
11679  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11680  ""
11681  "")
11682
11683 ;; Align to a four byte boundary.
11684 ;; align_4 and align_log are instructions for the starts of loops, or
11685 ;; after unconditional branches, which may take up extra room.
11686 (define_expand "align_4"
11687  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11688  ""
11689  "")
11690
11691 ;; Align to a cache line boundary.
11692 (define_insn "align_log"
11693  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11694  ""
11695  ""
11696  [(set_attr "length" "0")
11697   (set_attr "in_delay_slot" "no")])
11698
11699 ;; Emitted at the end of the literal table, used to emit the
11700 ;; 32bit branch labels if needed.
11701 (define_insn "consttable_end"
11702   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11703   ""
11704 {
11705   return output_jump_label_table ();
11706 }
11707   [(set_attr "in_delay_slot" "no")])
11708
11709 ;; Emitted at the end of the window in the literal table.
11710 (define_insn "consttable_window_end"
11711   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11712   ""
11713   ""
11714   [(set_attr "length" "0")
11715    (set_attr "in_delay_slot" "no")])
11716
11717 ;; -------------------------------------------------------------------------
11718 ;; Misc
11719 ;; -------------------------------------------------------------------------
11720
11721 ;; String/block move insn.
11722
11723 (define_expand "movmemsi"
11724   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
11725                    (mem:BLK (match_operand:BLK 1 "" "")))
11726               (use (match_operand:SI 2 "nonmemory_operand" ""))
11727               (use (match_operand:SI 3 "immediate_operand" ""))
11728               (clobber (reg:SI PR_REG))
11729               (clobber (reg:SI R4_REG))
11730               (clobber (reg:SI R5_REG))
11731               (clobber (reg:SI R0_REG))])]
11732   "TARGET_SH1 && ! TARGET_SH5"
11733 {
11734   if(expand_block_move (operands))
11735      DONE;
11736   else FAIL;
11737 })
11738
11739 (define_insn "block_move_real"
11740   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11741                    (mem:BLK (reg:SI R5_REG)))
11742               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11743               (clobber (reg:SI PR_REG))
11744               (clobber (reg:SI R0_REG))])]
11745   "TARGET_SH1 && ! TARGET_HARD_SH4"
11746   "jsr  @%0%#"
11747   [(set_attr "type" "sfunc")
11748    (set_attr "needs_delay_slot" "yes")])
11749
11750 (define_insn "block_lump_real"
11751   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11752                    (mem:BLK (reg:SI R5_REG)))
11753               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11754               (use (reg:SI R6_REG))
11755               (clobber (reg:SI PR_REG))
11756               (clobber (reg:SI T_REG))
11757               (clobber (reg:SI R4_REG))
11758               (clobber (reg:SI R5_REG))
11759               (clobber (reg:SI R6_REG))
11760               (clobber (reg:SI R0_REG))])]
11761   "TARGET_SH1 && ! TARGET_HARD_SH4"
11762   "jsr  @%0%#"
11763   [(set_attr "type" "sfunc")
11764    (set_attr "needs_delay_slot" "yes")])
11765
11766 (define_insn "block_move_real_i4"
11767   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11768                    (mem:BLK (reg:SI R5_REG)))
11769               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11770               (clobber (reg:SI PR_REG))
11771               (clobber (reg:SI R0_REG))
11772               (clobber (reg:SI R1_REG))
11773               (clobber (reg:SI R2_REG))])]
11774   "TARGET_HARD_SH4"
11775   "jsr  @%0%#"
11776   [(set_attr "type" "sfunc")
11777    (set_attr "needs_delay_slot" "yes")])
11778
11779 (define_insn "block_lump_real_i4"
11780   [(parallel [(set (mem:BLK (reg:SI R4_REG))
11781                    (mem:BLK (reg:SI R5_REG)))
11782               (use (match_operand:SI 0 "arith_reg_operand" "r"))
11783               (use (reg:SI R6_REG))
11784               (clobber (reg:SI PR_REG))
11785               (clobber (reg:SI T_REG))
11786               (clobber (reg:SI R4_REG))
11787               (clobber (reg:SI R5_REG))
11788               (clobber (reg:SI R6_REG))
11789               (clobber (reg:SI R0_REG))
11790               (clobber (reg:SI R1_REG))
11791               (clobber (reg:SI R2_REG))
11792               (clobber (reg:SI R3_REG))])]
11793   "TARGET_HARD_SH4"
11794   "jsr  @%0%#"
11795   [(set_attr "type" "sfunc")
11796    (set_attr "needs_delay_slot" "yes")])
11797 \f
11798 ;; -------------------------------------------------------------------------
11799 ;; Floating point instructions.
11800 ;; -------------------------------------------------------------------------
11801
11802 ;; ??? All patterns should have a type attribute.
11803
11804 (define_expand "movpsi"
11805   [(set (match_operand:PSI 0 "register_operand" "")
11806         (match_operand:PSI 1 "general_movsrc_operand" ""))]
11807   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11808   "")
11809
11810 ;; The c / m alternative is a fake to guide reload to load directly into
11811 ;; fpscr, since reload doesn't know how to use post-increment.
11812 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
11813 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
11814 ;; predicate after reload.
11815 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
11816 ;; like a mac -> gpr move.
11817 (define_insn "fpu_switch"
11818   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
11819         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
11820   "TARGET_SH2E
11821    && (! reload_completed
11822        || true_regnum (operands[0]) != FPSCR_REG
11823        || !MEM_P (operands[1])
11824        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
11825   "@
11826         ! precision stays the same
11827         lds.l   %1,fpscr
11828         mov.l   %1,%0
11829         #
11830         lds     %1,fpscr
11831         mov     %1,%0
11832         mov.l   %1,%0
11833         sts     fpscr,%0
11834         sts.l   fpscr,%0"
11835   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
11836    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,
11837                      mac_gp,fstore")])
11838
11839 (define_peephole2
11840   [(set (reg:PSI FPSCR_REG)
11841         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11842   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
11843   [(const_int 0)]
11844 {
11845   rtx fpscr, mem, new_insn;
11846
11847   fpscr = SET_DEST (PATTERN (curr_insn));
11848   mem = SET_SRC (PATTERN (curr_insn));
11849   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11850
11851   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11852   add_reg_note (new_insn, REG_INC, operands[0]);
11853   DONE;
11854 })
11855
11856 (define_split
11857   [(set (reg:PSI FPSCR_REG)
11858         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
11860    && (flag_peephole2 ? epilogue_completed : reload_completed)"
11861   [(const_int 0)]
11862 {
11863   rtx fpscr, mem, new_insn;
11864
11865   fpscr = SET_DEST (PATTERN (curr_insn));
11866   mem = SET_SRC (PATTERN (curr_insn));
11867   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11868
11869   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11870   add_reg_note (new_insn, REG_INC, operands[0]);
11871
11872   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
11873     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
11874   DONE;
11875 })
11876
11877 ;; ??? This uses the fp unit, but has no type indicating that.
11878 ;; If we did that, this would either give a bogus latency or introduce
11879 ;; a bogus FIFO constraint.
11880 ;; Since this insn is currently only used for prologues/epilogues,
11881 ;; it is probably best to claim no function unit, which matches the
11882 ;; current setting.
11883 (define_insn "toggle_sz"
11884   [(set (reg:PSI FPSCR_REG)
11885         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
11886   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11887   "fschg"
11888   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
11889
11890 ;; There's no way we can use it today, since optimize mode switching
11891 ;; doesn't enable us to know from which mode we're switching to the
11892 ;; mode it requests, to tell whether we can use a relative mode switch
11893 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
11894 ;; memory).
11895 (define_insn "toggle_pr"
11896   [(set (reg:PSI FPSCR_REG)
11897         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
11898   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
11899   "fpchg"
11900   [(set_attr "type" "fpscr_toggle")])
11901
11902 (define_expand "addsf3"
11903   [(set (match_operand:SF 0 "arith_reg_operand" "")
11904         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
11905                  (match_operand:SF 2 "arith_reg_operand" "")))]
11906   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11907 {
11908   if (TARGET_SH2E)
11909     {
11910       expand_sf_binop (&gen_addsf3_i, operands);
11911       DONE;
11912     }
11913 })
11914
11915 (define_insn "*addsf3_media"
11916   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11917         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
11918                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11919   "TARGET_SHMEDIA_FPU"
11920   "fadd.s       %1, %2, %0"
11921   [(set_attr "type" "fparith_media")])
11922
11923 (define_insn_and_split "unary_sf_op"
11924   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11925         (vec_select:V2SF
11926          (vec_concat:V2SF
11927           (vec_select:SF
11928            (match_dup 0)
11929            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
11930           (match_operator:SF 2 "unary_float_operator"
11931             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11932                             (parallel [(match_operand 4
11933                                         "const_int_operand" "n")]))]))
11934          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
11935   "TARGET_SHMEDIA_FPU"
11936   "#"
11937   "TARGET_SHMEDIA_FPU && reload_completed"
11938   [(set (match_dup 5) (match_dup 6))]
11939 {
11940   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11941   rtx op1 = gen_rtx_REG (SFmode,
11942                          (true_regnum (operands[1])
11943                           + (INTVAL (operands[4]) ^ endian)));
11944
11945   operands[7] = gen_rtx_REG (SFmode,
11946                              (true_regnum (operands[0])
11947                               + (INTVAL (operands[3]) ^ endian)));
11948   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
11949 }
11950   [(set_attr "type" "fparith_media")])
11951
11952 (define_insn_and_split "binary_sf_op0"
11953   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11954         (vec_concat:V2SF
11955           (match_operator:SF 3 "binary_float_operator"
11956             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11957                             (parallel [(const_int 0)]))
11958              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11959                             (parallel [(const_int 0)]))])
11960           (vec_select:SF
11961            (match_dup 0)
11962            (parallel [(const_int 1)]))))]
11963   "TARGET_SHMEDIA_FPU"
11964   "#"
11965   "&& reload_completed"
11966   [(set (match_dup 4) (match_dup 5))]
11967 {
11968   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11969   rtx op1 = gen_rtx_REG (SFmode,
11970                          true_regnum (operands[1]) + endian);
11971   rtx op2 = gen_rtx_REG (SFmode,
11972                          true_regnum (operands[2]) + endian);
11973
11974   operands[4] = gen_rtx_REG (SFmode,
11975                              true_regnum (operands[0]) + endian);
11976   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11977 }
11978   [(set_attr "type" "fparith_media")])
11979
11980 (define_insn_and_split "binary_sf_op1"
11981   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11982         (vec_concat:V2SF
11983           (vec_select:SF
11984            (match_dup 0)
11985            (parallel [(const_int 0)]))
11986           (match_operator:SF 3 "binary_float_operator"
11987             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11988                             (parallel [(const_int 1)]))
11989              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11990                             (parallel [(const_int 1)]))])))]
11991   "TARGET_SHMEDIA_FPU"
11992   "#"
11993   "&& reload_completed"
11994   [(set (match_dup 4) (match_dup 5))]
11995 {
11996   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11997   rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
11998   rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
11999
12000   operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
12001   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12002 }
12003   [(set_attr "type" "fparith_media")])
12004
12005 (define_insn "addsf3_i"
12006   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12007         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12008                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12009    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12010   "TARGET_SH2E"
12011   "fadd %2,%0"
12012   [(set_attr "type" "fp")
12013    (set_attr "fp_mode" "single")])
12014
12015 (define_expand "subsf3"
12016   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12017         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12018                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12019   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12020 {
12021   if (TARGET_SH2E)
12022     {
12023       expand_sf_binop (&gen_subsf3_i, operands);
12024       DONE;
12025     }
12026 })
12027
12028 (define_insn "*subsf3_media"
12029   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12030         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12031                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12032   "TARGET_SHMEDIA_FPU"
12033   "fsub.s       %1, %2, %0"
12034   [(set_attr "type" "fparith_media")])
12035
12036 (define_insn "subsf3_i"
12037   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12038         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12039                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12040    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12041   "TARGET_SH2E"
12042   "fsub %2,%0"
12043   [(set_attr "type" "fp")
12044    (set_attr "fp_mode" "single")])
12045
12046 (define_expand "mulsf3"
12047   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12048         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12049                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12050   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12051 {
12052   if (TARGET_SH2E)
12053     {
12054       emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2],
12055                  get_fpscr_rtx ()));
12056       DONE;
12057     }
12058 })
12059
12060 (define_insn "*mulsf3_media"
12061   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12062         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12063                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12064   "TARGET_SHMEDIA_FPU"
12065   "fmul.s       %1, %2, %0"
12066   [(set_attr "type" "fparith_media")])
12067
12068 (define_insn "mulsf3_i"
12069   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12070         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12071                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12072    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12073   "TARGET_SH2E"
12074   "fmul %2,%0"
12075   [(set_attr "type" "fp")
12076    (set_attr "fp_mode" "single")])
12077
12078 ;; FMA (fused multiply-add) patterns
12079 (define_expand "fmasf4"
12080   [(set (match_operand:SF 0 "fp_arith_reg_operand")
12081         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand")
12082                 (match_operand:SF 2 "fp_arith_reg_operand")
12083                 (match_operand:SF 3 "fp_arith_reg_operand")))]
12084   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12085 {
12086   if (TARGET_SH2E)
12087     {
12088       emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12089                                   operands[3], get_fpscr_rtx ()));
12090       DONE;
12091     }
12092 })
12093
12094 (define_insn "fmasf4_i"
12095   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12096         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12097                 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12098                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12099    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
12100   "TARGET_SH2E"
12101   "fmac %1,%2,%0"
12102   [(set_attr "type" "fp")
12103    (set_attr "fp_mode" "single")])
12104
12105 (define_insn "fmasf4_media"
12106   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12107         (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12108                 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12109                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12110   "TARGET_SHMEDIA_FPU"
12111   "fmac.s %1, %2, %0"
12112   [(set_attr "type" "fparith_media")])
12113
12114 ;; For some cases such as 'a * b + a' the FMA pattern is not generated by
12115 ;; previous transformations.  If FMA is generally allowed, let the combine
12116 ;; pass utilize it.
12117 (define_insn_and_split "*fmasf4"
12118   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12119         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
12120                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12121                  (match_operand:SF 3 "arith_reg_operand" "0")))
12122    (use (match_operand:PSI 4 "fpscr_operand"))]
12123   "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
12124   "fmac %1,%2,%0"
12125   "&& can_create_pseudo_p ()"
12126   [(parallel [(set (match_dup 0)
12127                    (fma:SF (match_dup 1) (match_dup 2) (match_dup 3)))
12128               (use (match_dup 4))])]
12129 {
12130   /* Change 'b * a + a' into 'a * b + a'.
12131      This is better for register allocation.  */
12132   if (REGNO (operands[2]) == REGNO (operands[3]))
12133     {
12134       rtx tmp = operands[1];
12135       operands[1] = operands[2];
12136       operands[2] = tmp;
12137     }
12138 }
12139   [(set_attr "type" "fp")
12140    (set_attr "fp_mode" "single")])
12141
12142 (define_insn "*fmasf4_media"
12143   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12144         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12145                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12146                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12147   "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF"
12148   "fmac.s %1, %2, %0"
12149   [(set_attr "type" "fparith_media")])
12150
12151 (define_expand "divsf3"
12152   [(set (match_operand:SF 0 "arith_reg_operand" "")
12153         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
12154                 (match_operand:SF 2 "arith_reg_operand" "")))]
12155   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12156 {
12157   if (TARGET_SH2E)
12158     {
12159       expand_sf_binop (&gen_divsf3_i, operands);
12160       DONE;
12161     }
12162 })
12163
12164 (define_insn "*divsf3_media"
12165   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12166         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12167                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12168   "TARGET_SHMEDIA_FPU"
12169   "fdiv.s       %1, %2, %0"
12170   [(set_attr "type" "fdiv_media")])
12171
12172 (define_insn "divsf3_i"
12173   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
12174         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
12175                  (match_operand:SF 2 "arith_reg_operand" "f")))
12176    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12177   "TARGET_SH2E"
12178   "fdiv %2,%0"
12179   [(set_attr "type" "fdiv")
12180    (set_attr "fp_mode" "single")])
12181
12182 (define_insn "floatdisf2"
12183   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12184         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12185   "TARGET_SHMEDIA_FPU"
12186   "float.qs %1, %0"
12187   [(set_attr "type" "fpconv_media")])
12188
12189 (define_expand "floatsisf2"
12190   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12191         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12192   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12193 {
12194   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12195     {
12196       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1],
12197                                        get_fpscr_rtx ()));
12198       DONE;
12199     }
12200 })
12201
12202 (define_insn "*floatsisf2_media"
12203   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12204         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12205   "TARGET_SHMEDIA_FPU"
12206   "float.ls     %1, %0"
12207   [(set_attr "type" "fpconv_media")])
12208
12209 (define_insn "floatsisf2_i4"
12210   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12211         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12212    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12213   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12214   "float        %1,%0"
12215   [(set_attr "type" "fp")
12216    (set_attr "fp_mode" "single")])
12217
12218 (define_insn "*floatsisf2_ie"
12219   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12220         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
12221   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12222   "float        %1,%0"
12223   [(set_attr "type" "fp")])
12224
12225 (define_insn "fix_truncsfdi2"
12226   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12227         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12228   "TARGET_SHMEDIA_FPU"
12229   "ftrc.sq %1, %0"
12230   [(set_attr "type" "fpconv_media")])
12231
12232 (define_expand "fix_truncsfsi2"
12233   [(set (match_operand:SI 0 "fpul_operand" "=y")
12234         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12235   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12236 {
12237   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12238     {
12239       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1],
12240                                            get_fpscr_rtx ()));
12241       DONE;
12242     }
12243 })
12244
12245 (define_insn "*fix_truncsfsi2_media"
12246   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12247         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12248   "TARGET_SHMEDIA_FPU"
12249   "ftrc.sl      %1, %0"
12250   [(set_attr "type" "fpconv_media")])
12251
12252 (define_insn "fix_truncsfsi2_i4"
12253   [(set (match_operand:SI 0 "fpul_operand" "=y")
12254         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12255    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12256   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12257   "ftrc %1,%0"
12258   [(set_attr "type" "ftrc_s")
12259    (set_attr "fp_mode" "single")])
12260
12261 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
12262 ;; fix_truncsfsi2_i4.
12263 ;; (define_insn "fix_truncsfsi2_i4_2"
12264 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12265 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12266 ;;   (use (reg:PSI FPSCR_REG))
12267 ;;   (clobber (reg:SI FPUL_REG))]
12268 ;;  "TARGET_SH4"
12269 ;;  "#"
12270 ;;  [(set_attr "length" "4")
12271 ;;   (set_attr "fp_mode" "single")])
12272
12273 ;;(define_split
12274 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12275 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12276 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
12277 ;;   (clobber (reg:SI FPUL_REG))]
12278 ;;  "TARGET_SH4"
12279 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12280 ;;            (use (match_dup 2))])
12281 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
12282
12283 (define_insn "*fixsfsi"
12284   [(set (match_operand:SI 0 "fpul_operand" "=y")
12285         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12286   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12287   "ftrc %1,%0"
12288   [(set_attr "type" "fp")])
12289
12290 (define_insn "cmpgtsf_t"
12291   [(set (reg:SI T_REG)
12292         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12293                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12294   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12295   "fcmp/gt      %1,%0"
12296   [(set_attr "type" "fp_cmp")
12297    (set_attr "fp_mode" "single")])
12298
12299 (define_insn "cmpeqsf_t"
12300   [(set (reg:SI T_REG)
12301         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12302                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12303   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12304   "fcmp/eq      %1,%0"
12305   [(set_attr "type" "fp_cmp")
12306    (set_attr "fp_mode" "single")])
12307
12308 (define_insn "ieee_ccmpeqsf_t"
12309   [(set (reg:SI T_REG)
12310         (ior:SI (reg:SI T_REG)
12311                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12312                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
12313   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12314 {
12315   return output_ieee_ccmpeq (insn, operands);
12316 }
12317   [(set_attr "length" "4")])
12318
12319
12320 (define_insn "cmpgtsf_t_i4"
12321   [(set (reg:SI T_REG)
12322         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12323                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12324    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12325   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12326   "fcmp/gt      %1,%0"
12327   [(set_attr "type" "fp_cmp")
12328    (set_attr "fp_mode" "single")])
12329
12330 (define_insn "cmpeqsf_t_i4"
12331   [(set (reg:SI T_REG)
12332         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12333                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12334    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12335   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12336   "fcmp/eq      %1,%0"
12337   [(set_attr "type" "fp_cmp")
12338    (set_attr "fp_mode" "single")])
12339
12340 (define_insn "*ieee_ccmpeqsf_t_4"
12341   [(set (reg:SI T_REG)
12342         (ior:SI (reg:SI T_REG)
12343                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12344                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12345    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12346   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12347 {
12348   return output_ieee_ccmpeq (insn, operands);
12349 }
12350   [(set_attr "length" "4")
12351    (set_attr "fp_mode" "single")])
12352
12353 (define_insn "cmpeqsf_media"
12354   [(set (match_operand:SI 0 "register_operand" "=r")
12355         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12356                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12357   "TARGET_SHMEDIA_FPU"
12358   "fcmpeq.s     %1, %2, %0"
12359   [(set_attr "type" "fcmp_media")])
12360
12361 (define_insn "cmpgtsf_media"
12362   [(set (match_operand:SI 0 "register_operand" "=r")
12363         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12364                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12365   "TARGET_SHMEDIA_FPU"
12366   "fcmpgt.s     %1, %2, %0"
12367   [(set_attr "type" "fcmp_media")])
12368
12369 (define_insn "cmpgesf_media"
12370   [(set (match_operand:SI 0 "register_operand" "=r")
12371         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12372                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12373   "TARGET_SHMEDIA_FPU"
12374   "fcmpge.s     %1, %2, %0"
12375   [(set_attr "type" "fcmp_media")])
12376
12377 (define_insn "cmpunsf_media"
12378   [(set (match_operand:SI 0 "register_operand" "=r")
12379         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12380                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12381   "TARGET_SHMEDIA_FPU"
12382   "fcmpun.s     %1, %2, %0"
12383   [(set_attr "type" "fcmp_media")])
12384
12385 (define_expand "cbranchsf4"
12386   [(set (pc)
12387         (if_then_else (match_operator 0 "sh_float_comparison_operator"
12388                        [(match_operand:SF 1 "arith_operand" "")
12389                         (match_operand:SF 2 "arith_operand" "")])
12390                       (match_operand 3 "" "")
12391                       (pc)))]
12392   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12393 {
12394   if (TARGET_SHMEDIA)
12395     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12396                                           operands[3]));
12397   else
12398     sh_emit_compare_and_branch (operands, SFmode);
12399   DONE;
12400 })
12401
12402 (define_expand "negsf2"
12403   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12404         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12405   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12406 {
12407   if (TARGET_SH2E)
12408     {
12409       expand_sf_unop (&gen_negsf2_i, operands);
12410       DONE;
12411     }
12412 })
12413
12414 (define_insn "*negsf2_media"
12415   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12416         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12417   "TARGET_SHMEDIA_FPU"
12418   "fneg.s       %1, %0"
12419   [(set_attr "type" "fmove_media")])
12420
12421 (define_insn "negsf2_i"
12422   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12423         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12424    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12425   "TARGET_SH2E"
12426   "fneg %0"
12427   [(set_attr "type" "fmove")
12428    (set_attr "fp_mode" "single")])
12429
12430 (define_expand "sqrtsf2"
12431   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12432         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12433   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12434 {
12435   if (TARGET_SH3E)
12436     {
12437       expand_sf_unop (&gen_sqrtsf2_i, operands);
12438       DONE;
12439     }
12440 })
12441
12442 (define_insn "*sqrtsf2_media"
12443   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12444         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12445   "TARGET_SHMEDIA_FPU"
12446   "fsqrt.s      %1, %0"
12447   [(set_attr "type" "fdiv_media")])
12448
12449 (define_insn "sqrtsf2_i"
12450   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12451         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12452    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12453   "TARGET_SH3E"
12454   "fsqrt        %0"
12455   [(set_attr "type" "fdiv")
12456    (set_attr "fp_mode" "single")])
12457
12458 (define_insn "rsqrtsf2"
12459   [(set (match_operand:SF 0 "register_operand" "=f")
12460         (div:SF (match_operand:SF 1 "immediate_operand" "i")
12461                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
12462    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12463   "TARGET_FPU_ANY && TARGET_FSRRA
12464    && operands[1] == CONST1_RTX (SFmode)"
12465   "fsrra        %0"
12466   [(set_attr "type" "fsrra")
12467    (set_attr "fp_mode" "single")])
12468
12469 ;; When the sincos pattern is defined, the builtin functions sin and cos
12470 ;; will be expanded to the sincos pattern and one of the output values will
12471 ;; remain unused.
12472 (define_expand "sincossf3"
12473   [(set (match_operand:SF 0 "nonimmediate_operand")
12474         (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12475    (set (match_operand:SF 1 "nonimmediate_operand")
12476         (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12477   "TARGET_FPU_ANY && TARGET_FSCA"
12478 {
12479   rtx scaled = gen_reg_rtx (SFmode);
12480   rtx truncated = gen_reg_rtx (SImode);
12481   rtx fsca = gen_reg_rtx (V2SFmode);
12482   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12483
12484   emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12485   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
12486   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
12487                           get_fpscr_rtx ()));
12488
12489   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12490   emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12491   DONE;
12492 })
12493
12494 (define_insn_and_split "fsca"
12495   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12496         (vec_concat:V2SF
12497          (unspec:SF [(mult:SF
12498                       (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12499                       (match_operand:SF 2 "fsca_scale_factor" "i"))
12500                     ] UNSPEC_FSINA)
12501          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12502                     ] UNSPEC_FCOSA)))
12503    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12504   "TARGET_FPU_ANY && TARGET_FSCA"
12505   "fsca fpul,%d0"
12506   "&& !fpul_operand (operands[1], SImode)"
12507   [(const_int 0)]
12508 {
12509   /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12510      to a simple reg, otherwise reload will have trouble reloading the
12511      pseudo into fpul.  */
12512   rtx x = XEXP (operands[1], 0);
12513   while (x != NULL_RTX && !fpul_operand (x, SImode))
12514     {
12515       gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12516       x = XEXP (x, 0);
12517     }
12518
12519   gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12520   emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
12521   DONE;
12522 }
12523   [(set_attr "type" "fsca")
12524    (set_attr "fp_mode" "single")])
12525
12526 (define_expand "abssf2"
12527   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12528         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12529   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12530 {
12531   if (TARGET_SH2E)
12532     {
12533       expand_sf_unop (&gen_abssf2_i, operands);
12534       DONE;
12535     }
12536 })
12537
12538 (define_insn "*abssf2_media"
12539   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12540         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12541   "TARGET_SHMEDIA_FPU"
12542   "fabs.s       %1, %0"
12543   [(set_attr "type" "fmove_media")])
12544
12545 (define_insn "abssf2_i"
12546   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12547         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12548    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12549   "TARGET_SH2E"
12550   "fabs %0"
12551   [(set_attr "type" "fmove")
12552    (set_attr "fp_mode" "single")])
12553
12554 (define_expand "adddf3"
12555   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12556         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12557                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12558   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12559 {
12560   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12561     {
12562       expand_df_binop (&gen_adddf3_i, operands);
12563       DONE;
12564     }
12565 })
12566
12567 (define_insn "*adddf3_media"
12568   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12569         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12570                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12571   "TARGET_SHMEDIA_FPU"
12572   "fadd.d       %1, %2, %0"
12573   [(set_attr "type" "dfparith_media")])
12574
12575 (define_insn "adddf3_i"
12576   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12577         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12578                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12579    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12580   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12581   "fadd %2,%0"
12582   [(set_attr "type" "dfp_arith")
12583    (set_attr "fp_mode" "double")])
12584
12585 (define_expand "subdf3"
12586   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12587         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12588                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12589   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12590 {
12591   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12592     {
12593       expand_df_binop (&gen_subdf3_i, operands);
12594       DONE;
12595     }
12596 })
12597
12598 (define_insn "*subdf3_media"
12599   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12600         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12601                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12602   "TARGET_SHMEDIA_FPU"
12603   "fsub.d       %1, %2, %0"
12604   [(set_attr "type" "dfparith_media")])
12605
12606 (define_insn "subdf3_i"
12607   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12608         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12609                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12610    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12611   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12612   "fsub %2,%0"
12613   [(set_attr "type" "dfp_arith")
12614    (set_attr "fp_mode" "double")])
12615
12616 (define_expand "muldf3"
12617   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12618         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12619                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12620   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12621 {
12622   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12623     {
12624       expand_df_binop (&gen_muldf3_i, operands);
12625       DONE;
12626     }
12627 })
12628
12629 (define_insn "*muldf3_media"
12630   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12631         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12632                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12633   "TARGET_SHMEDIA_FPU"
12634   "fmul.d       %1, %2, %0"
12635   [(set_attr "type" "dfmul_media")])
12636
12637 (define_insn "muldf3_i"
12638   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12639         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12640                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12641    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12642   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12643   "fmul %2,%0"
12644   [(set_attr "type" "dfp_mul")
12645    (set_attr "fp_mode" "double")])
12646
12647 (define_expand "divdf3"
12648   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12649         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12650                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12651   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12652 {
12653   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12654     {
12655       expand_df_binop (&gen_divdf3_i, operands);
12656       DONE;
12657     }
12658 })
12659
12660 (define_insn "*divdf3_media"
12661   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12662         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12663                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12664   "TARGET_SHMEDIA_FPU"
12665   "fdiv.d       %1, %2, %0"
12666   [(set_attr "type" "dfdiv_media")])
12667
12668 (define_insn "divdf3_i"
12669   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12670         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12671                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12672    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12673   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12674   "fdiv %2,%0"
12675   [(set_attr "type" "dfdiv")
12676    (set_attr "fp_mode" "double")])
12677
12678 (define_insn "floatdidf2"
12679   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12680         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12681   "TARGET_SHMEDIA_FPU"
12682   "float.qd     %1, %0"
12683   [(set_attr "type" "dfpconv_media")])
12684
12685 (define_expand "floatsidf2"
12686   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12687         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
12688   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12689 {
12690   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12691     {
12692       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
12693                                       get_fpscr_rtx ()));
12694       DONE;
12695     }
12696 })
12697
12698 (define_insn "*floatsidf2_media"
12699   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12700         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12701   "TARGET_SHMEDIA_FPU"
12702   "float.ld     %1, %0"
12703   [(set_attr "type" "dfpconv_media")])
12704
12705 (define_insn "floatsidf2_i"
12706   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12707         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
12708    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12709   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12710   "float        %1,%0"
12711   [(set_attr "type" "dfp_conv")
12712    (set_attr "fp_mode" "double")])
12713
12714 (define_insn "fix_truncdfdi2"
12715   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12716         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12717   "TARGET_SHMEDIA_FPU"
12718   "ftrc.dq      %1, %0"
12719   [(set_attr "type" "dfpconv_media")])
12720
12721 (define_expand "fix_truncdfsi2"
12722   [(set (match_operand:SI 0 "fpul_operand" "")
12723         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12724   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12725 {
12726   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12727     {
12728       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
12729                                           get_fpscr_rtx ()));
12730       DONE;
12731     }
12732 })
12733
12734 (define_insn "*fix_truncdfsi2_media"
12735   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12736         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12737   "TARGET_SHMEDIA_FPU"
12738   "ftrc.dl      %1, %0"
12739   [(set_attr "type" "dfpconv_media")])
12740
12741 (define_insn "fix_truncdfsi2_i"
12742   [(set (match_operand:SI 0 "fpul_operand" "=y")
12743         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12744    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12745   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12746   "ftrc %1,%0"
12747   [(set_attr "type" "dfp_conv")
12748    (set_attr "dfp_comp" "no")
12749    (set_attr "fp_mode" "double")])
12750
12751 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
12752 ;; fix_truncdfsi2_i.
12753 ;; (define_insn "fix_truncdfsi2_i4"
12754 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12755 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12756 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
12757 ;;    (clobber (reg:SI FPUL_REG))]
12758 ;;   "TARGET_SH4"
12759 ;;   "#"
12760 ;;   [(set_attr "length" "4")
12761 ;;    (set_attr "fp_mode" "double")])
12762 ;;
12763 ;; (define_split
12764 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12765 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12766 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
12767 ;;    (clobber (reg:SI FPUL_REG))]
12768 ;;   "TARGET_SH4"
12769 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12770 ;;            (use (match_dup 2))])
12771 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
12772
12773 (define_insn "cmpgtdf_t"
12774   [(set (reg:SI T_REG)
12775         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
12776                (match_operand:DF 1 "arith_reg_operand" "f")))
12777    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12778   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12779   "fcmp/gt      %1,%0"
12780   [(set_attr "type" "dfp_cmp")
12781    (set_attr "fp_mode" "double")])
12782
12783 (define_insn "cmpeqdf_t"
12784   [(set (reg:SI T_REG)
12785         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12786                (match_operand:DF 1 "arith_reg_operand" "f")))
12787    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12788   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12789   "fcmp/eq      %1,%0"
12790   [(set_attr "type" "dfp_cmp")
12791    (set_attr "fp_mode" "double")])
12792
12793 (define_insn "*ieee_ccmpeqdf_t"
12794   [(set (reg:SI T_REG)
12795         (ior:SI (reg:SI T_REG)
12796                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12797                        (match_operand:DF 1 "arith_reg_operand" "f"))))
12798    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12799   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12800 {
12801   return output_ieee_ccmpeq (insn, operands);
12802 }
12803   [(set_attr "length" "4")
12804    (set_attr "fp_mode" "double")])
12805
12806 (define_insn "cmpeqdf_media"
12807   [(set (match_operand:SI 0 "register_operand" "=r")
12808         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12809                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12810   "TARGET_SHMEDIA_FPU"
12811   "fcmpeq.d     %1,%2,%0"
12812   [(set_attr "type" "fcmp_media")])
12813
12814 (define_insn "cmpgtdf_media"
12815   [(set (match_operand:SI 0 "register_operand" "=r")
12816         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12817                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12818   "TARGET_SHMEDIA_FPU"
12819   "fcmpgt.d     %1,%2,%0"
12820   [(set_attr "type" "fcmp_media")])
12821
12822 (define_insn "cmpgedf_media"
12823   [(set (match_operand:SI 0 "register_operand" "=r")
12824         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12825                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12826   "TARGET_SHMEDIA_FPU"
12827   "fcmpge.d     %1,%2,%0"
12828   [(set_attr "type" "fcmp_media")])
12829
12830 (define_insn "cmpundf_media"
12831   [(set (match_operand:SI 0 "register_operand" "=r")
12832         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12833                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12834   "TARGET_SHMEDIA_FPU"
12835   "fcmpun.d     %1,%2,%0"
12836   [(set_attr "type" "fcmp_media")])
12837
12838 (define_expand "cbranchdf4"
12839   [(set (pc)
12840         (if_then_else (match_operator 0 "sh_float_comparison_operator"
12841                        [(match_operand:DF 1 "arith_operand" "")
12842                         (match_operand:DF 2 "arith_operand" "")])
12843                       (match_operand 3 "" "")
12844                       (pc)))]
12845   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12846 {
12847   if (TARGET_SHMEDIA)
12848     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12849                                           operands[3]));
12850   else
12851     sh_emit_compare_and_branch (operands, DFmode);
12852   DONE;
12853 })
12854
12855
12856 (define_expand "negdf2"
12857   [(set (match_operand:DF 0 "arith_reg_operand" "")
12858         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12860 {
12861   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12862     {
12863       expand_df_unop (&gen_negdf2_i, operands);
12864       DONE;
12865     }
12866 })
12867
12868 (define_insn "*negdf2_media"
12869   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12870         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12871   "TARGET_SHMEDIA_FPU"
12872   "fneg.d       %1, %0"
12873   [(set_attr "type" "fmove_media")])
12874
12875 (define_insn "negdf2_i"
12876   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12877         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12878    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12879   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12880   "fneg %0"
12881   [(set_attr "type" "fmove")
12882    (set_attr "fp_mode" "double")])
12883
12884 (define_expand "sqrtdf2"
12885   [(set (match_operand:DF 0 "arith_reg_operand" "")
12886         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12887   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12888 {
12889   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12890     {
12891       expand_df_unop (&gen_sqrtdf2_i, operands);
12892       DONE;
12893     }
12894 })
12895
12896 (define_insn "*sqrtdf2_media"
12897   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12898         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12899   "TARGET_SHMEDIA_FPU"
12900   "fsqrt.d      %1, %0"
12901   [(set_attr "type" "dfdiv_media")])
12902
12903 (define_insn "sqrtdf2_i"
12904   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12905         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12906    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12907   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12908   "fsqrt        %0"
12909   [(set_attr "type" "dfdiv")
12910    (set_attr "fp_mode" "double")])
12911
12912 (define_expand "absdf2"
12913   [(set (match_operand:DF 0 "arith_reg_operand" "")
12914         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12915   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12916 {
12917   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12918     {
12919       expand_df_unop (&gen_absdf2_i, operands);
12920       DONE;
12921     }
12922 })
12923
12924 (define_insn "*absdf2_media"
12925   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12926         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12927   "TARGET_SHMEDIA_FPU"
12928   "fabs.d       %1, %0"
12929   [(set_attr "type" "fmove_media")])
12930
12931 (define_insn "absdf2_i"
12932   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12933         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12934    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12935   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12936   "fabs %0"
12937   [(set_attr "type" "fmove")
12938    (set_attr "fp_mode" "double")])
12939
12940 (define_expand "extendsfdf2"
12941   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12942         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
12943   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12944 {
12945   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12946     {
12947       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
12948                                         get_fpscr_rtx ()));
12949       DONE;
12950     }
12951 })
12952
12953 (define_insn "*extendsfdf2_media"
12954   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12955         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12956   "TARGET_SHMEDIA_FPU"
12957   "fcnv.sd      %1, %0"
12958   [(set_attr "type" "dfpconv_media")])
12959
12960 (define_insn "extendsfdf2_i4"
12961   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12962         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
12963    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12964   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12965   "fcnvsd  %1,%0"
12966   [(set_attr "type" "fp")
12967    (set_attr "fp_mode" "double")])
12968
12969 (define_expand "truncdfsf2"
12970   [(set (match_operand:SF 0 "fpul_operand" "")
12971         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12972   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12973 {
12974   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12975     {
12976       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
12977                                        get_fpscr_rtx ()));
12978       DONE;
12979     }
12980 })
12981
12982 (define_insn "*truncdfsf2_media"
12983   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12984         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12985   "TARGET_SHMEDIA_FPU"
12986   "fcnv.ds      %1, %0"
12987   [(set_attr "type" "dfpconv_media")])
12988
12989 (define_insn "truncdfsf2_i4"
12990   [(set (match_operand:SF 0 "fpul_operand" "=y")
12991         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12992    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12993   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12994   "fcnvds  %1,%0"
12995   [(set_attr "type" "fp")
12996    (set_attr "fp_mode" "double")])
12997 \f
12998 ;; -------------------------------------------------------------------------
12999 ;; Bit field extract patterns.
13000 ;; -------------------------------------------------------------------------
13001
13002 ;; These give better code for packed bitfields,  because they allow
13003 ;; auto-increment addresses to be generated.
13004
13005 (define_expand "insv"
13006   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
13007                          (match_operand:SI 1 "immediate_operand" "")
13008                          (match_operand:SI 2 "immediate_operand" ""))
13009         (match_operand:SI 3 "general_operand" ""))]
13010   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
13011 {
13012   rtx addr_target, orig_address, shift_reg, qi_val;
13013   HOST_WIDE_INT bitsize, size, v = 0;
13014   rtx x = operands[3];
13015
13016   if (TARGET_SH2A && TARGET_BITOPS
13017       && (satisfies_constraint_Sbw (operands[0])
13018           || satisfies_constraint_Sbv (operands[0]))
13019       && satisfies_constraint_M (operands[1])
13020       && satisfies_constraint_K03 (operands[2]))
13021     {
13022       if (satisfies_constraint_N (operands[3]))
13023         {
13024           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
13025           DONE;
13026         }
13027       else if (satisfies_constraint_M (operands[3]))
13028         {
13029           emit_insn (gen_bset_m2a (operands[0], operands[2]));
13030           DONE;
13031         }
13032       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
13033                 && satisfies_constraint_M (operands[1]))
13034         {
13035           emit_insn (gen_bst_m2a (operands[0], operands[2]));
13036           DONE;
13037         }
13038       else if (REG_P (operands[3])
13039                && satisfies_constraint_M (operands[1]))
13040         {
13041           emit_insn (gen_bld_reg (operands[3], const0_rtx));
13042           emit_insn (gen_bst_m2a (operands[0], operands[2]));
13043           DONE;
13044         }
13045     }
13046   /* ??? expmed doesn't care for non-register predicates.  */
13047   if (! memory_operand (operands[0], VOIDmode)
13048       || ! immediate_operand (operands[1], VOIDmode)
13049       || ! immediate_operand (operands[2], VOIDmode)
13050       || ! general_operand (x, VOIDmode))
13051     FAIL;
13052   /* If this isn't a 16 / 24 / 32 bit field, or if
13053      it doesn't start on a byte boundary, then fail.  */
13054   bitsize = INTVAL (operands[1]);
13055   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13056       || (INTVAL (operands[2]) % 8) != 0)
13057     FAIL;
13058
13059   size = bitsize / 8;
13060   orig_address = XEXP (operands[0], 0);
13061   shift_reg = gen_reg_rtx (SImode);
13062   if (CONST_INT_P (x))
13063     {
13064       v = INTVAL (x);
13065       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13066     }
13067   else
13068     {
13069       emit_insn (gen_movsi (shift_reg, operands[3]));
13070       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13071     }
13072   addr_target = copy_addr_to_reg (plus_constant (Pmode,
13073                                                  orig_address, size - 1));
13074
13075   operands[0] = replace_equiv_address (operands[0], addr_target);
13076   emit_insn (gen_movqi (operands[0], qi_val));
13077
13078   while (size -= 1)
13079     {
13080       if (CONST_INT_P (x))
13081         qi_val
13082           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13083       else
13084         {
13085           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13086           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13087         }
13088       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13089       emit_insn (gen_movqi (operands[0], qi_val));
13090     }
13091
13092   DONE;
13093 })
13094
13095 (define_insn "movua"
13096   [(set (match_operand:SI 0 "register_operand" "=z")
13097         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13098                    UNSPEC_MOVUA))]
13099   "TARGET_SH4A_ARCH"
13100   "movua.l      %1,%0"
13101   [(set_attr "type" "movua")])
13102
13103 ;; We shouldn't need this, but cse replaces increments with references
13104 ;; to other regs before flow has a chance to create post_inc
13105 ;; addressing modes, and only postreload's cse_move2add brings the
13106 ;; increments back to a usable form.
13107 (define_peephole2
13108   [(set (match_operand:SI 0 "register_operand" "")
13109         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13110                          (const_int 32) (const_int 0)))
13111    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13112   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
13113   [(set (match_operand:SI 0 "register_operand" "")
13114         (sign_extract:SI (mem:SI (post_inc:SI
13115                                   (match_operand:SI 1 "register_operand" "")))
13116                          (const_int 32) (const_int 0)))]
13117   "")
13118
13119 (define_expand "extv"
13120   [(set (match_operand:SI 0 "register_operand" "")
13121         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13122                          (match_operand 2 "const_int_operand" "")
13123                          (match_operand 3 "const_int_operand" "")))]
13124   "TARGET_SH4A_ARCH || TARGET_SH2A"
13125 {
13126   if (TARGET_SH2A && TARGET_BITOPS
13127       && (satisfies_constraint_Sbw (operands[1])
13128           || satisfies_constraint_Sbv (operands[1]))
13129       && satisfies_constraint_M (operands[2])
13130       && satisfies_constraint_K03 (operands[3]))
13131    {
13132       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13133       if (REGNO (operands[0]) != T_REG)
13134         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13135       DONE;
13136    }
13137   if (TARGET_SH4A_ARCH
13138       && INTVAL (operands[2]) == 32
13139       && INTVAL (operands[3]) == 0
13140       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13141     {
13142       rtx src = adjust_address (operands[1], BLKmode, 0);
13143       set_mem_size (src, 4);
13144       emit_insn (gen_movua (operands[0], src));
13145       DONE;
13146     }
13147
13148   FAIL;
13149 })
13150
13151 (define_expand "extzv"
13152   [(set (match_operand:SI 0 "register_operand" "")
13153         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13154                          (match_operand 2 "const_int_operand" "")
13155                          (match_operand 3 "const_int_operand" "")))]
13156   "TARGET_SH4A_ARCH || TARGET_SH2A"
13157 {
13158   if (TARGET_SH2A && TARGET_BITOPS
13159       && (satisfies_constraint_Sbw (operands[1])
13160           || satisfies_constraint_Sbv (operands[1]))
13161       && satisfies_constraint_M (operands[2])
13162       && satisfies_constraint_K03 (operands[3]))
13163     {
13164       emit_insn (gen_bld_m2a (operands[1], operands[3]));
13165       if (REGNO (operands[0]) != T_REG)
13166         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13167       DONE;
13168     }
13169   if (TARGET_SH4A_ARCH
13170       && INTVAL (operands[2]) == 32
13171       && INTVAL (operands[3]) == 0
13172       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13173     {
13174       rtx src = adjust_address (operands[1], BLKmode, 0);
13175       set_mem_size (src, 4);
13176       emit_insn (gen_movua (operands[0], src));
13177       DONE;
13178     }
13179
13180   FAIL;
13181 })
13182
13183 ;; SH2A instructions for bitwise operations.
13184 ;; FIXME: Convert multiple instruction insns to insn_and_split.
13185 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
13186
13187 ;; Clear a bit in a memory location.
13188 (define_insn "bclr_m2a"
13189   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13190         (and:QI
13191             (not:QI (ashift:QI (const_int 1)
13192                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
13193             (match_dup 0)))]
13194   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13195   "@
13196         bclr.b  %1,%0
13197         bclr.b  %1,@(0,%t0)"
13198 [(set_attr "length" "4,4")])
13199
13200 (define_insn "bclrmem_m2a"
13201   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13202         (and:QI (match_dup 0)
13203                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13204   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13205   "@
13206         bclr.b  %W1,%0
13207         bclr.b  %W1,@(0,%t0)"
13208   [(set_attr "length" "4,4")])
13209
13210 ;; Set a bit in a memory location.
13211 (define_insn "bset_m2a"
13212   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13213         (ior:QI
13214             (ashift:QI (const_int 1)
13215                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
13216             (match_dup 0)))]
13217   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13218   "@
13219         bset.b  %1,%0
13220         bset.b  %1,@(0,%t0)"
13221   [(set_attr "length" "4,4")])
13222
13223 (define_insn "bsetmem_m2a"
13224   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13225         (ior:QI (match_dup 0)
13226                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13227   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13228   "@
13229         bset.b  %V1,%0
13230         bset.b  %V1,@(0,%t0)"
13231   [(set_attr "length" "4,4")])
13232
13233 ;;; Transfer the contents of the T bit to a specified bit of memory.
13234 (define_insn "bst_m2a"
13235   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13236         (if_then_else (eq (reg:SI T_REG) (const_int 0))
13237             (and:QI
13238                 (not:QI (ashift:QI (const_int 1)
13239                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
13240                 (match_dup 0))
13241             (ior:QI
13242                 (ashift:QI (const_int 1) (match_dup 1))
13243                 (match_dup 0))))]
13244   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13245   "@
13246         bst.b   %1,%0
13247         bst.b   %1,@(0,%t0)"
13248   [(set_attr "length" "4")])
13249
13250 ;; Store a specified bit of memory in the T bit.
13251 (define_insn "bld_m2a"
13252   [(set (reg:SI T_REG)
13253         (zero_extract:SI
13254             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13255             (const_int 1)
13256             (match_operand 1 "const_int_operand" "K03,K03")))]
13257   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13258   "@
13259         bld.b   %1,%0
13260         bld.b   %1,@(0,%t0)"
13261   [(set_attr "length" "4,4")])
13262
13263 ;; Store a specified bit of memory in the T bit.
13264 (define_insn "bldsign_m2a"
13265   [(set (reg:SI T_REG)
13266         (sign_extract:SI
13267             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13268             (const_int 1)
13269             (match_operand 1 "const_int_operand" "K03,K03")))]
13270   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13271   "@
13272         bld.b   %1,%0
13273         bld.b   %1,@(0,%t0)"
13274   [(set_attr "length" "4,4")])
13275
13276 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13277 (define_insn "bld_reg"
13278   [(set (reg:SI T_REG)
13279         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13280                          (const_int 1)
13281                          (match_operand 1 "const_int_operand" "K03")))]
13282   "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13283   "bld  %1,%0")
13284
13285 (define_insn "*bld_regqi"
13286   [(set (reg:SI T_REG)
13287         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13288                          (const_int 1)
13289                          (match_operand 1 "const_int_operand" "K03")))]
13290   "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13291   "bld  %1,%0")
13292
13293 ;; Take logical and of a specified bit of memory with the T bit and
13294 ;; store its result in the T bit.
13295 (define_insn "band_m2a"
13296   [(set (reg:SI T_REG)
13297         (and:SI (reg:SI T_REG)
13298                 (zero_extract:SI
13299                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13300                     (const_int 1)
13301                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13302   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13303   "@
13304         band.b  %1,%0
13305         band.b  %1,@(0,%t0)"
13306   [(set_attr "length" "4,4")])
13307
13308 (define_insn "bandreg_m2a"
13309   [(set (match_operand:SI 0 "register_operand" "=r,r")
13310         (and:SI (zero_extract:SI
13311                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13312                     (const_int 1)
13313                     (match_operand 2 "const_int_operand" "K03,K03"))
13314                 (match_operand:SI 3 "register_operand" "r,r")))]
13315   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13316 {
13317   static const char* alt[] =
13318   {
13319        "band.b  %2,%1"          "\n"
13320     "   movt    %0",
13321
13322        "band.b  %2,@(0,%t1)"    "\n"
13323     "   movt    %0"
13324   };
13325   return alt[which_alternative];
13326 }
13327   [(set_attr "length" "6,6")])
13328
13329 ;; Take logical or of a specified bit of memory with the T bit and
13330 ;; store its result in the T bit.
13331 (define_insn "bor_m2a"
13332   [(set (reg:SI T_REG)
13333         (ior:SI (reg:SI T_REG)
13334                 (zero_extract:SI
13335                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13336                     (const_int 1)
13337                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13338   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13339   "@
13340         bor.b   %1,%0
13341         bor.b   %1,@(0,%t0)"
13342   [(set_attr "length" "4,4")])
13343
13344 (define_insn "borreg_m2a"
13345   [(set (match_operand:SI 0 "register_operand" "=r,r")
13346         (ior:SI (zero_extract:SI
13347                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13348                     (const_int 1)
13349                     (match_operand 2 "const_int_operand" "K03,K03"))
13350                 (match_operand:SI 3 "register_operand" "=r,r")))]
13351   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13352 {
13353   static const char* alt[] =
13354   {
13355        "bor.b   %2,%1"          "\n"
13356     "   movt    %0",
13357
13358        "bor.b   %2,@(0,%t1)"    "\n"
13359     "   movt    %0"
13360   };
13361   return alt[which_alternative];
13362 }
13363   [(set_attr "length" "6,6")])
13364
13365 ;; Take exclusive or of a specified bit of memory with the T bit and
13366 ;; store its result in the T bit.
13367 (define_insn "bxor_m2a"
13368   [(set (reg:SI T_REG)
13369         (xor:SI (reg:SI T_REG)
13370                 (zero_extract:SI
13371                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13372                     (const_int 1)
13373                     (match_operand 1 "const_int_operand" "K03,K03"))))]
13374   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13375   "@
13376         bxor.b  %1,%0
13377         bxor.b  %1,@(0,%t0)"
13378   [(set_attr "length" "4,4")])
13379
13380 (define_insn "bxorreg_m2a"
13381   [(set (match_operand:SI 0 "register_operand" "=r,r")
13382         (xor:SI (zero_extract:SI
13383                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13384                     (const_int 1)
13385                     (match_operand 2 "const_int_operand" "K03,K03"))
13386                 (match_operand:SI 3 "register_operand" "=r,r")))]
13387   "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13388 {
13389   static const char* alt[] =
13390   {
13391        "bxor.b  %2,%1"          "\n"
13392     "   movt    %0",
13393
13394        "bxor.b  %2,@(0,%t1)"    "\n"
13395     "   movt    %0"
13396   };
13397   return alt[which_alternative];
13398 }
13399   [(set_attr "length" "6,6")])
13400 \f
13401 ;; -------------------------------------------------------------------------
13402 ;; Peepholes
13403 ;; -------------------------------------------------------------------------
13404 ;; This matches cases where the bit in a memory location is set.
13405 (define_peephole2
13406   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13407         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13408    (set (match_dup 0)
13409         (ior:SI (match_dup 0)
13410         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
13411    (set (match_dup 1)
13412         (match_operand 3 "arith_reg_operand" "r,r"))]
13413   "TARGET_SH2A && TARGET_BITOPS
13414    && satisfies_constraint_Pso (operands[2])
13415    && REGNO (operands[0]) == REGNO (operands[3])"
13416   [(set (match_dup 1)
13417         (ior:QI (match_dup 1) (match_dup 2)))]
13418   "")
13419
13420 ;; This matches cases where the bit in a memory location is cleared.
13421 (define_peephole2
13422   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13423         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13424    (set (match_dup 0)
13425         (and:SI (match_dup 0)
13426         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
13427    (set (match_dup 1)
13428         (match_operand 3 "arith_reg_operand" "r,r"))]
13429   "TARGET_SH2A && TARGET_BITOPS
13430    && satisfies_constraint_Psz (operands[2])
13431    && REGNO (operands[0]) == REGNO (operands[3])"
13432   [(set (match_dup 1)
13433         (and:QI (match_dup 1) (match_dup 2)))]
13434   "")
13435
13436 ;; This matches cases where a stack pointer increment at the start of the
13437 ;; epilogue combines with a stack slot read loading the return value.
13438 (define_peephole
13439   [(set (match_operand:SI 0 "arith_reg_operand" "")
13440         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13441    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13442   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13443   "mov.l        @%1+,%0")
13444
13445 ;; See the comment on the dt combiner pattern above.
13446 (define_peephole
13447   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13448         (plus:SI (match_dup 0)
13449                  (const_int -1)))
13450    (set (reg:SI T_REG)
13451         (eq:SI (match_dup 0) (const_int 0)))]
13452   "TARGET_SH2"
13453   "dt   %0")
13454
13455 ;; The following peepholes fold load sequences for which reload was not
13456 ;; able to generate a displacement addressing move insn.
13457 ;; This can happen when reload has to transform a move insn 
13458 ;; without displacement into one with displacement.  Or when reload can't
13459 ;; fit a displacement into the insn's constraints.  In the latter case, the
13460 ;; load destination reg remains at r0, which reload compensates by inserting
13461 ;; another mov insn.
13462
13463 ;; Fold sequence:
13464 ;;      mov #54,r0
13465 ;;      mov.{b,w} @(r0,r15),r0
13466 ;;      mov r0,r3
13467 ;; into:
13468 ;;      mov.{b,w} @(54,r15),r3
13469 ;;
13470 (define_peephole2
13471   [(set (match_operand:SI 0 "arith_reg_dest" "")
13472         (match_operand:SI 1 "const_int_operand" ""))
13473    (set (match_operand:SI 2 "arith_reg_dest" "")
13474         (sign_extend:SI
13475          (mem:QI (plus:SI (match_dup 0)
13476                           (match_operand:SI 3 "arith_reg_operand" "")))))
13477    (set (match_operand:QI 4 "arith_reg_dest" "")
13478         (match_operand:QI 5 "arith_reg_operand" ""))]
13479   "TARGET_SH2A
13480    && sh_legitimate_index_p (QImode, operands[1], true, true)
13481    && REGNO (operands[2]) == REGNO (operands[5])
13482    && peep2_reg_dead_p (3, operands[5])"
13483   [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13484   "")
13485
13486 (define_peephole2
13487   [(set (match_operand:SI 0 "arith_reg_dest" "")
13488         (match_operand:SI 1 "const_int_operand" ""))
13489    (set (match_operand:SI 2 "arith_reg_dest" "")
13490         (sign_extend:SI
13491          (mem:HI (plus:SI (match_dup 0)
13492                           (match_operand:SI 3 "arith_reg_operand" "")))))
13493    (set (match_operand:HI 4 "arith_reg_dest" "")
13494         (match_operand:HI 5 "arith_reg_operand" ""))]
13495   "TARGET_SH2A
13496    && sh_legitimate_index_p (HImode, operands[1], true, true)
13497    && REGNO (operands[2]) == REGNO (operands[5])
13498    && peep2_reg_dead_p (3, operands[5])"
13499   [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13500   "")
13501
13502 ;; Fold sequence:
13503 ;;      mov #54,r0
13504 ;;      mov.{b,w} @(r0,r15),r1
13505 ;; into:
13506 ;;      mov.{b,w} @(54,r15),r1
13507 ;;
13508 (define_peephole2
13509   [(set (match_operand:SI 0 "arith_reg_dest" "")
13510         (match_operand:SI 1 "const_int_operand" ""))
13511    (set (match_operand:SI 2 "arith_reg_dest" "")
13512          (sign_extend:SI
13513          (mem:QI (plus:SI (match_dup 0)
13514                           (match_operand:SI 3 "arith_reg_operand" "")))))]
13515   "TARGET_SH2A
13516    && sh_legitimate_index_p (QImode, operands[1], true, true)
13517    && (peep2_reg_dead_p (2, operands[0])
13518        || REGNO (operands[0]) == REGNO (operands[2]))"
13519   [(set (match_dup 2)
13520         (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13521   "")
13522
13523 (define_peephole2
13524   [(set (match_operand:SI 0 "arith_reg_dest" "")
13525         (match_operand:SI 1 "const_int_operand" ""))
13526    (set (match_operand:SI 2 "arith_reg_dest" "")
13527          (sign_extend:SI
13528          (mem:HI (plus:SI (match_dup 0)
13529                           (match_operand:SI 3 "arith_reg_operand" "")))))]
13530   "TARGET_SH2A
13531    && sh_legitimate_index_p (HImode, operands[1], true, true)
13532    && (peep2_reg_dead_p (2, operands[0])
13533        || REGNO (operands[0]) == REGNO (operands[2]))"
13534   [(set (match_dup 2)
13535         (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13536   "")
13537
13538 ;; Fold sequence:
13539 ;;      mov.{b,w} @(r0,r15),r0
13540 ;;      mov r0,r3
13541 ;; into:
13542 ;;      mov.{b,w} @(r0,r15),r3
13543 ;;
13544 ;; This can happen when initially a displacement address is picked, where
13545 ;; the destination reg is fixed to r0, and then the address is transformed
13546 ;; into 'r0 + reg'.
13547 (define_peephole2
13548   [(set (match_operand:SI 0 "arith_reg_dest" "")
13549         (sign_extend:SI
13550          (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13551                           (match_operand:SI 2 "arith_reg_operand" "")))))
13552    (set (match_operand:QI 3 "arith_reg_dest" "")
13553         (match_operand:QI 4 "arith_reg_operand" ""))]
13554   "TARGET_SH1
13555    && REGNO (operands[0]) == REGNO (operands[4])
13556    && peep2_reg_dead_p (2, operands[0])"
13557   [(set (match_dup 3)
13558         (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13559   "")
13560
13561 (define_peephole2
13562   [(set (match_operand:SI 0 "arith_reg_dest" "")
13563         (sign_extend:SI
13564          (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13565                           (match_operand:SI 2 "arith_reg_operand" "")))))
13566    (set (match_operand:HI 3 "arith_reg_dest" "")
13567         (match_operand:HI 4 "arith_reg_operand" ""))]
13568   "TARGET_SH1
13569    && REGNO (operands[0]) == REGNO (operands[4])
13570    && peep2_reg_dead_p (2, operands[0])"
13571   [(set (match_dup 3)
13572         (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13573   "")
13574
13575 (define_peephole
13576   [(set (match_operand:SI 0 "register_operand" "=r")
13577         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13578    (set (mem:SF (match_dup 0))
13579         (match_operand:SF 2 "general_movsrc_operand" ""))]
13580   "TARGET_SH1 && REGNO (operands[0]) == 0
13581    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13582        || (GET_CODE (operands[2]) == SUBREG
13583            && REGNO (SUBREG_REG (operands[2])) < 16))
13584    && reg_unused_after (operands[0], insn)"
13585   "mov.l        %2,@(%0,%1)")
13586
13587 (define_peephole
13588   [(set (match_operand:SI 0 "register_operand" "=r")
13589         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13590    (set (match_operand:SF 2 "general_movdst_operand" "")
13591
13592         (mem:SF (match_dup 0)))]
13593   "TARGET_SH1 && REGNO (operands[0]) == 0
13594    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13595        || (GET_CODE (operands[2]) == SUBREG
13596            && REGNO (SUBREG_REG (operands[2])) < 16))
13597    && reg_unused_after (operands[0], insn)"
13598   "mov.l        @(%0,%1),%2")
13599
13600 (define_peephole
13601   [(set (match_operand:SI 0 "register_operand" "=r")
13602         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13603    (set (mem:SF (match_dup 0))
13604         (match_operand:SF 2 "general_movsrc_operand" ""))]
13605   "TARGET_SH2E && REGNO (operands[0]) == 0
13606    && ((REG_P (operands[2])
13607         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13608        || (GET_CODE (operands[2]) == SUBREG
13609            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13610    && reg_unused_after (operands[0], insn)"
13611   "fmov{.s|}    %2,@(%0,%1)")
13612
13613 (define_peephole
13614   [(set (match_operand:SI 0 "register_operand" "=r")
13615         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13616    (set (match_operand:SF 2 "general_movdst_operand" "")
13617
13618         (mem:SF (match_dup 0)))]
13619   "TARGET_SH2E && REGNO (operands[0]) == 0
13620    && ((REG_P (operands[2])
13621         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13622        || (GET_CODE (operands[2]) == SUBREG
13623            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13624    && reg_unused_after (operands[0], insn)"
13625   "fmov{.s|}    @(%0,%1),%2")
13626
13627 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13628 (define_insn "sp_switch_1"
13629   [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
13630     UNSPECV_SP_SWITCH_B))]
13631   "TARGET_SH1"
13632 {
13633   return       "mov.l   r0,@-r15"       "\n"
13634          "      mov.l   %0,r0"          "\n"
13635          "      mov.l   @r0,r0"         "\n"
13636          "      mov.l   r15,@-r0"       "\n"
13637          "      mov     r0,r15";
13638 }
13639   [(set_attr "length" "10")])
13640
13641 ;; Switch back to the original stack for interrupt functions with the
13642 ;; sp_switch attribute.
13643 (define_insn "sp_switch_2"
13644   [(unspec_volatile [(const_int 0)]
13645     UNSPECV_SP_SWITCH_E)]
13646   "TARGET_SH1"
13647 {
13648   return       "mov.l   @r15,r15"       "\n"
13649          "      mov.l   @r15+,r0";
13650 }
13651   [(set_attr "length" "4")])
13652
13653 ;; -------------------------------------------------------------------------
13654 ;; Integer vector moves
13655 ;; -------------------------------------------------------------------------
13656
13657 (define_expand "movv8qi"
13658   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13659         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13660   "TARGET_SHMEDIA"
13661 {
13662   prepare_move_operands (operands, V8QImode);
13663 })
13664
13665 (define_insn "movv8qi_i"
13666   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13667         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13668   "TARGET_SHMEDIA
13669    && (register_operand (operands[0], V8QImode)
13670        || sh_register_operand (operands[1], V8QImode))"
13671   "@
13672         add     %1, r63, %0
13673         movi    %1, %0
13674         #
13675         ld%M1.q %m1, %0
13676         st%M0.q %m0, %N1"
13677   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13678    (set_attr "length" "4,4,16,4,4")])
13679
13680 (define_split
13681   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13682         (subreg:V8QI (const_int 0) 0))]
13683   "TARGET_SHMEDIA"
13684   [(set (match_dup 0)
13685         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13686                             (const_int 0) (const_int 0) (const_int 0)
13687                             (const_int 0) (const_int 0)]))])
13688
13689 (define_split
13690   [(set (match_operand 0 "arith_reg_dest" "")
13691         (match_operand 1 "sh_rep_vec" ""))]
13692   "TARGET_SHMEDIA && reload_completed
13693    && GET_MODE (operands[0]) == GET_MODE (operands[1])
13694    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13695    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13696    && (XVECEXP (operands[1], 0, 0) != const0_rtx
13697        || XVECEXP (operands[1], 0, 1) != const0_rtx)
13698    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13699        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13700   [(set (match_dup 0) (match_dup 1))
13701    (match_dup 2)]
13702 {
13703   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
13704   rtx elt1 = XVECEXP (operands[1], 0, 1);
13705
13706   if (unit_size > 2)
13707     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
13708   else
13709     {
13710       if (unit_size < 2)
13711         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
13712       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
13713     }
13714   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
13715   operands[1] = XVECEXP (operands[1], 0, 0);
13716   if (unit_size < 2)
13717     {
13718       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
13719         operands[1]
13720           = GEN_INT (TARGET_LITTLE_ENDIAN
13721                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
13722                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
13723       else
13724         {
13725           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
13726           operands[1]
13727             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
13728         }
13729     }
13730 })
13731
13732 (define_split
13733   [(set (match_operand 0 "arith_reg_dest" "")
13734         (match_operand 1 "sh_const_vec" ""))]
13735   "TARGET_SHMEDIA && reload_completed
13736    && GET_MODE (operands[0]) == GET_MODE (operands[1])
13737    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
13738   [(set (match_dup 0) (match_dup 1))]
13739 {
13740   rtx v = operands[1];
13741   enum machine_mode new_mode
13742     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
13743
13744   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
13745   operands[1]
13746     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
13747 })
13748
13749 (define_expand "movv2hi"
13750   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
13751         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
13752   "TARGET_SHMEDIA"
13753 {
13754   prepare_move_operands (operands, V2HImode);
13755 })
13756
13757 (define_insn "movv2hi_i"
13758   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13759         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13760   "TARGET_SHMEDIA
13761    && (register_operand (operands[0], V2HImode)
13762        || sh_register_operand (operands[1], V2HImode))"
13763   "@
13764         add.l   %1, r63, %0
13765         movi    %1, %0
13766         #
13767         ld%M1.l %m1, %0
13768         st%M0.l %m0, %N1"
13769   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13770    (set_attr "length" "4,4,16,4,4")
13771    (set (attr "highpart")
13772         (cond [(match_test "sh_contains_memref_p (insn)")
13773                (const_string "user")]
13774               (const_string "ignore")))])
13775
13776 (define_expand "movv4hi"
13777   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
13778         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
13779   "TARGET_SHMEDIA"
13780 {
13781   prepare_move_operands (operands, V4HImode);
13782 })
13783
13784 (define_insn "movv4hi_i"
13785   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13786         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13787   "TARGET_SHMEDIA
13788    && (register_operand (operands[0], V4HImode)
13789        || sh_register_operand (operands[1], V4HImode))"
13790   "@
13791         add     %1, r63, %0
13792         movi    %1, %0
13793         #
13794         ld%M1.q %m1, %0
13795         st%M0.q %m0, %N1"
13796   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13797    (set_attr "length" "4,4,16,4,4")
13798    (set_attr "highpart" "depend")])
13799
13800 (define_expand "movv2si"
13801   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
13802         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
13803   "TARGET_SHMEDIA"
13804 {
13805   prepare_move_operands (operands, V2SImode);
13806 })
13807
13808 (define_insn "movv2si_i"
13809   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
13810         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13811   "TARGET_SHMEDIA
13812    && (register_operand (operands[0], V2SImode)
13813        || sh_register_operand (operands[1], V2SImode))"
13814   "@
13815         add     %1, r63, %0
13816         #
13817         #
13818         ld%M1.q %m1, %0
13819         st%M0.q %m0, %N1"
13820   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
13821    (set_attr "length" "4,4,16,4,4")
13822    (set_attr "highpart" "depend")])
13823
13824 ;; -------------------------------------------------------------------------
13825 ;; Multimedia Intrinsics
13826 ;; -------------------------------------------------------------------------
13827
13828 (define_insn "absv2si2"
13829   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13830         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
13831   "TARGET_SHMEDIA"
13832   "mabs.l       %1, %0"
13833   [(set_attr "type" "mcmp_media")
13834    (set_attr "highpart" "depend")])
13835
13836 (define_insn "absv4hi2"
13837   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13838         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
13839   "TARGET_SHMEDIA"
13840   "mabs.w       %1, %0"
13841   [(set_attr "type" "mcmp_media")
13842    (set_attr "highpart" "depend")])
13843
13844 (define_insn "addv2si3"
13845   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13846         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13847                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13848   "TARGET_SHMEDIA"
13849   "madd.l       %1, %2, %0"
13850   [(set_attr "type" "arith_media")
13851    (set_attr "highpart" "depend")])
13852
13853 (define_insn "addv4hi3"
13854   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13855         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13856                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13857   "TARGET_SHMEDIA"
13858   "madd.w       %1, %2, %0"
13859   [(set_attr "type" "arith_media")
13860    (set_attr "highpart" "depend")])
13861
13862 (define_insn_and_split "addv2hi3"
13863   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13864         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
13865                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
13866   "TARGET_SHMEDIA"
13867   "#"
13868   "TARGET_SHMEDIA"
13869   [(const_int 0)]
13870 {
13871   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13872   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13873   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13874   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13875   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13876
13877   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
13878   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13879   DONE;
13880 }
13881   [(set_attr "highpart" "must_split")])
13882
13883 (define_insn "ssaddv2si3"
13884   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13885         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13886                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13887   "TARGET_SHMEDIA"
13888   "madds.l      %1, %2, %0"
13889   [(set_attr "type" "mcmp_media")
13890    (set_attr "highpart" "depend")])
13891
13892 (define_insn "usaddv8qi3"
13893   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13894         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
13895                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13896   "TARGET_SHMEDIA"
13897   "madds.ub     %1, %2, %0"
13898   [(set_attr "type" "mcmp_media")
13899    (set_attr "highpart" "depend")])
13900
13901 (define_insn "ssaddv4hi3"
13902   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13903         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13904                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13905   "TARGET_SHMEDIA"
13906   "madds.w      %1, %2, %0"
13907   [(set_attr "type" "mcmp_media")
13908    (set_attr "highpart" "depend")])
13909
13910 (define_insn "negcmpeqv8qi"
13911   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13912         (neg:V8QI (eq:V8QI
13913                     (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13914                     (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13915   "TARGET_SHMEDIA"
13916   "mcmpeq.b     %N1, %N2, %0"
13917   [(set_attr "type" "mcmp_media")
13918    (set_attr "highpart" "depend")])
13919
13920 (define_insn "negcmpeqv2si"
13921   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13922         (neg:V2SI (eq:V2SI
13923                     (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13924                     (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13925   "TARGET_SHMEDIA"
13926   "mcmpeq.l     %N1, %N2, %0"
13927   [(set_attr "type" "mcmp_media")
13928    (set_attr "highpart" "depend")])
13929
13930 (define_insn "negcmpeqv4hi"
13931   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13932         (neg:V4HI (eq:V4HI
13933                     (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13934                     (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13935   "TARGET_SHMEDIA"
13936   "mcmpeq.w     %N1, %N2, %0"
13937   [(set_attr "type" "mcmp_media")
13938    (set_attr "highpart" "depend")])
13939
13940 (define_insn "negcmpgtuv8qi"
13941   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13942         (neg:V8QI (gtu:V8QI
13943                     (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13944                     (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13945   "TARGET_SHMEDIA"
13946   "mcmpgt.ub    %N1, %N2, %0"
13947   [(set_attr "type" "mcmp_media")
13948    (set_attr "highpart" "depend")])
13949
13950 (define_insn "negcmpgtv2si"
13951   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13952         (neg:V2SI (gt:V2SI
13953                     (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13954                     (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13955   "TARGET_SHMEDIA"
13956   "mcmpgt.l     %N1, %N2, %0"
13957   [(set_attr "type" "mcmp_media")
13958    (set_attr "highpart" "depend")])
13959
13960 (define_insn "negcmpgtv4hi"
13961   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13962         (neg:V4HI (gt:V4HI
13963                     (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13964                     (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13965   "TARGET_SHMEDIA"
13966   "mcmpgt.w     %N1, %N2, %0"
13967   [(set_attr "type" "mcmp_media")
13968    (set_attr "highpart" "depend")])
13969
13970 (define_insn "mcmv"
13971   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13972         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13973                         (match_operand:DI 2 "arith_reg_operand" "r"))
13974                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
13975                         (not:DI (match_dup 2)))))]
13976   "TARGET_SHMEDIA"
13977   "mcmv %N1, %2, %0"
13978   [(set_attr "type" "arith_media")
13979    (set_attr "highpart" "depend")])
13980
13981 (define_insn "mcnvs_lw"
13982   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13983         (vec_concat:V4HI
13984          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
13985          (ss_truncate:V2HI
13986            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13987   "TARGET_SHMEDIA"
13988   "mcnvs.lw     %N1, %N2, %0"
13989   [(set_attr "type" "mcmp_media")])
13990
13991 (define_insn "mcnvs_wb"
13992   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13993         (vec_concat:V8QI
13994          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13995          (ss_truncate:V4QI
13996            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13997   "TARGET_SHMEDIA"
13998   "mcnvs.wb     %N1, %N2, %0"
13999   [(set_attr "type" "mcmp_media")])
14000
14001 (define_insn "mcnvs_wub"
14002   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14003         (vec_concat:V8QI
14004          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14005          (us_truncate:V4QI
14006            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14007   "TARGET_SHMEDIA"
14008   "mcnvs.wub    %N1, %N2, %0"
14009   [(set_attr "type" "mcmp_media")])
14010
14011 (define_insn "mextr_rl"
14012   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14013         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14014                              (match_operand:HI 3 "mextr_bit_offset" "i"))
14015                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14016                            (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14017   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14018 {
14019   static char templ[21];
14020   sprintf (templ, "mextr%d      %%N1, %%N2, %%0",
14021            (int) INTVAL (operands[3]) >> 3);
14022   return templ;
14023 }
14024   [(set_attr "type" "arith_media")])
14025
14026 (define_insn "*mextr_lr"
14027   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14028         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14029                            (match_operand:HI 3 "mextr_bit_offset" "i"))
14030                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14031                              (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14032   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14033 {
14034   static char templ[21];
14035   sprintf (templ, "mextr%d      %%N2, %%N1, %%0",
14036            (int) INTVAL (operands[4]) >> 3);
14037   return templ;
14038 }
14039   [(set_attr "type" "arith_media")])
14040
14041 ; mextrN can be modelled with vec_select / vec_concat, but the selection
14042 ; vector then varies depending on endianness.
14043 (define_expand "mextr1"
14044   [(match_operand:DI 0 "arith_reg_dest" "")
14045    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14046    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14047   "TARGET_SHMEDIA"
14048 {
14049   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14050                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
14051   DONE;
14052 })
14053
14054 (define_expand "mextr2"
14055   [(match_operand:DI 0 "arith_reg_dest" "")
14056    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14057    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14058   "TARGET_SHMEDIA"
14059 {
14060   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14061                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
14062   DONE;
14063 })
14064
14065 (define_expand "mextr3"
14066   [(match_operand:DI 0 "arith_reg_dest" "")
14067    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14068    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14069   "TARGET_SHMEDIA"
14070 {
14071   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14072                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
14073   DONE;
14074 })
14075
14076 (define_expand "mextr4"
14077   [(match_operand:DI 0 "arith_reg_dest" "")
14078    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14079    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14080   "TARGET_SHMEDIA"
14081 {
14082   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14083                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
14084   DONE;
14085 })
14086
14087 (define_expand "mextr5"
14088   [(match_operand:DI 0 "arith_reg_dest" "")
14089    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14090    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14091   "TARGET_SHMEDIA"
14092 {
14093   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14094                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
14095   DONE;
14096 })
14097
14098 (define_expand "mextr6"
14099   [(match_operand:DI 0 "arith_reg_dest" "")
14100    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14101    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14102   "TARGET_SHMEDIA"
14103 {
14104   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14105                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
14106   DONE;
14107 })
14108
14109 (define_expand "mextr7"
14110   [(match_operand:DI 0 "arith_reg_dest" "")
14111    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14112    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14113   "TARGET_SHMEDIA"
14114 {
14115   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14116                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
14117   DONE;
14118 })
14119
14120 (define_expand "mmacfx_wl"
14121   [(match_operand:V2SI 0 "arith_reg_dest" "")
14122    (match_operand:V2HI 1 "extend_reg_operand" "")
14123    (match_operand:V2HI 2 "extend_reg_operand" "")
14124    (match_operand:V2SI 3 "arith_reg_operand" "")]
14125   "TARGET_SHMEDIA"
14126 {
14127   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14128                               operands[1], operands[2]));
14129   DONE;
14130 })
14131
14132 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14133 ;; is depend
14134 (define_insn "mmacfx_wl_i"
14135   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14136         (ss_plus:V2SI
14137          (match_operand:V2SI 1 "arith_reg_operand" "0")
14138          (ss_truncate:V2SI
14139           (ashift:V2DI
14140            (sign_extend:V2DI
14141             (mult:V2SI
14142              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14143              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14144            (const_int 1)))))]
14145   "TARGET_SHMEDIA"
14146   "mmacfx.wl    %2, %3, %0"
14147   [(set_attr "type" "mac_media")
14148    (set_attr "highpart" "depend")])
14149
14150 (define_expand "mmacnfx_wl"
14151   [(match_operand:V2SI 0 "arith_reg_dest" "")
14152    (match_operand:V2HI 1 "extend_reg_operand" "")
14153    (match_operand:V2HI 2 "extend_reg_operand" "")
14154    (match_operand:V2SI 3 "arith_reg_operand" "")]
14155   "TARGET_SHMEDIA"
14156 {
14157   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14158                                operands[1], operands[2]));
14159   DONE;
14160 })
14161
14162 (define_insn "mmacnfx_wl_i"
14163   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14164         (ss_minus:V2SI
14165          (match_operand:V2SI 1 "arith_reg_operand" "0")
14166          (ss_truncate:V2SI
14167           (ashift:V2DI
14168            (sign_extend:V2DI
14169             (mult:V2SI
14170              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14171              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14172            (const_int 1)))))]
14173   "TARGET_SHMEDIA"
14174   "mmacnfx.wl   %2, %3, %0"
14175   [(set_attr "type" "mac_media")
14176    (set_attr "highpart" "depend")])
14177
14178 (define_insn "mulv2si3"
14179   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14180         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14181                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14182   "TARGET_SHMEDIA"
14183   "mmul.l       %1, %2, %0"
14184   [(set_attr "type" "d2mpy_media")
14185    (set_attr "highpart" "depend")])
14186
14187 (define_insn "mulv4hi3"
14188   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14189         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14190                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14191   "TARGET_SHMEDIA"
14192   "mmul.w       %1, %2, %0"
14193   [(set_attr "type" "dmpy_media")
14194    (set_attr "highpart" "depend")])
14195
14196 (define_insn "mmulfx_l"
14197   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14198         (ss_truncate:V2SI
14199          (ashiftrt:V2DI
14200           (mult:V2DI
14201            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14202            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14203           (const_int 31))))]
14204   "TARGET_SHMEDIA"
14205   "mmulfx.l     %1, %2, %0"
14206   [(set_attr "type" "d2mpy_media")
14207    (set_attr "highpart" "depend")])
14208
14209 (define_insn "mmulfx_w"
14210   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14211         (ss_truncate:V4HI
14212          (ashiftrt:V4SI
14213           (mult:V4SI
14214            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14215            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14216           (const_int 15))))]
14217   "TARGET_SHMEDIA"
14218   "mmulfx.w     %1, %2, %0"
14219   [(set_attr "type" "dmpy_media")
14220    (set_attr "highpart" "depend")])
14221
14222 (define_insn "mmulfxrp_w"
14223   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14224         (ss_truncate:V4HI
14225          (ashiftrt:V4SI
14226           (plus:V4SI
14227            (mult:V4SI
14228             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14229             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14230            (const_int 16384))
14231           (const_int 15))))]
14232   "TARGET_SHMEDIA"
14233   "mmulfxrp.w   %1, %2, %0"
14234   [(set_attr "type" "dmpy_media")
14235    (set_attr "highpart" "depend")])
14236
14237
14238 (define_expand "mmulhi_wl"
14239   [(match_operand:V2SI 0 "arith_reg_dest" "")
14240    (match_operand:V4HI 1 "arith_reg_operand" "")
14241    (match_operand:V4HI 2 "arith_reg_operand" "")]
14242   "TARGET_SHMEDIA"
14243 {
14244   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14245              (operands[0], operands[1], operands[2]));
14246   DONE;
14247 })
14248
14249 (define_expand "mmullo_wl"
14250   [(match_operand:V2SI 0 "arith_reg_dest" "")
14251    (match_operand:V4HI 1 "arith_reg_operand" "")
14252    (match_operand:V4HI 2 "arith_reg_operand" "")]
14253   "TARGET_SHMEDIA"
14254 {
14255   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14256              (operands[0], operands[1], operands[2]));
14257   DONE;
14258 })
14259
14260 (define_insn "mmul23_wl"
14261   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14262         (vec_select:V2SI
14263          (mult:V4SI
14264           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14265           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14266          (parallel [(const_int 2) (const_int 3)])))]
14267   "TARGET_SHMEDIA"
14268 {
14269   return (TARGET_LITTLE_ENDIAN
14270           ? "mmulhi.wl  %1, %2, %0"
14271           : "mmullo.wl  %1, %2, %0");
14272 }
14273   [(set_attr "type" "dmpy_media")
14274    (set (attr "highpart")
14275         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14276          (const_string "user")))])
14277
14278 (define_insn "mmul01_wl"
14279   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14280         (vec_select:V2SI
14281          (mult:V4SI
14282           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14283           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14284          (parallel [(const_int 0) (const_int 1)])))]
14285   "TARGET_SHMEDIA"
14286 {
14287   return (TARGET_LITTLE_ENDIAN
14288           ? "mmullo.wl  %1, %2, %0"
14289           : "mmulhi.wl  %1, %2, %0");
14290 }
14291   [(set_attr "type" "dmpy_media")
14292    (set (attr "highpart")
14293         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14294          (const_string "user")))])
14295
14296
14297 (define_expand "mmulsum_wq"
14298   [(match_operand:DI 0 "arith_reg_dest" "")
14299    (match_operand:V4HI 1 "arith_reg_operand" "")
14300    (match_operand:V4HI 2 "arith_reg_operand" "")
14301    (match_operand:DI 3 "arith_reg_operand" "")]
14302   "TARGET_SHMEDIA"
14303 {
14304   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14305                                operands[1], operands[2]));
14306   DONE;
14307 })
14308
14309 (define_insn "mmulsum_wq_i"
14310   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14311         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14312          (plus:DI
14313           (plus:DI
14314            (vec_select:DI
14315             (mult:V4DI
14316              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14317              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14318             (parallel [(const_int 0)]))
14319            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14320                                      (sign_extend:V4DI (match_dup 3)))
14321                           (parallel [(const_int 1)])))
14322           (plus:DI
14323            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14324                                      (sign_extend:V4DI (match_dup 3)))
14325                           (parallel [(const_int 2)]))
14326            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14327                                      (sign_extend:V4DI (match_dup 3)))
14328                           (parallel [(const_int 3)]))))))]
14329   "TARGET_SHMEDIA"
14330   "mmulsum.wq   %2, %3, %0"
14331   [(set_attr "type" "mac_media")])
14332
14333 (define_expand "mperm_w"
14334   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14335    (match_operand:V4HI 1 "arith_reg_operand" "r")
14336    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14337   "TARGET_SHMEDIA"
14338 {
14339   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14340              (operands[0], operands[1], operands[2]));
14341   DONE;
14342 })
14343
14344 ; This use of vec_select isn't exactly correct according to rtl.texi
14345 ; (because not constant), but it seems a straightforward extension.
14346 (define_insn "mperm_w_little"
14347   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14348         (vec_select:V4HI
14349          (match_operand:V4HI 1 "arith_reg_operand" "r")
14350          (parallel
14351           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14352                             (const_int 2) (const_int 0))
14353            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14354            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14355            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14356   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14357   "mperm.w      %1, %N2, %0"
14358   [(set_attr "type" "arith_media")])
14359
14360 (define_insn "mperm_w_big"
14361   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14362         (vec_select:V4HI
14363          (match_operand:V4HI 1 "arith_reg_operand" "r")
14364          (parallel
14365           [(zero_extract:QI (not:QI (match_operand:QI 2
14366                                      "extend_reg_or_0_operand" "rZ"))
14367                             (const_int 2) (const_int 0))
14368            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14369            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14370            (zero_extract:QI (not:QI (match_dup 2))
14371                             (const_int 2) (const_int 6))])))]
14372   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
14373   "mperm.w      %1, %N2, %0"
14374   [(set_attr "type" "arith_media")])
14375
14376 (define_insn "mperm_w0"
14377   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14378         (vec_duplicate:V4HI (truncate:HI (match_operand 1
14379                                           "trunc_hi_operand" "r"))))]
14380   "TARGET_SHMEDIA"
14381   "mperm.w      %1, r63, %0"
14382   [(set_attr "type" "arith_media")
14383    (set_attr "highpart" "ignore")])
14384
14385 (define_expand "msad_ubq"
14386   [(match_operand:DI 0 "arith_reg_dest" "")
14387    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14388    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14389    (match_operand:DI 3 "arith_reg_operand" "")]
14390   "TARGET_SHMEDIA"
14391 {
14392   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14393                              operands[1], operands[2]));
14394   DONE;
14395 })
14396
14397 (define_insn "msad_ubq_i"
14398   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14399         (plus:DI
14400          (plus:DI
14401           (plus:DI
14402            (plus:DI
14403             (match_operand:DI 1 "arith_reg_operand" "0")
14404             (abs:DI (vec_select:DI
14405                      (minus:V8DI
14406                       (zero_extend:V8DI
14407                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14408                       (zero_extend:V8DI
14409                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14410                      (parallel [(const_int 0)]))))
14411            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14412                                               (zero_extend:V8DI (match_dup 3)))
14413                                   (parallel [(const_int 1)]))))
14414           (plus:DI
14415            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14416                                               (zero_extend:V8DI (match_dup 3)))
14417                                   (parallel [(const_int 2)])))
14418            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14419                                               (zero_extend:V8DI (match_dup 3)))
14420                                   (parallel [(const_int 3)])))))
14421          (plus:DI
14422           (plus:DI
14423            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14424                                               (zero_extend:V8DI (match_dup 3)))
14425                                   (parallel [(const_int 4)])))
14426            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14427                                               (zero_extend:V8DI (match_dup 3)))
14428                                   (parallel [(const_int 5)]))))
14429           (plus:DI
14430            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14431                                               (zero_extend:V8DI (match_dup 3)))
14432                                   (parallel [(const_int 6)])))
14433            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14434                                               (zero_extend:V8DI (match_dup 3)))
14435                                   (parallel [(const_int 7)])))))))]
14436   "TARGET_SHMEDIA"
14437   "msad.ubq     %N2, %N3, %0"
14438   [(set_attr "type" "mac_media")])
14439
14440 (define_insn "mshalds_l"
14441   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14442         (ss_truncate:V2SI
14443          (ashift:V2DI
14444           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14445           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14446                   (const_int 31)))))]
14447   "TARGET_SHMEDIA"
14448   "mshalds.l    %1, %2, %0"
14449   [(set_attr "type" "mcmp_media")
14450    (set_attr "highpart" "depend")])
14451
14452 (define_insn "mshalds_w"
14453   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14454         (ss_truncate:V4HI
14455          (ashift:V4SI
14456           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14457           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14458                   (const_int 15)))))]
14459   "TARGET_SHMEDIA"
14460   "mshalds.w    %1, %2, %0"
14461   [(set_attr "type" "mcmp_media")
14462    (set_attr "highpart" "depend")])
14463
14464 (define_insn "ashrv2si3"
14465   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14466         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14467                        (match_operand:DI 2 "arith_reg_operand" "r")))]
14468   "TARGET_SHMEDIA"
14469   "mshard.l     %1, %2, %0"
14470   [(set_attr "type" "arith_media")
14471    (set_attr "highpart" "depend")])
14472
14473 (define_insn "ashrv4hi3"
14474   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14475         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14476                        (match_operand:DI 2 "arith_reg_operand" "r")))]
14477   "TARGET_SHMEDIA"
14478   "mshard.w     %1, %2, %0"
14479   [(set_attr "type" "arith_media")
14480    (set_attr "highpart" "depend")])
14481
14482 (define_insn "mshards_q"
14483   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14484         (ss_truncate:HI
14485          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14486                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14487   "TARGET_SHMEDIA"
14488   "mshards.q    %1, %N2, %0"
14489   [(set_attr "type" "mcmp_media")])
14490
14491 (define_expand "mshfhi_b"
14492   [(match_operand:V8QI 0 "arith_reg_dest" "")
14493    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14494    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14495   "TARGET_SHMEDIA"
14496 {
14497   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14498              (operands[0], operands[1], operands[2]));
14499   DONE;
14500 })
14501
14502 (define_expand "mshflo_b"
14503   [(match_operand:V8QI 0 "arith_reg_dest" "")
14504    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14505    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14506   "TARGET_SHMEDIA"
14507 {
14508   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14509              (operands[0], operands[1], operands[2]));
14510   DONE;
14511 })
14512
14513 (define_insn "mshf4_b"
14514   [(set
14515     (match_operand:V8QI 0 "arith_reg_dest" "=r")
14516     (vec_select:V8QI
14517      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14518                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14519      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14520                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14521   "TARGET_SHMEDIA"
14522 {
14523   return (TARGET_LITTLE_ENDIAN
14524           ? "mshfhi.b   %N1, %N2, %0"
14525           : "mshflo.b   %N1, %N2, %0");
14526 }
14527   [(set_attr "type" "arith_media")
14528    (set (attr "highpart")
14529         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14530          (const_string "user")))])
14531
14532 (define_insn "mshf0_b"
14533   [(set
14534     (match_operand:V8QI 0 "arith_reg_dest" "=r")
14535     (vec_select:V8QI
14536      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14537                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14538      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14539                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14540   "TARGET_SHMEDIA"
14541 {
14542   return (TARGET_LITTLE_ENDIAN
14543           ? "mshflo.b   %N1, %N2, %0"
14544           : "mshfhi.b   %N1, %N2, %0");
14545 }
14546   [(set_attr "type" "arith_media")
14547    (set (attr "highpart")
14548         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14549          (const_string "user")))])
14550
14551 (define_expand "mshfhi_l"
14552   [(match_operand:V2SI 0 "arith_reg_dest" "")
14553    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14554    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14555   "TARGET_SHMEDIA"
14556 {
14557   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14558              (operands[0], operands[1], operands[2]));
14559   DONE;
14560 })
14561
14562 (define_expand "mshflo_l"
14563   [(match_operand:V2SI 0 "arith_reg_dest" "")
14564    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14565    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14566   "TARGET_SHMEDIA"
14567 {
14568   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14569              (operands[0], operands[1], operands[2]));
14570   DONE;
14571 })
14572
14573 (define_insn "mshf4_l"
14574   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14575         (vec_select:V2SI
14576          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14577                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14578          (parallel [(const_int 1) (const_int 3)])))]
14579   "TARGET_SHMEDIA"
14580 {
14581   return (TARGET_LITTLE_ENDIAN
14582           ? "mshfhi.l   %N1, %N2, %0"
14583           : "mshflo.l   %N1, %N2, %0");
14584 }
14585   [(set_attr "type" "arith_media")
14586    (set (attr "highpart")
14587         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14588          (const_string "user")))])
14589
14590 (define_insn "mshf0_l"
14591   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14592         (vec_select:V2SI
14593          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14594                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14595          (parallel [(const_int 0) (const_int 2)])))]
14596   "TARGET_SHMEDIA"
14597 {
14598   return (TARGET_LITTLE_ENDIAN
14599           ? "mshflo.l   %N1, %N2, %0"
14600           : "mshfhi.l   %N1, %N2, %0");
14601 }
14602   [(set_attr "type" "arith_media")
14603    (set (attr "highpart")
14604         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14605          (const_string "user")))])
14606
14607 (define_expand "mshfhi_w"
14608   [(match_operand:V4HI 0 "arith_reg_dest" "")
14609    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14610    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14611   "TARGET_SHMEDIA"
14612 {
14613   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14614              (operands[0], operands[1], operands[2]));
14615   DONE;
14616 })
14617
14618 (define_expand "mshflo_w"
14619   [(match_operand:V4HI 0 "arith_reg_dest" "")
14620    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14621    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14622   "TARGET_SHMEDIA"
14623 {
14624   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14625              (operands[0], operands[1], operands[2]));
14626   DONE;
14627 })
14628
14629 (define_insn "mshf4_w"
14630   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14631         (vec_select:V4HI
14632          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14633                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14634          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14635   "TARGET_SHMEDIA"
14636 {
14637   return (TARGET_LITTLE_ENDIAN
14638           ? "mshfhi.w   %N1, %N2, %0"
14639           : "mshflo.w   %N1, %N2, %0");
14640 }
14641   [(set_attr "type" "arith_media")
14642    (set (attr "highpart")
14643         (cond [(eq_attr "endian" "big") (const_string "ignore")]
14644          (const_string "user")))])
14645
14646 (define_insn "mshf0_w"
14647   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14648         (vec_select:V4HI
14649          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14650                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14651          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14652   "TARGET_SHMEDIA"
14653 {
14654   return (TARGET_LITTLE_ENDIAN
14655           ? "mshflo.w   %N1, %N2, %0"
14656           : "mshfhi.w   %N1, %N2, %0");
14657 }
14658   [(set_attr "type" "arith_media")
14659    (set (attr "highpart")
14660         (cond [(eq_attr "endian" "little") (const_string "ignore")]
14661          (const_string "user")))])
14662
14663 (define_insn "mshflo_w_x"
14664   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14665         (vec_select:V4HI
14666          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14667                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14668          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14669   "TARGET_SHMEDIA"
14670   "mshflo.w     %N1, %N2, %0"
14671   [(set_attr "type" "arith_media")
14672    (set_attr "highpart" "ignore")])
14673
14674 ;; These are useful to expand ANDs and as combiner patterns.
14675 (define_insn_and_split "mshfhi_l_di"
14676   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14677         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14678                              (const_int 32))
14679                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14680                         (const_int -4294967296))))]
14681   "TARGET_SHMEDIA"
14682   "@
14683         mshfhi.l        %N1, %N2, %0
14684         #"
14685   "TARGET_SHMEDIA && reload_completed
14686    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14687   [(set (match_dup 3) (match_dup 4))
14688    (set (match_dup 5) (match_dup 6))]
14689 {
14690   operands[3] = gen_lowpart (SImode, operands[0]);
14691   operands[4] = gen_highpart (SImode, operands[1]);
14692   operands[5] = gen_highpart (SImode, operands[0]);
14693   operands[6] = gen_highpart (SImode, operands[2]);
14694 }
14695   [(set_attr "type" "arith_media")])
14696
14697 (define_insn "*mshfhi_l_di_rev"
14698   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14699         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14700                         (const_int -4294967296))
14701                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14702                              (const_int 32))))]
14703   "TARGET_SHMEDIA"
14704   "mshfhi.l     %N2, %N1, %0"
14705   [(set_attr "type" "arith_media")])
14706
14707 (define_split
14708   [(set (match_operand:DI 0 "arith_reg_dest" "")
14709         (ior:DI (zero_extend:DI (match_operand:SI 1
14710                                               "extend_reg_or_0_operand" ""))
14711                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
14712                         (const_int -4294967296))))
14713    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
14714   "TARGET_SHMEDIA"
14715   [(const_int 0)]
14716 {
14717   emit_insn (gen_ashldi3_media (operands[3],
14718                                 simplify_gen_subreg (DImode, operands[1],
14719                                                      SImode, 0),
14720                                 GEN_INT (32)));
14721   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
14722   DONE;
14723 })
14724
14725 (define_insn "mshflo_l_di"
14726   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14727         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14728                         (const_int 4294967295))
14729                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14730                            (const_int 32))))]
14731
14732   "TARGET_SHMEDIA"
14733   "mshflo.l     %N1, %N2, %0"
14734   [(set_attr "type" "arith_media")
14735    (set_attr "highpart" "ignore")])
14736
14737 (define_insn "*mshflo_l_di_rev"
14738   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14739         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14740                            (const_int 32))
14741                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14742                         (const_int 4294967295))))]
14743
14744   "TARGET_SHMEDIA"
14745   "mshflo.l     %N2, %N1, %0"
14746   [(set_attr "type" "arith_media")
14747    (set_attr "highpart" "ignore")])
14748
14749 ;; Combiner pattern for trampoline initialization.
14750 (define_insn_and_split "*double_shori"
14751   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14752         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
14753                            (const_int 32))
14754                 (match_operand:DI 2 "const_int_operand" "n")))]
14755   "TARGET_SHMEDIA
14756    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
14757   "#"
14758   "rtx_equal_p (operands[0], operands[1])"
14759   [(const_int 0)]
14760 {
14761   HOST_WIDE_INT v = INTVAL (operands[2]);
14762
14763   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
14764   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
14765   DONE;
14766 }
14767   [(set_attr "highpart" "ignore")])
14768
14769 (define_insn "*mshflo_l_di_x"
14770   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14771         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
14772                                  "rZ"))
14773                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14774                            (const_int 32))))]
14775   "TARGET_SHMEDIA"
14776   "mshflo.l     %N1, %N2, %0"
14777   [(set_attr "type" "arith_media")
14778    (set_attr "highpart" "ignore")])
14779
14780 (define_insn_and_split "concat_v2sf"
14781   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
14782 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
14783         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
14784                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
14785   "TARGET_SHMEDIA"
14786   "@
14787         mshflo.l        %N1, %N2, %0
14788         #
14789         #"
14790   "TARGET_SHMEDIA && reload_completed
14791    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14792   [(set (match_dup 3) (match_dup 1))
14793    (set (match_dup 4) (match_dup 2))]
14794 {
14795   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
14796   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
14797 }
14798   [(set_attr "type" "arith_media")
14799    (set_attr "highpart" "ignore")])
14800
14801 (define_insn "*mshflo_l_di_x_rev"
14802   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14803         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14804                            (const_int 32))
14805                 (zero_extend:DI
14806                   (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
14807   "TARGET_SHMEDIA"
14808   "mshflo.l     %N2, %N1, %0"
14809   [(set_attr "type" "arith_media")
14810    (set_attr "highpart" "ignore")])
14811
14812 (define_insn "ashlv2si3"
14813   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14814         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14815                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14816   "TARGET_SHMEDIA"
14817   "mshlld.l     %1, %2, %0"
14818   [(set_attr "type" "arith_media")
14819    (set_attr "highpart" "depend")])
14820
14821 (define_split
14822   [(set (match_operand 0 "any_register_operand" "")
14823         (match_operator 3 "shift_operator"
14824           [(match_operand 1 "any_register_operand" "")
14825            (match_operand 2 "shift_count_reg_operand" "")]))]
14826   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
14827   [(set (match_dup 0) (match_dup 3))]
14828 {
14829   rtx count = operands[2];
14830   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
14831
14832   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
14833          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
14834          || GET_CODE (count) == TRUNCATE)
14835     count = XEXP (count, 0);
14836   inner_mode = GET_MODE (count);
14837   count = simplify_gen_subreg (outer_mode, count, inner_mode,
14838                                subreg_lowpart_offset (outer_mode, inner_mode));
14839   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
14840                                 operands[1], count);
14841 })
14842
14843 (define_insn "ashlv4hi3"
14844   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14845         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14846                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14847   "TARGET_SHMEDIA"
14848   "mshlld.w     %1, %2, %0"
14849   [(set_attr "type" "arith_media")
14850    (set_attr "highpart" "depend")])
14851
14852 (define_insn "lshrv2si3"
14853   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14854         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14855                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14856   "TARGET_SHMEDIA"
14857   "mshlrd.l     %1, %2, %0"
14858   [(set_attr "type" "arith_media")
14859    (set_attr "highpart" "depend")])
14860
14861 (define_insn "lshrv4hi3"
14862   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14863         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14864                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14865   "TARGET_SHMEDIA"
14866   "mshlrd.w     %1, %2, %0"
14867   [(set_attr "type" "arith_media")
14868    (set_attr "highpart" "depend")])
14869
14870 (define_insn "subv2si3"
14871   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14872         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14873                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14874   "TARGET_SHMEDIA"
14875   "msub.l       %N1, %2, %0"
14876   [(set_attr "type" "arith_media")
14877    (set_attr "highpart" "depend")])
14878
14879 (define_insn "subv4hi3"
14880   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14881         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14882                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14883   "TARGET_SHMEDIA"
14884   "msub.w       %N1, %2, %0"
14885   [(set_attr "type" "arith_media")
14886    (set_attr "highpart" "depend")])
14887
14888 (define_insn_and_split "subv2hi3"
14889   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14890         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
14891                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
14892   "TARGET_SHMEDIA"
14893   "#"
14894   "TARGET_SHMEDIA"
14895   [(const_int 0)]
14896 {
14897   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14898   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14899   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14900   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14901   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14902
14903   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
14904   emit_insn (gen_truncdisi2 (si_dst, di_dst));
14905   DONE;
14906 }
14907   [(set_attr "highpart" "must_split")])
14908
14909 (define_insn "sssubv2si3"
14910   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14911         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14912                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14913   "TARGET_SHMEDIA"
14914   "msubs.l      %N1, %2, %0"
14915   [(set_attr "type" "mcmp_media")
14916    (set_attr "highpart" "depend")])
14917
14918 (define_insn "ussubv8qi3"
14919   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14920         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14921                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14922   "TARGET_SHMEDIA"
14923   "msubs.ub     %N1, %2, %0"
14924   [(set_attr "type" "mcmp_media")
14925    (set_attr "highpart" "depend")])
14926
14927 (define_insn "sssubv4hi3"
14928   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14929         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14930                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14931   "TARGET_SHMEDIA"
14932   "msubs.w      %N1, %2, %0"
14933   [(set_attr "type" "mcmp_media")
14934    (set_attr "highpart" "depend")])
14935
14936 ;; -------------------------------------------------------------------------
14937 ;; Floating Point Intrinsics
14938 ;; -------------------------------------------------------------------------
14939
14940 (define_insn "fcosa_s"
14941   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14942         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14943                    UNSPEC_FCOSA))]
14944   "TARGET_SHMEDIA"
14945   "fcosa.s      %1, %0"
14946   [(set_attr "type" "atrans_media")])
14947
14948 (define_insn "fsina_s"
14949   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14950         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14951                    UNSPEC_FSINA))]
14952   "TARGET_SHMEDIA"
14953   "fsina.s      %1, %0"
14954   [(set_attr "type" "atrans_media")])
14955
14956 (define_insn "fipr"
14957   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14958         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
14959                                                     "fp_arith_reg_operand" "f")
14960                                                    (match_operand:V4SF 2
14961                                                     "fp_arith_reg_operand" "f"))
14962                                          (parallel [(const_int 0)]))
14963                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14964                                          (parallel [(const_int 1)])))
14965                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14966                                          (parallel [(const_int 2)]))
14967                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14968                                          (parallel [(const_int 3)])))))]
14969   "TARGET_SHMEDIA"
14970   "fipr.s       %1, %2, %0"
14971   [(set_attr "type" "fparith_media")])
14972
14973 (define_insn "fsrra_s"
14974   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14975         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
14976                    UNSPEC_FSRRA))]
14977   "TARGET_SHMEDIA"
14978   "fsrra.s      %1, %0"
14979   [(set_attr "type" "atrans_media")])
14980
14981 (define_insn "ftrv"
14982   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
14983         (plus:V4SF
14984          (plus:V4SF
14985           (mult:V4SF
14986            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
14987                             (parallel [(const_int 0) (const_int 5)
14988                                        (const_int 10) (const_int 15)]))
14989            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
14990           (mult:V4SF
14991            (vec_select:V4SF (match_dup 1)
14992                             (parallel [(const_int 4) (const_int 9)
14993                                        (const_int 14) (const_int 3)]))
14994            (vec_select:V4SF (match_dup 2)
14995                             (parallel [(const_int 1) (const_int 2)
14996                                        (const_int 3) (const_int 0)]))))
14997          (plus:V4SF
14998           (mult:V4SF
14999            (vec_select:V4SF (match_dup 1)
15000                             (parallel [(const_int 8) (const_int 13)
15001                                        (const_int 2) (const_int 7)]))
15002            (vec_select:V4SF (match_dup 2)
15003                             (parallel [(const_int 2) (const_int 3)
15004                                        (const_int 0) (const_int 1)])))
15005           (mult:V4SF
15006            (vec_select:V4SF (match_dup 1)
15007                             (parallel [(const_int 12) (const_int 1)
15008                                        (const_int 6) (const_int 11)]))
15009            (vec_select:V4SF (match_dup 2)
15010                             (parallel [(const_int 3) (const_int 0)
15011                                        (const_int 1) (const_int 2)]))))))]
15012   "TARGET_SHMEDIA"
15013   "ftrv.s %1, %2, %0"
15014   [(set_attr "type" "fparith_media")])
15015
15016 (define_insn "ldhi_l"
15017   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15018         (zero_extract:SI
15019          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15020                                   (const_int 3))
15021                           (const_int -3)))
15022          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
15023          (const_int 0)))]
15024   "TARGET_SHMEDIA32"
15025   "ldhi.l       %U1, %0"
15026   [(set_attr "type" "load_media")])
15027
15028 (define_insn "ldhi_q"
15029   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15030         (zero_extract:DI
15031          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15032                                   (const_int 7))
15033                           (const_int -7)))
15034          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
15035          (const_int 0)))]
15036   "TARGET_SHMEDIA32"
15037   "ldhi.q       %U1, %0"
15038   [(set_attr "type" "load_media")])
15039
15040 (define_insn_and_split "*ldhi_q_comb0"
15041   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15042         (zero_extract:DI
15043          (mem:DI (plus:SI (ior:SI (plus:SI
15044                                     (match_operand:SI 1 "register_operand" "r")
15045                                     (match_operand:SI 2 "ua_offset" "I06"))
15046                                   (const_int 7))
15047                           (const_int -7)))
15048          (plus:SI (and:SI (match_dup 1) (const_int 7))
15049                   (const_int 1))
15050          (const_int 0)))]
15051   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15052   "#"
15053   ""
15054   [(pc)]
15055 {
15056   emit_insn (gen_ldhi_q (operands[0],
15057                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15058   DONE;
15059 })
15060
15061 (define_insn_and_split "*ldhi_q_comb1"
15062   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15063         (zero_extract:DI
15064          (mem:DI (plus:SI (ior:SI (plus:SI
15065                                     (match_operand:SI 1 "register_operand" "r")
15066                                     (match_operand:SI 2 "ua_offset" "I06"))
15067                                   (const_int 7))
15068                           (const_int -7)))
15069          (plus:SI (and:SI (plus:SI (match_dup 1)
15070                                    (match_operand:SI 3 "ua_offset" "I06"))
15071                           (const_int 7))
15072                   (const_int 1))
15073          (const_int 0)))]
15074   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15075    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15076   "#"
15077   ""
15078   [(pc)]
15079 {
15080   emit_insn (gen_ldhi_q (operands[0],
15081                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15082   DONE;
15083 })
15084
15085 (define_insn "ldlo_l"
15086   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15087         (zero_extract:SI
15088          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15089                          (const_int -4)))
15090          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15091          (and:SI (match_dup 1) (const_int 3))))]
15092   "TARGET_SHMEDIA32"
15093   "ldlo.l       %U1, %0"
15094   [(set_attr "type" "load_media")])
15095
15096 (define_insn "ldlo_q"
15097   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15098         (zero_extract:DI
15099          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15100                          (const_int -8)))
15101          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15102          (and:SI (match_dup 1) (const_int 7))))]
15103   "TARGET_SHMEDIA32"
15104   "ldlo.q       %U1, %0"
15105   [(set_attr "type" "load_media")])
15106
15107 (define_insn_and_split "*ldlo_q_comb0"
15108   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15109         (zero_extract:DI
15110          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15111                                   (match_operand:SI 2 "ua_offset" "I06"))
15112                          (const_int -8)))
15113          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15114          (and:SI (match_dup 1) (const_int 7))))]
15115   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15116   "#"
15117   ""
15118   [(pc)]
15119 {
15120   emit_insn (gen_ldlo_q (operands[0],
15121                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15122   DONE;
15123 })
15124
15125 (define_insn_and_split "*ldlo_q_comb1"
15126   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15127         (zero_extract:DI
15128          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15129                                   (match_operand:SI 2 "ua_offset" "I06"))
15130                          (const_int -8)))
15131          (minus:SI (const_int 8)
15132                    (and:SI (plus:SI (match_dup 1)
15133                                     (match_operand:SI 3 "ua_offset" "I06"))
15134                            (const_int 7)))
15135          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15136   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15137    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15138   "#"
15139   ""
15140   [(pc)]
15141 {
15142   emit_insn (gen_ldlo_q (operands[0],
15143                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
15144   DONE;
15145 })
15146
15147 (define_insn "sthi_l"
15148   [(set (zero_extract:SI
15149          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15150                                   (const_int 3))
15151                           (const_int -3)))
15152          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15153          (const_int 0))
15154         (match_operand:SI 1 "arith_reg_operand" "r"))]
15155   "TARGET_SHMEDIA32"
15156   "sthi.l       %U0, %1"
15157   [(set_attr "type" "ustore_media")])
15158
15159 ;; All unaligned stores are considered to be 'narrow' because they typically
15160 ;; operate on less that a quadword, and when they operate on a full quadword,
15161 ;; the vanilla store high / store low sequence will cause a stall if not
15162 ;; scheduled apart.
15163 (define_insn "sthi_q"
15164   [(set (zero_extract:DI
15165          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15166                                   (const_int 7))
15167                           (const_int -7)))
15168          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15169          (const_int 0))
15170         (match_operand:DI 1 "arith_reg_operand" "r"))]
15171   "TARGET_SHMEDIA32"
15172   "sthi.q       %U0, %1"
15173   [(set_attr "type" "ustore_media")])
15174
15175 (define_insn_and_split "*sthi_q_comb0"
15176   [(set (zero_extract:DI
15177          (mem:DI (plus:SI (ior:SI (plus:SI
15178                                     (match_operand:SI 0 "register_operand" "r")
15179                                     (match_operand:SI 1 "ua_offset" "I06"))
15180                                   (const_int 7))
15181                           (const_int -7)))
15182          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15183          (const_int 0))
15184         (match_operand:DI 2 "arith_reg_operand" "r"))]
15185   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15186   "#"
15187   ""
15188   [(pc)]
15189 {
15190   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15191                          operands[2]));
15192   DONE;
15193 })
15194
15195 (define_insn_and_split "*sthi_q_comb1"
15196   [(set (zero_extract:DI
15197          (mem:DI (plus:SI (ior:SI (plus:SI
15198                                     (match_operand:SI 0 "register_operand" "r")
15199                                     (match_operand:SI 1 "ua_offset" "I06"))
15200                                   (const_int 7))
15201                           (const_int -7)))
15202          (plus:SI (and:SI (plus:SI (match_dup 0)
15203                                    (match_operand:SI 2 "ua_offset" "I06"))
15204                           (const_int 7))
15205                   (const_int 1))
15206          (const_int 0))
15207         (match_operand:DI 3 "arith_reg_operand" "r"))]
15208   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15209    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15210   "#"
15211   ""
15212   [(pc)]
15213 {
15214   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15215                          operands[3]));
15216   DONE;
15217 })
15218
15219 ;; This is highpart user because the address is used as full 64 bit.
15220 (define_insn "stlo_l"
15221   [(set (zero_extract:SI
15222          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15223                          (const_int -4)))
15224          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15225          (and:SI (match_dup 0) (const_int 3)))
15226         (match_operand:SI 1 "arith_reg_operand" "r"))]
15227   "TARGET_SHMEDIA32"
15228   "stlo.l       %U0, %1"
15229   [(set_attr "type" "ustore_media")])
15230
15231 (define_insn "stlo_q"
15232   [(set (zero_extract:DI
15233          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15234                          (const_int -8)))
15235          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15236          (and:SI (match_dup 0) (const_int 7)))
15237         (match_operand:DI 1 "arith_reg_operand" "r"))]
15238   "TARGET_SHMEDIA32"
15239   "stlo.q       %U0, %1"
15240   [(set_attr "type" "ustore_media")])
15241
15242 (define_insn_and_split "*stlo_q_comb0"
15243   [(set (zero_extract:DI
15244          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15245                                   (match_operand:SI 1 "ua_offset" "I06"))
15246                          (const_int -8)))
15247          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15248          (and:SI (match_dup 0) (const_int 7)))
15249         (match_operand:DI 2 "arith_reg_operand" "r"))]
15250   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15251   "#"
15252   ""
15253   [(pc)]
15254 {
15255   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15256                          operands[2]));
15257   DONE;
15258 })
15259
15260 (define_insn_and_split "*stlo_q_comb1"
15261   [(set (zero_extract:DI
15262          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15263                                   (match_operand:SI 1 "ua_offset" "I06"))
15264                          (const_int -8)))
15265          (minus:SI (const_int 8)
15266                    (and:SI (plus:SI (match_dup 0)
15267                                     (match_operand:SI 2 "ua_offset" "I06"))
15268                            (const_int 7)))
15269          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15270         (match_operand:DI 3 "arith_reg_operand" "r"))]
15271   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15272   "#"
15273   ""
15274   [(pc)]
15275 {
15276   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15277                          operands[3]));
15278    DONE;
15279 })
15280
15281 (define_insn "ldhi_l64"
15282   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15283         (zero_extract:SI
15284          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15285                                   (const_int 3))
15286                           (const_int -3)))
15287          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15288          (const_int 0)))]
15289   "TARGET_SHMEDIA64"
15290   "ldhi.l       %U1, %0"
15291   [(set_attr "type" "load_media")])
15292
15293 (define_insn "ldhi_q64"
15294   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15295         (zero_extract:DI
15296          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15297                                   (const_int 7))
15298                           (const_int -7)))
15299          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15300          (const_int 0)))]
15301   "TARGET_SHMEDIA64"
15302   "ldhi.q       %U1, %0"
15303   [(set_attr "type" "load_media")])
15304
15305 (define_insn "ldlo_l64"
15306   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15307         (zero_extract:SI
15308          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15309                          (const_int -4)))
15310          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15311          (and:DI (match_dup 1) (const_int 3))))]
15312   "TARGET_SHMEDIA64"
15313   "ldlo.l       %U1, %0"
15314   [(set_attr "type" "load_media")])
15315
15316 (define_insn "ldlo_q64"
15317   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15318         (zero_extract:DI
15319          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15320                          (const_int -8)))
15321          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15322          (and:DI (match_dup 1) (const_int 7))))]
15323   "TARGET_SHMEDIA64"
15324   "ldlo.q       %U1, %0"
15325   [(set_attr "type" "load_media")])
15326
15327 (define_insn "sthi_l64"
15328   [(set (zero_extract:SI
15329          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15330                                   (const_int 3))
15331                           (const_int -3)))
15332          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15333          (const_int 0))
15334         (match_operand:SI 1 "arith_reg_operand" "r"))]
15335   "TARGET_SHMEDIA64"
15336   "sthi.l       %U0, %1"
15337   [(set_attr "type" "ustore_media")])
15338
15339 (define_insn "sthi_q64"
15340   [(set (zero_extract:DI
15341          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15342                                   (const_int 7))
15343                           (const_int -7)))
15344          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15345          (const_int 0))
15346         (match_operand:DI 1 "arith_reg_operand" "r"))]
15347   "TARGET_SHMEDIA64"
15348   "sthi.q       %U0, %1"
15349   [(set_attr "type" "ustore_media")])
15350
15351 (define_insn "stlo_l64"
15352   [(set (zero_extract:SI
15353          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15354                          (const_int -4)))
15355          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15356          (and:DI (match_dup 0) (const_int 3)))
15357         (match_operand:SI 1 "arith_reg_operand" "r"))]
15358   "TARGET_SHMEDIA64"
15359   "stlo.l       %U0, %1"
15360   [(set_attr "type" "ustore_media")])
15361
15362 (define_insn "stlo_q64"
15363   [(set (zero_extract:DI
15364          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15365                          (const_int -8)))
15366          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15367          (and:DI (match_dup 0) (const_int 7)))
15368         (match_operand:DI 1 "arith_reg_operand" "r"))]
15369   "TARGET_SHMEDIA64"
15370   "stlo.q       %U0, %1"
15371   [(set_attr "type" "ustore_media")])
15372
15373 (define_insn "nsb"
15374   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15375         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15376                    UNSPEC_NSB))]
15377   "TARGET_SHMEDIA"
15378   "nsb  %1, %0"
15379   [(set_attr "type" "arith_media")])
15380
15381 (define_insn "nsbsi"
15382   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15383         (zero_extend:SI
15384          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15385                     UNSPEC_NSB)))]
15386   "TARGET_SHMEDIA"
15387   "nsb  %1, %0"
15388   [(set_attr "type" "arith_media")])
15389
15390 (define_insn "nsbdi"
15391   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15392         (zero_extend:DI
15393          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15394                     UNSPEC_NSB)))]
15395   "TARGET_SHMEDIA"
15396   "nsb  %1, %0"
15397   [(set_attr "type" "arith_media")])
15398
15399 (define_expand "ffsdi2"
15400   [(set (match_operand:DI 0 "arith_reg_dest" "")
15401         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15402   "TARGET_SHMEDIA"
15403 {
15404   rtx scratch = gen_reg_rtx (DImode);
15405   rtx last;
15406
15407   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15408   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15409   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15410   emit_insn (gen_nsbdi (scratch, scratch));
15411   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15412   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15413   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15414   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15415
15416   DONE;
15417 })
15418
15419 (define_expand "ffssi2"
15420   [(set (match_operand:SI 0 "arith_reg_dest" "")
15421         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15422   "TARGET_SHMEDIA"
15423 {
15424   rtx scratch = gen_reg_rtx (SImode);
15425   rtx discratch = gen_reg_rtx (DImode);
15426   rtx last;
15427
15428   emit_insn (gen_adddi3 (discratch,
15429                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
15430                          constm1_rtx));
15431   emit_insn (gen_andcdi3 (discratch,
15432                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
15433                           discratch));
15434   emit_insn (gen_nsbsi (scratch, discratch));
15435   last = emit_insn (gen_subsi3 (operands[0],
15436                                 force_reg (SImode, GEN_INT (63)), scratch));
15437   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15438
15439   DONE;
15440 })
15441
15442 (define_insn "byterev"
15443   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15444         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15445                          (parallel [(const_int 7) (const_int 6) (const_int 5)
15446                                     (const_int 4) (const_int 3) (const_int 2)
15447                                     (const_int 1) (const_int 0)])))]
15448   "TARGET_SHMEDIA"
15449   "byterev      %1, %0"
15450   [(set_attr "type" "arith_media")])
15451
15452 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15453 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
15454 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15455 (define_expand "prefetch"
15456   [(prefetch (match_operand 0 "address_operand" "")
15457              (match_operand:SI 1 "const_int_operand" "")
15458              (match_operand:SI 2 "const_int_operand" ""))]
15459   "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15460    && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15461
15462 (define_insn "*prefetch"
15463   [(prefetch (match_operand:SI 0 "register_operand" "r")
15464              (match_operand:SI 1 "const_int_operand" "n")
15465              (match_operand:SI 2 "const_int_operand" "n"))]
15466   "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15467   "pref @%0"
15468   [(set_attr "type" "other")])
15469
15470 (define_insn "*prefetch_media"
15471   [(prefetch (match_operand:QI 0 "address_operand" "p")
15472              (match_operand:SI 1 "const_int_operand" "n")
15473              (match_operand:SI 2 "const_int_operand" "n"))]
15474   "TARGET_SHMEDIA"
15475 {
15476   operands[0] = gen_rtx_MEM (QImode, operands[0]);
15477   output_asm_insn ("ld%M0.b     %m0,r63", operands);
15478   return "";
15479 }
15480   [(set_attr "type" "other")])
15481
15482 (define_insn "alloco_i"
15483   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15484         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15485   "TARGET_SHMEDIA32"
15486 {
15487   rtx xops[2];
15488
15489   if (GET_CODE (operands[0]) == PLUS)
15490     {
15491       xops[0] = XEXP (operands[0], 0);
15492       xops[1] = XEXP (operands[0], 1);
15493     }
15494   else
15495     {
15496       xops[0] = operands[0];
15497       xops[1] = const0_rtx;
15498     }
15499   output_asm_insn ("alloco      %0, %1", xops);
15500   return "";
15501 }
15502   [(set_attr "type" "other")])
15503
15504 (define_split
15505   [(set (match_operand 0 "any_register_operand" "")
15506         (match_operand 1 "" ""))]
15507   "TARGET_SHMEDIA && reload_completed"
15508   [(set (match_dup 0) (match_dup 1))]
15509 {
15510   int n_changes = 0;
15511
15512   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
15513   if (!n_changes)
15514     FAIL;
15515 })
15516
15517 ;; -------------------------------------------------------------------------
15518 ;; Stack Protector Patterns
15519 ;; -------------------------------------------------------------------------
15520
15521 (define_expand "stack_protect_set"
15522   [(set (match_operand 0 "memory_operand" "")
15523         (match_operand 1 "memory_operand" ""))]
15524   ""
15525 {
15526   if (TARGET_SHMEDIA)
15527     {
15528       if (TARGET_SHMEDIA64)
15529         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15530       else
15531         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15532     }
15533   else
15534     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15535
15536   DONE;
15537 })
15538
15539 (define_insn "stack_protect_set_si"
15540   [(set (match_operand:SI 0 "memory_operand" "=m")
15541         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15542    (set (match_scratch:SI 2 "=&r") (const_int 0))]
15543   "!TARGET_SHMEDIA"
15544 {
15545   return       "mov.l   %1,%2"  "\n"
15546          "      mov.l   %2,%0"  "\n"
15547          "      mov     #0,%2";
15548 }
15549   [(set_attr "type" "other")
15550    (set_attr "length" "6")])
15551
15552 (define_insn "stack_protect_set_si_media"
15553   [(set (match_operand:SI 0 "memory_operand" "=m")
15554         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15555    (set (match_scratch:SI 2 "=&r") (const_int 0))]
15556   "TARGET_SHMEDIA"
15557 {
15558   return       "ld%M1.l %m1,%2" "\n"
15559          "      st%M0.l %m0,%2" "\n"
15560          "      movi    0,%2";
15561 }
15562   [(set_attr "type" "other")
15563    (set_attr "length" "12")])
15564
15565 (define_insn "stack_protect_set_di_media"
15566   [(set (match_operand:DI 0 "memory_operand" "=m")
15567         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15568    (set (match_scratch:DI 2 "=&r") (const_int 0))]
15569   "TARGET_SHMEDIA64"
15570 {
15571   return       "ld%M1.q %m1,%2" "\n"
15572          "      st%M0.q %m0,%2" "\n"
15573          "      movi    0,%2";
15574 }
15575   [(set_attr "type" "other")
15576    (set_attr "length" "12")])
15577
15578 (define_expand "stack_protect_test"
15579   [(match_operand 0 "memory_operand" "")
15580    (match_operand 1 "memory_operand" "")
15581    (match_operand 2 "" "")]
15582   ""
15583 {
15584   if (TARGET_SHMEDIA)
15585     {
15586       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15587       rtx test;
15588
15589       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15590       if (TARGET_SHMEDIA64)
15591         {
15592           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15593                                                       operands[1]));
15594           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15595         }
15596       else
15597         {
15598           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15599                                                       operands[1]));
15600           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15601         }
15602     }
15603   else
15604     {
15605       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15606       emit_jump_insn (gen_branch_true (operands[2]));
15607     }
15608
15609   DONE;
15610 })
15611
15612 (define_insn "stack_protect_test_si"
15613   [(set (reg:SI T_REG)
15614         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15615                     (match_operand:SI 1 "memory_operand" "m")]
15616                    UNSPEC_SP_TEST))
15617   (set (match_scratch:SI 2 "=&r") (const_int 0))
15618   (set (match_scratch:SI 3 "=&r") (const_int 0))]
15619   "!TARGET_SHMEDIA"
15620 {
15621   return       "mov.l   %0,%2"  "\n"
15622          "      mov.l   %1,%3"  "\n"
15623          "      cmp/eq  %2,%3"  "\n"
15624          "      mov     #0,%2"  "\n"
15625          "      mov     #0,%3";
15626 }
15627   [(set_attr "type" "other")
15628    (set_attr "length" "10")])
15629
15630 (define_insn "stack_protect_test_si_media"
15631   [(set (match_operand:SI 0 "register_operand" "=&r")
15632         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15633                     (match_operand:SI 2 "memory_operand" "m")]
15634                    UNSPEC_SP_TEST))
15635   (set (match_scratch:SI 3 "=&r") (const_int 0))]
15636   "TARGET_SHMEDIA"
15637 {
15638   return       "ld%M1.l %m1,%0"         "\n"
15639          "      ld%M2.l %m2,%3"         "\n"
15640          "      cmpeq   %0,%3,%0"       "\n"
15641          "      movi    0,%3";
15642 }
15643   [(set_attr "type" "other")
15644    (set_attr "length" "16")])
15645
15646 (define_insn "stack_protect_test_di_media"
15647   [(set (match_operand:DI 0 "register_operand" "=&r")
15648         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15649                     (match_operand:DI 2 "memory_operand" "m")]
15650                    UNSPEC_SP_TEST))
15651   (set (match_scratch:DI 3 "=&r") (const_int 0))]
15652   "TARGET_SHMEDIA64"
15653 {
15654   return       "ld%M1.q %m1,%0"         "\n"
15655          "      ld%M2.q %m2,%3"         "\n"
15656          "      cmpeq   %0,%3,%0"       "\n"
15657          "      movi    0,%3";
15658 }
15659   [(set_attr "type" "other")
15660    (set_attr "length" "16")])
15661
15662 ;; -------------------------------------------------------------------------
15663 ;; Atomic operations
15664 ;; -------------------------------------------------------------------------
15665
15666 (include "sync.md")