OSDN Git Service

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