OSDN Git Service

PR target/19389
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
166
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
170
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
175
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
185
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; movua        SH4a unaligned load
222 ;; fsrra        square root reciprocal approximate
223 ;; fsca         sine and cosine approximate
224 ;; tls_load     load TLS related address
225 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media    SHmedia compare instructions
228 ;; dfdiv_media  SHmedia double precision divide and square root
229 ;; dfmul_media  SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media   SHmedia longword multiply
233 ;; fcmp_media   SHmedia floating point compare instructions
234 ;; fdiv_media   SHmedia single precision divide and square root
235 ;; fload_media  SHmedia floating point register load instructions
236 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media  SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media   SHmedia unconditional branch instructions
243 ;; load_media   SHmedia general register load instructions
244 ;; pt_media     SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media  SHmedia ptabs instruction
246 ;; store_media  SHmedia general register store instructions
247 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media    SHmedia mac-style fixed point operations
249 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
250 ;; atrans       SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil          no-op move, will be deleted.
253
254 (define_attr "type"
255  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
256   (const_string "other"))
257
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
260 ;;
261 ;; mt_group      SH4 "mt" group instructions.
262 ;;
263 ;; ex_group      SH4 "ex" group instructions.
264 ;;
265 ;; ls_group      SH4 "ls" group instructions.
266 ;;
267
268 (define_attr "insn_class"
269   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273          (eq_attr "type" "cbranch,jump") (const_string "br_group")
274          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275            (const_string "fe_group")
276          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
277         (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
281
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
283
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
285
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
293
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long.  Something in the
296 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
300
301 ;; The maximum range used for SImode constant pool entries is 1018.  A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table.  That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
313 ;;
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
316
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321          (const_string "no")
322          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323          (const_string "yes")
324          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327          (const_string "yes")
328          ] (const_string "no")))
329
330 (define_attr "med_branch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332               (const_int 1988))
333          (const_string "yes")
334          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337               (const_int 8186))
338          (const_string "yes")
339          ] (const_string "no")))
340
341 (define_attr "med_cbranch_p" "no,yes"
342   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343               (const_int 1986))
344          (const_string "yes")
345          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346          (const_string "no")
347          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348                (const_int 8184))
349          (const_string "yes")
350          ] (const_string "no")))
351
352 (define_attr "braf_branch_p" "no,yes"
353   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356               (const_int 20660))
357          (const_string "yes")
358          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359          (const_string "no")
360          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361               (const_int 65530))
362          (const_string "yes")
363          ] (const_string "no")))
364
365 (define_attr "braf_cbranch_p" "no,yes"
366   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367          (const_string "no")
368          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369               (const_int 20658))
370          (const_string "yes")
371          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372          (const_string "no")
373          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374               (const_int 65528))
375          (const_string "yes")
376          ] (const_string "no")))
377
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
384
385 ; All other instructions are two bytes long by default.
386
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390   (cond [(eq_attr "type" "cbranch")
391          (cond [(eq_attr "short_cbranch_p" "yes")
392                 (const_int 2)
393                 (eq_attr "med_cbranch_p" "yes")
394                 (const_int 6)
395                 (eq_attr "braf_cbranch_p" "yes")
396                 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398                 (ne (match_dup 0) (match_dup 0))
399                 (const_int 14)
400                 (ne (symbol_ref ("flag_pic")) (const_int 0))
401                 (const_int 24)
402                 ] (const_int 16))
403          (eq_attr "type" "jump")
404          (cond [(eq_attr "med_branch_p" "yes")
405                 (const_int 2)
406                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407                          (symbol_ref "INSN"))
408                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409                          (symbol_ref "code_for_indirect_jump_scratch")))
410                 (cond [(eq_attr "braf_branch_p" "yes")
411                        (const_int 6)
412                        (eq (symbol_ref "flag_pic") (const_int 0))
413                        (const_int 10)
414                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
415                        (const_int 10)] (const_int 18))
416                 (eq_attr "braf_branch_p" "yes")
417                 (const_int 10)
418 ;; ??? using pc is not computed transitively.
419                 (ne (match_dup 0) (match_dup 0))
420                 (const_int 12)
421                 (ne (symbol_ref ("flag_pic")) (const_int 0))
422                 (const_int 22)
423                 ] (const_int 14))
424          (eq_attr "type" "pt_media")
425          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
426                        (const_int 20) (const_int 12))
427          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
428                          (const_int 4)
429                          (const_int 2))))
430
431 ;; DFA descriptions for the pipelines
432
433 (include "sh1.md")
434 (include "shmedia.md")
435 (include "sh4.md")
436
437 ;; Definitions for filling delay slots
438
439 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
440
441 ;; ??? This should be (nil) instead of (const_int 0)
442 (define_attr "hit_stack" "yes,no"
443         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
444                    (const_int 0))
445                (const_string "no")]
446               (const_string "yes")))
447
448 (define_attr "interrupt_function" "no,yes"
449   (const (symbol_ref "current_function_interrupt")))
450
451 (define_attr "in_delay_slot" "yes,no"
452   (cond [(eq_attr "type" "cbranch") (const_string "no")
453          (eq_attr "type" "pcload,pcload_si") (const_string "no")
454          (eq_attr "needs_delay_slot" "yes") (const_string "no")
455          (eq_attr "length" "2") (const_string "yes")
456          ] (const_string "no")))
457
458 (define_attr "cond_delay_slot" "yes,no"
459   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
460          ] (const_string "no")))
461
462 (define_attr "is_sfunc" ""
463   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
464
465 (define_attr "is_mac_media" ""
466   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
467
468 (define_attr "branch_zero" "yes,no"
469   (cond [(eq_attr "type" "!cbranch") (const_string "no")
470          (ne (symbol_ref "(next_active_insn (insn)\
471                            == (prev_active_insn\
472                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
473                           && get_attr_length (next_active_insn (insn)) == 2")
474              (const_int 0))
475          (const_string "yes")]
476         (const_string "no")))
477
478 ;; SH4 Double-precision computation with double-precision result -
479 ;; the two halves are ready at different times.
480 (define_attr "dfp_comp" "yes,no"
481   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
482         (const_string "no")))
483
484 ;; Insns for which the latency of a preceding fp insn is decreased by one.
485 (define_attr "late_fp_use" "yes,no" (const_string "no"))
486 ;; And feeding insns for which this relevant.
487 (define_attr "any_fp_comp" "yes,no"
488   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
489          (const_string "yes")]
490         (const_string "no")))
491
492 (define_attr "any_int_load" "yes,no"
493   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
494          (const_string "yes")]
495         (const_string "no")))
496
497 (define_delay
498   (eq_attr "needs_delay_slot" "yes")
499   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
500
501 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
502 ;; and thus we can't put a pop instruction in its delay slot.
503 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
504 ;; instruction can go in the delay slot.
505
506 ;; Since a normal return (rts) implicitly uses the PR register,
507 ;; we can't allow PR register loads in an rts delay slot.
508
509 (define_delay
510   (eq_attr "type" "return")
511   [(and (eq_attr "in_delay_slot" "yes")
512         (ior (and (eq_attr "interrupt_function" "no")
513                   (eq_attr "type" "!pload,prset"))
514              (and (eq_attr "interrupt_function" "yes")
515                   (ior
516                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
517                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
518
519 ;; Since a call implicitly uses the PR register, we can't allow
520 ;; a PR register store in a jsr delay slot.
521
522 (define_delay
523   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
524   [(and (eq_attr "in_delay_slot" "yes")
525         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
526
527 ;; Say that we have annulled true branches, since this gives smaller and
528 ;; faster code when branches are predicted as not taken.
529
530 ;; ??? The non-annulled condition should really be "in_delay_slot",
531 ;; but insns that can be filled in non-annulled get priority over insns
532 ;; that can only be filled in anulled.
533
534 (define_delay
535   (and (eq_attr "type" "cbranch")
536        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
537   ;; SH2e has a hardware bug that pretty much prohibits the use of
538   ;; annuled delay slots.
539   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
540                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
541 \f
542 ;; -------------------------------------------------------------------------
543 ;; SImode signed integer comparisons
544 ;; -------------------------------------------------------------------------
545
546 (define_insn ""
547   [(set (reg:SI T_REG)
548         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
549                        (match_operand:SI 1 "arith_operand" "K08,r"))
550                (const_int 0)))]
551   "TARGET_SH1"
552   "tst  %1,%0"
553   [(set_attr "type" "mt_group")])
554
555 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
556 ;; That would still allow reload to create cmpi instructions, but would
557 ;; perhaps allow forcing the constant into a register when that is better.
558 ;; Probably should use r0 for mem/imm compares, but force constant into a
559 ;; register for pseudo/imm compares.
560
561 (define_insn "cmpeqsi_t"
562   [(set (reg:SI T_REG)
563         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
564                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
565   "TARGET_SH1"
566   "@
567         tst     %0,%0
568         cmp/eq  %1,%0
569         cmp/eq  %1,%0"
570    [(set_attr "type" "mt_group")])
571
572 (define_insn "cmpgtsi_t"
573   [(set (reg:SI T_REG)
574         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
575                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
576   "TARGET_SH1"
577   "@
578         cmp/gt  %1,%0
579         cmp/pl  %0"
580    [(set_attr "type" "mt_group")])
581
582 (define_insn "cmpgesi_t"
583   [(set (reg:SI T_REG)
584         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
585                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
586   "TARGET_SH1"
587   "@
588         cmp/ge  %1,%0
589         cmp/pz  %0"
590    [(set_attr "type" "mt_group")])
591
592 ;; -------------------------------------------------------------------------
593 ;; SImode unsigned integer comparisons
594 ;; -------------------------------------------------------------------------
595
596 (define_insn "cmpgeusi_t"
597   [(set (reg:SI T_REG)
598         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
599                 (match_operand:SI 1 "arith_reg_operand" "r")))]
600   "TARGET_SH1"
601   "cmp/hs       %1,%0"
602    [(set_attr "type" "mt_group")])
603
604 (define_insn "cmpgtusi_t"
605   [(set (reg:SI T_REG)
606         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
607                 (match_operand:SI 1 "arith_reg_operand" "r")))]
608   "TARGET_SH1"
609   "cmp/hi       %1,%0"
610    [(set_attr "type" "mt_group")])
611
612 ;; We save the compare operands in the cmpxx patterns and use them when
613 ;; we generate the branch.
614
615 (define_expand "cmpsi"
616   [(set (reg:SI T_REG)
617         (compare (match_operand:SI 0 "cmpsi_operand" "")
618                  (match_operand:SI 1 "arith_operand" "")))]
619   "TARGET_SH1"
620   "
621 {
622   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
623       && GET_CODE (operands[1]) != CONST_INT)
624     operands[0] = copy_to_mode_reg (SImode, operands[0]);
625   sh_compare_op0 = operands[0];
626   sh_compare_op1 = operands[1];
627   DONE;
628 }")
629 \f
630 ;; -------------------------------------------------------------------------
631 ;; DImode signed integer comparisons
632 ;; -------------------------------------------------------------------------
633
634 ;; ??? Could get better scheduling by splitting the initial test from the
635 ;; rest of the insn after reload.  However, the gain would hardly justify
636 ;; the sh.md size increase necessary to do that.
637
638 (define_insn ""
639   [(set (reg:SI T_REG)
640         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
641                        (match_operand:DI 1 "arith_operand" "r"))
642                (const_int 0)))]
643   "TARGET_SH1"
644   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
645                                  insn, operands);"
646   [(set_attr "length" "6")
647    (set_attr "type" "arith3b")])
648
649 (define_insn "cmpeqdi_t"
650   [(set (reg:SI T_REG)
651         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
652                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
653   "TARGET_SH1"
654   "@
655         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
656         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
657   [(set_attr "length" "6")
658    (set_attr "type" "arith3b")])
659
660 (define_split
661   [(set (reg:SI T_REG)
662         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
663                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
664 ;; If we applied this split when not optimizing, it would only be
665 ;; applied during the machine-dependent reorg, when no new basic blocks
666 ;; may be created.
667   "TARGET_SH1 && reload_completed && optimize"
668   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
669    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
670                            (label_ref (match_dup 6))
671                            (pc)))
672    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
673    (match_dup 6)]
674   "
675 {
676   operands[2]
677     = gen_rtx_REG (SImode,
678                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
679   operands[3]
680     = (operands[1] == const0_rtx
681        ? const0_rtx
682        : gen_rtx_REG (SImode,
683                       true_regnum (operands[1])
684                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
685   operands[4] = gen_lowpart (SImode, operands[0]);
686   operands[5] = gen_lowpart (SImode, operands[1]);
687   operands[6] = gen_label_rtx ();
688 }")
689
690 (define_insn "cmpgtdi_t"
691   [(set (reg:SI T_REG)
692         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
693                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
694   "TARGET_SH2"
695   "@
696         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
697         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
698   [(set_attr "length" "8")
699    (set_attr "type" "arith3")])
700
701 (define_insn "cmpgedi_t"
702   [(set (reg:SI T_REG)
703         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
704                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
705   "TARGET_SH2"
706   "@
707         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
708         cmp/pz\\t%S0"
709   [(set_attr "length" "8,2")
710    (set_attr "type" "arith3,mt_group")])
711 \f
712 ;; -------------------------------------------------------------------------
713 ;; DImode unsigned integer comparisons
714 ;; -------------------------------------------------------------------------
715
716 (define_insn "cmpgeudi_t"
717   [(set (reg:SI T_REG)
718         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
719                 (match_operand:DI 1 "arith_reg_operand" "r")))]
720   "TARGET_SH2"
721   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
722   [(set_attr "length" "8")
723    (set_attr "type" "arith3")])
724
725 (define_insn "cmpgtudi_t"
726   [(set (reg:SI T_REG)
727         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
728                 (match_operand:DI 1 "arith_reg_operand" "r")))]
729   "TARGET_SH2"
730   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
731   [(set_attr "length" "8")
732    (set_attr "type" "arith3")])
733
734 (define_insn "cmpeqdi_media"
735   [(set (match_operand:DI 0 "register_operand" "=r")
736         (eq:DI (match_operand:DI 1 "register_operand" "%r")
737                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
738   "TARGET_SHMEDIA"
739   "cmpeq        %1, %N2, %0"
740   [(set_attr "type" "cmp_media")])
741
742 (define_insn "cmpgtdi_media"
743   [(set (match_operand:DI 0 "register_operand" "=r")
744         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
745                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
746   "TARGET_SHMEDIA"
747   "cmpgt        %N1, %N2, %0"
748   [(set_attr "type" "cmp_media")])
749
750 (define_insn "cmpgtudi_media"
751   [(set (match_operand:DI 0 "register_operand" "=r")
752         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
753                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
754   "TARGET_SHMEDIA"
755   "cmpgtu       %N1, %N2, %0"
756   [(set_attr "type" "cmp_media")])
757
758 ;; We save the compare operands in the cmpxx patterns and use them when
759 ;; we generate the branch.
760
761 (define_expand "cmpdi"
762   [(set (reg:SI T_REG)
763         (compare (match_operand:DI 0 "arith_operand" "")
764                  (match_operand:DI 1 "arith_operand" "")))]
765   "TARGET_SH2 || TARGET_SHMEDIA"
766   "
767 {
768   sh_compare_op0 = operands[0];
769   sh_compare_op1 = operands[1];
770   DONE;
771 }")
772 ;; -------------------------------------------------------------------------
773 ;; Conditional move instructions
774 ;; -------------------------------------------------------------------------
775
776 ;; The insn names may seem reversed, but note that cmveq performs the move
777 ;; if op1 == 0, and cmvne does it if op1 != 0.
778
779 (define_insn "movdicc_false"
780   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
781         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
782                              (const_int 0))
783          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
784          (match_operand:DI 3 "arith_reg_operand" "0")))]
785   "TARGET_SHMEDIA"
786   "cmveq        %1, %N2, %0"
787   [(set_attr "type" "arith_media")])
788
789 (define_insn "movdicc_true"
790   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
791         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
792                              (const_int 0))
793          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
794          (match_operand:DI 3 "arith_reg_operand" "0")))]
795   "TARGET_SHMEDIA"
796   "cmvne        %1, %N2, %0"
797   [(set_attr "type" "arith_media")])
798
799 (define_expand "movdicc"
800   [(set (match_operand:DI 0 "register_operand" "")
801         (if_then_else:DI (match_operand 1 "comparison_operator" "")
802                          (match_operand:DI 2 "register_operand" "")
803                          (match_operand:DI 3 "register_operand" "")))]
804   "TARGET_SHMEDIA"
805   "
806 {
807   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
808       && GET_MODE (sh_compare_op0) == DImode
809       && sh_compare_op1 == const0_rtx)
810     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
811                                   sh_compare_op0, sh_compare_op1);
812   else
813     {
814       rtx tmp;
815
816       if (no_new_pseudos)
817         FAIL;
818
819       tmp = gen_reg_rtx (DImode);
820
821       switch (GET_CODE (operands[1]))
822         {
823         case EQ:
824           emit_insn (gen_seq (tmp));
825           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
826           break;
827
828         case NE:
829           emit_insn (gen_seq (tmp));
830           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
831           break;
832
833         case GT:
834           emit_insn (gen_sgt (tmp));
835           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
836           break;
837
838         case LT:
839           emit_insn (gen_slt (tmp));
840           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
841           break;
842
843         case GE:
844           emit_insn (gen_slt (tmp));
845           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
846           break;
847
848         case LE:
849           emit_insn (gen_sgt (tmp));
850           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
851           break;
852
853         case GTU:
854           emit_insn (gen_sgtu (tmp));
855           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
856           break;
857
858         case LTU:
859           emit_insn (gen_sltu (tmp));
860           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
861           break;
862
863         case GEU:
864           emit_insn (gen_sltu (tmp));
865           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
866           break;
867
868         case LEU:
869           emit_insn (gen_sgtu (tmp));
870           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
871           break;
872
873         case UNORDERED:
874           emit_insn (gen_sunordered (tmp));
875           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
876           break;
877
878         case ORDERED:
879           emit_insn (gen_sunordered (tmp));
880           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
881           break;
882
883         case UNEQ:
884         case UNGE:
885         case UNGT:
886         case UNLE:
887         case UNLT:
888         case LTGT:
889           FAIL;
890
891         default:
892           abort ();
893         }
894     }
895 }")
896 \f
897 ;; -------------------------------------------------------------------------
898 ;; Addition instructions
899 ;; -------------------------------------------------------------------------
900
901 (define_expand "adddi3"
902   [(set (match_operand:DI 0 "arith_reg_operand" "")
903         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
904                  (match_operand:DI 2 "arith_operand" "")))]
905   ""
906   "
907 {
908   if (TARGET_SH1)
909     {
910       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
911         FAIL;
912       operands[2] = force_reg (DImode, operands[2]);
913       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
914       DONE;
915     }
916 }")
917
918 (define_insn "*adddi3_media"
919   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
920         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
921                  (match_operand:DI 2 "arith_operand" "r,I10")))]
922   "TARGET_SHMEDIA"
923   "@
924         add     %1, %2, %0
925         addi    %1, %2, %0"
926   [(set_attr "type" "arith_media")])
927
928 (define_insn "adddi3z_media"
929   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
930         (zero_extend:DI
931          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
932                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
933   "TARGET_SHMEDIA"
934   "addz.l       %1, %N2, %0"
935   [(set_attr "type" "arith_media")])
936
937 (define_insn "adddi3_compact"
938   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
939         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
940                  (match_operand:DI 2 "arith_reg_operand" "r")))
941    (clobber (reg:SI T_REG))]
942   "TARGET_SH1"
943   "#"
944   [(set_attr "length" "6")])
945
946 (define_split
947   [(set (match_operand:DI 0 "arith_reg_operand" "")
948         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
949                  (match_operand:DI 2 "arith_reg_operand" "")))
950    (clobber (reg:SI T_REG))]
951   "TARGET_SH1 && reload_completed"
952   [(const_int 0)]
953   "
954 {
955   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
956   high0 = gen_rtx_REG (SImode,
957                        true_regnum (operands[0])
958                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959   high2 = gen_rtx_REG (SImode,
960                        true_regnum (operands[2])
961                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
962   emit_insn (gen_clrt ());
963   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
964   emit_insn (gen_addc1 (high0, high0, high2));
965   DONE;
966 }")
967
968 (define_insn "addc"
969   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
970         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
971                           (match_operand:SI 2 "arith_reg_operand" "r"))
972                  (reg:SI T_REG)))
973    (set (reg:SI T_REG)
974         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
975   "TARGET_SH1"
976   "addc %2,%0"
977   [(set_attr "type" "arith")])
978
979 (define_insn "addc1"
980   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
981         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
982                           (match_operand:SI 2 "arith_reg_operand" "r"))
983                  (reg:SI T_REG)))
984    (clobber (reg:SI T_REG))]
985   "TARGET_SH1"
986   "addc %2,%0"
987   [(set_attr "type" "arith")])
988
989 (define_expand "addsi3"
990   [(set (match_operand:SI 0 "arith_reg_operand" "")
991         (plus:SI (match_operand:SI 1 "arith_operand" "")
992                  (match_operand:SI 2 "arith_operand" "")))]
993   ""
994   "
995 {
996   if (TARGET_SHMEDIA)
997     operands[1] = force_reg (SImode, operands[1]);
998 }")
999
1000 (define_insn "addsi3_media"
1001   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1002         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1003                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1004   "TARGET_SHMEDIA"
1005   "@
1006         add.l   %1, %2, %0
1007         addi.l  %1, %2, %0"
1008   [(set_attr "type" "arith_media")])
1009
1010 (define_insn "*addsi3_compact"
1011   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1012         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1013                  (match_operand:SI 2 "arith_operand" "rI08")))]
1014   "TARGET_SH1"
1015   "add  %2,%0"
1016   [(set_attr "type" "arith")])
1017
1018 ;; -------------------------------------------------------------------------
1019 ;; Subtraction instructions
1020 ;; -------------------------------------------------------------------------
1021
1022 (define_expand "subdi3"
1023   [(set (match_operand:DI 0 "arith_reg_operand" "")
1024         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1025                   (match_operand:DI 2 "arith_reg_operand" "")))]
1026   ""
1027   "
1028 {
1029   if (TARGET_SH1)
1030     {
1031       operands[1] = force_reg (DImode, operands[1]);
1032       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1033       DONE;
1034     }
1035 }")
1036
1037 (define_insn "*subdi3_media"
1038   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1039         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1040                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1041   "TARGET_SHMEDIA"
1042   "sub  %N1, %2, %0"
1043   [(set_attr "type" "arith_media")])
1044
1045 (define_insn "subdi3_compact"
1046   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1047         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1048                  (match_operand:DI 2 "arith_reg_operand" "r")))
1049    (clobber (reg:SI T_REG))]
1050   "TARGET_SH1"
1051   "#"
1052   [(set_attr "length" "6")])
1053
1054 (define_split
1055   [(set (match_operand:DI 0 "arith_reg_operand" "")
1056         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1057                   (match_operand:DI 2 "arith_reg_operand" "")))
1058    (clobber (reg:SI T_REG))]
1059   "TARGET_SH1 && reload_completed"
1060   [(const_int 0)]
1061   "
1062 {
1063   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1064   high0 = gen_rtx_REG (SImode,
1065                        true_regnum (operands[0])
1066                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067   high2 = gen_rtx_REG (SImode,
1068                        true_regnum (operands[2])
1069                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1070   emit_insn (gen_clrt ());
1071   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1072   emit_insn (gen_subc1 (high0, high0, high2));
1073   DONE;
1074 }")
1075
1076 (define_insn "subc"
1077   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1078         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1079                             (match_operand:SI 2 "arith_reg_operand" "r"))
1080                   (reg:SI T_REG)))
1081    (set (reg:SI T_REG)
1082         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1083                           (reg:SI T_REG))
1084                 (match_dup 1)))]
1085   "TARGET_SH1"
1086   "subc %2,%0"
1087   [(set_attr "type" "arith")])
1088
1089 (define_insn "subc1"
1090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1092                             (match_operand:SI 2 "arith_reg_operand" "r"))
1093                   (reg:SI T_REG)))
1094    (clobber (reg:SI T_REG))]
1095   "TARGET_SH1"
1096   "subc %2,%0"
1097   [(set_attr "type" "arith")])
1098
1099 (define_insn "*subsi3_internal"
1100   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1101         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1102                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1103   "TARGET_SH1"
1104   "sub  %2,%0"
1105   [(set_attr "type" "arith")])
1106
1107 (define_insn "*subsi3_media"
1108   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1109         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1110                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1111   "TARGET_SHMEDIA"
1112   "sub.l        %N1, %2, %0"
1113   [(set_attr "type" "arith_media")])
1114
1115 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1116 ;; will sometimes save one instruction.  Otherwise we might get
1117 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1118 ;; are the same.
1119
1120 (define_expand "subsi3"
1121   [(set (match_operand:SI 0 "arith_reg_operand" "")
1122         (minus:SI (match_operand:SI 1 "arith_operand" "")
1123                   (match_operand:SI 2 "arith_reg_operand" "")))]
1124   ""
1125   "
1126 {
1127   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1128     {
1129       emit_insn (gen_negsi2 (operands[0], operands[2]));
1130       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1131       DONE;
1132     }
1133   if (TARGET_SHMEDIA)
1134     {
1135       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1136         FAIL;
1137       if (operands[1] != const0_rtx)
1138         operands[1] = force_reg (SImode, operands[1]);
1139     }
1140 }")
1141 \f
1142 ;; -------------------------------------------------------------------------
1143 ;; Division instructions
1144 ;; -------------------------------------------------------------------------
1145
1146 ;; We take advantage of the library routines which don't clobber as many
1147 ;; registers as a normal function call would.
1148
1149 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1150 ;; also has an effect on the register that holds the address of the sfunc.
1151 ;; To make this work, we have an extra dummy insn that shows the use
1152 ;; of this register for reorg.
1153
1154 (define_insn "use_sfunc_addr"
1155   [(set (reg:SI PR_REG)
1156         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1157   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1158   ""
1159   [(set_attr "length" "0")])
1160
1161 (define_insn "udivsi3_sh2a"
1162   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1163         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1164                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1165   "TARGET_SH2A"
1166   "divu %2,%1"
1167   [(set_attr "type" "arith")])
1168
1169 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1170 ;; hard register 0.  If we used hard register 0, then the next instruction
1171 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1172 ;; gets allocated to a stack slot that needs its address reloaded, then
1173 ;; there is nothing to prevent reload from using r0 to reload the address.
1174 ;; This reload would clobber the value in r0 we are trying to store.
1175 ;; If we let reload allocate r0, then this problem can never happen.
1176
1177 (define_insn "udivsi3_i1"
1178   [(set (match_operand:SI 0 "register_operand" "=z")
1179         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1180    (clobber (reg:SI T_REG))
1181    (clobber (reg:SI PR_REG))
1182    (clobber (reg:SI R4_REG))
1183    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1184   "TARGET_SH1 && ! TARGET_SH4"
1185   "jsr  @%1%#"
1186   [(set_attr "type" "sfunc")
1187    (set_attr "needs_delay_slot" "yes")])
1188
1189 ; Since shmedia-nofpu code could be linked against shcompact code, and
1190 ; the udivsi3 libcall has the same name, we must consider all registers
1191 ; clobbered that are in the union of the registers clobbered by the
1192 ; shmedia and the shcompact implementation.  Note, if the shcompact
1193 ; implementation actually used shcompact code, we'd need to clobber
1194 ; also r23 and fr23.
1195 (define_insn "udivsi3_i1_media"
1196   [(set (match_operand:SI 0 "register_operand" "=z")
1197         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1198    (clobber (reg:SI T_MEDIA_REG))
1199    (clobber (reg:SI PR_MEDIA_REG))
1200    (clobber (reg:SI R20_REG))
1201    (clobber (reg:SI R21_REG))
1202    (clobber (reg:SI R22_REG))
1203    (clobber (reg:DI TR0_REG))
1204    (clobber (reg:DI TR1_REG))
1205    (clobber (reg:DI TR2_REG))
1206    (use (match_operand:DI 1 "target_operand" "b"))]
1207   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1208   "blink        %1, r18"
1209   [(set_attr "type" "sfunc")
1210    (set_attr "needs_delay_slot" "yes")])
1211
1212 (define_expand "udivsi3_i4_media"
1213   [(set (match_dup 3)
1214         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1215    (set (match_dup 4)
1216         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1217    (set (match_dup 5) (float:DF (match_dup 3)))
1218    (set (match_dup 6) (float:DF (match_dup 4)))
1219    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1220    (set (match_dup 8) (fix:DI (match_dup 7)))
1221    (set (match_operand:SI 0 "register_operand" "")
1222         (truncate:SI (match_dup 8)))]
1223   "TARGET_SHMEDIA_FPU"
1224   "
1225 {
1226   operands[3] = gen_reg_rtx (DImode);
1227   operands[4] = gen_reg_rtx (DImode);
1228   operands[5] = gen_reg_rtx (DFmode);
1229   operands[6] = gen_reg_rtx (DFmode);
1230   operands[7] = gen_reg_rtx (DFmode);
1231   operands[8] = gen_reg_rtx (DImode);
1232 }")
1233
1234 (define_insn "udivsi3_i4"
1235   [(set (match_operand:SI 0 "register_operand" "=y")
1236         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1237    (clobber (reg:SI T_REG))
1238    (clobber (reg:SI PR_REG))
1239    (clobber (reg:DF DR0_REG))
1240    (clobber (reg:DF DR2_REG))
1241    (clobber (reg:DF DR4_REG))
1242    (clobber (reg:SI R0_REG))
1243    (clobber (reg:SI R1_REG))
1244    (clobber (reg:SI R4_REG))
1245    (clobber (reg:SI R5_REG))
1246    (use (reg:PSI FPSCR_REG))
1247    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1248   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1249   "jsr  @%1%#"
1250   [(set_attr "type" "sfunc")
1251    (set_attr "fp_mode" "double")
1252    (set_attr "needs_delay_slot" "yes")])
1253
1254 (define_insn "udivsi3_i4_single"
1255   [(set (match_operand:SI 0 "register_operand" "=y")
1256         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257    (clobber (reg:SI T_REG))
1258    (clobber (reg:SI PR_REG))
1259    (clobber (reg:DF DR0_REG))
1260    (clobber (reg:DF DR2_REG))
1261    (clobber (reg:DF DR4_REG))
1262    (clobber (reg:SI R0_REG))
1263    (clobber (reg:SI R1_REG))
1264    (clobber (reg:SI R4_REG))
1265    (clobber (reg:SI R5_REG))
1266    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1268   "jsr  @%1%#"
1269   [(set_attr "type" "sfunc")
1270    (set_attr "needs_delay_slot" "yes")])
1271
1272 (define_expand "udivsi3"
1273   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1274    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1275    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1276    (parallel [(set (match_operand:SI 0 "register_operand" "")
1277                    (udiv:SI (reg:SI R4_REG)
1278                             (reg:SI R5_REG)))
1279               (clobber (reg:SI T_REG))
1280               (clobber (reg:SI PR_REG))
1281               (clobber (reg:SI R4_REG))
1282               (use (match_dup 3))])]
1283   ""
1284   "
1285 {
1286   rtx first, last;
1287
1288   operands[3] = gen_reg_rtx (Pmode);
1289   /* Emit the move of the address to a pseudo outside of the libcall.  */
1290   if (TARGET_HARD_SH4 && TARGET_SH2E)
1291     {
1292       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1293       if (TARGET_FPU_SINGLE)
1294         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1295       else
1296         last = gen_udivsi3_i4 (operands[0], operands[3]);
1297     }
1298   else if (TARGET_SHMEDIA_FPU)
1299     {
1300       operands[1] = force_reg (SImode, operands[1]);
1301       operands[2] = force_reg (SImode, operands[2]);
1302       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1303       DONE;
1304     }
1305   else if (TARGET_SH2A)
1306     {
1307       operands[1] = force_reg (SImode, operands[1]);
1308       operands[2] = force_reg (SImode, operands[2]);
1309       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1310       DONE;
1311     }
1312   else if (TARGET_SH5)
1313     {
1314       emit_move_insn (operands[3],
1315                       function_symbol (TARGET_FPU_ANY
1316                                        ? \"__udivsi3_i4\"
1317                                        : \"__udivsi3\"));
1318
1319       if (TARGET_SHMEDIA)
1320         last = gen_udivsi3_i1_media (operands[0],
1321                                      Pmode == DImode
1322                                      ? operands[3]
1323                                      : gen_rtx_SUBREG (DImode, operands[3],
1324                                                        0));
1325       else if (TARGET_FPU_ANY)
1326         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1327       else
1328         last = gen_udivsi3_i1 (operands[0], operands[3]);
1329     }
1330   else
1331     {
1332       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1333       last = gen_udivsi3_i1 (operands[0], operands[3]);
1334     }
1335   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1336   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1337   last = emit_insn (last);
1338   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1339      invariant code motion can move it.  */
1340   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1341   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1342   DONE;
1343 }")
1344
1345 (define_insn "divsi3_sh2a"
1346   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1347         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1349   "TARGET_SH2A"
1350   "divs %2,%1"
1351   [(set_attr "type" "arith")])
1352
1353 (define_insn "divsi3_i1"
1354   [(set (match_operand:SI 0 "register_operand" "=z")
1355         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1356    (clobber (reg:SI T_REG))
1357    (clobber (reg:SI PR_REG))
1358    (clobber (reg:SI R1_REG))
1359    (clobber (reg:SI R2_REG))
1360    (clobber (reg:SI R3_REG))
1361    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1362   "TARGET_SH1 && ! TARGET_SH4"
1363   "jsr  @%1%#"
1364   [(set_attr "type" "sfunc")
1365    (set_attr "needs_delay_slot" "yes")])
1366
1367 ; Since shmedia-nofpu code could be linked against shcompact code, and
1368 ; the sdivsi3 libcall has the same name, we must consider all registers
1369 ; clobbered that are in the union of the registers clobbered by the
1370 ; shmedia and the shcompact implementation.  Note, if the shcompact
1371 ; implementation actually used shcompact code, we'd need to clobber
1372 ; also r22, r23 and fr23.
1373 (define_insn "divsi3_i1_media"
1374   [(set (match_operand:SI 0 "register_operand" "=z")
1375         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1376    (clobber (reg:SI T_MEDIA_REG))
1377    (clobber (reg:SI PR_MEDIA_REG))
1378    (clobber (reg:SI R1_REG))
1379    (clobber (reg:SI R2_REG))
1380    (clobber (reg:SI R3_REG))
1381    (clobber (reg:SI R20_REG))
1382    (clobber (reg:SI R21_REG))
1383    (clobber (reg:DI TR0_REG))
1384    (clobber (reg:DI TR1_REG))
1385    (clobber (reg:DI TR2_REG))
1386    (use (match_operand:DI 1 "target_operand" "b"))]
1387   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1388   "blink        %1, r18"
1389   [(set_attr "type" "sfunc")])
1390
1391 (define_expand "divsi3_i4_media"
1392   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1393    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1394    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1395    (set (match_operand:SI 0 "register_operand" "=r")
1396         (fix:SI (match_dup 5)))]
1397   "TARGET_SHMEDIA_FPU"
1398   "
1399 {
1400   operands[3] = gen_reg_rtx (DFmode);
1401   operands[4] = gen_reg_rtx (DFmode);
1402   operands[5] = gen_reg_rtx (DFmode);
1403 }")
1404
1405 (define_insn "divsi3_i4"
1406   [(set (match_operand:SI 0 "register_operand" "=y")
1407         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1408    (clobber (reg:SI PR_REG))
1409    (clobber (reg:DF DR0_REG))
1410    (clobber (reg:DF DR2_REG))
1411    (use (reg:PSI FPSCR_REG))
1412    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1413   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1414   "jsr  @%1%#"
1415   [(set_attr "type" "sfunc")
1416    (set_attr "fp_mode" "double")
1417    (set_attr "needs_delay_slot" "yes")])
1418
1419 (define_insn "divsi3_i4_single"
1420   [(set (match_operand:SI 0 "register_operand" "=y")
1421         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1422    (clobber (reg:SI PR_REG))
1423    (clobber (reg:DF DR0_REG))
1424    (clobber (reg:DF DR2_REG))
1425    (clobber (reg:SI R2_REG))
1426    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1427   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1428   "jsr  @%1%#"
1429   [(set_attr "type" "sfunc")
1430    (set_attr "needs_delay_slot" "yes")])
1431
1432 (define_expand "divsi3"
1433   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1434    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1435    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1436    (parallel [(set (match_operand:SI 0 "register_operand" "")
1437                    (div:SI (reg:SI R4_REG)
1438                            (reg:SI R5_REG)))
1439               (clobber (reg:SI T_REG))
1440               (clobber (reg:SI PR_REG))
1441               (clobber (reg:SI R1_REG))
1442               (clobber (reg:SI R2_REG))
1443               (clobber (reg:SI R3_REG))
1444               (use (match_dup 3))])]
1445   ""
1446   "
1447 {
1448   rtx first, last;
1449
1450   operands[3] = gen_reg_rtx (Pmode);
1451   /* Emit the move of the address to a pseudo outside of the libcall.  */
1452   if (TARGET_HARD_SH4 && TARGET_SH2E)
1453     {
1454       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1455       if (TARGET_FPU_SINGLE)
1456         last = gen_divsi3_i4_single (operands[0], operands[3]);
1457       else
1458         last = gen_divsi3_i4 (operands[0], operands[3]);
1459     }
1460   else if (TARGET_SH2A)
1461     {
1462       operands[1] = force_reg (SImode, operands[1]);
1463       operands[2] = force_reg (SImode, operands[2]);
1464       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1465       DONE;
1466     }
1467   else if (TARGET_SHMEDIA_FPU)
1468     {
1469       operands[1] = force_reg (SImode, operands[1]);
1470       operands[2] = force_reg (SImode, operands[2]);
1471       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1472       DONE;
1473     }
1474   else if (TARGET_SH5)
1475     {
1476       emit_move_insn (operands[3],
1477                       function_symbol (TARGET_FPU_ANY
1478                                        ? \"__sdivsi3_i4\"
1479                                        : \"__sdivsi3\"));
1480
1481       if (TARGET_SHMEDIA)
1482         last = gen_divsi3_i1_media (operands[0],
1483                                     Pmode == DImode
1484                                     ? operands[3]
1485                                     : gen_rtx_SUBREG (DImode, operands[3],
1486                                                       0));
1487       else if (TARGET_FPU_ANY)
1488         last = gen_divsi3_i4_single (operands[0], operands[3]);
1489       else
1490         last = gen_divsi3_i1 (operands[0], operands[3]);
1491     }
1492   else
1493     {
1494       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1495       last = gen_divsi3_i1 (operands[0], operands[3]);
1496     }
1497   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1498   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1499   last = emit_insn (last);
1500   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1501      invariant code motion can move it.  */
1502   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1503   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1504   DONE;
1505 }")
1506 \f
1507 ;; -------------------------------------------------------------------------
1508 ;; Multiplication instructions
1509 ;; -------------------------------------------------------------------------
1510
1511 (define_insn "umulhisi3_i"
1512   [(set (reg:SI MACL_REG)
1513         (mult:SI (zero_extend:SI
1514                   (match_operand:HI 0 "arith_reg_operand" "r"))
1515                  (zero_extend:SI
1516                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1517   "TARGET_SH1"
1518   "mulu.w       %1,%0"
1519   [(set_attr "type" "smpy")])
1520
1521 (define_insn "mulhisi3_i"
1522   [(set (reg:SI MACL_REG)
1523         (mult:SI (sign_extend:SI
1524                   (match_operand:HI 0 "arith_reg_operand" "r"))
1525                  (sign_extend:SI
1526                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1527   "TARGET_SH1"
1528   "muls.w       %1,%0"
1529   [(set_attr "type" "smpy")])
1530
1531 (define_expand "mulhisi3"
1532   [(set (reg:SI MACL_REG)
1533         (mult:SI (sign_extend:SI
1534                   (match_operand:HI 1 "arith_reg_operand" ""))
1535                  (sign_extend:SI
1536                   (match_operand:HI 2 "arith_reg_operand" ""))))
1537    (set (match_operand:SI 0 "arith_reg_operand" "")
1538         (reg:SI MACL_REG))]
1539   "TARGET_SH1"
1540   "
1541 {
1542   rtx first, last;
1543
1544   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1545   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1546   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1547      invariant code motion can move it.  */
1548   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1549   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1550   /* expand_binop can't find a suitable code in umul_widen_optab to
1551      make a REG_EQUAL note from, so make one here.
1552      See also smulsi3_highpart.
1553      ??? Alternatively, we could put this at the calling site of expand_binop,
1554      i.e. expand_expr.  */
1555   REG_NOTES (last)
1556     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1557                          REG_NOTES (last));
1558   DONE;
1559 }")
1560
1561 (define_expand "umulhisi3"
1562   [(set (reg:SI MACL_REG)
1563         (mult:SI (zero_extend:SI
1564                   (match_operand:HI 1 "arith_reg_operand" ""))
1565                  (zero_extend:SI
1566                   (match_operand:HI 2 "arith_reg_operand" ""))))
1567    (set (match_operand:SI 0 "arith_reg_operand" "")
1568         (reg:SI MACL_REG))]
1569   "TARGET_SH1"
1570   "
1571 {
1572   rtx first, last;
1573
1574   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1575   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1576   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1577      invariant code motion can move it.  */
1578   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1579   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1580   /* expand_binop can't find a suitable code in umul_widen_optab to
1581      make a REG_EQUAL note from, so make one here.
1582      See also smulsi3_highpart.
1583      ??? Alternatively, we could put this at the calling site of expand_binop,
1584      i.e. expand_expr.  */
1585   REG_NOTES (last)
1586     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1587                          REG_NOTES (last));
1588   DONE;
1589 }")
1590
1591 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1592 ;; a call to a routine which clobbers known registers.
1593
1594 (define_insn ""
1595   [(set (match_operand:SI 1 "register_operand" "=z")
1596         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1597    (clobber (reg:SI MACL_REG))
1598    (clobber (reg:SI T_REG))
1599    (clobber (reg:SI PR_REG))
1600    (clobber (reg:SI R3_REG))
1601    (clobber (reg:SI R2_REG))
1602    (clobber (reg:SI R1_REG))
1603    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1604   "TARGET_SH1"
1605   "jsr  @%0%#"
1606   [(set_attr "type" "sfunc")
1607    (set_attr "needs_delay_slot" "yes")])
1608
1609 (define_expand "mulsi3_call"
1610   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1611    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1612    (parallel[(set (match_operand:SI 0 "register_operand" "")
1613                   (mult:SI (reg:SI R4_REG)
1614                            (reg:SI R5_REG)))
1615              (clobber (reg:SI MACL_REG))
1616              (clobber (reg:SI T_REG))
1617              (clobber (reg:SI PR_REG))
1618              (clobber (reg:SI R3_REG))
1619              (clobber (reg:SI R2_REG))
1620              (clobber (reg:SI R1_REG))
1621              (use (match_operand:SI 3 "register_operand" ""))])]
1622   "TARGET_SH1"
1623   "")
1624
1625 (define_insn "mul_r"
1626   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1627         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1628                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1629   "TARGET_SH2A"
1630   "mulr %2,%0"
1631   [(set_attr "type" "dmpy")])
1632
1633 (define_insn "mul_l"
1634   [(set (reg:SI MACL_REG)
1635         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1636                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1637   "TARGET_SH2"
1638   "mul.l        %1,%0"
1639   [(set_attr "type" "dmpy")])
1640
1641 (define_expand "mulsi3"
1642   [(set (reg:SI MACL_REG)
1643         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1644                   (match_operand:SI 2 "arith_reg_operand" "")))
1645    (set (match_operand:SI 0 "arith_reg_operand" "")
1646         (reg:SI MACL_REG))]
1647   "TARGET_SH1"
1648   "
1649 {
1650   rtx first, last;
1651
1652   if (!TARGET_SH2)
1653     {
1654       /* The address must be set outside the libcall,
1655          since it goes into a pseudo.  */
1656       rtx sym = function_symbol (\"__mulsi3\");
1657       rtx addr = force_reg (SImode, sym);
1658       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1659                                    operands[2], addr);
1660       first = insns;
1661       last = emit_insn (insns);
1662     }
1663   else
1664     {
1665       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1666
1667       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1668       /* consec_sets_giv can only recognize the first insn that sets a
1669          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1670          note.  */
1671       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1672     }
1673   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1674      invariant code motion can move it.  */
1675   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1676   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1677   DONE;
1678 }")
1679
1680 (define_insn "mulsidi3_i"
1681   [(set (reg:SI MACH_REG)
1682         (truncate:SI
1683          (lshiftrt:DI
1684           (mult:DI
1685            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1686            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1687           (const_int 32))))
1688    (set (reg:SI MACL_REG)
1689         (mult:SI (match_dup 0)
1690                  (match_dup 1)))]
1691   "TARGET_SH2"
1692   "dmuls.l      %1,%0"
1693   [(set_attr "type" "dmpy")])
1694
1695 (define_expand "mulsidi3"
1696   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1697         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1698                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1699   "TARGET_SH2 || TARGET_SHMEDIA"
1700   "
1701 {
1702   if (TARGET_SH2)
1703     {
1704        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1705                                         operands[2]));
1706        DONE;
1707     }
1708 }")
1709
1710 (define_insn "mulsidi3_media"
1711   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1712         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1713                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1714   "TARGET_SHMEDIA"
1715   "muls.l       %1, %2, %0"
1716   [(set_attr "type" "dmpy_media")])
1717
1718 (define_insn "mulsidi3_compact"
1719   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1720         (mult:DI
1721          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1722          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1723    (clobber (reg:SI MACH_REG))
1724    (clobber (reg:SI MACL_REG))]
1725   "TARGET_SH2"
1726   "#")
1727
1728 (define_split
1729   [(set (match_operand:DI 0 "arith_reg_operand" "")
1730         (mult:DI
1731          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1732          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1733    (clobber (reg:SI MACH_REG))
1734    (clobber (reg:SI MACL_REG))]
1735   "TARGET_SH2"
1736   [(const_int 0)]
1737   "
1738 {
1739   rtx low_dst = gen_lowpart (SImode, operands[0]);
1740   rtx high_dst = gen_highpart (SImode, operands[0]);
1741
1742   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1743
1744   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1745   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1746   /* We need something to tag the possible REG_EQUAL notes on to.  */
1747   emit_move_insn (operands[0], operands[0]);
1748   DONE;
1749 }")
1750
1751 (define_insn "umulsidi3_i"
1752   [(set (reg:SI MACH_REG)
1753         (truncate:SI
1754          (lshiftrt:DI
1755           (mult:DI
1756            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1757            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1758           (const_int 32))))
1759    (set (reg:SI MACL_REG)
1760         (mult:SI (match_dup 0)
1761                  (match_dup 1)))]
1762   "TARGET_SH2"
1763   "dmulu.l      %1,%0"
1764   [(set_attr "type" "dmpy")])
1765
1766 (define_expand "umulsidi3"
1767   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1768         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1769                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1770   "TARGET_SH2 || TARGET_SHMEDIA"
1771   "
1772 {
1773   if (TARGET_SH2)
1774     {
1775        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1776                                          operands[2]));
1777        DONE;
1778     }
1779 }")
1780
1781 (define_insn "umulsidi3_media"
1782   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1783         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1784                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1785   "TARGET_SHMEDIA"
1786   "mulu.l       %1, %2, %0"
1787   [(set_attr "type" "dmpy_media")])
1788
1789 (define_insn "umulsidi3_compact"
1790   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1791         (mult:DI
1792          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1793          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1794    (clobber (reg:SI MACH_REG))
1795    (clobber (reg:SI MACL_REG))]
1796   "TARGET_SH2"
1797   "#")
1798
1799 (define_split
1800   [(set (match_operand:DI 0 "arith_reg_operand" "")
1801         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1802                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1803    (clobber (reg:SI MACH_REG))
1804    (clobber (reg:SI MACL_REG))]
1805   "TARGET_SH2"
1806   [(const_int 0)]
1807   "
1808 {
1809   rtx low_dst = gen_lowpart (SImode, operands[0]);
1810   rtx high_dst = gen_highpart (SImode, operands[0]);
1811
1812   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1813
1814   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1815   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1816   /* We need something to tag the possible REG_EQUAL notes on to.  */
1817   emit_move_insn (operands[0], operands[0]);
1818   DONE;
1819 }")
1820
1821 (define_insn "smulsi3_highpart_i"
1822   [(set (reg:SI MACH_REG)
1823         (truncate:SI
1824          (lshiftrt:DI
1825           (mult:DI
1826            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1827            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1828           (const_int 32))))
1829    (clobber (reg:SI MACL_REG))]
1830   "TARGET_SH2"
1831   "dmuls.l      %1,%0"
1832   [(set_attr "type" "dmpy")])
1833
1834 (define_expand "smulsi3_highpart"
1835   [(parallel
1836     [(set (reg:SI MACH_REG)
1837           (truncate:SI
1838            (lshiftrt:DI
1839             (mult:DI
1840              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1842             (const_int 32))))
1843     (clobber (reg:SI MACL_REG))])
1844    (set (match_operand:SI 0 "arith_reg_operand" "")
1845         (reg:SI MACH_REG))]
1846   "TARGET_SH2"
1847   "
1848 {
1849   rtx first, last;
1850
1851   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1852   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1853   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1854      invariant code motion can move it.  */
1855   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1856   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1857   /* expand_binop can't find a suitable code in mul_highpart_optab to
1858      make a REG_EQUAL note from, so make one here.
1859      See also {,u}mulhisi.
1860      ??? Alternatively, we could put this at the calling site of expand_binop,
1861      i.e. expand_mult_highpart.  */
1862   REG_NOTES (last)
1863     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1864                          REG_NOTES (last));
1865   DONE;
1866 }")
1867
1868 (define_insn "umulsi3_highpart_i"
1869   [(set (reg:SI MACH_REG)
1870         (truncate:SI
1871          (lshiftrt:DI
1872           (mult:DI
1873            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1874            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1875           (const_int 32))))
1876    (clobber (reg:SI MACL_REG))]
1877   "TARGET_SH2"
1878   "dmulu.l      %1,%0"
1879   [(set_attr "type" "dmpy")])
1880
1881 (define_expand "umulsi3_highpart"
1882   [(parallel
1883     [(set (reg:SI MACH_REG)
1884           (truncate:SI
1885            (lshiftrt:DI
1886             (mult:DI
1887              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1888              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1889             (const_int 32))))
1890     (clobber (reg:SI MACL_REG))])
1891    (set (match_operand:SI 0 "arith_reg_operand" "")
1892         (reg:SI MACH_REG))]
1893   "TARGET_SH2"
1894   "
1895 {
1896   rtx first, last;
1897
1898   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1899   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1900   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1901      invariant code motion can move it.  */
1902   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1903   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1904   DONE;
1905 }")
1906 \f
1907 ;; -------------------------------------------------------------------------
1908 ;; Logical operations
1909 ;; -------------------------------------------------------------------------
1910
1911 (define_insn "*andsi3_compact"
1912   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1913         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1914                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1915   "TARGET_SH1"
1916   "and  %2,%0"
1917   [(set_attr "type" "arith")])
1918
1919 ;; If the constant is 255, then emit an extu.b instruction instead of an
1920 ;; and, since that will give better code.
1921
1922 (define_expand "andsi3"
1923   [(set (match_operand:SI 0 "arith_reg_operand" "")
1924         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1925                 (match_operand:SI 2 "logical_operand" "")))]
1926   "TARGET_SH1"
1927   "
1928 {
1929   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1930     {
1931       emit_insn (gen_zero_extendqisi2 (operands[0],
1932                                        gen_lowpart (QImode, operands[1])));
1933       DONE;
1934     }
1935 }")
1936
1937 (define_insn_and_split "anddi3"
1938   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1939         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1940                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1941   "TARGET_SHMEDIA"
1942   "@
1943         and     %1, %2, %0
1944         andi    %1, %2, %0
1945         #"
1946   "reload_completed
1947    && ! logical_operand (operands[2], DImode)"
1948   [(const_int 0)]
1949   "
1950 {
1951   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1952     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1953   else
1954     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1955   DONE;
1956 }"
1957   [(set_attr "type" "arith_media")])
1958
1959 (define_insn "andcdi3"
1960   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1961         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1962                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1963   "TARGET_SHMEDIA"
1964   "andc %1,%2,%0"
1965   [(set_attr "type" "arith_media")])
1966
1967 (define_insn "iorsi3"
1968   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1969         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1970                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1971   "TARGET_SH1"
1972   "or   %2,%0"
1973   [(set_attr "type" "arith")])
1974
1975 (define_insn "iordi3"
1976   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1977         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1978                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1979   "TARGET_SHMEDIA"
1980   "@
1981         or      %1, %2, %0
1982         ori     %1, %2, %0"
1983   [(set_attr "type" "arith_media")])
1984
1985 (define_insn "xorsi3"
1986   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1987         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1988                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1989   "TARGET_SH1"
1990   "xor  %2,%0"
1991   [(set_attr "type" "arith")])
1992
1993 (define_insn "xordi3"
1994   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1995         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1996                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1997   "TARGET_SHMEDIA"
1998   "@
1999         xor     %1, %2, %0
2000         xori    %1, %2, %0"
2001   [(set_attr "type" "arith_media")])
2002
2003 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2004 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2005 (define_split
2006   [(set (match_operand:DI 0 "arith_reg_operand" "")
2007         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2008                           [(match_operand 1 "any_register_operand" "")
2009                            (match_operand 2 "any_register_operand" "")])))]
2010   "TARGET_SHMEDIA"
2011   [(set (match_dup 5) (match_dup 4))
2012    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2013 "
2014 {
2015   enum machine_mode inmode = GET_MODE (operands[1]);
2016   int offset = 0;
2017
2018   if (GET_CODE (operands[0]) == SUBREG)
2019     {
2020       offset = SUBREG_BYTE (operands[0]);
2021       operands[0] = SUBREG_REG (operands[0]);
2022     }
2023   if (GET_CODE (operands[0]) != REG)
2024     abort ();
2025   if (! TARGET_LITTLE_ENDIAN)
2026     offset += 8 - GET_MODE_SIZE (inmode);
2027   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2028 }")
2029 \f
2030 ;; -------------------------------------------------------------------------
2031 ;; Shifts and rotates
2032 ;; -------------------------------------------------------------------------
2033
2034 (define_expand "rotldi3"
2035   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2036         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2037                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2038   "TARGET_SHMEDIA"
2039   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2040
2041 (define_insn "rotldi3_mextr"
2042   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2043         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2044                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2045   "TARGET_SHMEDIA"
2046   "*
2047 {
2048   static char templ[16];
2049
2050   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2051            8 - (int) (INTVAL (operands[2]) >> 3));
2052   return templ;
2053 }"
2054   [(set_attr "type" "arith_media")])
2055
2056 (define_expand "rotrdi3"
2057   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2058         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2059                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2060   "TARGET_SHMEDIA"
2061   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2062
2063 (define_insn "rotrdi3_mextr"
2064   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2065         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2066                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2067   "TARGET_SHMEDIA"
2068   "*
2069 {
2070   static char templ[16];
2071
2072   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2073   return templ;
2074 }"
2075   [(set_attr "type" "arith_media")])
2076
2077 (define_insn "rotlsi3_1"
2078   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2079         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2080                    (const_int 1)))
2081    (set (reg:SI T_REG)
2082         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2083   "TARGET_SH1"
2084   "rotl %0"
2085   [(set_attr "type" "arith")])
2086
2087 (define_insn "rotlsi3_31"
2088   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2089         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2090                    (const_int 31)))
2091    (clobber (reg:SI T_REG))]
2092   "TARGET_SH1"
2093   "rotr %0"
2094   [(set_attr "type" "arith")])
2095
2096 (define_insn "rotlsi3_16"
2097   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2098         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2099                    (const_int 16)))]
2100   "TARGET_SH1"
2101   "swap.w       %1,%0"
2102   [(set_attr "type" "arith")])
2103
2104 (define_expand "rotlsi3"
2105   [(set (match_operand:SI 0 "arith_reg_operand" "")
2106         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2107                    (match_operand:SI 2 "immediate_operand" "")))]
2108   "TARGET_SH1"
2109   "
2110 {
2111   static const char rot_tab[] = {
2112     000, 000, 000, 000, 000, 000, 010, 001,
2113     001, 001, 011, 013, 003, 003, 003, 003,
2114     003, 003, 003, 003, 003, 013, 012, 002,
2115     002, 002, 010, 000, 000, 000, 000, 000,
2116   };
2117
2118   int count, choice;
2119
2120   if (GET_CODE (operands[2]) != CONST_INT)
2121     FAIL;
2122   count = INTVAL (operands[2]);
2123   choice = rot_tab[count];
2124   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2125     FAIL;
2126   choice &= 7;
2127   switch (choice)
2128     {
2129     case 0:
2130       emit_move_insn (operands[0], operands[1]);
2131       count -= (count & 16) * 2;
2132       break;
2133     case 3:
2134      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2135      count -= 16;
2136      break;
2137     case 1:
2138     case 2:
2139       {
2140         rtx parts[2];
2141         parts[0] = gen_reg_rtx (SImode);
2142         parts[1] = gen_reg_rtx (SImode);
2143         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2144         emit_move_insn (parts[choice-1], operands[1]);
2145         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2146         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2147         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2148         count = (count & ~16) - 8;
2149       }
2150     }
2151
2152   for (; count > 0; count--)
2153     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2154   for (; count < 0; count++)
2155     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2156
2157   DONE;
2158 }")
2159
2160 (define_insn "*rotlhi3_8"
2161   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2162         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2163                    (const_int 8)))]
2164   "TARGET_SH1"
2165   "swap.b       %1,%0"
2166   [(set_attr "type" "arith")])
2167
2168 (define_expand "rotlhi3"
2169   [(set (match_operand:HI 0 "arith_reg_operand" "")
2170         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2171                    (match_operand:HI 2 "immediate_operand" "")))]
2172   "TARGET_SH1"
2173   "
2174 {
2175   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2176     FAIL;
2177 }")
2178
2179 ;;
2180 ;; shift left
2181
2182 (define_insn "ashlsi3_sh2a"
2183   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2184         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2185                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2186   "TARGET_SH2A"
2187   "shad %2,%0"
2188   [(set_attr "type" "arith")
2189    (set_attr "length" "4")])
2190
2191 ;; This pattern is used by init_expmed for computing the costs of shift
2192 ;; insns.
2193
2194 (define_insn_and_split "ashlsi3_std"
2195   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2196         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2197                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2198    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2199   "TARGET_SH3
2200    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2201        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2202   "@
2203    shld %2,%0
2204    add  %0,%0
2205    shll%O2      %0
2206    #"
2207   "TARGET_SH3
2208    && reload_completed
2209    && GET_CODE (operands[2]) == CONST_INT
2210    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2211   [(set (match_dup 3) (match_dup 2))
2212    (parallel
2213     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2214      (clobber (match_dup 4))])]
2215   "operands[4] = gen_rtx_SCRATCH (SImode);"
2216   [(set_attr "length" "*,*,*,4")
2217    (set_attr "type" "dyn_shift,arith,arith,arith")])
2218
2219 (define_insn "ashlhi3_k"
2220   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2221         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2222                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2223   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2224   "@
2225         add     %0,%0
2226         shll%O2 %0"
2227   [(set_attr "type" "arith")])
2228
2229 (define_insn "ashlsi3_n"
2230   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2231         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2232                    (match_operand:SI 2 "const_int_operand" "n")))
2233    (clobber (reg:SI T_REG))]
2234   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2235   "#"
2236   [(set (attr "length")
2237         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2238                (const_string "2")
2239                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2240                (const_string "4")
2241                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2242                (const_string "6")]
2243               (const_string "8")))
2244    (set_attr "type" "arith")])
2245
2246 (define_split
2247   [(set (match_operand:SI 0 "arith_reg_operand" "")
2248         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2249                    (match_operand:SI 2 "const_int_operand" "")))
2250    (clobber (reg:SI T_REG))]
2251   "TARGET_SH1 && reload_completed"
2252   [(use (reg:SI R0_REG))]
2253   "
2254 {
2255   gen_shifty_op (ASHIFT, operands);
2256   DONE;
2257 }")
2258
2259 (define_insn "ashlsi3_media"
2260   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2261         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2262                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2263   "TARGET_SHMEDIA"
2264   "@
2265         shlld.l %1, %2, %0
2266         shlli.l %1, %2, %0"
2267   [(set_attr "type" "arith_media")])
2268
2269 (define_expand "ashlsi3"
2270   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2271                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2272                               (match_operand:SI 2 "nonmemory_operand" "")))
2273               (clobber (reg:SI T_REG))])]
2274   ""
2275   "
2276 {
2277   if (TARGET_SHMEDIA)
2278     {
2279       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2280       DONE;
2281     }
2282   if (GET_CODE (operands[2]) == CONST_INT
2283       && sh_dynamicalize_shift_p (operands[2]))
2284     operands[2] = force_reg (SImode, operands[2]);
2285   if (TARGET_SH3)
2286     {
2287       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2288       DONE;
2289     }
2290   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2291     FAIL;
2292 }")
2293
2294 (define_insn "ashlhi3"
2295   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2296         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2297                    (match_operand:HI 2 "const_int_operand" "n")))
2298    (clobber (reg:SI T_REG))]
2299   "TARGET_SH1"
2300   "#"
2301   [(set (attr "length")
2302         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2303                (const_string "2")
2304                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2305                (const_string "4")]
2306               (const_string "6")))
2307    (set_attr "type" "arith")])
2308
2309 (define_split
2310   [(set (match_operand:HI 0 "arith_reg_operand" "")
2311         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2312                    (match_operand:HI 2 "const_int_operand" "")))
2313    (clobber (reg:SI T_REG))]
2314   "TARGET_SH1 && reload_completed"
2315   [(use (reg:SI R0_REG))]
2316   "
2317 {
2318   gen_shifty_hi_op (ASHIFT, operands);
2319   DONE;
2320 }")
2321
2322 ;
2323 ; arithmetic shift right
2324 ;
2325
2326 (define_insn "ashrsi3_sh2a"
2327   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2328         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2329                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2330   "TARGET_SH2A"
2331   "shad %2,%0"
2332   [(set_attr "type" "dyn_shift")
2333    (set_attr "length" "4")])
2334
2335 (define_insn "ashrsi3_k"
2336   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2337         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2338                      (match_operand:SI 2 "const_int_operand" "M")))
2339    (clobber (reg:SI T_REG))]
2340   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2341   "shar %0"
2342   [(set_attr "type" "arith")])
2343
2344 ;; We can't do HImode right shifts correctly unless we start out with an
2345 ;; explicit zero / sign extension; doing that would result in worse overall
2346 ;; code, so just let the machine independent code widen the mode.
2347 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2348
2349
2350 ;; ??? This should be a define expand.
2351
2352 (define_insn "ashrsi2_16"
2353   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2354         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2355                      (const_int 16)))]
2356   "TARGET_SH1"
2357   "#"
2358   [(set_attr "length" "4")])
2359
2360 (define_split
2361   [(set (match_operand:SI 0 "arith_reg_operand" "")
2362         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2363                      (const_int 16)))]
2364   "TARGET_SH1"
2365   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2366    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2367   "operands[2] = gen_lowpart (HImode, operands[0]);")
2368
2369 ;; ??? This should be a define expand.
2370
2371 (define_insn "ashrsi2_31"
2372   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2373         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2374                      (const_int 31)))
2375    (clobber (reg:SI T_REG))]
2376   "TARGET_SH1"
2377   "#"
2378   [(set_attr "length" "4")])
2379
2380 (define_split
2381   [(set (match_operand:SI 0 "arith_reg_operand" "")
2382         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2383                      (const_int 31)))
2384    (clobber (reg:SI T_REG))]
2385   "TARGET_SH1"
2386   [(const_int 0)]
2387   "
2388 {
2389   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2390   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2391   DONE;
2392 }")
2393
2394 (define_insn "ashlsi_c"
2395   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2396         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2397    (set (reg:SI T_REG)
2398         (lt:SI (match_dup 1) (const_int 0)))]
2399   "TARGET_SH1"
2400   "shll %0"
2401   [(set_attr "type" "arith")])
2402
2403 (define_insn "ashrsi3_d"
2404   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2405         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2406                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2407   "TARGET_SH3"
2408   "shad %2,%0"
2409   [(set_attr "type" "dyn_shift")])
2410
2411 (define_insn "ashrsi3_n"
2412   [(set (reg:SI R4_REG)
2413         (ashiftrt:SI (reg:SI R4_REG)
2414                      (match_operand:SI 0 "const_int_operand" "i")))
2415    (clobber (reg:SI T_REG))
2416    (clobber (reg:SI PR_REG))
2417    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2418   "TARGET_SH1"
2419   "jsr  @%1%#"
2420   [(set_attr "type" "sfunc")
2421    (set_attr "needs_delay_slot" "yes")])
2422
2423 (define_insn "ashrsi3_media"
2424   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2425         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2426                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2427   "TARGET_SHMEDIA"
2428   "@
2429         shard.l %1, %2, %0
2430         shari.l %1, %2, %0"
2431   [(set_attr "type" "arith_media")])
2432
2433 (define_expand "ashrsi3"
2434   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2435                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2436                                 (match_operand:SI 2 "nonmemory_operand" "")))
2437               (clobber (reg:SI T_REG))])]
2438   ""
2439   "
2440 {
2441   if (TARGET_SHMEDIA)
2442     {
2443       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2444       DONE;
2445     }
2446   if (expand_ashiftrt (operands))
2447     DONE;
2448   else
2449     FAIL;
2450 }")
2451
2452 ;; logical shift right
2453
2454 (define_insn "lshrsi3_sh2a"
2455   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2456         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2457                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2458   "TARGET_SH2A"
2459   "shld %2,%0"
2460   [(set_attr "type" "dyn_shift")
2461    (set_attr "length" "4")])
2462
2463 (define_insn "lshrsi3_d"
2464   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2465         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2466                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2467   "TARGET_SH3"
2468   "shld %2,%0"
2469   [(set_attr "type" "dyn_shift")])
2470
2471 ;;  Only the single bit shift clobbers the T bit.
2472
2473 (define_insn "lshrsi3_m"
2474   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2475         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2476                      (match_operand:SI 2 "const_int_operand" "M")))
2477    (clobber (reg:SI T_REG))]
2478   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2479   "shlr %0"
2480   [(set_attr "type" "arith")])
2481
2482 (define_insn "lshrsi3_k"
2483   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2484         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2485                      (match_operand:SI 2 "const_int_operand" "P27")))]
2486   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2487    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2488   "shlr%O2      %0"
2489   [(set_attr "type" "arith")])
2490
2491 (define_insn "lshrsi3_n"
2492   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2493         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2494                      (match_operand:SI 2 "const_int_operand" "n")))
2495    (clobber (reg:SI T_REG))]
2496   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2497   "#"
2498   [(set (attr "length")
2499         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2500                (const_string "2")
2501                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2502                (const_string "4")
2503                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2504                (const_string "6")]
2505               (const_string "8")))
2506    (set_attr "type" "arith")])
2507
2508 (define_split
2509   [(set (match_operand:SI 0 "arith_reg_operand" "")
2510         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2511                      (match_operand:SI 2 "const_int_operand" "")))
2512    (clobber (reg:SI T_REG))]
2513   "TARGET_SH1 && reload_completed"
2514   [(use (reg:SI R0_REG))]
2515   "
2516 {
2517   gen_shifty_op (LSHIFTRT, operands);
2518   DONE;
2519 }")
2520
2521 (define_insn "lshrsi3_media"
2522   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2523         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2524                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2525   "TARGET_SHMEDIA"
2526   "@
2527         shlrd.l %1, %2, %0
2528         shlri.l %1, %2, %0"
2529   [(set_attr "type" "arith_media")])
2530
2531 (define_expand "lshrsi3"
2532   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2533                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2534                                 (match_operand:SI 2 "nonmemory_operand" "")))
2535               (clobber (reg:SI T_REG))])]
2536   ""
2537   "
2538 {
2539   if (TARGET_SHMEDIA)
2540     {
2541       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2542       DONE;
2543     }
2544   if (GET_CODE (operands[2]) == CONST_INT
2545       && sh_dynamicalize_shift_p (operands[2]))
2546     operands[2] = force_reg (SImode, operands[2]);
2547   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2548     {
2549       rtx count = copy_to_mode_reg (SImode, operands[2]);
2550       emit_insn (gen_negsi2 (count, count));
2551       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2552       DONE;
2553     }
2554   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2555     FAIL;
2556 }")
2557
2558 ;; ??? This should be a define expand.
2559
2560 (define_insn "ashldi3_k"
2561   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2562         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2563                    (const_int 1)))
2564    (clobber (reg:SI T_REG))]
2565   "TARGET_SH1"
2566   "shll %R0\;rotcl      %S0"
2567   [(set_attr "length" "4")
2568    (set_attr "type" "arith")])
2569
2570 (define_insn "ashldi3_media"
2571   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2572         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2573                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2574   "TARGET_SHMEDIA"
2575   "@
2576         shlld   %1, %2, %0
2577         shlli   %1, %2, %0"
2578   [(set_attr "type" "arith_media")])
2579
2580 (define_expand "ashldi3"
2581   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2582                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2583                               (match_operand:DI 2 "immediate_operand" "")))
2584               (clobber (reg:SI T_REG))])]
2585   ""
2586   "
2587 {
2588   if (TARGET_SHMEDIA)
2589     {
2590       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2591       DONE;
2592     }
2593   if (GET_CODE (operands[2]) != CONST_INT
2594       || INTVAL (operands[2]) != 1)
2595     FAIL;
2596 }")
2597
2598 ;; ??? This should be a define expand.
2599
2600 (define_insn "lshrdi3_k"
2601   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2602         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2603                      (const_int 1)))
2604    (clobber (reg:SI T_REG))]
2605   "TARGET_SH1"
2606   "shlr %S0\;rotcr      %R0"
2607   [(set_attr "length" "4")
2608    (set_attr "type" "arith")])
2609
2610 (define_insn "lshrdi3_media"
2611   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2612         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2613                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2614   "TARGET_SHMEDIA"
2615   "@
2616         shlrd   %1, %2, %0
2617         shlri   %1, %2, %0"
2618   [(set_attr "type" "arith_media")])
2619
2620 (define_expand "lshrdi3"
2621   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2622                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2623                                (match_operand:DI 2 "immediate_operand" "")))
2624              (clobber (reg:SI T_REG))])]
2625   ""
2626   "
2627 {
2628   if (TARGET_SHMEDIA)
2629     {
2630       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2631       DONE;
2632     }
2633   if (GET_CODE (operands[2]) != CONST_INT
2634       || INTVAL (operands[2]) != 1)
2635     FAIL;
2636 }")
2637
2638 ;; ??? This should be a define expand.
2639
2640 (define_insn "ashrdi3_k"
2641   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2642         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2643                      (const_int 1)))
2644    (clobber (reg:SI T_REG))]
2645   "TARGET_SH1"
2646   "shar %S0\;rotcr      %R0"
2647   [(set_attr "length" "4")
2648    (set_attr "type" "arith")])
2649
2650 (define_insn "ashrdi3_media"
2651   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2652         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2653                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2654   "TARGET_SHMEDIA"
2655   "@
2656         shard   %1, %2, %0
2657         shari   %1, %2, %0"
2658   [(set_attr "type" "arith_media")])
2659
2660 (define_expand "ashrdi3"
2661   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2662                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2663                                 (match_operand:DI 2 "immediate_operand" "")))
2664               (clobber (reg:SI T_REG))])]
2665   ""
2666   "
2667 {
2668   if (TARGET_SHMEDIA)
2669     {
2670       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2671       DONE;
2672     }
2673   if (GET_CODE (operands[2]) != CONST_INT
2674       || INTVAL (operands[2]) != 1)
2675     FAIL;
2676 }")
2677
2678 ;; combined left/right shift
2679
2680 (define_split
2681   [(set (match_operand:SI 0 "register_operand" "")
2682         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2683                            (match_operand:SI 2 "const_int_operand" ""))
2684                 (match_operand:SI 3 "const_int_operand" "")))]
2685   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2686   [(use (reg:SI R0_REG))]
2687   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2688    DONE;")
2689
2690 (define_split
2691   [(set (match_operand:SI 0 "register_operand" "")
2692         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2693                            (match_operand:SI 2 "const_int_operand" ""))
2694                 (match_operand:SI 3 "const_int_operand" "")))
2695    (clobber (reg:SI T_REG))]
2696   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2697   [(use (reg:SI R0_REG))]
2698   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2699    DONE;")
2700
2701 (define_insn ""
2702   [(set (match_operand:SI 0 "register_operand" "=r")
2703         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2704                            (match_operand:SI 2 "const_int_operand" "n"))
2705                 (match_operand:SI 3 "const_int_operand" "n")))
2706    (clobber (reg:SI T_REG))]
2707   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2708  "#"
2709   [(set (attr "length")
2710         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2711                (const_string "4")
2712                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2713                (const_string "6")
2714                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2715                (const_string "8")
2716                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2717                (const_string "10")
2718                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2719                (const_string "12")
2720                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2721                (const_string "14")
2722                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2723                (const_string "16")]
2724               (const_string "18")))
2725    (set_attr "type" "arith")])
2726
2727 (define_insn ""
2728   [(set (match_operand:SI 0 "register_operand" "=z")
2729         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730                            (match_operand:SI 2 "const_int_operand" "n"))
2731                 (match_operand:SI 3 "const_int_operand" "n")))
2732    (clobber (reg:SI T_REG))]
2733   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2734  "#"
2735   [(set (attr "length")
2736         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2737                (const_string "4")
2738                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2739                (const_string "6")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2741                (const_string "8")]
2742               (const_string "10")))
2743    (set_attr "type" "arith")])
2744
2745 ;; shift left / and combination with a scratch register: The combine pass
2746 ;; does not accept the individual instructions, even though they are
2747 ;; cheap.  But it needs a precise description so that it is usable after
2748 ;; reload.
2749 (define_insn "and_shl_scratch"
2750   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2751         (lshiftrt:SI
2752          (ashift:SI
2753           (and:SI
2754            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2755                         (match_operand:SI 2 "const_int_operand" "N,n"))
2756            (match_operand:SI 3 "" "0,r"))
2757           (match_operand:SI 4 "const_int_operand" "n,n"))
2758          (match_operand:SI 5 "const_int_operand" "n,n")))
2759    (clobber (reg:SI T_REG))]
2760   "TARGET_SH1"
2761   "#"
2762   [(set (attr "length")
2763         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2764                (const_string "4")
2765                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2766                (const_string "6")
2767                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2768                (const_string "8")
2769                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2770                (const_string "10")]
2771               (const_string "12")))
2772    (set_attr "type" "arith")])
2773
2774 (define_split
2775   [(set (match_operand:SI 0 "register_operand" "")
2776         (lshiftrt:SI
2777          (ashift:SI
2778           (and:SI
2779            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2780                         (match_operand:SI 2 "const_int_operand" ""))
2781            (match_operand:SI 3 "register_operand" ""))
2782           (match_operand:SI 4 "const_int_operand" ""))
2783          (match_operand:SI 5 "const_int_operand" "")))
2784    (clobber (reg:SI T_REG))]
2785   "TARGET_SH1"
2786   [(use (reg:SI R0_REG))]
2787   "
2788 {
2789   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2790
2791   if (INTVAL (operands[2]))
2792     {
2793       gen_shifty_op (LSHIFTRT, operands);
2794     }
2795   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2796   operands[2] = operands[4];
2797   gen_shifty_op (ASHIFT, operands);
2798   if (INTVAL (operands[5]))
2799     {
2800       operands[2] = operands[5];
2801       gen_shifty_op (LSHIFTRT, operands);
2802     }
2803   DONE;
2804 }")
2805
2806 ;; signed left/right shift combination.
2807 (define_split
2808   [(set (match_operand:SI 0 "register_operand" "")
2809         (sign_extract:SI
2810          (ashift:SI (match_operand:SI 1 "register_operand" "")
2811                     (match_operand:SI 2 "const_int_operand" ""))
2812          (match_operand:SI 3 "const_int_operand" "")
2813          (const_int 0)))
2814    (clobber (reg:SI T_REG))]
2815   "TARGET_SH1"
2816   [(use (reg:SI R0_REG))]
2817   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2818    DONE;")
2819
2820 (define_insn "shl_sext_ext"
2821   [(set (match_operand:SI 0 "register_operand" "=r")
2822         (sign_extract:SI
2823          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2824                     (match_operand:SI 2 "const_int_operand" "n"))
2825          (match_operand:SI 3 "const_int_operand" "n")
2826          (const_int 0)))
2827    (clobber (reg:SI T_REG))]
2828   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2829   "#"
2830   [(set (attr "length")
2831         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2832                (const_string "2")
2833                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2834                (const_string "4")
2835                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2836                (const_string "6")
2837                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2838                (const_string "8")
2839                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2840                (const_string "10")
2841                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2842                (const_string "12")
2843                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2844                (const_string "14")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2846                (const_string "16")]
2847               (const_string "18")))
2848     (set_attr "type" "arith")])
2849
2850 (define_insn "shl_sext_sub"
2851   [(set (match_operand:SI 0 "register_operand" "=z")
2852         (sign_extract:SI
2853          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2854                     (match_operand:SI 2 "const_int_operand" "n"))
2855          (match_operand:SI 3 "const_int_operand" "n")
2856          (const_int 0)))
2857    (clobber (reg:SI T_REG))]
2858   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2859   "#"
2860   [(set (attr "length")
2861         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2862                (const_string "6")
2863                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2864                (const_string "8")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2866                (const_string "10")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2868                (const_string "12")]
2869               (const_string "14")))
2870     (set_attr "type" "arith")])
2871
2872 ;; These patterns are found in expansions of DImode shifts by 16, and
2873 ;; allow the xtrct instruction to be generated from C source.
2874
2875 (define_insn "xtrct_left"
2876   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2877         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2878                            (const_int 16))
2879                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2880                              (const_int 16))))]
2881   "TARGET_SH1"
2882   "xtrct        %1,%0"
2883   [(set_attr "type" "arith")])
2884
2885 (define_insn "xtrct_right"
2886   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2887         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2888                              (const_int 16))
2889                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2890                            (const_int 16))))]
2891   "TARGET_SH1"
2892   "xtrct        %2,%0"
2893   [(set_attr "type" "arith")])
2894
2895 ;; -------------------------------------------------------------------------
2896 ;; Unary arithmetic
2897 ;; -------------------------------------------------------------------------
2898
2899 (define_insn "negc"
2900   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2901         (neg:SI (plus:SI (reg:SI T_REG)
2902                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2903    (set (reg:SI T_REG)
2904         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2905                (const_int 0)))]
2906   "TARGET_SH1"
2907   "negc %1,%0"
2908   [(set_attr "type" "arith")])
2909
2910 (define_insn "*negdi_media"
2911   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2912         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2913   "TARGET_SHMEDIA"
2914   "sub  r63, %1, %0"
2915   [(set_attr "type" "arith_media")])
2916
2917 (define_expand "negdi2"
2918   [(set (match_operand:DI 0 "arith_reg_operand" "")
2919         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2920   ""
2921   "
2922 {
2923   if (TARGET_SH1)
2924     {
2925       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2926       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2927
2928       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2929       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2930
2931       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2932       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2933
2934       emit_insn (gen_clrt ());
2935       emit_insn (gen_negc (low_dst, low_src));
2936       emit_insn (gen_negc (high_dst, high_src));
2937       DONE;
2938     }
2939 }")
2940
2941 (define_insn "negsi2"
2942   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2943         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2944   "TARGET_SH1"
2945   "neg  %1,%0"
2946   [(set_attr "type" "arith")])
2947
2948 (define_insn "one_cmplsi2"
2949   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2951   "TARGET_SH1"
2952   "not  %1,%0"
2953   [(set_attr "type" "arith")])
2954
2955 (define_expand "one_cmpldi2"
2956   [(set (match_operand:DI 0 "arith_reg_operand" "")
2957         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2958                 (const_int -1)))]
2959   "TARGET_SHMEDIA" "")
2960 \f
2961 ;; -------------------------------------------------------------------------
2962 ;; Zero extension instructions
2963 ;; -------------------------------------------------------------------------
2964
2965 (define_insn "zero_extendsidi2"
2966   [(set (match_operand:DI 0 "register_operand" "=r")
2967         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2968   "TARGET_SHMEDIA"
2969   "addz.l       %1, r63, %0"
2970   [(set_attr "type" "arith_media")])
2971
2972 (define_insn "zero_extendhidi2"
2973   [(set (match_operand:DI 0 "register_operand" "=r,r")
2974         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2975   "TARGET_SHMEDIA"
2976   "@
2977         #
2978         ld%M1.uw        %m1, %0"
2979   [(set_attr "type" "*,load_media")])
2980
2981 (define_split
2982   [(set (match_operand:DI 0 "register_operand" "")
2983         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2984   "TARGET_SHMEDIA && reload_completed"
2985   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2986    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2987   "
2988 {
2989   if (GET_CODE (operands[1]) == TRUNCATE)
2990     operands[1] = XEXP (operands[1], 0);
2991 }")
2992
2993 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2994 ;; reload the entire truncate expression.
2995 (define_insn_and_split "*loaddi_trunc"
2996   [(set (match_operand 0 "int_gpr_dest" "=r")
2997         (truncate (match_operand:DI 1 "memory_operand" "m")))]
2998   "TARGET_SHMEDIA && reload_completed"
2999   "#"
3000   "TARGET_SHMEDIA && reload_completed"
3001   [(set (match_dup 0) (match_dup 1))]
3002   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3003
3004 (define_insn "zero_extendqidi2"
3005   [(set (match_operand:DI 0 "register_operand" "=r,r")
3006         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3007   "TARGET_SHMEDIA"
3008   "@
3009         andi    %1, 255, %0
3010         ld%M1.ub        %m1, %0"
3011   [(set_attr "type" "arith_media,load_media")])
3012
3013 (define_expand "zero_extendhisi2"
3014   [(set (match_operand:SI 0 "arith_reg_operand" "")
3015         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3016   ""
3017   "
3018 {
3019   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3020     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3021 }")
3022
3023 (define_insn "*zero_extendhisi2_compact"
3024   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3025         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3026   "TARGET_SH1"
3027   "extu.w       %1,%0"
3028   [(set_attr "type" "arith")])
3029
3030 (define_insn "*zero_extendhisi2_media"
3031   [(set (match_operand:SI 0 "register_operand" "=r,r")
3032         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3033   "TARGET_SHMEDIA"
3034   "@
3035         #
3036         ld%M1.uw        %m1, %0"
3037   [(set_attr "type" "arith_media,load_media")])
3038
3039 (define_split
3040   [(set (match_operand:SI 0 "register_operand" "")
3041         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3042   "TARGET_SHMEDIA && reload_completed"
3043   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3044    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3045   "
3046 {
3047   if (GET_CODE (operands[1]) == TRUNCATE)
3048     operands[1] = XEXP (operands[1], 0);
3049 }")
3050
3051 (define_expand "zero_extendqisi2"
3052   [(set (match_operand:SI 0 "arith_reg_operand" "")
3053         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3054   ""
3055   "
3056 {
3057   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3058     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3059 }")
3060
3061 (define_insn "*zero_extendqisi2_compact"
3062   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3063         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3064   "TARGET_SH1"
3065   "extu.b       %1,%0"
3066   [(set_attr "type" "arith")])
3067
3068 (define_insn "*zero_extendqisi2_media"
3069   [(set (match_operand:SI 0 "register_operand" "=r,r")
3070         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3071   "TARGET_SHMEDIA"
3072   "@
3073         andi    %1, 255, %0
3074         ld%M1.ub        %m1, %0"
3075   [(set_attr "type" "arith_media,load_media")])
3076
3077 (define_insn "zero_extendqihi2"
3078   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3079         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3080   "TARGET_SH1"
3081   "extu.b       %1,%0"
3082   [(set_attr "type" "arith")])
3083
3084 ;; -------------------------------------------------------------------------
3085 ;; Sign extension instructions
3086 ;; -------------------------------------------------------------------------
3087
3088 ;; ??? This should be a define expand.
3089 ;; ??? Or perhaps it should be dropped?
3090
3091 ;; convert_move generates good code for SH[1-4].
3092 (define_insn "extendsidi2"
3093   [(set (match_operand:DI 0 "register_operand" "=r,r")
3094         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3095   "TARGET_SHMEDIA"
3096   "@
3097         add.l   %1, r63, %0
3098         ld%M1.l %m1, %0"
3099   [(set_attr "type" "arith_media,load_media")])
3100
3101 (define_insn "extendhidi2"
3102   [(set (match_operand:DI 0 "register_operand" "=r,r")
3103         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3104   "TARGET_SHMEDIA"
3105   "@
3106         #
3107         ld%M1.w %m1, %0"
3108   [(set_attr "type" "*,load_media")])
3109
3110 (define_split
3111   [(set (match_operand:DI 0 "register_operand" "")
3112         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3113   "TARGET_SHMEDIA && reload_completed"
3114   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3115    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3116   "
3117 {
3118   if (GET_CODE (operands[1]) == TRUNCATE)
3119     operands[1] = XEXP (operands[1], 0);
3120 }")
3121
3122 (define_insn "extendqidi2"
3123   [(set (match_operand:DI 0 "register_operand" "=r,r")
3124         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3125   "TARGET_SHMEDIA"
3126   "@
3127         #
3128         ld%M1.b %m1, %0"
3129   [(set_attr "type" "*,load_media")])
3130
3131 (define_split
3132   [(set (match_operand:DI 0 "register_operand" "")
3133         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3134   "TARGET_SHMEDIA && reload_completed"
3135   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3136    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3137   "
3138 {
3139   if (GET_CODE (operands[1]) == TRUNCATE)
3140     operands[1] = XEXP (operands[1], 0);
3141 }")
3142
3143 (define_expand "extendhisi2"
3144   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3145         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3146   ""
3147   "")
3148
3149 (define_insn "*extendhisi2_compact"
3150   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3151         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3152   "TARGET_SH1"
3153   "@
3154         exts.w  %1,%0
3155         mov.w   %1,%0"
3156   [(set_attr "type" "arith,load")])
3157
3158 (define_insn "*extendhisi2_media"
3159   [(set (match_operand:SI 0 "register_operand" "=r,r")
3160         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3161   "TARGET_SHMEDIA"
3162   "@
3163         #
3164         ld%M1.w %m1, %0"
3165   [(set_attr "type" "arith_media,load_media")])
3166
3167 (define_split
3168   [(set (match_operand:SI 0 "register_operand" "")
3169         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3170   "TARGET_SHMEDIA && reload_completed"
3171   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3172    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3173   "
3174 {
3175   if (GET_CODE (operands[1]) == TRUNCATE)
3176     operands[1] = XEXP (operands[1], 0);
3177 }")
3178
3179 (define_expand "extendqisi2"
3180   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3181         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3182   ""
3183   "")
3184
3185 (define_insn "*extendqisi2_compact"
3186   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3187         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3188   "TARGET_SH1"
3189   "@
3190         exts.b  %1,%0
3191         mov.b   %1,%0"
3192   [(set_attr "type" "arith,load")])
3193
3194 (define_insn "*extendqisi2_media"
3195   [(set (match_operand:SI 0 "register_operand" "=r,r")
3196         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3197   "TARGET_SHMEDIA"
3198   "@
3199         #
3200         ld%M1.b %m1, %0"
3201   [(set_attr "type" "arith_media,load_media")])
3202
3203 (define_split
3204   [(set (match_operand:SI 0 "register_operand" "")
3205         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3206   "TARGET_SHMEDIA && reload_completed"
3207   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3208    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3209    "
3210 {
3211   if (GET_CODE (operands[1]) == TRUNCATE)
3212     operands[1] = XEXP (operands[1], 0);
3213 }")
3214
3215 (define_insn "extendqihi2"
3216   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3217         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3218   "TARGET_SH1"
3219   "@
3220         exts.b  %1,%0
3221         mov.b   %1,%0"
3222   [(set_attr "type" "arith,load")])
3223
3224 /* It would seem useful to combine the truncXi patterns into the movXi
3225    patterns, but unary operators are ignored when matching constraints,
3226    so we need separate patterns.  */
3227 (define_insn "truncdisi2"
3228   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3229         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3230   "TARGET_SHMEDIA"
3231   "@
3232         add.l   %1, r63, %0
3233         st%M0.l %m0, %1
3234         fst%M0.s        %m0, %T1
3235         fmov.ls %1, %0
3236         fmov.sl %T1, %0
3237         fmov.s  %T1, %0"
3238   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3239
3240
3241 (define_insn "truncdihi2"
3242   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3243         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3244   "TARGET_SHMEDIA"
3245   "@
3246         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3247         st%M0.w %m0, %1"
3248   [(set_attr "type"   "arith_media,store_media")
3249    (set_attr "length" "8,4")])
3250
3251 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3252 ; Because we use zero extension, we can't provide signed QImode compares
3253 ; using a simple compare or conditional banch insn.
3254 (define_insn "truncdiqi2"
3255   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3256         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3257   "TARGET_SHMEDIA"
3258   "@
3259         andi    %1, 255, %0
3260         st%M0.b %m0, %1"
3261   [(set_attr "type"   "arith_media,store")])
3262
3263 ;; -------------------------------------------------------------------------
3264 ;; Move instructions
3265 ;; -------------------------------------------------------------------------
3266
3267 ;; define push and pop so it is easy for sh.c
3268 ;; We can't use push and pop on SHcompact because the stack must always
3269 ;; be 8-byte aligned.
3270
3271 (define_expand "push"
3272   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3273         (match_operand:SI 0 "register_operand" "r,l,x"))]
3274   "TARGET_SH1 && ! TARGET_SH5"
3275   "")
3276
3277 (define_expand "pop"
3278   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3279         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3280   "TARGET_SH1 && ! TARGET_SH5"
3281   "")
3282
3283 (define_expand "push_e"
3284   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3285                    (match_operand:SF 0 "" ""))
3286               (use (reg:PSI FPSCR_REG))
3287               (clobber (scratch:SI))])]
3288   "TARGET_SH1 && ! TARGET_SH5"
3289   "")
3290
3291 (define_insn "push_fpul"
3292   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3293   "TARGET_SH2E && ! TARGET_SH5"
3294   "sts.l        fpul,@-r15"
3295   [(set_attr "type" "store")
3296    (set_attr "late_fp_use" "yes")
3297    (set_attr "hit_stack" "yes")])
3298
3299 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3300 ;; so use that.
3301 (define_expand "push_4"
3302   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3303                    (match_operand:DF 0 "" ""))
3304               (use (reg:PSI FPSCR_REG))
3305               (clobber (scratch:SI))])]
3306   "TARGET_SH1 && ! TARGET_SH5"
3307   "")
3308
3309 (define_expand "pop_e"
3310   [(parallel [(set (match_operand:SF 0 "" "")
3311               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3312               (use (reg:PSI FPSCR_REG))
3313               (clobber (scratch:SI))])]
3314   "TARGET_SH1 && ! TARGET_SH5"
3315   "")
3316
3317 (define_insn "pop_fpul"
3318   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3319   "TARGET_SH2E && ! TARGET_SH5"
3320   "lds.l        @r15+,fpul"
3321   [(set_attr "type" "load")
3322    (set_attr "hit_stack" "yes")])
3323
3324 (define_expand "pop_4"
3325   [(parallel [(set (match_operand:DF 0 "" "")
3326                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3327               (use (reg:PSI FPSCR_REG))
3328               (clobber (scratch:SI))])]
3329   "TARGET_SH1 && ! TARGET_SH5"
3330   "")
3331
3332 (define_expand "push_fpscr"
3333   [(const_int 0)]
3334   "TARGET_SH2E"
3335   "
3336 {
3337   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3338                                                  gen_rtx_PRE_DEC (Pmode,
3339                                                           stack_pointer_rtx)),
3340                                         get_fpscr_rtx ()));
3341   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3342   DONE;
3343 }")
3344
3345 (define_expand "pop_fpscr"
3346   [(const_int 0)]
3347   "TARGET_SH2E"
3348   "
3349 {
3350   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3351                                         gen_rtx_MEM (PSImode,
3352                                                  gen_rtx_POST_INC (Pmode,
3353                                                           stack_pointer_rtx))));
3354   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3355   DONE;
3356 }")
3357
3358 ;; These two patterns can happen as the result of optimization, when
3359 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3360 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3361
3362 (define_insn "clrt"
3363   [(set (reg:SI T_REG) (const_int 0))]
3364   "TARGET_SH1"
3365   "clrt")
3366
3367 (define_insn "sett"
3368   [(set (reg:SI T_REG) (const_int 1))]
3369   "TARGET_SH1"
3370   "sett")
3371
3372 ;; t/r must come after r/r, lest reload will try to reload stuff like
3373 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3374 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3375 (define_insn "movsi_i"
3376   [(set (match_operand:SI 0 "general_movdst_operand"
3377             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3378         (match_operand:SI 1 "general_movsrc_operand"
3379          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3380   "TARGET_SH1
3381    && ! TARGET_SH2E
3382    && ! TARGET_SH2A
3383    && (register_operand (operands[0], SImode)
3384        || register_operand (operands[1], SImode))"
3385   "@
3386         mov.l   %1,%0
3387         mov     %1,%0
3388         cmp/pl  %1
3389         mov.l   %1,%0
3390         sts     %1,%0
3391         sts     %1,%0
3392         movt    %0
3393         mov.l   %1,%0
3394         sts.l   %1,%0
3395         sts.l   %1,%0
3396         lds     %1,%0
3397         lds     %1,%0
3398         lds.l   %1,%0
3399         lds.l   %1,%0
3400         fake    %1,%0"
3401   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3402    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3403
3404 ;; t/r must come after r/r, lest reload will try to reload stuff like
3405 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3406 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3407 ;; will require a reload.
3408 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3409 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3410 (define_insn "movsi_ie"
3411   [(set (match_operand:SI 0 "general_movdst_operand"
3412             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3413         (match_operand:SI 1 "general_movsrc_operand"
3414          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3415   "(TARGET_SH2E || TARGET_SH2A)
3416    && (register_operand (operands[0], SImode)
3417        || register_operand (operands[1], SImode))"
3418   "@
3419         mov.l   %1,%0
3420         mov     %1,%0
3421         movi20  %1,%0
3422         cmp/pl  %1
3423         mov.l   %1,%0
3424         sts     %1,%0
3425         sts     %1,%0
3426         movt    %0
3427         mov.l   %1,%0
3428         sts.l   %1,%0
3429         sts.l   %1,%0
3430         lds     %1,%0
3431         lds     %1,%0
3432         lds.l   %1,%0
3433         lds.l   %1,%0
3434         lds.l   %1,%0
3435         sts.l   %1,%0
3436         fake    %1,%0
3437         lds     %1,%0
3438         sts     %1,%0
3439         fsts    fpul,%0
3440         flds    %1,fpul
3441         fmov    %1,%0
3442         ! move optimized away"
3443   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3444    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3445    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3446
3447 (define_insn "movsi_i_lowpart"
3448   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" &q