OSDN Git Service

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