OSDN Git Service

(udivsi3_sh2a, divsi3_sh2a): Give these patterns an "in_delay_slot" attribute
[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    (set_attr "in_delay_slot" "no")])
1169
1170 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1171 ;; hard register 0.  If we used hard register 0, then the next instruction
1172 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1173 ;; gets allocated to a stack slot that needs its address reloaded, then
1174 ;; there is nothing to prevent reload from using r0 to reload the address.
1175 ;; This reload would clobber the value in r0 we are trying to store.
1176 ;; If we let reload allocate r0, then this problem can never happen.
1177
1178 (define_insn "udivsi3_i1"
1179   [(set (match_operand:SI 0 "register_operand" "=z")
1180         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1181    (clobber (reg:SI T_REG))
1182    (clobber (reg:SI PR_REG))
1183    (clobber (reg:SI R4_REG))
1184    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1185   "TARGET_SH1 && ! TARGET_SH4"
1186   "jsr  @%1%#"
1187   [(set_attr "type" "sfunc")
1188    (set_attr "needs_delay_slot" "yes")])
1189
1190 ; Since shmedia-nofpu code could be linked against shcompact code, and
1191 ; the udivsi3 libcall has the same name, we must consider all registers
1192 ; clobbered that are in the union of the registers clobbered by the
1193 ; shmedia and the shcompact implementation.  Note, if the shcompact
1194 ; implementation actually used shcompact code, we'd need to clobber
1195 ; also r23 and fr23.
1196 (define_insn "udivsi3_i1_media"
1197   [(set (match_operand:SI 0 "register_operand" "=z")
1198         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1199    (clobber (reg:SI T_MEDIA_REG))
1200    (clobber (reg:SI PR_MEDIA_REG))
1201    (clobber (reg:SI R20_REG))
1202    (clobber (reg:SI R21_REG))
1203    (clobber (reg:SI R22_REG))
1204    (clobber (reg:DI TR0_REG))
1205    (clobber (reg:DI TR1_REG))
1206    (clobber (reg:DI TR2_REG))
1207    (use (match_operand:DI 1 "target_operand" "b"))]
1208   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1209   "blink        %1, r18"
1210   [(set_attr "type" "sfunc")
1211    (set_attr "needs_delay_slot" "yes")])
1212
1213 (define_expand "udivsi3_i4_media"
1214   [(set (match_dup 3)
1215         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1216    (set (match_dup 4)
1217         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1218    (set (match_dup 5) (float:DF (match_dup 3)))
1219    (set (match_dup 6) (float:DF (match_dup 4)))
1220    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1221    (set (match_dup 8) (fix:DI (match_dup 7)))
1222    (set (match_operand:SI 0 "register_operand" "")
1223         (truncate:SI (match_dup 8)))]
1224   "TARGET_SHMEDIA_FPU"
1225   "
1226 {
1227   operands[3] = gen_reg_rtx (DImode);
1228   operands[4] = gen_reg_rtx (DImode);
1229   operands[5] = gen_reg_rtx (DFmode);
1230   operands[6] = gen_reg_rtx (DFmode);
1231   operands[7] = gen_reg_rtx (DFmode);
1232   operands[8] = gen_reg_rtx (DImode);
1233 }")
1234
1235 (define_insn "udivsi3_i4"
1236   [(set (match_operand:SI 0 "register_operand" "=y")
1237         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1238    (clobber (reg:SI T_REG))
1239    (clobber (reg:SI PR_REG))
1240    (clobber (reg:DF DR0_REG))
1241    (clobber (reg:DF DR2_REG))
1242    (clobber (reg:DF DR4_REG))
1243    (clobber (reg:SI R0_REG))
1244    (clobber (reg:SI R1_REG))
1245    (clobber (reg:SI R4_REG))
1246    (clobber (reg:SI R5_REG))
1247    (use (reg:PSI FPSCR_REG))
1248    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1249   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1250   "jsr  @%1%#"
1251   [(set_attr "type" "sfunc")
1252    (set_attr "fp_mode" "double")
1253    (set_attr "needs_delay_slot" "yes")])
1254
1255 (define_insn "udivsi3_i4_single"
1256   [(set (match_operand:SI 0 "register_operand" "=y")
1257         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258    (clobber (reg:SI T_REG))
1259    (clobber (reg:SI PR_REG))
1260    (clobber (reg:DF DR0_REG))
1261    (clobber (reg:DF DR2_REG))
1262    (clobber (reg:DF DR4_REG))
1263    (clobber (reg:SI R0_REG))
1264    (clobber (reg:SI R1_REG))
1265    (clobber (reg:SI R4_REG))
1266    (clobber (reg:SI R5_REG))
1267    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1268   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1269   "jsr  @%1%#"
1270   [(set_attr "type" "sfunc")
1271    (set_attr "needs_delay_slot" "yes")])
1272
1273 (define_expand "udivsi3"
1274   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1275    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1276    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1277    (parallel [(set (match_operand:SI 0 "register_operand" "")
1278                    (udiv:SI (reg:SI R4_REG)
1279                             (reg:SI R5_REG)))
1280               (clobber (reg:SI T_REG))
1281               (clobber (reg:SI PR_REG))
1282               (clobber (reg:SI R4_REG))
1283               (use (match_dup 3))])]
1284   ""
1285   "
1286 {
1287   rtx first, last;
1288
1289   operands[3] = gen_reg_rtx (Pmode);
1290   /* Emit the move of the address to a pseudo outside of the libcall.  */
1291   if (TARGET_HARD_SH4 && TARGET_SH2E)
1292     {
1293       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1294       if (TARGET_FPU_SINGLE)
1295         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1296       else
1297         last = gen_udivsi3_i4 (operands[0], operands[3]);
1298     }
1299   else if (TARGET_SHMEDIA_FPU)
1300     {
1301       operands[1] = force_reg (SImode, operands[1]);
1302       operands[2] = force_reg (SImode, operands[2]);
1303       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1304       DONE;
1305     }
1306   else if (TARGET_SH2A)
1307     {
1308       operands[1] = force_reg (SImode, operands[1]);
1309       operands[2] = force_reg (SImode, operands[2]);
1310       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1311       DONE;
1312     }
1313   else if (TARGET_SH5)
1314     {
1315       emit_move_insn (operands[3],
1316                       function_symbol (TARGET_FPU_ANY
1317                                        ? \"__udivsi3_i4\"
1318                                        : \"__udivsi3\"));
1319
1320       if (TARGET_SHMEDIA)
1321         last = gen_udivsi3_i1_media (operands[0],
1322                                      Pmode == DImode
1323                                      ? operands[3]
1324                                      : gen_rtx_SUBREG (DImode, operands[3],
1325                                                        0));
1326       else if (TARGET_FPU_ANY)
1327         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1328       else
1329         last = gen_udivsi3_i1 (operands[0], operands[3]);
1330     }
1331   else
1332     {
1333       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1334       last = gen_udivsi3_i1 (operands[0], operands[3]);
1335     }
1336   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1337   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1338   last = emit_insn (last);
1339   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1340      invariant code motion can move it.  */
1341   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1342   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1343   DONE;
1344 }")
1345
1346 (define_insn "divsi3_sh2a"
1347   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1348         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1349                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1350   "TARGET_SH2A"
1351   "divs %2,%1"
1352   [(set_attr "type" "arith")
1353    (set_attr "in_delay_slot" "no")])
1354
1355 (define_insn "divsi3_i1"
1356   [(set (match_operand:SI 0 "register_operand" "=z")
1357         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1358    (clobber (reg:SI T_REG))
1359    (clobber (reg:SI PR_REG))
1360    (clobber (reg:SI R1_REG))
1361    (clobber (reg:SI R2_REG))
1362    (clobber (reg:SI R3_REG))
1363    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1364   "TARGET_SH1 && ! TARGET_SH4"
1365   "jsr  @%1%#"
1366   [(set_attr "type" "sfunc")
1367    (set_attr "needs_delay_slot" "yes")])
1368
1369 ; Since shmedia-nofpu code could be linked against shcompact code, and
1370 ; the sdivsi3 libcall has the same name, we must consider all registers
1371 ; clobbered that are in the union of the registers clobbered by the
1372 ; shmedia and the shcompact implementation.  Note, if the shcompact
1373 ; implementation actually used shcompact code, we'd need to clobber
1374 ; also r22, r23 and fr23.
1375 (define_insn "divsi3_i1_media"
1376   [(set (match_operand:SI 0 "register_operand" "=z")
1377         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1378    (clobber (reg:SI T_MEDIA_REG))
1379    (clobber (reg:SI PR_MEDIA_REG))
1380    (clobber (reg:SI R1_REG))
1381    (clobber (reg:SI R2_REG))
1382    (clobber (reg:SI R3_REG))
1383    (clobber (reg:SI R20_REG))
1384    (clobber (reg:SI R21_REG))
1385    (clobber (reg:DI TR0_REG))
1386    (clobber (reg:DI TR1_REG))
1387    (clobber (reg:DI TR2_REG))
1388    (use (match_operand:DI 1 "target_operand" "b"))]
1389   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1390   "blink        %1, r18"
1391   [(set_attr "type" "sfunc")])
1392
1393 (define_expand "divsi3_i4_media"
1394   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1395    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1396    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1397    (set (match_operand:SI 0 "register_operand" "=r")
1398         (fix:SI (match_dup 5)))]
1399   "TARGET_SHMEDIA_FPU"
1400   "
1401 {
1402   operands[3] = gen_reg_rtx (DFmode);
1403   operands[4] = gen_reg_rtx (DFmode);
1404   operands[5] = gen_reg_rtx (DFmode);
1405 }")
1406
1407 (define_insn "divsi3_i4"
1408   [(set (match_operand:SI 0 "register_operand" "=y")
1409         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1410    (clobber (reg:SI PR_REG))
1411    (clobber (reg:DF DR0_REG))
1412    (clobber (reg:DF DR2_REG))
1413    (use (reg:PSI FPSCR_REG))
1414    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1415   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1416   "jsr  @%1%#"
1417   [(set_attr "type" "sfunc")
1418    (set_attr "fp_mode" "double")
1419    (set_attr "needs_delay_slot" "yes")])
1420
1421 (define_insn "divsi3_i4_single"
1422   [(set (match_operand:SI 0 "register_operand" "=y")
1423         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424    (clobber (reg:SI PR_REG))
1425    (clobber (reg:DF DR0_REG))
1426    (clobber (reg:DF DR2_REG))
1427    (clobber (reg:SI R2_REG))
1428    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1429   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1430   "jsr  @%1%#"
1431   [(set_attr "type" "sfunc")
1432    (set_attr "needs_delay_slot" "yes")])
1433
1434 (define_expand "divsi3"
1435   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1436    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1437    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1438    (parallel [(set (match_operand:SI 0 "register_operand" "")
1439                    (div:SI (reg:SI R4_REG)
1440                            (reg:SI R5_REG)))
1441               (clobber (reg:SI T_REG))
1442               (clobber (reg:SI PR_REG))
1443               (clobber (reg:SI R1_REG))
1444               (clobber (reg:SI R2_REG))
1445               (clobber (reg:SI R3_REG))
1446               (use (match_dup 3))])]
1447   ""
1448   "
1449 {
1450   rtx first, last;
1451
1452   operands[3] = gen_reg_rtx (Pmode);
1453   /* Emit the move of the address to a pseudo outside of the libcall.  */
1454   if (TARGET_HARD_SH4 && TARGET_SH2E)
1455     {
1456       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1457       if (TARGET_FPU_SINGLE)
1458         last = gen_divsi3_i4_single (operands[0], operands[3]);
1459       else
1460         last = gen_divsi3_i4 (operands[0], operands[3]);
1461     }
1462   else if (TARGET_SH2A)
1463     {
1464       operands[1] = force_reg (SImode, operands[1]);
1465       operands[2] = force_reg (SImode, operands[2]);
1466       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1467       DONE;
1468     }
1469   else if (TARGET_SHMEDIA_FPU)
1470     {
1471       operands[1] = force_reg (SImode, operands[1]);
1472       operands[2] = force_reg (SImode, operands[2]);
1473       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1474       DONE;
1475     }
1476   else if (TARGET_SH5)
1477     {
1478       emit_move_insn (operands[3],
1479                       function_symbol (TARGET_FPU_ANY
1480                                        ? \"__sdivsi3_i4\"
1481                                        : \"__sdivsi3\"));
1482
1483       if (TARGET_SHMEDIA)
1484         last = gen_divsi3_i1_media (operands[0],
1485                                     Pmode == DImode
1486                                     ? operands[3]
1487                                     : gen_rtx_SUBREG (DImode, operands[3],
1488                                                       0));
1489       else if (TARGET_FPU_ANY)
1490         last = gen_divsi3_i4_single (operands[0], operands[3]);
1491       else
1492         last = gen_divsi3_i1 (operands[0], operands[3]);
1493     }
1494   else
1495     {
1496       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1497       last = gen_divsi3_i1 (operands[0], operands[3]);
1498     }
1499   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1500   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1501   last = emit_insn (last);
1502   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1503      invariant code motion can move it.  */
1504   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1505   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1506   DONE;
1507 }")
1508 \f
1509 ;; -------------------------------------------------------------------------
1510 ;; Multiplication instructions
1511 ;; -------------------------------------------------------------------------
1512
1513 (define_insn "umulhisi3_i"
1514   [(set (reg:SI MACL_REG)
1515         (mult:SI (zero_extend:SI
1516                   (match_operand:HI 0 "arith_reg_operand" "r"))
1517                  (zero_extend:SI
1518                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1519   "TARGET_SH1"
1520   "mulu.w       %1,%0"
1521   [(set_attr "type" "smpy")])
1522
1523 (define_insn "mulhisi3_i"
1524   [(set (reg:SI MACL_REG)
1525         (mult:SI (sign_extend:SI
1526                   (match_operand:HI 0 "arith_reg_operand" "r"))
1527                  (sign_extend:SI
1528                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1529   "TARGET_SH1"
1530   "muls.w       %1,%0"
1531   [(set_attr "type" "smpy")])
1532
1533 (define_expand "mulhisi3"
1534   [(set (reg:SI MACL_REG)
1535         (mult:SI (sign_extend:SI
1536                   (match_operand:HI 1 "arith_reg_operand" ""))
1537                  (sign_extend:SI
1538                   (match_operand:HI 2 "arith_reg_operand" ""))))
1539    (set (match_operand:SI 0 "arith_reg_operand" "")
1540         (reg:SI MACL_REG))]
1541   "TARGET_SH1"
1542   "
1543 {
1544   rtx first, last;
1545
1546   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1547   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1548   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549      invariant code motion can move it.  */
1550   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1552   /* expand_binop can't find a suitable code in umul_widen_optab to
1553      make a REG_EQUAL note from, so make one here.
1554      See also smulsi3_highpart.
1555      ??? Alternatively, we could put this at the calling site of expand_binop,
1556      i.e. expand_expr.  */
1557   REG_NOTES (last)
1558     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1559                          REG_NOTES (last));
1560   DONE;
1561 }")
1562
1563 (define_expand "umulhisi3"
1564   [(set (reg:SI MACL_REG)
1565         (mult:SI (zero_extend:SI
1566                   (match_operand:HI 1 "arith_reg_operand" ""))
1567                  (zero_extend:SI
1568                   (match_operand:HI 2 "arith_reg_operand" ""))))
1569    (set (match_operand:SI 0 "arith_reg_operand" "")
1570         (reg:SI MACL_REG))]
1571   "TARGET_SH1"
1572   "
1573 {
1574   rtx first, last;
1575
1576   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1577   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1578   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1579      invariant code motion can move it.  */
1580   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1581   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1582   /* expand_binop can't find a suitable code in umul_widen_optab to
1583      make a REG_EQUAL note from, so make one here.
1584      See also smulsi3_highpart.
1585      ??? Alternatively, we could put this at the calling site of expand_binop,
1586      i.e. expand_expr.  */
1587   REG_NOTES (last)
1588     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1589                          REG_NOTES (last));
1590   DONE;
1591 }")
1592
1593 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1594 ;; a call to a routine which clobbers known registers.
1595
1596 (define_insn ""
1597   [(set (match_operand:SI 1 "register_operand" "=z")
1598         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1599    (clobber (reg:SI MACL_REG))
1600    (clobber (reg:SI T_REG))
1601    (clobber (reg:SI PR_REG))
1602    (clobber (reg:SI R3_REG))
1603    (clobber (reg:SI R2_REG))
1604    (clobber (reg:SI R1_REG))
1605    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1606   "TARGET_SH1"
1607   "jsr  @%0%#"
1608   [(set_attr "type" "sfunc")
1609    (set_attr "needs_delay_slot" "yes")])
1610
1611 (define_expand "mulsi3_call"
1612   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1613    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1614    (parallel[(set (match_operand:SI 0 "register_operand" "")
1615                   (mult:SI (reg:SI R4_REG)
1616                            (reg:SI R5_REG)))
1617              (clobber (reg:SI MACL_REG))
1618              (clobber (reg:SI T_REG))
1619              (clobber (reg:SI PR_REG))
1620              (clobber (reg:SI R3_REG))
1621              (clobber (reg:SI R2_REG))
1622              (clobber (reg:SI R1_REG))
1623              (use (match_operand:SI 3 "register_operand" ""))])]
1624   "TARGET_SH1"
1625   "")
1626
1627 (define_insn "mul_r"
1628   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1629         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1631   "TARGET_SH2A"
1632   "mulr %2,%0"
1633   [(set_attr "type" "dmpy")])
1634
1635 (define_insn "mul_l"
1636   [(set (reg:SI MACL_REG)
1637         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1638                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1639   "TARGET_SH2"
1640   "mul.l        %1,%0"
1641   [(set_attr "type" "dmpy")])
1642
1643 (define_expand "mulsi3"
1644   [(set (reg:SI MACL_REG)
1645         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1646                   (match_operand:SI 2 "arith_reg_operand" "")))
1647    (set (match_operand:SI 0 "arith_reg_operand" "")
1648         (reg:SI MACL_REG))]
1649   "TARGET_SH1"
1650   "
1651 {
1652   rtx first, last;
1653
1654   if (!TARGET_SH2)
1655     {
1656       /* The address must be set outside the libcall,
1657          since it goes into a pseudo.  */
1658       rtx sym = function_symbol (\"__mulsi3\");
1659       rtx addr = force_reg (SImode, sym);
1660       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1661                                    operands[2], addr);
1662       first = insns;
1663       last = emit_insn (insns);
1664     }
1665   else
1666     {
1667       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1668
1669       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1670       /* consec_sets_giv can only recognize the first insn that sets a
1671          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1672          note.  */
1673       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1674     }
1675   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1676      invariant code motion can move it.  */
1677   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1678   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1679   DONE;
1680 }")
1681
1682 (define_insn "mulsidi3_i"
1683   [(set (reg:SI MACH_REG)
1684         (truncate:SI
1685          (lshiftrt:DI
1686           (mult:DI
1687            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1688            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1689           (const_int 32))))
1690    (set (reg:SI MACL_REG)
1691         (mult:SI (match_dup 0)
1692                  (match_dup 1)))]
1693   "TARGET_SH2"
1694   "dmuls.l      %1,%0"
1695   [(set_attr "type" "dmpy")])
1696
1697 (define_expand "mulsidi3"
1698   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1699         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1700                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1701   "TARGET_SH2 || TARGET_SHMEDIA"
1702   "
1703 {
1704   if (TARGET_SH2)
1705     {
1706        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1707                                         operands[2]));
1708        DONE;
1709     }
1710 }")
1711
1712 (define_insn "mulsidi3_media"
1713   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1714         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1715                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1716   "TARGET_SHMEDIA"
1717   "muls.l       %1, %2, %0"
1718   [(set_attr "type" "dmpy_media")])
1719
1720 (define_insn "mulsidi3_compact"
1721   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1722         (mult:DI
1723          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1724          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1725    (clobber (reg:SI MACH_REG))
1726    (clobber (reg:SI MACL_REG))]
1727   "TARGET_SH2"
1728   "#")
1729
1730 (define_split
1731   [(set (match_operand:DI 0 "arith_reg_operand" "")
1732         (mult:DI
1733          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1734          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1735    (clobber (reg:SI MACH_REG))
1736    (clobber (reg:SI MACL_REG))]
1737   "TARGET_SH2"
1738   [(const_int 0)]
1739   "
1740 {
1741   rtx low_dst = gen_lowpart (SImode, operands[0]);
1742   rtx high_dst = gen_highpart (SImode, operands[0]);
1743
1744   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1745
1746   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1747   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1748   /* We need something to tag the possible REG_EQUAL notes on to.  */
1749   emit_move_insn (operands[0], operands[0]);
1750   DONE;
1751 }")
1752
1753 (define_insn "umulsidi3_i"
1754   [(set (reg:SI MACH_REG)
1755         (truncate:SI
1756          (lshiftrt:DI
1757           (mult:DI
1758            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1759            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1760           (const_int 32))))
1761    (set (reg:SI MACL_REG)
1762         (mult:SI (match_dup 0)
1763                  (match_dup 1)))]
1764   "TARGET_SH2"
1765   "dmulu.l      %1,%0"
1766   [(set_attr "type" "dmpy")])
1767
1768 (define_expand "umulsidi3"
1769   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1771                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1772   "TARGET_SH2 || TARGET_SHMEDIA"
1773   "
1774 {
1775   if (TARGET_SH2)
1776     {
1777        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1778                                          operands[2]));
1779        DONE;
1780     }
1781 }")
1782
1783 (define_insn "umulsidi3_media"
1784   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1785         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1786                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1787   "TARGET_SHMEDIA"
1788   "mulu.l       %1, %2, %0"
1789   [(set_attr "type" "dmpy_media")])
1790
1791 (define_insn "umulsidi3_compact"
1792   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1793         (mult:DI
1794          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1795          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1796    (clobber (reg:SI MACH_REG))
1797    (clobber (reg:SI MACL_REG))]
1798   "TARGET_SH2"
1799   "#")
1800
1801 (define_split
1802   [(set (match_operand:DI 0 "arith_reg_operand" "")
1803         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1804                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1805    (clobber (reg:SI MACH_REG))
1806    (clobber (reg:SI MACL_REG))]
1807   "TARGET_SH2"
1808   [(const_int 0)]
1809   "
1810 {
1811   rtx low_dst = gen_lowpart (SImode, operands[0]);
1812   rtx high_dst = gen_highpart (SImode, operands[0]);
1813
1814   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1815
1816   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1817   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1818   /* We need something to tag the possible REG_EQUAL notes on to.  */
1819   emit_move_insn (operands[0], operands[0]);
1820   DONE;
1821 }")
1822
1823 (define_insn "smulsi3_highpart_i"
1824   [(set (reg:SI MACH_REG)
1825         (truncate:SI
1826          (lshiftrt:DI
1827           (mult:DI
1828            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1829            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1830           (const_int 32))))
1831    (clobber (reg:SI MACL_REG))]
1832   "TARGET_SH2"
1833   "dmuls.l      %1,%0"
1834   [(set_attr "type" "dmpy")])
1835
1836 (define_expand "smulsi3_highpart"
1837   [(parallel
1838     [(set (reg:SI MACH_REG)
1839           (truncate:SI
1840            (lshiftrt:DI
1841             (mult:DI
1842              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1843              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1844             (const_int 32))))
1845     (clobber (reg:SI MACL_REG))])
1846    (set (match_operand:SI 0 "arith_reg_operand" "")
1847         (reg:SI MACH_REG))]
1848   "TARGET_SH2"
1849   "
1850 {
1851   rtx first, last;
1852
1853   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1854   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1855   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1856      invariant code motion can move it.  */
1857   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1858   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1859   /* expand_binop can't find a suitable code in mul_highpart_optab to
1860      make a REG_EQUAL note from, so make one here.
1861      See also {,u}mulhisi.
1862      ??? Alternatively, we could put this at the calling site of expand_binop,
1863      i.e. expand_mult_highpart.  */
1864   REG_NOTES (last)
1865     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1866                          REG_NOTES (last));
1867   DONE;
1868 }")
1869
1870 (define_insn "umulsi3_highpart_i"
1871   [(set (reg:SI MACH_REG)
1872         (truncate:SI
1873          (lshiftrt:DI
1874           (mult:DI
1875            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1876            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1877           (const_int 32))))
1878    (clobber (reg:SI MACL_REG))]
1879   "TARGET_SH2"
1880   "dmulu.l      %1,%0"
1881   [(set_attr "type" "dmpy")])
1882
1883 (define_expand "umulsi3_highpart"
1884   [(parallel
1885     [(set (reg:SI MACH_REG)
1886           (truncate:SI
1887            (lshiftrt:DI
1888             (mult:DI
1889              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1890              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1891             (const_int 32))))
1892     (clobber (reg:SI MACL_REG))])
1893    (set (match_operand:SI 0 "arith_reg_operand" "")
1894         (reg:SI MACH_REG))]
1895   "TARGET_SH2"
1896   "
1897 {
1898   rtx first, last;
1899
1900   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1901   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1902   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1903      invariant code motion can move it.  */
1904   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1905   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1906   DONE;
1907 }")
1908 \f
1909 ;; -------------------------------------------------------------------------
1910 ;; Logical operations
1911 ;; -------------------------------------------------------------------------
1912
1913 (define_insn "*andsi3_compact"
1914   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1915         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1916                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1917   "TARGET_SH1"
1918   "and  %2,%0"
1919   [(set_attr "type" "arith")])
1920
1921 ;; If the constant is 255, then emit an extu.b instruction instead of an
1922 ;; and, since that will give better code.
1923
1924 (define_expand "andsi3"
1925   [(set (match_operand:SI 0 "arith_reg_operand" "")
1926         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1927                 (match_operand:SI 2 "logical_operand" "")))]
1928   "TARGET_SH1"
1929   "
1930 {
1931   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1932     {
1933       emit_insn (gen_zero_extendqisi2 (operands[0],
1934                                        gen_lowpart (QImode, operands[1])));
1935       DONE;
1936     }
1937 }")
1938
1939 (define_insn_and_split "anddi3"
1940   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1941         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1942                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1943   "TARGET_SHMEDIA"
1944   "@
1945         and     %1, %2, %0
1946         andi    %1, %2, %0
1947         #"
1948   "reload_completed
1949    && ! logical_operand (operands[2], DImode)"
1950   [(const_int 0)]
1951   "
1952 {
1953   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1954     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1955   else
1956     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1957   DONE;
1958 }"
1959   [(set_attr "type" "arith_media")])
1960
1961 (define_insn "andcdi3"
1962   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1963         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1964                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1965   "TARGET_SHMEDIA"
1966   "andc %1,%2,%0"
1967   [(set_attr "type" "arith_media")])
1968
1969 (define_insn "iorsi3"
1970   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1971         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1972                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1973   "TARGET_SH1"
1974   "or   %2,%0"
1975   [(set_attr "type" "arith")])
1976
1977 (define_insn "iordi3"
1978   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1979         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1980                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1981   "TARGET_SHMEDIA"
1982   "@
1983         or      %1, %2, %0
1984         ori     %1, %2, %0"
1985   [(set_attr "type" "arith_media")])
1986
1987 (define_insn "xorsi3"
1988   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1989         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1990                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1991   "TARGET_SH1"
1992   "xor  %2,%0"
1993   [(set_attr "type" "arith")])
1994
1995 (define_insn "xordi3"
1996   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1997         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1998                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1999   "TARGET_SHMEDIA"
2000   "@
2001         xor     %1, %2, %0
2002         xori    %1, %2, %0"
2003   [(set_attr "type" "arith_media")])
2004
2005 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2006 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2007 (define_split
2008   [(set (match_operand:DI 0 "arith_reg_operand" "")
2009         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2010                           [(match_operand 1 "any_register_operand" "")
2011                            (match_operand 2 "any_register_operand" "")])))]
2012   "TARGET_SHMEDIA"
2013   [(set (match_dup 5) (match_dup 4))
2014    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2015 "
2016 {
2017   enum machine_mode inmode = GET_MODE (operands[1]);
2018   int offset = 0;
2019
2020   if (GET_CODE (operands[0]) == SUBREG)
2021     {
2022       offset = SUBREG_BYTE (operands[0]);
2023       operands[0] = SUBREG_REG (operands[0]);
2024     }
2025   if (GET_CODE (operands[0]) != REG)
2026     abort ();
2027   if (! TARGET_LITTLE_ENDIAN)
2028     offset += 8 - GET_MODE_SIZE (inmode);
2029   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2030 }")
2031 \f
2032 ;; -------------------------------------------------------------------------
2033 ;; Shifts and rotates
2034 ;; -------------------------------------------------------------------------
2035
2036 (define_expand "rotldi3"
2037   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2038         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2039                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2040   "TARGET_SHMEDIA"
2041   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2042
2043 (define_insn "rotldi3_mextr"
2044   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2045         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2046                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2047   "TARGET_SHMEDIA"
2048   "*
2049 {
2050   static char templ[16];
2051
2052   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2053            8 - (int) (INTVAL (operands[2]) >> 3));
2054   return templ;
2055 }"
2056   [(set_attr "type" "arith_media")])
2057
2058 (define_expand "rotrdi3"
2059   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2060         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2061                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2062   "TARGET_SHMEDIA"
2063   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2064
2065 (define_insn "rotrdi3_mextr"
2066   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2067         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2068                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2069   "TARGET_SHMEDIA"
2070   "*
2071 {
2072   static char templ[16];
2073
2074   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2075   return templ;
2076 }"
2077   [(set_attr "type" "arith_media")])
2078
2079 (define_insn "rotlsi3_1"
2080   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2081         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2082                    (const_int 1)))
2083    (set (reg:SI T_REG)
2084         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2085   "TARGET_SH1"
2086   "rotl %0"
2087   [(set_attr "type" "arith")])
2088
2089 (define_insn "rotlsi3_31"
2090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2092                    (const_int 31)))
2093    (clobber (reg:SI T_REG))]
2094   "TARGET_SH1"
2095   "rotr %0"
2096   [(set_attr "type" "arith")])
2097
2098 (define_insn "rotlsi3_16"
2099   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2100         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2101                    (const_int 16)))]
2102   "TARGET_SH1"
2103   "swap.w       %1,%0"
2104   [(set_attr "type" "arith")])
2105
2106 (define_expand "rotlsi3"
2107   [(set (match_operand:SI 0 "arith_reg_operand" "")
2108         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2109                    (match_operand:SI 2 "immediate_operand" "")))]
2110   "TARGET_SH1"
2111   "
2112 {
2113   static const char rot_tab[] = {
2114     000, 000, 000, 000, 000, 000, 010, 001,
2115     001, 001, 011, 013, 003, 003, 003, 003,
2116     003, 003, 003, 003, 003, 013, 012, 002,
2117     002, 002, 010, 000, 000, 000, 000, 000,
2118   };
2119
2120   int count, choice;
2121
2122   if (GET_CODE (operands[2]) != CONST_INT)
2123     FAIL;
2124   count = INTVAL (operands[2]);
2125   choice = rot_tab[count];
2126   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2127     FAIL;
2128   choice &= 7;
2129   switch (choice)
2130     {
2131     case 0:
2132       emit_move_insn (operands[0], operands[1]);
2133       count -= (count & 16) * 2;
2134       break;
2135     case 3:
2136      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2137      count -= 16;
2138      break;
2139     case 1:
2140     case 2:
2141       {
2142         rtx parts[2];
2143         parts[0] = gen_reg_rtx (SImode);
2144         parts[1] = gen_reg_rtx (SImode);
2145         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2146         emit_move_insn (parts[choice-1], operands[1]);
2147         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2148         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2149         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2150         count = (count & ~16) - 8;
2151       }
2152     }
2153
2154   for (; count > 0; count--)
2155     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2156   for (; count < 0; count++)
2157     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2158
2159   DONE;
2160 }")
2161
2162 (define_insn "*rotlhi3_8"
2163   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2164         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2165                    (const_int 8)))]
2166   "TARGET_SH1"
2167   "swap.b       %1,%0"
2168   [(set_attr "type" "arith")])
2169
2170 (define_expand "rotlhi3"
2171   [(set (match_operand:HI 0 "arith_reg_operand" "")
2172         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2173                    (match_operand:HI 2 "immediate_operand" "")))]
2174   "TARGET_SH1"
2175   "
2176 {
2177   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2178     FAIL;
2179 }")
2180
2181 ;;
2182 ;; shift left
2183
2184 (define_insn "ashlsi3_sh2a"
2185   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2186         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2187                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2188   "TARGET_SH2A"
2189   "shad %2,%0"
2190   [(set_attr "type" "arith")
2191    (set_attr "length" "4")])
2192
2193 ;; This pattern is used by init_expmed for computing the costs of shift
2194 ;; insns.
2195
2196 (define_insn_and_split "ashlsi3_std"
2197   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2198         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2199                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2200    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2201   "TARGET_SH3
2202    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2203        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2204   "@
2205    shld %2,%0
2206    add  %0,%0
2207    shll%O2      %0
2208    #"
2209   "TARGET_SH3
2210    && reload_completed
2211    && GET_CODE (operands[2]) == CONST_INT
2212    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2213   [(set (match_dup 3) (match_dup 2))
2214    (parallel
2215     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2216      (clobber (match_dup 4))])]
2217   "operands[4] = gen_rtx_SCRATCH (SImode);"
2218   [(set_attr "length" "*,*,*,4")
2219    (set_attr "type" "dyn_shift,arith,arith,arith")])
2220
2221 (define_insn "ashlhi3_k"
2222   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2223         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2224                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2225   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2226   "@
2227         add     %0,%0
2228         shll%O2 %0"
2229   [(set_attr "type" "arith")])
2230
2231 (define_insn "ashlsi3_n"
2232   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2233         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2234                    (match_operand:SI 2 "const_int_operand" "n")))
2235    (clobber (reg:SI T_REG))]
2236   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2237   "#"
2238   [(set (attr "length")
2239         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2240                (const_string "2")
2241                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2242                (const_string "4")
2243                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2244                (const_string "6")]
2245               (const_string "8")))
2246    (set_attr "type" "arith")])
2247
2248 (define_split
2249   [(set (match_operand:SI 0 "arith_reg_operand" "")
2250         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2251                    (match_operand:SI 2 "const_int_operand" "")))
2252    (clobber (reg:SI T_REG))]
2253   "TARGET_SH1 && reload_completed"
2254   [(use (reg:SI R0_REG))]
2255   "
2256 {
2257   gen_shifty_op (ASHIFT, operands);
2258   DONE;
2259 }")
2260
2261 (define_insn "ashlsi3_media"
2262   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2263         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2264                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2265   "TARGET_SHMEDIA"
2266   "@
2267         shlld.l %1, %2, %0
2268         shlli.l %1, %2, %0"
2269   [(set_attr "type" "arith_media")])
2270
2271 (define_expand "ashlsi3"
2272   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2273                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2274                               (match_operand:SI 2 "nonmemory_operand" "")))
2275               (clobber (reg:SI T_REG))])]
2276   ""
2277   "
2278 {
2279   if (TARGET_SHMEDIA)
2280     {
2281       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2282       DONE;
2283     }
2284   if (GET_CODE (operands[2]) == CONST_INT
2285       && sh_dynamicalize_shift_p (operands[2]))
2286     operands[2] = force_reg (SImode, operands[2]);
2287   if (TARGET_SH3)
2288     {
2289       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2290       DONE;
2291     }
2292   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2293     FAIL;
2294 }")
2295
2296 (define_insn "ashlhi3"
2297   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2298         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2299                    (match_operand:HI 2 "const_int_operand" "n")))
2300    (clobber (reg:SI T_REG))]
2301   "TARGET_SH1"
2302   "#"
2303   [(set (attr "length")
2304         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2305                (const_string "2")
2306                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2307                (const_string "4")]
2308               (const_string "6")))
2309    (set_attr "type" "arith")])
2310
2311 (define_split
2312   [(set (match_operand:HI 0 "arith_reg_operand" "")
2313         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2314                    (match_operand:HI 2 "const_int_operand" "")))
2315    (clobber (reg:SI T_REG))]
2316   "TARGET_SH1 && reload_completed"
2317   [(use (reg:SI R0_REG))]
2318   "
2319 {
2320   gen_shifty_hi_op (ASHIFT, operands);
2321   DONE;
2322 }")
2323
2324 ;
2325 ; arithmetic shift right
2326 ;
2327
2328 (define_insn "ashrsi3_sh2a"
2329   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2330         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2331                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2332   "TARGET_SH2A"
2333   "shad %2,%0"
2334   [(set_attr "type" "dyn_shift")
2335    (set_attr "length" "4")])
2336
2337 (define_insn "ashrsi3_k"
2338   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2339         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2340                      (match_operand:SI 2 "const_int_operand" "M")))
2341    (clobber (reg:SI T_REG))]
2342   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2343   "shar %0"
2344   [(set_attr "type" "arith")])
2345
2346 ;; We can't do HImode right shifts correctly unless we start out with an
2347 ;; explicit zero / sign extension; doing that would result in worse overall
2348 ;; code, so just let the machine independent code widen the mode.
2349 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2350
2351
2352 ;; ??? This should be a define expand.
2353
2354 (define_insn "ashrsi2_16"
2355   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2356         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2357                      (const_int 16)))]
2358   "TARGET_SH1"
2359   "#"
2360   [(set_attr "length" "4")])
2361
2362 (define_split
2363   [(set (match_operand:SI 0 "arith_reg_operand" "")
2364         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2365                      (const_int 16)))]
2366   "TARGET_SH1"
2367   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2368    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2369   "operands[2] = gen_lowpart (HImode, operands[0]);")
2370
2371 ;; ??? This should be a define expand.
2372
2373 (define_insn "ashrsi2_31"
2374   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2376                      (const_int 31)))
2377    (clobber (reg:SI T_REG))]
2378   "TARGET_SH1"
2379   "#"
2380   [(set_attr "length" "4")])
2381
2382 (define_split
2383   [(set (match_operand:SI 0 "arith_reg_operand" "")
2384         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2385                      (const_int 31)))
2386    (clobber (reg:SI T_REG))]
2387   "TARGET_SH1"
2388   [(const_int 0)]
2389   "
2390 {
2391   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2392   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2393   DONE;
2394 }")
2395
2396 (define_insn "ashlsi_c"
2397   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2398         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2399    (set (reg:SI T_REG)
2400         (lt:SI (match_dup 1) (const_int 0)))]
2401   "TARGET_SH1"
2402   "shll %0"
2403   [(set_attr "type" "arith")])
2404
2405 (define_insn "ashrsi3_d"
2406   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2407         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2408                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2409   "TARGET_SH3"
2410   "shad %2,%0"
2411   [(set_attr "type" "dyn_shift")])
2412
2413 (define_insn "ashrsi3_n"
2414   [(set (reg:SI R4_REG)
2415         (ashiftrt:SI (reg:SI R4_REG)
2416                      (match_operand:SI 0 "const_int_operand" "i")))
2417    (clobber (reg:SI T_REG))
2418    (clobber (reg:SI PR_REG))
2419    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2420   "TARGET_SH1"
2421   "jsr  @%1%#"
2422   [(set_attr "type" "sfunc")
2423    (set_attr "needs_delay_slot" "yes")])
2424
2425 (define_insn "ashrsi3_media"
2426   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2427         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2428                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2429   "TARGET_SHMEDIA"
2430   "@
2431         shard.l %1, %2, %0
2432         shari.l %1, %2, %0"
2433   [(set_attr "type" "arith_media")])
2434
2435 (define_expand "ashrsi3"
2436   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2437                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2438                                 (match_operand:SI 2 "nonmemory_operand" "")))
2439               (clobber (reg:SI T_REG))])]
2440   ""
2441   "
2442 {
2443   if (TARGET_SHMEDIA)
2444     {
2445       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2446       DONE;
2447     }
2448   if (expand_ashiftrt (operands))
2449     DONE;
2450   else
2451     FAIL;
2452 }")
2453
2454 ;; logical shift right
2455
2456 (define_insn "lshrsi3_sh2a"
2457   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2458         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2459                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2460   "TARGET_SH2A"
2461   "shld %2,%0"
2462   [(set_attr "type" "dyn_shift")
2463    (set_attr "length" "4")])
2464
2465 (define_insn "lshrsi3_d"
2466   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2467         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2468                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2469   "TARGET_SH3"
2470   "shld %2,%0"
2471   [(set_attr "type" "dyn_shift")])
2472
2473 ;;  Only the single bit shift clobbers the T bit.
2474
2475 (define_insn "lshrsi3_m"
2476   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478                      (match_operand:SI 2 "const_int_operand" "M")))
2479    (clobber (reg:SI T_REG))]
2480   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2481   "shlr %0"
2482   [(set_attr "type" "arith")])
2483
2484 (define_insn "lshrsi3_k"
2485   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487                      (match_operand:SI 2 "const_int_operand" "P27")))]
2488   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2489    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2490   "shlr%O2      %0"
2491   [(set_attr "type" "arith")])
2492
2493 (define_insn "lshrsi3_n"
2494   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2495         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2496                      (match_operand:SI 2 "const_int_operand" "n")))
2497    (clobber (reg:SI T_REG))]
2498   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2499   "#"
2500   [(set (attr "length")
2501         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2502                (const_string "2")
2503                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2504                (const_string "4")
2505                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2506                (const_string "6")]
2507               (const_string "8")))
2508    (set_attr "type" "arith")])
2509
2510 (define_split
2511   [(set (match_operand:SI 0 "arith_reg_operand" "")
2512         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2513                      (match_operand:SI 2 "const_int_operand" "")))
2514    (clobber (reg:SI T_REG))]
2515   "TARGET_SH1 && reload_completed"
2516   [(use (reg:SI R0_REG))]
2517   "
2518 {
2519   gen_shifty_op (LSHIFTRT, operands);
2520   DONE;
2521 }")
2522
2523 (define_insn "lshrsi3_media"
2524   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2525         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2526                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2527   "TARGET_SHMEDIA"
2528   "@
2529         shlrd.l %1, %2, %0
2530         shlri.l %1, %2, %0"
2531   [(set_attr "type" "arith_media")])
2532
2533 (define_expand "lshrsi3"
2534   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2535                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2536                                 (match_operand:SI 2 "nonmemory_operand" "")))
2537               (clobber (reg:SI T_REG))])]
2538   ""
2539   "
2540 {
2541   if (TARGET_SHMEDIA)
2542     {
2543       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2544       DONE;
2545     }
2546   if (GET_CODE (operands[2]) == CONST_INT
2547       && sh_dynamicalize_shift_p (operands[2]))
2548     operands[2] = force_reg (SImode, operands[2]);
2549   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2550     {
2551       rtx count = copy_to_mode_reg (SImode, operands[2]);
2552       emit_insn (gen_negsi2 (count, count));
2553       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2554       DONE;
2555     }
2556   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2557     FAIL;
2558 }")
2559
2560 ;; ??? This should be a define expand.
2561
2562 (define_insn "ashldi3_k"
2563   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2564         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2565                    (const_int 1)))
2566    (clobber (reg:SI T_REG))]
2567   "TARGET_SH1"
2568   "shll %R0\;rotcl      %S0"
2569   [(set_attr "length" "4")
2570    (set_attr "type" "arith")])
2571
2572 (define_insn "ashldi3_media"
2573   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2574         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2575                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2576   "TARGET_SHMEDIA"
2577   "@
2578         shlld   %1, %2, %0
2579         shlli   %1, %2, %0"
2580   [(set_attr "type" "arith_media")])
2581
2582 (define_expand "ashldi3"
2583   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2584                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2585                               (match_operand:DI 2 "immediate_operand" "")))
2586               (clobber (reg:SI T_REG))])]
2587   ""
2588   "
2589 {
2590   if (TARGET_SHMEDIA)
2591     {
2592       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2593       DONE;
2594     }
2595   if (GET_CODE (operands[2]) != CONST_INT
2596       || INTVAL (operands[2]) != 1)
2597     FAIL;
2598 }")
2599
2600 ;; ??? This should be a define expand.
2601
2602 (define_insn "lshrdi3_k"
2603   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2604         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2605                      (const_int 1)))
2606    (clobber (reg:SI T_REG))]
2607   "TARGET_SH1"
2608   "shlr %S0\;rotcr      %R0"
2609   [(set_attr "length" "4")
2610    (set_attr "type" "arith")])
2611
2612 (define_insn "lshrdi3_media"
2613   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2614         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2615                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2616   "TARGET_SHMEDIA"
2617   "@
2618         shlrd   %1, %2, %0
2619         shlri   %1, %2, %0"
2620   [(set_attr "type" "arith_media")])
2621
2622 (define_expand "lshrdi3"
2623   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2624                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2625                                (match_operand:DI 2 "immediate_operand" "")))
2626              (clobber (reg:SI T_REG))])]
2627   ""
2628   "
2629 {
2630   if (TARGET_SHMEDIA)
2631     {
2632       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2633       DONE;
2634     }
2635   if (GET_CODE (operands[2]) != CONST_INT
2636       || INTVAL (operands[2]) != 1)
2637     FAIL;
2638 }")
2639
2640 ;; ??? This should be a define expand.
2641
2642 (define_insn "ashrdi3_k"
2643   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2644         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2645                      (const_int 1)))
2646    (clobber (reg:SI T_REG))]
2647   "TARGET_SH1"
2648   "shar %S0\;rotcr      %R0"
2649   [(set_attr "length" "4")
2650    (set_attr "type" "arith")])
2651
2652 (define_insn "ashrdi3_media"
2653   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2654         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2655                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2656   "TARGET_SHMEDIA"
2657   "@
2658         shard   %1, %2, %0
2659         shari   %1, %2, %0"
2660   [(set_attr "type" "arith_media")])
2661
2662 (define_expand "ashrdi3"
2663   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2664                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2665                                 (match_operand:DI 2 "immediate_operand" "")))
2666               (clobber (reg:SI T_REG))])]
2667   ""
2668   "
2669 {
2670   if (TARGET_SHMEDIA)
2671     {
2672       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2673       DONE;
2674     }
2675   if (GET_CODE (operands[2]) != CONST_INT
2676       || INTVAL (operands[2]) != 1)
2677     FAIL;
2678 }")
2679
2680 ;; combined left/right shift
2681
2682 (define_split
2683   [(set (match_operand:SI 0 "register_operand" "")
2684         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2685                            (match_operand:SI 2 "const_int_operand" ""))
2686                 (match_operand:SI 3 "const_int_operand" "")))]
2687   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2688   [(use (reg:SI R0_REG))]
2689   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2690    DONE;")
2691
2692 (define_split
2693   [(set (match_operand:SI 0 "register_operand" "")
2694         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695                            (match_operand:SI 2 "const_int_operand" ""))
2696                 (match_operand:SI 3 "const_int_operand" "")))
2697    (clobber (reg:SI T_REG))]
2698   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2699   [(use (reg:SI R0_REG))]
2700   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2701    DONE;")
2702
2703 (define_insn ""
2704   [(set (match_operand:SI 0 "register_operand" "=r")
2705         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2706                            (match_operand:SI 2 "const_int_operand" "n"))
2707                 (match_operand:SI 3 "const_int_operand" "n")))
2708    (clobber (reg:SI T_REG))]
2709   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2710  "#"
2711   [(set (attr "length")
2712         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2713                (const_string "4")
2714                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2715                (const_string "6")
2716                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2717                (const_string "8")
2718                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2719                (const_string "10")
2720                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2721                (const_string "12")
2722                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2723                (const_string "14")
2724                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2725                (const_string "16")]
2726               (const_string "18")))
2727    (set_attr "type" "arith")])
2728
2729 (define_insn ""
2730   [(set (match_operand:SI 0 "register_operand" "=z")
2731         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2732                            (match_operand:SI 2 "const_int_operand" "n"))
2733                 (match_operand:SI 3 "const_int_operand" "n")))
2734    (clobber (reg:SI T_REG))]
2735   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2736  "#"
2737   [(set (attr "length")
2738         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2739                (const_string "4")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2741                (const_string "6")
2742                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2743                (const_string "8")]
2744               (const_string "10")))
2745    (set_attr "type" "arith")])
2746
2747 ;; shift left / and combination with a scratch register: The combine pass
2748 ;; does not accept the individual instructions, even though they are
2749 ;; cheap.  But it needs a precise description so that it is usable after
2750 ;; reload.
2751 (define_insn "and_shl_scratch"
2752   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2753         (lshiftrt:SI
2754          (ashift:SI
2755           (and:SI
2756            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2757                         (match_operand:SI 2 "const_int_operand" "N,n"))
2758            (match_operand:SI 3 "" "0,r"))
2759           (match_operand:SI 4 "const_int_operand" "n,n"))
2760          (match_operand:SI 5 "const_int_operand" "n,n")))
2761    (clobber (reg:SI T_REG))]
2762   "TARGET_SH1"
2763   "#"
2764   [(set (attr "length")
2765         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2766                (const_string "4")
2767                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2768                (const_string "6")
2769                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2770                (const_string "8")
2771                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2772                (const_string "10")]
2773               (const_string "12")))
2774    (set_attr "type" "arith")])
2775
2776 (define_split
2777   [(set (match_operand:SI 0 "register_operand" "")
2778         (lshiftrt:SI
2779          (ashift:SI
2780           (and:SI
2781            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2782                         (match_operand:SI 2 "const_int_operand" ""))
2783            (match_operand:SI 3 "register_operand" ""))
2784           (match_operand:SI 4 "const_int_operand" ""))
2785          (match_operand:SI 5 "const_int_operand" "")))
2786    (clobber (reg:SI T_REG))]
2787   "TARGET_SH1"
2788   [(use (reg:SI R0_REG))]
2789   "
2790 {
2791   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2792
2793   if (INTVAL (operands[2]))
2794     {
2795       gen_shifty_op (LSHIFTRT, operands);
2796     }
2797   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2798   operands[2] = operands[4];
2799   gen_shifty_op (ASHIFT, operands);
2800   if (INTVAL (operands[5]))
2801     {
2802       operands[2] = operands[5];
2803       gen_shifty_op (LSHIFTRT, operands);
2804     }
2805   DONE;
2806 }")
2807
2808 ;; signed left/right shift combination.
2809 (define_split
2810   [(set (match_operand:SI 0 "register_operand" "")
2811         (sign_extract:SI
2812          (ashift:SI (match_operand:SI 1 "register_operand" "")
2813                     (match_operand:SI 2 "const_int_operand" ""))
2814          (match_operand:SI 3 "const_int_operand" "")
2815          (const_int 0)))
2816    (clobber (reg:SI T_REG))]
2817   "TARGET_SH1"
2818   [(use (reg:SI R0_REG))]
2819   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2820    DONE;")
2821
2822 (define_insn "shl_sext_ext"
2823   [(set (match_operand:SI 0 "register_operand" "=r")
2824         (sign_extract:SI
2825          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2826                     (match_operand:SI 2 "const_int_operand" "n"))
2827          (match_operand:SI 3 "const_int_operand" "n")
2828          (const_int 0)))
2829    (clobber (reg:SI T_REG))]
2830   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2831   "#"
2832   [(set (attr "length")
2833         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2834                (const_string "2")
2835                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2836                (const_string "4")
2837                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2838                (const_string "6")
2839                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2840                (const_string "8")
2841                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2842                (const_string "10")
2843                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2844                (const_string "12")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2846                (const_string "14")
2847                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2848                (const_string "16")]
2849               (const_string "18")))
2850     (set_attr "type" "arith")])
2851
2852 (define_insn "shl_sext_sub"
2853   [(set (match_operand:SI 0 "register_operand" "=z")
2854         (sign_extract:SI
2855          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2856                     (match_operand:SI 2 "const_int_operand" "n"))
2857          (match_operand:SI 3 "const_int_operand" "n")
2858          (const_int 0)))
2859    (clobber (reg:SI T_REG))]
2860   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2861   "#"
2862   [(set (attr "length")
2863         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2864                (const_string "6")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2866                (const_string "8")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2868                (const_string "10")
2869                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2870                (const_string "12")]
2871               (const_string "14")))
2872     (set_attr "type" "arith")])
2873
2874 ;; These patterns are found in expansions of DImode shifts by 16, and
2875 ;; allow the xtrct instruction to be generated from C source.
2876
2877 (define_insn "xtrct_left"
2878   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2879         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2880                            (const_int 16))
2881                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2882                              (const_int 16))))]
2883   "TARGET_SH1"
2884   "xtrct        %1,%0"
2885   [(set_attr "type" "arith")])
2886
2887 (define_insn "xtrct_right"
2888   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2890                              (const_int 16))
2891                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2892                            (const_int 16))))]
2893   "TARGET_SH1"
2894   "xtrct        %2,%0"
2895   [(set_attr "type" "arith")])
2896
2897 ;; -------------------------------------------------------------------------
2898 ;; Unary arithmetic
2899 ;; -------------------------------------------------------------------------
2900
2901 (define_insn "negc"
2902   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903         (neg:SI (plus:SI (reg:SI T_REG)
2904                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2905    (set (reg:SI T_REG)
2906         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2907                (const_int 0)))]
2908   "TARGET_SH1"
2909   "negc %1,%0"
2910   [(set_attr "type" "arith")])
2911
2912 (define_insn "*negdi_media"
2913   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2914         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2915   "TARGET_SHMEDIA"
2916   "sub  r63, %1, %0"
2917   [(set_attr "type" "arith_media")])
2918
2919 (define_expand "negdi2"
2920   [(set (match_operand:DI 0 "arith_reg_operand" "")
2921         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2922   ""
2923   "
2924 {
2925   if (TARGET_SH1)
2926     {
2927       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2928       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2929
2930       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2931       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2932
2933       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2934       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2935
2936       emit_insn (gen_clrt ());
2937       emit_insn (gen_negc (low_dst, low_src));
2938       emit_insn (gen_negc (high_dst, high_src));
2939       DONE;
2940     }
2941 }")
2942
2943 (define_insn "negsi2"
2944   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2945         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2946   "TARGET_SH1"
2947   "neg  %1,%0"
2948   [(set_attr "type" "arith")])
2949
2950 (define_insn "one_cmplsi2"
2951   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2952         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2953   "TARGET_SH1"
2954   "not  %1,%0"
2955   [(set_attr "type" "arith")])
2956
2957 (define_expand "one_cmpldi2"
2958   [(set (match_operand:DI 0 "arith_reg_operand" "")
2959         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2960                 (const_int -1)))]
2961   "TARGET_SHMEDIA" "")
2962 \f
2963 ;; -------------------------------------------------------------------------
2964 ;; Zero extension instructions
2965 ;; -------------------------------------------------------------------------
2966
2967 (define_insn "zero_extendsidi2"
2968   [(set (match_operand:DI 0 "register_operand" "=r")
2969         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2970   "TARGET_SHMEDIA"
2971   "addz.l       %1, r63, %0"
2972   [(set_attr "type" "arith_media")])
2973
2974 (define_insn "zero_extendhidi2"
2975   [(set (match_operand:DI 0 "register_operand" "=r,r")
2976         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2977   "TARGET_SHMEDIA"
2978   "@
2979         #
2980         ld%M1.uw        %m1, %0"
2981   [(set_attr "type" "*,load_media")])
2982
2983 (define_split
2984   [(set (match_operand:DI 0 "register_operand" "")
2985         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2986   "TARGET_SHMEDIA && reload_completed"
2987   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2988    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2989   "
2990 {
2991   if (GET_CODE (operands[1]) == TRUNCATE)
2992     operands[1] = XEXP (operands[1], 0);
2993 }")
2994
2995 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2996 ;; reload the entire truncate expression.
2997 (define_insn_and_split "*loaddi_trunc"
2998   [(set (match_operand 0 "int_gpr_dest" "=r")
2999         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3000   "TARGET_SHMEDIA && reload_completed"
3001   "#"
3002   "TARGET_SHMEDIA && reload_completed"
3003   [(set (match_dup 0) (match_dup 1))]
3004   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3005
3006 (define_insn "zero_extendqidi2"
3007   [(set (match_operand:DI 0 "register_operand" "=r,r")
3008         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3009   "TARGET_SHMEDIA"
3010   "@
3011         andi    %1, 255, %0
3012         ld%M1.ub        %m1, %0"
3013   [(set_attr "type" "arith_media,load_media")])
3014
3015 (define_expand "zero_extendhisi2"
3016   [(set (match_operand:SI 0 "arith_reg_operand" "")
3017         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3018   ""
3019   "
3020 {
3021   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3022     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3023 }")
3024
3025 (define_insn "*zero_extendhisi2_compact"
3026   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3027         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3028   "TARGET_SH1"
3029   "extu.w       %1,%0"
3030   [(set_attr "type" "arith")])
3031
3032 (define_insn "*zero_extendhisi2_media"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3035   "TARGET_SHMEDIA"
3036   "@
3037         #
3038         ld%M1.uw        %m1, %0"
3039   [(set_attr "type" "arith_media,load_media")])
3040
3041 (define_split
3042   [(set (match_operand:SI 0 "register_operand" "")
3043         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3044   "TARGET_SHMEDIA && reload_completed"
3045   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3046    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3047   "
3048 {
3049   if (GET_CODE (operands[1]) == TRUNCATE)
3050     operands[1] = XEXP (operands[1], 0);
3051 }")
3052
3053 (define_expand "zero_extendqisi2"
3054   [(set (match_operand:SI 0 "arith_reg_operand" "")
3055         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3056   ""
3057   "
3058 {
3059   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3060     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3061 }")
3062
3063 (define_insn "*zero_extendqisi2_compact"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3065         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3066   "TARGET_SH1"
3067   "extu.b       %1,%0"
3068   [(set_attr "type" "arith")])
3069
3070 (define_insn "*zero_extendqisi2_media"
3071   [(set (match_operand:SI 0 "register_operand" "=r,r")
3072         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3073   "TARGET_SHMEDIA"
3074   "@
3075         andi    %1, 255, %0
3076         ld%M1.ub        %m1, %0"
3077   [(set_attr "type" "arith_media,load_media")])
3078
3079 (define_insn "zero_extendqihi2"
3080   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3081         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3082   "TARGET_SH1"
3083   "extu.b       %1,%0"
3084   [(set_attr "type" "arith")])
3085
3086 ;; -------------------------------------------------------------------------
3087 ;; Sign extension instructions
3088 ;; -------------------------------------------------------------------------
3089
3090 ;; ??? This should be a define expand.
3091 ;; ??? Or perhaps it should be dropped?
3092
3093 ;; convert_move generates good code for SH[1-4].
3094 (define_insn "extendsidi2"
3095   [(set (match_operand:DI 0 "register_operand" "=r,r")
3096         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3097   "TARGET_SHMEDIA"
3098   "@
3099         add.l   %1, r63, %0
3100         ld%M1.l %m1, %0"
3101   [(set_attr "type" "arith_media,load_media")])
3102
3103 (define_insn "extendhidi2"
3104   [(set (match_operand:DI 0 "register_operand" "=r,r")
3105         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3106   "TARGET_SHMEDIA"
3107   "@
3108         #
3109         ld%M1.w %m1, %0"
3110   [(set_attr "type" "*,load_media")])
3111
3112 (define_split
3113   [(set (match_operand:DI 0 "register_operand" "")
3114         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3115   "TARGET_SHMEDIA && reload_completed"
3116   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3117    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3118   "
3119 {
3120   if (GET_CODE (operands[1]) == TRUNCATE)
3121     operands[1] = XEXP (operands[1], 0);
3122 }")
3123
3124 (define_insn "extendqidi2"
3125   [(set (match_operand:DI 0 "register_operand" "=r,r")
3126         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3127   "TARGET_SHMEDIA"
3128   "@
3129         #
3130         ld%M1.b %m1, %0"
3131   [(set_attr "type" "*,load_media")])
3132
3133 (define_split
3134   [(set (match_operand:DI 0 "register_operand" "")
3135         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3136   "TARGET_SHMEDIA && reload_completed"
3137   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3138    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3139   "
3140 {
3141   if (GET_CODE (operands[1]) == TRUNCATE)
3142     operands[1] = XEXP (operands[1], 0);
3143 }")
3144
3145 (define_expand "extendhisi2"
3146   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3147         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3148   ""
3149   "")
3150
3151 (define_insn "*extendhisi2_compact"
3152   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3153         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3154   "TARGET_SH1"
3155   "@
3156         exts.w  %1,%0
3157         mov.w   %1,%0"
3158   [(set_attr "type" "arith,load")])
3159
3160 (define_insn "*extendhisi2_media"
3161   [(set (match_operand:SI 0 "register_operand" "=r,r")
3162         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3163   "TARGET_SHMEDIA"
3164   "@
3165         #
3166         ld%M1.w %m1, %0"
3167   [(set_attr "type" "arith_media,load_media")])
3168
3169 (define_split
3170   [(set (match_operand:SI 0 "register_operand" "")
3171         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3172   "TARGET_SHMEDIA && reload_completed"
3173   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3174    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3175   "
3176 {
3177   if (GET_CODE (operands[1]) == TRUNCATE)
3178     operands[1] = XEXP (operands[1], 0);
3179 }")
3180
3181 (define_expand "extendqisi2"
3182   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3183         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3184   ""
3185   "")
3186
3187 (define_insn "*extendqisi2_compact"
3188   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3189         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3190   "TARGET_SH1"
3191   "@
3192         exts.b  %1,%0
3193         mov.b   %1,%0"
3194   [(set_attr "type" "arith,load")])
3195
3196 (define_insn "*extendqisi2_media"
3197   [(set (match_operand:SI 0 "register_operand" "=r,r")
3198         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3199   "TARGET_SHMEDIA"
3200   "@
3201         #
3202         ld%M1.b %m1, %0"
3203   [(set_attr "type" "arith_media,load_media")])
3204
3205 (define_split
3206   [(set (match_operand:SI 0 "register_operand" "")
3207         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3208   "TARGET_SHMEDIA && reload_completed"
3209   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3210    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3211    "
3212 {
3213   if (GET_CODE (operands[1]) == TRUNCATE)
3214     operands[1] = XEXP (operands[1], 0);
3215 }")
3216
3217 (define_insn "extendqihi2"
3218   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3219         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3220   "TARGET_SH1"
3221   "@
3222         exts.b  %1,%0
3223         mov.b   %1,%0"
3224   [(set_attr "type" "arith,load")])
3225
3226 /* It would seem useful to combine the truncXi patterns into the movXi
3227    patterns, but unary operators are ignored when matching constraints,
3228    so we need separate patterns.  */
3229 (define_insn "truncdisi2"
3230   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3231         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3232   "TARGET_SHMEDIA"
3233   "@
3234         add.l   %1, r63, %0
3235         st%M0.l %m0, %1
3236         fst%M0.s        %m0, %T1
3237         fmov.ls %1, %0
3238         fmov.sl %T1, %0
3239         fmov.s  %T1, %0"
3240   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3241
3242
3243 (define_insn "truncdihi2"
3244   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3245         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3246   "TARGET_SHMEDIA"
3247   "@
3248         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3249         st%M0.w %m0, %1"
3250   [(set_attr "type"   "arith_media,store_media")
3251    (set_attr "length" "8,4")])
3252
3253 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3254 ; Because we use zero extension, we can't provide signed QImode compares
3255 ; using a simple compare or conditional banch insn.
3256 (define_insn "truncdiqi2"
3257   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3258         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3259   "TARGET_SHMEDIA"
3260   "@
3261         andi    %1, 255, %0
3262         st%M0.b %m0, %1"
3263   [(set_attr "type"   "arith_media,store")])
3264
3265 ;; -------------------------------------------------------------------------
3266 ;; Move instructions
3267 ;; -------------------------------------------------------------------------
3268
3269 ;; define push and pop so it is easy for sh.c
3270 ;; We can't use push and pop on SHcompact because the stack must always
3271 ;; be 8-byte aligned.
3272
3273 (define_expand "push"
3274   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3275         (match_operand:SI 0 "register_operand" "r,l,x"))]
3276   "TARGET_SH1 && ! TARGET_SH5"
3277   "")
3278
3279 (define_expand "pop"
3280   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3281         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3282   "TARGET_SH1 && ! TARGET_SH5"
3283   "")
3284
3285 (define_expand "push_e"
3286   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3287                    (match_operand:SF 0 "" ""))
3288               (use (reg:PSI FPSCR_REG))
3289               (clobber (scratch:SI))])]
3290   "TARGET_SH1 && ! TARGET_SH5"
3291   "")
3292
3293 (define_insn "push_fpul"
3294   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3295   "TARGET_SH2E && ! TARGET_SH5"
3296   "sts.l        fpul,@-r15"
3297   [(set_attr "type" "store")
3298    (set_attr "late_fp_use" "yes")
3299    (set_attr "hit_stack" "yes")])
3300
3301 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3302 ;; so use that.
3303 (define_expand "push_4"
3304   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3305                    (match_operand:DF 0 "" ""))
3306               (use (reg:PSI FPSCR_REG))
3307               (clobber (scratch:SI))])]
3308   "TARGET_SH1 && ! TARGET_SH5"
3309   "")
3310
3311 (define_expand "pop_e"
3312   [(parallel [(set (match_operand:SF 0 "" "")
3313               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3314               (use (reg:PSI FPSCR_REG))
3315               (clobber (scratch:SI))])]
3316   "TARGET_SH1 && ! TARGET_SH5"
3317   "")
3318
3319 (define_insn "pop_fpul"
3320   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3321   "TARGET_SH2E && ! TARGET_SH5"
3322   "lds.l        @r15+,fpul"
3323   [(set_attr "type" "load")
3324    (set_attr "hit_stack" "yes")])
3325
3326 (define_expand "pop_4"
3327   [(parallel [(set (match_operand:DF 0 "" "")
3328                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3329               (use (reg:PSI FPSCR_REG))
3330               (clobber (scratch:SI))])]
3331   "TARGET_SH1 && ! TARGET_SH5"
3332   "")
3333
3334 (define_expand "push_fpscr"
3335   [(const_int 0)]
3336   "TARGET_SH2E"
3337   "
3338 {
3339   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3340                                                  gen_rtx_PRE_DEC (Pmode,
3341                                                           stack_pointer_rtx)),
3342                                         get_fpscr_rtx ()));
3343   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3344   DONE;
3345 }")
3346
3347 (define_expand "pop_fpscr"
3348   [(const_int 0)]
3349   "TARGET_SH2E"
3350   "
3351 {
3352   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3353                                         gen_rtx_MEM (PSImode,
3354                                                  gen_rtx_POST_INC (Pmode,
3355                                                           stack_pointer_rtx))));
3356   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3357   DONE;
3358 }")
3359
3360 ;; These two patterns can happen as the result of optimization, when
3361 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3362 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3363
3364 (define_insn "clrt"
3365   [(set (reg:SI T_REG) (const_int 0))]
3366   "TARGET_SH1"
3367   "clrt")
3368
3369 (define_insn "sett"
3370   [(set (reg:SI T_REG) (const_int 1))]
3371   "TARGET_SH1"
3372   "sett")
3373
3374 ;; t/r must come after r/r, lest reload will try to reload stuff like
3375 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3376 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3377 (define_insn "movsi_i"
3378   [(set (match_operand:SI 0 "general_movdst_operand"
3379             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3380         (match_operand:SI 1 "general_movsrc_operand"
3381          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3382   "TARGET_SH1
3383    && ! TARGET_SH2E
3384    && ! TARGET_SH2A
3385    && (register_operand (operands[0], SImode)
3386        || register_operand (operands[1], SImode))"
3387   "@
3388         mov.l   %1,%0
3389         mov     %1,%0
3390         cmp/pl  %1
3391         mov.l   %1,%0
3392         sts     %1,%0
3393         sts     %1,%0
3394         movt    %0
3395         mov.l   %1,%0
3396         sts.l   %1,%0
3397         sts.l   %1,%0
3398         lds     %1,%0
3399         lds     %1,%0
3400         lds.l   %1,%0
3401         lds.l   %1,%0
3402         fake    %1,%0"
3403   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3404    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3405
3406 ;; t/r must come after r/r, lest reload will try to reload stuff like
3407 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3408 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3409 ;; will require a reload.
3410 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3411 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3412 (define_insn "movsi_ie"
3413   [(set (match_operand:SI 0 "general_movdst_operand"
3414             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3415         (match_operand:SI 1 "general_movsrc_operand"
3416          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3417   "(TARGET_SH2E || TARGET_SH2A)
3418    && (register_operand (operands[0], SImode)
3419        || register_operand (operands[1], SImode))"
3420   "@
3421         mov.l   %1,%0
3422         mov     %1,%0
3423         movi20  %1,%0
3424         cmp/pl  %1
3425         mov.l   %1,%0
3426         sts     %1,%0
3427         sts     %1,%0
3428         movt    %0
3429         mov.l   %1,%0
3430         sts.l   %1,%0
3431         sts.l   %1,%0
3432         lds     %1,%0
3433         lds     %1,%0
3434         lds.l   %1,%0
3435         lds.l   %1,%0
3436         lds.l   %1,%0
3437         sts.l   %1,%0
3438         fake    %1,%0
3439         lds     %1,%0
3440         sts     %1,%0
3441         fsts    fpul,%0
3442         flds    %1,fpul
3443         fmov    %1,%0
3444         ! move optimized away"
3445   [(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")
3446    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3447    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])