OSDN Git Service

174ae609578228d6c367e4940a9c09bee5b0df5b
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,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 "cmpsi_operand" "")
709                  (match_operand:SI 1 "arith_operand" "")))]
710   "TARGET_SH1"
711   "
712 {
713   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
714       && GET_CODE (operands[1]) != CONST_INT)
715     operands[0] = copy_to_mode_reg (SImode, operands[0]);
716   sh_compare_op0 = operands[0];
717   sh_compare_op1 = operands[1];
718   DONE;
719 }")
720 \f
721 ;; -------------------------------------------------------------------------
722 ;; DImode signed integer comparisons
723 ;; -------------------------------------------------------------------------
724
725 ;; ??? Could get better scheduling by splitting the initial test from the
726 ;; rest of the insn after reload.  However, the gain would hardly justify
727 ;; the sh.md size increase necessary to do that.
728
729 (define_insn ""
730   [(set (reg:SI T_REG)
731         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
732                        (match_operand:DI 1 "arith_operand" "r"))
733                (const_int 0)))]
734   "TARGET_SH1"
735   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
736                                  insn, operands);"
737   [(set_attr "length" "6")
738    (set_attr "type" "arith3b")])
739
740 (define_insn "cmpeqdi_t"
741   [(set (reg:SI T_REG)
742         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
743                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
744   "TARGET_SH1"
745   "@
746         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
747         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
748   [(set_attr "length" "6")
749    (set_attr "type" "arith3b")])
750
751 (define_split
752   [(set (reg:SI T_REG)
753         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
754                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
755 ;; If we applied this split when not optimizing, it would only be
756 ;; applied during the machine-dependent reorg, when no new basic blocks
757 ;; may be created.
758   "TARGET_SH1 && reload_completed && optimize"
759   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
760    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
761                            (label_ref (match_dup 6))
762                            (pc)))
763    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
764    (match_dup 6)]
765   "
766 {
767   operands[2]
768     = gen_rtx_REG (SImode,
769                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
770   operands[3]
771     = (operands[1] == const0_rtx
772        ? const0_rtx
773        : gen_rtx_REG (SImode,
774                       true_regnum (operands[1])
775                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
776   operands[4] = gen_lowpart (SImode, operands[0]);
777   operands[5] = gen_lowpart (SImode, operands[1]);
778   operands[6] = gen_label_rtx ();
779 }")
780
781 (define_insn "cmpgtdi_t"
782   [(set (reg:SI T_REG)
783         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
785   "TARGET_SH2"
786   "@
787         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
788         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
789   [(set_attr "length" "8")
790    (set_attr "type" "arith3")])
791
792 (define_insn "cmpgedi_t"
793   [(set (reg:SI T_REG)
794         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
795                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
796   "TARGET_SH2"
797   "@
798         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
799         cmp/pz\\t%S0"
800   [(set_attr "length" "8,2")
801    (set_attr "type" "arith3,mt_group")])
802 \f
803 ;; -------------------------------------------------------------------------
804 ;; DImode unsigned integer comparisons
805 ;; -------------------------------------------------------------------------
806
807 (define_insn "cmpgeudi_t"
808   [(set (reg:SI T_REG)
809         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
810                 (match_operand:DI 1 "arith_reg_operand" "r")))]
811   "TARGET_SH2"
812   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
813   [(set_attr "length" "8")
814    (set_attr "type" "arith3")])
815
816 (define_insn "cmpgtudi_t"
817   [(set (reg:SI T_REG)
818         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
819                 (match_operand:DI 1 "arith_reg_operand" "r")))]
820   "TARGET_SH2"
821   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
822   [(set_attr "length" "8")
823    (set_attr "type" "arith3")])
824
825 (define_insn "cmpeqdi_media"
826   [(set (match_operand:DI 0 "register_operand" "=r")
827         (eq:DI (match_operand:DI 1 "register_operand" "%r")
828                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
829   "TARGET_SHMEDIA"
830   "cmpeq        %1, %N2, %0"
831   [(set_attr "type" "cmp_media")])
832
833 (define_insn "cmpgtdi_media"
834   [(set (match_operand:DI 0 "register_operand" "=r")
835         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
836                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
837   "TARGET_SHMEDIA"
838   "cmpgt        %N1, %N2, %0"
839   [(set_attr "type" "cmp_media")])
840
841 (define_insn "cmpgtudi_media"
842   [(set (match_operand:DI 0 "register_operand" "=r")
843         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
845   "TARGET_SHMEDIA"
846   "cmpgtu       %N1, %N2, %0"
847   [(set_attr "type" "cmp_media")])
848
849 ;; We save the compare operands in the cmpxx patterns and use them when
850 ;; we generate the branch.
851
852 (define_expand "cmpdi"
853   [(set (reg:SI T_REG)
854         (compare (match_operand:DI 0 "arith_operand" "")
855                  (match_operand:DI 1 "arith_operand" "")))]
856   "TARGET_SH2 || TARGET_SHMEDIA"
857   "
858 {
859   sh_compare_op0 = operands[0];
860   sh_compare_op1 = operands[1];
861   DONE;
862 }")
863 ;; -------------------------------------------------------------------------
864 ;; Conditional move instructions
865 ;; -------------------------------------------------------------------------
866
867 ;; The insn names may seem reversed, but note that cmveq performs the move
868 ;; if op1 == 0, and cmvne does it if op1 != 0.
869
870 (define_insn "movdicc_false"
871   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
872         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
873                              (const_int 0))
874          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
875          (match_operand:DI 3 "arith_reg_operand" "0")))]
876   "TARGET_SHMEDIA"
877   "cmveq        %1, %N2, %0"
878   [(set_attr "type" "arith_media")])
879
880 (define_insn "movdicc_true"
881   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
882         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
883                              (const_int 0))
884          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
885          (match_operand:DI 3 "arith_reg_operand" "0")))]
886   "TARGET_SHMEDIA"
887   "cmvne        %1, %N2, %0"
888   [(set_attr "type" "arith_media")])
889
890 (define_expand "movdicc"
891   [(set (match_operand:DI 0 "register_operand" "")
892         (if_then_else:DI (match_operand 1 "comparison_operator" "")
893                          (match_operand:DI 2 "register_operand" "")
894                          (match_operand:DI 3 "register_operand" "")))]
895   "TARGET_SHMEDIA"
896   "
897 {
898   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
899       && GET_MODE (sh_compare_op0) == DImode
900       && sh_compare_op1 == const0_rtx)
901     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
902                                   sh_compare_op0, sh_compare_op1);
903   else
904     {
905       rtx tmp;
906
907       if (no_new_pseudos)
908         FAIL;
909
910       tmp = gen_reg_rtx (DImode);
911
912       switch (GET_CODE (operands[1]))
913         {
914         case EQ:
915           emit_insn (gen_seq (tmp));
916           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
917           break;
918
919         case NE:
920           emit_insn (gen_seq (tmp));
921           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
922           break;
923
924         case GT:
925           emit_insn (gen_sgt (tmp));
926           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
927           break;
928
929         case LT:
930           emit_insn (gen_slt (tmp));
931           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
932           break;
933
934         case GE:
935           emit_insn (gen_slt (tmp));
936           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
937           break;
938
939         case LE:
940           emit_insn (gen_sgt (tmp));
941           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
942           break;
943
944         case GTU:
945           emit_insn (gen_sgtu (tmp));
946           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
947           break;
948
949         case LTU:
950           emit_insn (gen_sltu (tmp));
951           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
952           break;
953
954         case GEU:
955           emit_insn (gen_sltu (tmp));
956           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
957           break;
958
959         case LEU:
960           emit_insn (gen_sgtu (tmp));
961           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
962           break;
963
964         case UNORDERED:
965           emit_insn (gen_sunordered (tmp));
966           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
967           break;
968
969         case ORDERED:
970           emit_insn (gen_sunordered (tmp));
971           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
972           break;
973
974         case UNEQ:
975         case UNGE:
976         case UNGT:
977         case UNLE:
978         case UNLT:
979         case LTGT:
980           FAIL;
981
982         default:
983           abort ();
984         }
985     }
986 }")
987 \f
988 ;; -------------------------------------------------------------------------
989 ;; Addition instructions
990 ;; -------------------------------------------------------------------------
991
992 (define_expand "adddi3"
993   [(set (match_operand:DI 0 "arith_reg_operand" "")
994         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
995                  (match_operand:DI 2 "arith_operand" "")))]
996   ""
997   "
998 {
999   if (TARGET_SH1)
1000     {
1001       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1002         FAIL;
1003       operands[2] = force_reg (DImode, operands[2]);
1004       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1005       DONE;
1006     }
1007 }")
1008
1009 (define_insn "*adddi3_media"
1010   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1011         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1012                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1013   "TARGET_SHMEDIA"
1014   "@
1015         add     %1, %2, %0
1016         addi    %1, %2, %0"
1017   [(set_attr "type" "arith_media")])
1018
1019 (define_insn "adddi3z_media"
1020   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1021         (zero_extend:DI
1022          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1023                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1024   "TARGET_SHMEDIA"
1025   "addz.l       %1, %N2, %0"
1026   [(set_attr "type" "arith_media")])
1027
1028 (define_insn "adddi3_compact"
1029   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1030         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1031                  (match_operand:DI 2 "arith_reg_operand" "r")))
1032    (clobber (reg:SI T_REG))]
1033   "TARGET_SH1"
1034   "#"
1035   [(set_attr "length" "6")])
1036
1037 (define_split
1038   [(set (match_operand:DI 0 "arith_reg_operand" "")
1039         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1040                  (match_operand:DI 2 "arith_reg_operand" "")))
1041    (clobber (reg:SI T_REG))]
1042   "TARGET_SH1 && reload_completed"
1043   [(const_int 0)]
1044   "
1045 {
1046   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1047   high0 = gen_rtx_REG (SImode,
1048                        true_regnum (operands[0])
1049                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050   high2 = gen_rtx_REG (SImode,
1051                        true_regnum (operands[2])
1052                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1053   emit_insn (gen_clrt ());
1054   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1055   emit_insn (gen_addc1 (high0, high0, high2));
1056   DONE;
1057 }")
1058
1059 (define_insn "addc"
1060   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062                           (match_operand:SI 2 "arith_reg_operand" "r"))
1063                  (reg:SI T_REG)))
1064    (set (reg:SI T_REG)
1065         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1066   "TARGET_SH1"
1067   "addc %2,%0"
1068   [(set_attr "type" "arith")])
1069
1070 (define_insn "addc1"
1071   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1072         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1073                           (match_operand:SI 2 "arith_reg_operand" "r"))
1074                  (reg:SI T_REG)))
1075    (clobber (reg:SI T_REG))]
1076   "TARGET_SH1"
1077   "addc %2,%0"
1078   [(set_attr "type" "arith")])
1079
1080 (define_expand "addsi3"
1081   [(set (match_operand:SI 0 "arith_reg_operand" "")
1082         (plus:SI (match_operand:SI 1 "arith_operand" "")
1083                  (match_operand:SI 2 "arith_operand" "")))]
1084   ""
1085   "
1086 {
1087   if (TARGET_SHMEDIA)
1088     operands[1] = force_reg (SImode, operands[1]);
1089 }")
1090
1091 (define_insn "addsi3_media"
1092   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1093         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1094                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1095   "TARGET_SHMEDIA"
1096   "@
1097         add.l   %1, %2, %0
1098         addi.l  %1, %2, %0"
1099   [(set_attr "type" "arith_media")])
1100
1101 (define_insn "*addsi3_compact"
1102   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1103         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1104                  (match_operand:SI 2 "arith_operand" "rI08")))]
1105   "TARGET_SH1"
1106   "add  %2,%0"
1107   [(set_attr "type" "arith")])
1108
1109 ;; -------------------------------------------------------------------------
1110 ;; Subtraction instructions
1111 ;; -------------------------------------------------------------------------
1112
1113 (define_expand "subdi3"
1114   [(set (match_operand:DI 0 "arith_reg_operand" "")
1115         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1116                   (match_operand:DI 2 "arith_reg_operand" "")))]
1117   ""
1118   "
1119 {
1120   if (TARGET_SH1)
1121     {
1122       operands[1] = force_reg (DImode, operands[1]);
1123       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1124       DONE;
1125     }
1126 }")
1127
1128 (define_insn "*subdi3_media"
1129   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1130         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1131                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1132   "TARGET_SHMEDIA"
1133   "sub  %N1, %2, %0"
1134   [(set_attr "type" "arith_media")])
1135
1136 (define_insn "subdi3_compact"
1137   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1138         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1139                  (match_operand:DI 2 "arith_reg_operand" "r")))
1140    (clobber (reg:SI T_REG))]
1141   "TARGET_SH1"
1142   "#"
1143   [(set_attr "length" "6")])
1144
1145 (define_split
1146   [(set (match_operand:DI 0 "arith_reg_operand" "")
1147         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1148                   (match_operand:DI 2 "arith_reg_operand" "")))
1149    (clobber (reg:SI T_REG))]
1150   "TARGET_SH1 && reload_completed"
1151   [(const_int 0)]
1152   "
1153 {
1154   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1155   high0 = gen_rtx_REG (SImode,
1156                        true_regnum (operands[0])
1157                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158   high2 = gen_rtx_REG (SImode,
1159                        true_regnum (operands[2])
1160                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1161   emit_insn (gen_clrt ());
1162   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1163   emit_insn (gen_subc1 (high0, high0, high2));
1164   DONE;
1165 }")
1166
1167 (define_insn "subc"
1168   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170                             (match_operand:SI 2 "arith_reg_operand" "r"))
1171                   (reg:SI T_REG)))
1172    (set (reg:SI T_REG)
1173         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1174                           (reg:SI T_REG))
1175                 (match_dup 1)))]
1176   "TARGET_SH1"
1177   "subc %2,%0"
1178   [(set_attr "type" "arith")])
1179
1180 (define_insn "subc1"
1181   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1182         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1183                             (match_operand:SI 2 "arith_reg_operand" "r"))
1184                   (reg:SI T_REG)))
1185    (clobber (reg:SI T_REG))]
1186   "TARGET_SH1"
1187   "subc %2,%0"
1188   [(set_attr "type" "arith")])
1189
1190 (define_insn "*subsi3_internal"
1191   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1192         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1193                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1194   "TARGET_SH1"
1195   "sub  %2,%0"
1196   [(set_attr "type" "arith")])
1197
1198 (define_insn "*subsi3_media"
1199   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1200         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1201                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1202   "TARGET_SHMEDIA"
1203   "sub.l        %N1, %2, %0"
1204   [(set_attr "type" "arith_media")])
1205
1206 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1207 ;; will sometimes save one instruction.  Otherwise we might get
1208 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1209 ;; are the same.
1210
1211 (define_expand "subsi3"
1212   [(set (match_operand:SI 0 "arith_reg_operand" "")
1213         (minus:SI (match_operand:SI 1 "arith_operand" "")
1214                   (match_operand:SI 2 "arith_reg_operand" "")))]
1215   ""
1216   "
1217 {
1218   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1219     {
1220       emit_insn (gen_negsi2 (operands[0], operands[2]));
1221       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1222       DONE;
1223     }
1224   if (TARGET_SHMEDIA)
1225     {
1226       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1227         FAIL;
1228       if (operands[1] != const0_rtx)
1229         operands[1] = force_reg (SImode, operands[1]);
1230     }
1231 }")
1232 \f
1233 ;; -------------------------------------------------------------------------
1234 ;; Division instructions
1235 ;; -------------------------------------------------------------------------
1236
1237 ;; We take advantage of the library routines which don't clobber as many
1238 ;; registers as a normal function call would.
1239
1240 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1241 ;; also has an effect on the register that holds the address of the sfunc.
1242 ;; To make this work, we have an extra dummy insn that shows the use
1243 ;; of this register for reorg.
1244
1245 (define_insn "use_sfunc_addr"
1246   [(set (reg:SI PR_REG)
1247         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1248   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1249   ""
1250   [(set_attr "length" "0")])
1251
1252 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1253 ;; hard register 0.  If we used hard register 0, then the next instruction
1254 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1255 ;; gets allocated to a stack slot that needs its address reloaded, then
1256 ;; there is nothing to prevent reload from using r0 to reload the address.
1257 ;; This reload would clobber the value in r0 we are trying to store.
1258 ;; If we let reload allocate r0, then this problem can never happen.
1259
1260 (define_insn "udivsi3_i1"
1261   [(set (match_operand:SI 0 "register_operand" "=z")
1262         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1263    (clobber (reg:SI T_REG))
1264    (clobber (reg:SI PR_REG))
1265    (clobber (reg:SI R4_REG))
1266    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267   "TARGET_SH1 && ! TARGET_SH4"
1268   "jsr  @%1%#"
1269   [(set_attr "type" "sfunc")
1270    (set_attr "needs_delay_slot" "yes")])
1271
1272 ; Since shmedia-nofpu code could be linked against shcompact code, and
1273 ; the udivsi3 libcall has the same name, we must consider all registers
1274 ; clobbered that are in the union of the registers clobbered by the
1275 ; shmedia and the shcompact implementation.  Note, if the shcompact
1276 ; implementation actually used shcompact code, we'd need to clobber
1277 ; also r23 and fr23.
1278 (define_insn "udivsi3_i1_media"
1279   [(set (match_operand:SI 0 "register_operand" "=z")
1280         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1281    (clobber (reg:SI T_MEDIA_REG))
1282    (clobber (reg:SI PR_MEDIA_REG))
1283    (clobber (reg:SI R20_REG))
1284    (clobber (reg:SI R21_REG))
1285    (clobber (reg:SI R22_REG))
1286    (clobber (reg:DI TR0_REG))
1287    (clobber (reg:DI TR1_REG))
1288    (clobber (reg:DI TR2_REG))
1289    (use (match_operand:DI 1 "target_operand" "b"))]
1290   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1291   "blink        %1, r18"
1292   [(set_attr "type" "sfunc")
1293    (set_attr "needs_delay_slot" "yes")])
1294
1295 (define_expand "udivsi3_i4_media"
1296   [(set (match_dup 3)
1297         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1298    (set (match_dup 4)
1299         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1300    (set (match_dup 5) (float:DF (match_dup 3)))
1301    (set (match_dup 6) (float:DF (match_dup 4)))
1302    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1303    (set (match_dup 8) (fix:DI (match_dup 7)))
1304    (set (match_operand:SI 0 "register_operand" "")
1305         (truncate:SI (match_dup 8)))]
1306   "TARGET_SHMEDIA_FPU"
1307   "
1308 {
1309   operands[3] = gen_reg_rtx (DImode);
1310   operands[4] = gen_reg_rtx (DImode);
1311   operands[5] = gen_reg_rtx (DFmode);
1312   operands[6] = gen_reg_rtx (DFmode);
1313   operands[7] = gen_reg_rtx (DFmode);
1314   operands[8] = gen_reg_rtx (DImode);
1315 }")
1316
1317 (define_insn "udivsi3_i4"
1318   [(set (match_operand:SI 0 "register_operand" "=y")
1319         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1320    (clobber (reg:SI T_REG))
1321    (clobber (reg:SI PR_REG))
1322    (clobber (reg:DF DR0_REG))
1323    (clobber (reg:DF DR2_REG))
1324    (clobber (reg:DF DR4_REG))
1325    (clobber (reg:SI R0_REG))
1326    (clobber (reg:SI R1_REG))
1327    (clobber (reg:SI R4_REG))
1328    (clobber (reg:SI R5_REG))
1329    (use (reg:PSI FPSCR_REG))
1330    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1331   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1332   "jsr  @%1%#"
1333   [(set_attr "type" "sfunc")
1334    (set_attr "fp_mode" "double")
1335    (set_attr "needs_delay_slot" "yes")])
1336
1337 (define_insn "udivsi3_i4_single"
1338   [(set (match_operand:SI 0 "register_operand" "=y")
1339         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1340    (clobber (reg:SI T_REG))
1341    (clobber (reg:SI PR_REG))
1342    (clobber (reg:DF DR0_REG))
1343    (clobber (reg:DF DR2_REG))
1344    (clobber (reg:DF DR4_REG))
1345    (clobber (reg:SI R0_REG))
1346    (clobber (reg:SI R1_REG))
1347    (clobber (reg:SI R4_REG))
1348    (clobber (reg:SI R5_REG))
1349    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1351   "jsr  @%1%#"
1352   [(set_attr "type" "sfunc")
1353    (set_attr "needs_delay_slot" "yes")])
1354
1355 (define_expand "udivsi3"
1356   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1357    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1358    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1359    (parallel [(set (match_operand:SI 0 "register_operand" "")
1360                    (udiv:SI (reg:SI R4_REG)
1361                             (reg:SI R5_REG)))
1362               (clobber (reg:SI T_REG))
1363               (clobber (reg:SI PR_REG))
1364               (clobber (reg:SI R4_REG))
1365               (use (match_dup 3))])]
1366   ""
1367   "
1368 {
1369   rtx first, last;
1370
1371   operands[3] = gen_reg_rtx (Pmode);
1372   /* Emit the move of the address to a pseudo outside of the libcall.  */
1373   if (TARGET_HARD_SH4 && TARGET_SH2E)
1374     {
1375       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1376       if (TARGET_FPU_SINGLE)
1377         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1378       else
1379         last = gen_udivsi3_i4 (operands[0], operands[3]);
1380     }
1381   else if (TARGET_SHMEDIA_FPU)
1382     {
1383       operands[1] = force_reg (SImode, operands[1]);
1384       operands[2] = force_reg (SImode, operands[2]);
1385       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1386       DONE;
1387     }
1388   else if (TARGET_SH5)
1389     {
1390       emit_move_insn (operands[3],
1391                       function_symbol (TARGET_FPU_ANY
1392                                        ? \"__udivsi3_i4\"
1393                                        : \"__udivsi3\"));
1394
1395       if (TARGET_SHMEDIA)
1396         last = gen_udivsi3_i1_media (operands[0],
1397                                      Pmode == DImode
1398                                      ? operands[3]
1399                                      : gen_rtx_SUBREG (DImode, operands[3],
1400                                                        0));
1401       else if (TARGET_FPU_ANY)
1402         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1403       else
1404         last = gen_udivsi3_i1 (operands[0], operands[3]);
1405     }
1406   else
1407     {
1408       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1409       last = gen_udivsi3_i1 (operands[0], operands[3]);
1410     }
1411   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1412   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1413   last = emit_insn (last);
1414   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1415      invariant code motion can move it.  */
1416   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1417   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1418   DONE;
1419 }")
1420
1421 (define_insn "divsi3_i1"
1422   [(set (match_operand:SI 0 "register_operand" "=z")
1423         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424    (clobber (reg:SI T_REG))
1425    (clobber (reg:SI PR_REG))
1426    (clobber (reg:SI R1_REG))
1427    (clobber (reg:SI R2_REG))
1428    (clobber (reg:SI R3_REG))
1429    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1430   "TARGET_SH1 && ! TARGET_SH4"
1431   "jsr  @%1%#"
1432   [(set_attr "type" "sfunc")
1433    (set_attr "needs_delay_slot" "yes")])
1434
1435 ; Since shmedia-nofpu code could be linked against shcompact code, and
1436 ; the sdivsi3 libcall has the same name, we must consider all registers
1437 ; clobbered that are in the union of the registers clobbered by the
1438 ; shmedia and the shcompact implementation.  Note, if the shcompact
1439 ; implementation actually used shcompact code, we'd need to clobber
1440 ; also r22, r23 and fr23.
1441 (define_insn "divsi3_i1_media"
1442   [(set (match_operand:SI 0 "register_operand" "=z")
1443         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1444    (clobber (reg:SI T_MEDIA_REG))
1445    (clobber (reg:SI PR_MEDIA_REG))
1446    (clobber (reg:SI R1_REG))
1447    (clobber (reg:SI R2_REG))
1448    (clobber (reg:SI R3_REG))
1449    (clobber (reg:SI R20_REG))
1450    (clobber (reg:SI R21_REG))
1451    (clobber (reg:DI TR0_REG))
1452    (clobber (reg:DI TR1_REG))
1453    (clobber (reg:DI TR2_REG))
1454    (use (match_operand:DI 1 "target_operand" "b"))]
1455   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1456   "blink        %1, r18"
1457   [(set_attr "type" "sfunc")])
1458
1459 (define_expand "divsi3_i4_media"
1460   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1461    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1462    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1463    (set (match_operand:SI 0 "register_operand" "=r")
1464         (fix:SI (match_dup 5)))]
1465   "TARGET_SHMEDIA_FPU"
1466   "
1467 {
1468   operands[3] = gen_reg_rtx (DFmode);
1469   operands[4] = gen_reg_rtx (DFmode);
1470   operands[5] = gen_reg_rtx (DFmode);
1471 }")
1472
1473 (define_insn "divsi3_i4"
1474   [(set (match_operand:SI 0 "register_operand" "=y")
1475         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1476    (clobber (reg:SI PR_REG))
1477    (clobber (reg:DF DR0_REG))
1478    (clobber (reg:DF DR2_REG))
1479    (use (reg:PSI FPSCR_REG))
1480    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1482   "jsr  @%1%#"
1483   [(set_attr "type" "sfunc")
1484    (set_attr "fp_mode" "double")
1485    (set_attr "needs_delay_slot" "yes")])
1486
1487 (define_insn "divsi3_i4_single"
1488   [(set (match_operand:SI 0 "register_operand" "=y")
1489         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1490    (clobber (reg:SI PR_REG))
1491    (clobber (reg:DF DR0_REG))
1492    (clobber (reg:DF DR2_REG))
1493    (clobber (reg:SI R2_REG))
1494    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1495   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1496   "jsr  @%1%#"
1497   [(set_attr "type" "sfunc")
1498    (set_attr "needs_delay_slot" "yes")])
1499
1500 (define_expand "divsi3"
1501   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1502    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1503    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1504    (parallel [(set (match_operand:SI 0 "register_operand" "")
1505                    (div:SI (reg:SI R4_REG)
1506                            (reg:SI R5_REG)))
1507               (clobber (reg:SI T_REG))
1508               (clobber (reg:SI PR_REG))
1509               (clobber (reg:SI R1_REG))
1510               (clobber (reg:SI R2_REG))
1511               (clobber (reg:SI R3_REG))
1512               (use (match_dup 3))])]
1513   ""
1514   "
1515 {
1516   rtx first, last;
1517
1518   operands[3] = gen_reg_rtx (Pmode);
1519   /* Emit the move of the address to a pseudo outside of the libcall.  */
1520   if (TARGET_HARD_SH4 && TARGET_SH2E)
1521     {
1522       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1523       if (TARGET_FPU_SINGLE)
1524         last = gen_divsi3_i4_single (operands[0], operands[3]);
1525       else
1526         last = gen_divsi3_i4 (operands[0], operands[3]);
1527     }
1528   else if (TARGET_SHMEDIA_FPU)
1529     {
1530       operands[1] = force_reg (SImode, operands[1]);
1531       operands[2] = force_reg (SImode, operands[2]);
1532       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1533       DONE;
1534     }
1535   else if (TARGET_SH5)
1536     {
1537       emit_move_insn (operands[3],
1538                       function_symbol (TARGET_FPU_ANY
1539                                        ? \"__sdivsi3_i4\"
1540                                        : \"__sdivsi3\"));
1541
1542       if (TARGET_SHMEDIA)
1543         last = gen_divsi3_i1_media (operands[0],
1544                                     Pmode == DImode
1545                                     ? operands[3]
1546                                     : gen_rtx_SUBREG (DImode, operands[3],
1547                                                       0));
1548       else if (TARGET_FPU_ANY)
1549         last = gen_divsi3_i4_single (operands[0], operands[3]);
1550       else
1551         last = gen_divsi3_i1 (operands[0], operands[3]);
1552     }
1553   else
1554     {
1555       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1556       last = gen_divsi3_i1 (operands[0], operands[3]);
1557     }
1558   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1559   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1560   last = emit_insn (last);
1561   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1562      invariant code motion can move it.  */
1563   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1564   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1565   DONE;
1566 }")
1567 \f
1568 ;; -------------------------------------------------------------------------
1569 ;; Multiplication instructions
1570 ;; -------------------------------------------------------------------------
1571
1572 (define_insn "umulhisi3_i"
1573   [(set (reg:SI MACL_REG)
1574         (mult:SI (zero_extend:SI
1575                   (match_operand:HI 0 "arith_reg_operand" "r"))
1576                  (zero_extend:SI
1577                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1578   "TARGET_SH1"
1579   "mulu.w       %1,%0"
1580   [(set_attr "type" "smpy")])
1581
1582 (define_insn "mulhisi3_i"
1583   [(set (reg:SI MACL_REG)
1584         (mult:SI (sign_extend:SI
1585                   (match_operand:HI 0 "arith_reg_operand" "r"))
1586                  (sign_extend:SI
1587                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1588   "TARGET_SH1"
1589   "muls.w       %1,%0"
1590   [(set_attr "type" "smpy")])
1591
1592 (define_expand "mulhisi3"
1593   [(set (reg:SI MACL_REG)
1594         (mult:SI (sign_extend:SI
1595                   (match_operand:HI 1 "arith_reg_operand" ""))
1596                  (sign_extend:SI
1597                   (match_operand:HI 2 "arith_reg_operand" ""))))
1598    (set (match_operand:SI 0 "arith_reg_operand" "")
1599         (reg:SI MACL_REG))]
1600   "TARGET_SH1"
1601   "
1602 {
1603   rtx first, last;
1604
1605   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1606   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1607   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1608      invariant code motion can move it.  */
1609   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1610   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1611   /* expand_binop can't find a suitable code in umul_widen_optab to
1612      make a REG_EQUAL note from, so make one here.
1613      See also smulsi3_highpart.
1614      ??? Alternatively, we could put this at the calling site of expand_binop,
1615      i.e. expand_expr.  */
1616   REG_NOTES (last)
1617     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1618                          REG_NOTES (last));
1619   DONE;
1620 }")
1621
1622 (define_expand "umulhisi3"
1623   [(set (reg:SI MACL_REG)
1624         (mult:SI (zero_extend:SI
1625                   (match_operand:HI 1 "arith_reg_operand" ""))
1626                  (zero_extend:SI
1627                   (match_operand:HI 2 "arith_reg_operand" ""))))
1628    (set (match_operand:SI 0 "arith_reg_operand" "")
1629         (reg:SI MACL_REG))]
1630   "TARGET_SH1"
1631   "
1632 {
1633   rtx first, last;
1634
1635   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1636   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1637   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1638      invariant code motion can move it.  */
1639   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1640   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1641   /* expand_binop can't find a suitable code in umul_widen_optab to
1642      make a REG_EQUAL note from, so make one here.
1643      See also smulsi3_highpart.
1644      ??? Alternatively, we could put this at the calling site of expand_binop,
1645      i.e. expand_expr.  */
1646   REG_NOTES (last)
1647     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1648                          REG_NOTES (last));
1649   DONE;
1650 }")
1651
1652 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1653 ;; a call to a routine which clobbers known registers.
1654
1655 (define_insn ""
1656   [(set (match_operand:SI 1 "register_operand" "=z")
1657         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1658    (clobber (reg:SI MACL_REG))
1659    (clobber (reg:SI T_REG))
1660    (clobber (reg:SI PR_REG))
1661    (clobber (reg:SI R3_REG))
1662    (clobber (reg:SI R2_REG))
1663    (clobber (reg:SI R1_REG))
1664    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1665   "TARGET_SH1"
1666   "jsr  @%0%#"
1667   [(set_attr "type" "sfunc")
1668    (set_attr "needs_delay_slot" "yes")])
1669
1670 (define_expand "mulsi3_call"
1671   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1672    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1673    (parallel[(set (match_operand:SI 0 "register_operand" "")
1674                   (mult:SI (reg:SI R4_REG)
1675                            (reg:SI R5_REG)))
1676              (clobber (reg:SI MACL_REG))
1677              (clobber (reg:SI T_REG))
1678              (clobber (reg:SI PR_REG))
1679              (clobber (reg:SI R3_REG))
1680              (clobber (reg:SI R2_REG))
1681              (clobber (reg:SI R1_REG))
1682              (use (match_operand:SI 3 "register_operand" ""))])]
1683   "TARGET_SH1"
1684   "")
1685
1686 (define_insn "mul_l"
1687   [(set (reg:SI MACL_REG)
1688         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1689                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1690   "TARGET_SH2"
1691   "mul.l        %1,%0"
1692   [(set_attr "type" "dmpy")])
1693
1694 (define_expand "mulsi3"
1695   [(set (reg:SI MACL_REG)
1696         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1697                   (match_operand:SI 2 "arith_reg_operand" "")))
1698    (set (match_operand:SI 0 "arith_reg_operand" "")
1699         (reg:SI MACL_REG))]
1700   "TARGET_SH1"
1701   "
1702 {
1703   rtx first, last;
1704
1705   if (!TARGET_SH2)
1706     {
1707       /* The address must be set outside the libcall,
1708          since it goes into a pseudo.  */
1709       rtx sym = function_symbol (\"__mulsi3\");
1710       rtx addr = force_reg (SImode, sym);
1711       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1712                                    operands[2], addr);
1713       first = insns;
1714       last = emit_insn (insns);
1715     }
1716   else
1717     {
1718       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1719
1720       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1721       /* consec_sets_giv can only recognize the first insn that sets a
1722          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1723          note.  */
1724       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1725     }
1726   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1727      invariant code motion can move it.  */
1728   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1729   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1730   DONE;
1731 }")
1732
1733 (define_insn "mulsidi3_i"
1734   [(set (reg:SI MACH_REG)
1735         (truncate:SI
1736          (lshiftrt:DI
1737           (mult:DI
1738            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1739            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1740           (const_int 32))))
1741    (set (reg:SI MACL_REG)
1742         (mult:SI (match_dup 0)
1743                  (match_dup 1)))]
1744   "TARGET_SH2"
1745   "dmuls.l      %1,%0"
1746   [(set_attr "type" "dmpy")])
1747
1748 (define_expand "mulsidi3"
1749   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1750         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1751                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1752   "TARGET_SH2 || TARGET_SHMEDIA"
1753   "
1754 {
1755   if (TARGET_SH2)
1756     {
1757        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1758                                         operands[2]));
1759        DONE;
1760     }
1761 }")
1762
1763 (define_insn "mulsidi3_media"
1764   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1766                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1767   "TARGET_SHMEDIA"
1768   "muls.l       %1, %2, %0"
1769   [(set_attr "type" "dmpy_media")])
1770
1771 (define_insn "mulsidi3_compact"
1772   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1773         (mult:DI
1774          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1775          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1776    (clobber (reg:SI MACH_REG))
1777    (clobber (reg:SI MACL_REG))]
1778   "TARGET_SH2"
1779   "#")
1780
1781 (define_split
1782   [(set (match_operand:DI 0 "arith_reg_operand" "")
1783         (mult:DI
1784          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1785          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1786    (clobber (reg:SI MACH_REG))
1787    (clobber (reg:SI MACL_REG))]
1788   "TARGET_SH2"
1789   [(const_int 0)]
1790   "
1791 {
1792   rtx low_dst = gen_lowpart (SImode, operands[0]);
1793   rtx high_dst = gen_highpart (SImode, operands[0]);
1794
1795   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1796
1797   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1798   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1799   /* We need something to tag the possible REG_EQUAL notes on to.  */
1800   emit_move_insn (operands[0], operands[0]);
1801   DONE;
1802 }")
1803
1804 (define_insn "umulsidi3_i"
1805   [(set (reg:SI MACH_REG)
1806         (truncate:SI
1807          (lshiftrt:DI
1808           (mult:DI
1809            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1810            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1811           (const_int 32))))
1812    (set (reg:SI MACL_REG)
1813         (mult:SI (match_dup 0)
1814                  (match_dup 1)))]
1815   "TARGET_SH2"
1816   "dmulu.l      %1,%0"
1817   [(set_attr "type" "dmpy")])
1818
1819 (define_expand "umulsidi3"
1820   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1821         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1822                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1823   "TARGET_SH2 || TARGET_SHMEDIA"
1824   "
1825 {
1826   if (TARGET_SH2)
1827     {
1828        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1829                                          operands[2]));
1830        DONE;
1831     }
1832 }")
1833
1834 (define_insn "umulsidi3_media"
1835   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1836         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1837                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1838   "TARGET_SHMEDIA"
1839   "mulu.l       %1, %2, %0"
1840   [(set_attr "type" "dmpy_media")])
1841
1842 (define_insn "umulsidi3_compact"
1843   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1844         (mult:DI
1845          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1846          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1847    (clobber (reg:SI MACH_REG))
1848    (clobber (reg:SI MACL_REG))]
1849   "TARGET_SH2"
1850   "#")
1851
1852 (define_split
1853   [(set (match_operand:DI 0 "arith_reg_operand" "")
1854         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1855                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1856    (clobber (reg:SI MACH_REG))
1857    (clobber (reg:SI MACL_REG))]
1858   "TARGET_SH2"
1859   [(const_int 0)]
1860   "
1861 {
1862   rtx low_dst = gen_lowpart (SImode, operands[0]);
1863   rtx high_dst = gen_highpart (SImode, operands[0]);
1864
1865   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1866
1867   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1868   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1869   /* We need something to tag the possible REG_EQUAL notes on to.  */
1870   emit_move_insn (operands[0], operands[0]);
1871   DONE;
1872 }")
1873
1874 (define_insn "smulsi3_highpart_i"
1875   [(set (reg:SI MACH_REG)
1876         (truncate:SI
1877          (lshiftrt:DI
1878           (mult:DI
1879            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1880            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1881           (const_int 32))))
1882    (clobber (reg:SI MACL_REG))]
1883   "TARGET_SH2"
1884   "dmuls.l      %1,%0"
1885   [(set_attr "type" "dmpy")])
1886
1887 (define_expand "smulsi3_highpart"
1888   [(parallel
1889     [(set (reg:SI MACH_REG)
1890           (truncate:SI
1891            (lshiftrt:DI
1892             (mult:DI
1893              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1894              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1895             (const_int 32))))
1896     (clobber (reg:SI MACL_REG))])
1897    (set (match_operand:SI 0 "arith_reg_operand" "")
1898         (reg:SI MACH_REG))]
1899   "TARGET_SH2"
1900   "
1901 {
1902   rtx first, last;
1903
1904   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1905   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1906   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1907      invariant code motion can move it.  */
1908   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1909   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1910   /* expand_binop can't find a suitable code in mul_highpart_optab to
1911      make a REG_EQUAL note from, so make one here.
1912      See also {,u}mulhisi.
1913      ??? Alternatively, we could put this at the calling site of expand_binop,
1914      i.e. expand_mult_highpart.  */
1915   REG_NOTES (last)
1916     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1917                          REG_NOTES (last));
1918   DONE;
1919 }")
1920
1921 (define_insn "umulsi3_highpart_i"
1922   [(set (reg:SI MACH_REG)
1923         (truncate:SI
1924          (lshiftrt:DI
1925           (mult:DI
1926            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1927            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1928           (const_int 32))))
1929    (clobber (reg:SI MACL_REG))]
1930   "TARGET_SH2"
1931   "dmulu.l      %1,%0"
1932   [(set_attr "type" "dmpy")])
1933
1934 (define_expand "umulsi3_highpart"
1935   [(parallel
1936     [(set (reg:SI MACH_REG)
1937           (truncate:SI
1938            (lshiftrt:DI
1939             (mult:DI
1940              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1941              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1942             (const_int 32))))
1943     (clobber (reg:SI MACL_REG))])
1944    (set (match_operand:SI 0 "arith_reg_operand" "")
1945         (reg:SI MACH_REG))]
1946   "TARGET_SH2"
1947   "
1948 {
1949   rtx first, last;
1950
1951   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1952   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1953   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1954      invariant code motion can move it.  */
1955   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1956   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1957   DONE;
1958 }")
1959 \f
1960 ;; -------------------------------------------------------------------------
1961 ;; Logical operations
1962 ;; -------------------------------------------------------------------------
1963
1964 (define_insn "*andsi3_compact"
1965   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1968   "TARGET_SH1"
1969   "and  %2,%0"
1970   [(set_attr "type" "arith")])
1971
1972 ;; If the constant is 255, then emit an extu.b instruction instead of an
1973 ;; and, since that will give better code.
1974
1975 (define_expand "andsi3"
1976   [(set (match_operand:SI 0 "arith_reg_operand" "")
1977         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1978                 (match_operand:SI 2 "logical_operand" "")))]
1979   "TARGET_SH1"
1980   "
1981 {
1982   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1983     {
1984       emit_insn (gen_zero_extendqisi2 (operands[0],
1985                                        gen_lowpart (QImode, operands[1])));
1986       DONE;
1987     }
1988 }")
1989
1990 (define_insn_and_split "anddi3"
1991   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1992         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1993                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1994   "TARGET_SHMEDIA"
1995   "@
1996         and     %1, %2, %0
1997         andi    %1, %2, %0
1998         #"
1999   "reload_completed
2000    && ! logical_operand (operands[2], DImode)"
2001   [(const_int 0)]
2002   "
2003 {
2004   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2005     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2006   else
2007     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2008   DONE;
2009 }"
2010   [(set_attr "type" "arith_media")])
2011
2012 (define_insn "andcdi3"
2013   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2014         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2015                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2016   "TARGET_SHMEDIA"
2017   "andc %1,%2,%0"
2018   [(set_attr "type" "arith_media")])
2019
2020 (define_insn "iorsi3"
2021   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2022         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2023                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2024   "TARGET_SH1"
2025   "or   %2,%0"
2026   [(set_attr "type" "arith")])
2027
2028 (define_insn "iordi3"
2029   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2030         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2031                 (match_operand:DI 2 "logical_operand" "r,I10")))]
2032   "TARGET_SHMEDIA"
2033   "@
2034         or      %1, %2, %0
2035         ori     %1, %2, %0"
2036   [(set_attr "type" "arith_media")])
2037
2038 (define_insn "xorsi3"
2039   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2040         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2041                 (match_operand:SI 2 "logical_operand" "K08,r")))]
2042   "TARGET_SH1"
2043   "xor  %2,%0"
2044   [(set_attr "type" "arith")])
2045
2046 (define_insn "xordi3"
2047   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2048         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2049                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2050   "TARGET_SHMEDIA"
2051   "@
2052         xor     %1, %2, %0
2053         xori    %1, %2, %0"
2054   [(set_attr "type" "arith_media")])
2055
2056 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2057 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2058 (define_split
2059   [(set (match_operand:DI 0 "arith_reg_operand" "")
2060         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2061                           [(match_operand 1 "any_register_operand" "")
2062                            (match_operand 2 "any_register_operand" "")])))]
2063   "TARGET_SHMEDIA"
2064   [(set (match_dup 5) (match_dup 4))
2065    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2066 "
2067 {
2068   enum machine_mode inmode = GET_MODE (operands[1]);
2069   int offset = 0;
2070
2071   if (GET_CODE (operands[0]) == SUBREG)
2072     {
2073       offset = SUBREG_BYTE (operands[0]);
2074       operands[0] = SUBREG_REG (operands[0]);
2075     }
2076   if (GET_CODE (operands[0]) != REG)
2077     abort ();
2078   if (! TARGET_LITTLE_ENDIAN)
2079     offset += 8 - GET_MODE_SIZE (inmode);
2080   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2081 }")
2082 \f
2083 ;; -------------------------------------------------------------------------
2084 ;; Shifts and rotates
2085 ;; -------------------------------------------------------------------------
2086
2087 (define_expand "rotldi3"
2088   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2089         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2090                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2091   "TARGET_SHMEDIA"
2092   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2093
2094 (define_insn "rotldi3_mextr"
2095   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2096         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2097                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2098   "TARGET_SHMEDIA"
2099   "*
2100 {
2101   static char templ[16];
2102
2103   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2104            8 - (int) (INTVAL (operands[2]) >> 3));
2105   return templ;
2106 }"
2107   [(set_attr "type" "arith_media")])
2108
2109 (define_expand "rotrdi3"
2110   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2111         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2112                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2113   "TARGET_SHMEDIA"
2114   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2115
2116 (define_insn "rotrdi3_mextr"
2117   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2118         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2119                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2120   "TARGET_SHMEDIA"
2121   "*
2122 {
2123   static char templ[16];
2124
2125   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2126   return templ;
2127 }"
2128   [(set_attr "type" "arith_media")])
2129
2130 (define_insn "rotlsi3_1"
2131   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2133                    (const_int 1)))
2134    (set (reg:SI T_REG)
2135         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2136   "TARGET_SH1"
2137   "rotl %0"
2138   [(set_attr "type" "arith")])
2139
2140 (define_insn "rotlsi3_31"
2141   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2142         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2143                    (const_int 31)))
2144    (clobber (reg:SI T_REG))]
2145   "TARGET_SH1"
2146   "rotr %0"
2147   [(set_attr "type" "arith")])
2148
2149 (define_insn "rotlsi3_16"
2150   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2151         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2152                    (const_int 16)))]
2153   "TARGET_SH1"
2154   "swap.w       %1,%0"
2155   [(set_attr "type" "arith")])
2156
2157 (define_expand "rotlsi3"
2158   [(set (match_operand:SI 0 "arith_reg_operand" "")
2159         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2160                    (match_operand:SI 2 "immediate_operand" "")))]
2161   "TARGET_SH1"
2162   "
2163 {
2164   static const char rot_tab[] = {
2165     000, 000, 000, 000, 000, 000, 010, 001,
2166     001, 001, 011, 013, 003, 003, 003, 003,
2167     003, 003, 003, 003, 003, 013, 012, 002,
2168     002, 002, 010, 000, 000, 000, 000, 000,
2169   };
2170
2171   int count, choice;
2172
2173   if (GET_CODE (operands[2]) != CONST_INT)
2174     FAIL;
2175   count = INTVAL (operands[2]);
2176   choice = rot_tab[count];
2177   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2178     FAIL;
2179   choice &= 7;
2180   switch (choice)
2181     {
2182     case 0:
2183       emit_move_insn (operands[0], operands[1]);
2184       count -= (count & 16) * 2;
2185       break;
2186     case 3:
2187      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2188      count -= 16;
2189      break;
2190     case 1:
2191     case 2:
2192       {
2193         rtx parts[2];
2194         parts[0] = gen_reg_rtx (SImode);
2195         parts[1] = gen_reg_rtx (SImode);
2196         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2197         emit_move_insn (parts[choice-1], operands[1]);
2198         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2199         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2200         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2201         count = (count & ~16) - 8;
2202       }
2203     }
2204
2205   for (; count > 0; count--)
2206     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2207   for (; count < 0; count++)
2208     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2209
2210   DONE;
2211 }")
2212
2213 (define_insn "*rotlhi3_8"
2214   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2215         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2216                    (const_int 8)))]
2217   "TARGET_SH1"
2218   "swap.b       %1,%0"
2219   [(set_attr "type" "arith")])
2220
2221 (define_expand "rotlhi3"
2222   [(set (match_operand:HI 0 "arith_reg_operand" "")
2223         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2224                    (match_operand:HI 2 "immediate_operand" "")))]
2225   "TARGET_SH1"
2226   "
2227 {
2228   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2229     FAIL;
2230 }")
2231
2232 ;;
2233 ;; shift left
2234
2235 ;; This pattern is used by init_expmed for computing the costs of shift
2236 ;; insns.
2237
2238 (define_insn_and_split "ashlsi3_std"
2239   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2240         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2241                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2242    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2243   "TARGET_SH3
2244    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2245        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2246   "@
2247    shld %2,%0
2248    add  %0,%0
2249    shll%O2      %0
2250    #"
2251   "TARGET_SH3
2252    && reload_completed
2253    && GET_CODE (operands[2]) == CONST_INT
2254    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2255   [(set (match_dup 3) (match_dup 2))
2256    (parallel
2257     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2258      (clobber (match_dup 4))])]
2259   "operands[4] = gen_rtx_SCRATCH (SImode);"
2260   [(set_attr "length" "*,*,*,4")
2261    (set_attr "type" "dyn_shift,arith,arith,arith")])
2262
2263 (define_insn "ashlhi3_k"
2264   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2265         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2266                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2267   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2268   "@
2269         add     %0,%0
2270         shll%O2 %0"
2271   [(set_attr "type" "arith")])
2272
2273 (define_insn "ashlsi3_n"
2274   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2275         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2276                    (match_operand:SI 2 "const_int_operand" "n")))
2277    (clobber (reg:SI T_REG))]
2278   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2279   "#"
2280   [(set (attr "length")
2281         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2282                (const_string "2")
2283                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2284                (const_string "4")
2285                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2286                (const_string "6")]
2287               (const_string "8")))
2288    (set_attr "type" "arith")])
2289
2290 (define_split
2291   [(set (match_operand:SI 0 "arith_reg_operand" "")
2292         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2293                    (match_operand:SI 2 "const_int_operand" "")))
2294    (clobber (reg:SI T_REG))]
2295   "TARGET_SH1 && reload_completed"
2296   [(use (reg:SI R0_REG))]
2297   "
2298 {
2299   gen_shifty_op (ASHIFT, operands);
2300   DONE;
2301 }")
2302
2303 (define_insn "ashlsi3_media"
2304   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2305         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2306                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2307   "TARGET_SHMEDIA"
2308   "@
2309         shlld.l %1, %2, %0
2310         shlli.l %1, %2, %0"
2311   [(set_attr "type" "arith_media")])
2312
2313 (define_expand "ashlsi3"
2314   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2315                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2316                               (match_operand:SI 2 "nonmemory_operand" "")))
2317               (clobber (reg:SI T_REG))])]
2318   ""
2319   "
2320 {
2321   if (TARGET_SHMEDIA)
2322     {
2323       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2324       DONE;
2325     }
2326   if (GET_CODE (operands[2]) == CONST_INT
2327       && sh_dynamicalize_shift_p (operands[2]))
2328     operands[2] = force_reg (SImode, operands[2]);
2329   if (TARGET_SH3)
2330     {
2331       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2332       DONE;
2333     }
2334   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2335     FAIL;
2336 }")
2337
2338 (define_insn "ashlhi3"
2339   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2340         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2341                    (match_operand:HI 2 "const_int_operand" "n")))
2342    (clobber (reg:SI T_REG))]
2343   "TARGET_SH1"
2344   "#"
2345   [(set (attr "length")
2346         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2347                (const_string "2")
2348                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2349                (const_string "4")]
2350               (const_string "6")))
2351    (set_attr "type" "arith")])
2352
2353 (define_split
2354   [(set (match_operand:HI 0 "arith_reg_operand" "")
2355         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2356                    (match_operand:HI 2 "const_int_operand" "")))
2357    (clobber (reg:SI T_REG))]
2358   "TARGET_SH1 && reload_completed"
2359   [(use (reg:SI R0_REG))]
2360   "
2361 {
2362   gen_shifty_hi_op (ASHIFT, operands);
2363   DONE;
2364 }")
2365
2366 ;
2367 ; arithmetic shift right
2368 ;
2369
2370 (define_insn "ashrsi3_k"
2371   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2372         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2373                      (match_operand:SI 2 "const_int_operand" "M")))
2374    (clobber (reg:SI T_REG))]
2375   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2376   "shar %0"
2377   [(set_attr "type" "arith")])
2378
2379 ;; We can't do HImode right shifts correctly unless we start out with an
2380 ;; explicit zero / sign extension; doing that would result in worse overall
2381 ;; code, so just let the machine independent code widen the mode.
2382 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2383
2384
2385 ;; ??? This should be a define expand.
2386
2387 (define_insn "ashrsi2_16"
2388   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2390                      (const_int 16)))]
2391   "TARGET_SH1"
2392   "#"
2393   [(set_attr "length" "4")])
2394
2395 (define_split
2396   [(set (match_operand:SI 0 "arith_reg_operand" "")
2397         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2398                      (const_int 16)))]
2399   "TARGET_SH1"
2400   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2401    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2402   "operands[2] = gen_lowpart (HImode, operands[0]);")
2403
2404 ;; ??? This should be a define expand.
2405
2406 (define_insn "ashrsi2_31"
2407   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2408         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2409                      (const_int 31)))
2410    (clobber (reg:SI T_REG))]
2411   "TARGET_SH1"
2412   "#"
2413   [(set_attr "length" "4")])
2414
2415 (define_split
2416   [(set (match_operand:SI 0 "arith_reg_operand" "")
2417         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2418                      (const_int 31)))
2419    (clobber (reg:SI T_REG))]
2420   "TARGET_SH1"
2421   [(const_int 0)]
2422   "
2423 {
2424   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2425   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2426   DONE;
2427 }")
2428
2429 (define_insn "ashlsi_c"
2430   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2431         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2432    (set (reg:SI T_REG)
2433         (lt:SI (match_dup 1) (const_int 0)))]
2434   "TARGET_SH1"
2435   "shll %0"
2436   [(set_attr "type" "arith")])
2437
2438 (define_insn "ashrsi3_d"
2439   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2440         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2441                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2442   "TARGET_SH3"
2443   "shad %2,%0"
2444   [(set_attr "type" "dyn_shift")])
2445
2446 (define_insn "ashrsi3_n"
2447   [(set (reg:SI R4_REG)
2448         (ashiftrt:SI (reg:SI R4_REG)
2449                      (match_operand:SI 0 "const_int_operand" "i")))
2450    (clobber (reg:SI T_REG))
2451    (clobber (reg:SI PR_REG))
2452    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2453   "TARGET_SH1"
2454   "jsr  @%1%#"
2455   [(set_attr "type" "sfunc")
2456    (set_attr "needs_delay_slot" "yes")])
2457
2458 (define_insn "ashrsi3_media"
2459   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2460         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2461                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2462   "TARGET_SHMEDIA"
2463   "@
2464         shard.l %1, %2, %0
2465         shari.l %1, %2, %0"
2466   [(set_attr "type" "arith_media")])
2467
2468 (define_expand "ashrsi3"
2469   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2470                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2471                                 (match_operand:SI 2 "nonmemory_operand" "")))
2472               (clobber (reg:SI T_REG))])]
2473   ""
2474   "
2475 {
2476   if (TARGET_SHMEDIA)
2477     {
2478       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2479       DONE;
2480     }
2481   if (expand_ashiftrt (operands))
2482     DONE;
2483   else
2484     FAIL;
2485 }")
2486
2487 ;; logical shift right
2488
2489 (define_insn "lshrsi3_d"
2490   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2493   "TARGET_SH3"
2494   "shld %2,%0"
2495   [(set_attr "type" "dyn_shift")])
2496
2497 ;;  Only the single bit shift clobbers the T bit.
2498
2499 (define_insn "lshrsi3_m"
2500   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2501         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2502                      (match_operand:SI 2 "const_int_operand" "M")))
2503    (clobber (reg:SI T_REG))]
2504   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2505   "shlr %0"
2506   [(set_attr "type" "arith")])
2507
2508 (define_insn "lshrsi3_k"
2509   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2510         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2511                      (match_operand:SI 2 "const_int_operand" "P27")))]
2512   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2513    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2514   "shlr%O2      %0"
2515   [(set_attr "type" "arith")])
2516
2517 (define_insn "lshrsi3_n"
2518   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2519         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2520                      (match_operand:SI 2 "const_int_operand" "n")))
2521    (clobber (reg:SI T_REG))]
2522   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2523   "#"
2524   [(set (attr "length")
2525         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2526                (const_string "2")
2527                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2528                (const_string "4")
2529                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2530                (const_string "6")]
2531               (const_string "8")))
2532    (set_attr "type" "arith")])
2533
2534 (define_split
2535   [(set (match_operand:SI 0 "arith_reg_operand" "")
2536         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2537                      (match_operand:SI 2 "const_int_operand" "")))
2538    (clobber (reg:SI T_REG))]
2539   "TARGET_SH1 && reload_completed"
2540   [(use (reg:SI R0_REG))]
2541   "
2542 {
2543   gen_shifty_op (LSHIFTRT, operands);
2544   DONE;
2545 }")
2546
2547 (define_insn "lshrsi3_media"
2548   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2549         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2550                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2551   "TARGET_SHMEDIA"
2552   "@
2553         shlrd.l %1, %2, %0
2554         shlri.l %1, %2, %0"
2555   [(set_attr "type" "arith_media")])
2556
2557 (define_expand "lshrsi3"
2558   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2559                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2560                                 (match_operand:SI 2 "nonmemory_operand" "")))
2561               (clobber (reg:SI T_REG))])]
2562   ""
2563   "
2564 {
2565   if (TARGET_SHMEDIA)
2566     {
2567       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2568       DONE;
2569     }
2570   if (GET_CODE (operands[2]) == CONST_INT
2571       && sh_dynamicalize_shift_p (operands[2]))
2572     operands[2] = force_reg (SImode, operands[2]);
2573   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2574     {
2575       rtx count = copy_to_mode_reg (SImode, operands[2]);
2576       emit_insn (gen_negsi2 (count, count));
2577       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2578       DONE;
2579     }
2580   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2581     FAIL;
2582 }")
2583
2584 ;; ??? This should be a define expand.
2585
2586 (define_insn "ashldi3_k"
2587   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2588         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2589                    (const_int 1)))
2590    (clobber (reg:SI T_REG))]
2591   "TARGET_SH1"
2592   "shll %R0\;rotcl      %S0"
2593   [(set_attr "length" "4")
2594    (set_attr "type" "arith")])
2595
2596 (define_insn "ashldi3_media"
2597   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2598         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2599                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2600   "TARGET_SHMEDIA"
2601   "@
2602         shlld   %1, %2, %0
2603         shlli   %1, %2, %0"
2604   [(set_attr "type" "arith_media")])
2605
2606 (define_expand "ashldi3"
2607   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2608                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2609                               (match_operand:DI 2 "immediate_operand" "")))
2610               (clobber (reg:SI T_REG))])]
2611   ""
2612   "
2613 {
2614   if (TARGET_SHMEDIA)
2615     {
2616       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2617       DONE;
2618     }
2619   if (GET_CODE (operands[2]) != CONST_INT
2620       || INTVAL (operands[2]) != 1)
2621     FAIL;
2622 }")
2623
2624 ;; ??? This should be a define expand.
2625
2626 (define_insn "lshrdi3_k"
2627   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2628         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2629                      (const_int 1)))
2630    (clobber (reg:SI T_REG))]
2631   "TARGET_SH1"
2632   "shlr %S0\;rotcr      %R0"
2633   [(set_attr "length" "4")
2634    (set_attr "type" "arith")])
2635
2636 (define_insn "lshrdi3_media"
2637   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2638         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2639                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2640   "TARGET_SHMEDIA"
2641   "@
2642         shlrd   %1, %2, %0
2643         shlri   %1, %2, %0"
2644   [(set_attr "type" "arith_media")])
2645
2646 (define_expand "lshrdi3"
2647   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2648                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2649                                (match_operand:DI 2 "immediate_operand" "")))
2650              (clobber (reg:SI T_REG))])]
2651   ""
2652   "
2653 {
2654   if (TARGET_SHMEDIA)
2655     {
2656       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2657       DONE;
2658     }
2659   if (GET_CODE (operands[2]) != CONST_INT
2660       || INTVAL (operands[2]) != 1)
2661     FAIL;
2662 }")
2663
2664 ;; ??? This should be a define expand.
2665
2666 (define_insn "ashrdi3_k"
2667   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2668         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2669                      (const_int 1)))
2670    (clobber (reg:SI T_REG))]
2671   "TARGET_SH1"
2672   "shar %S0\;rotcr      %R0"
2673   [(set_attr "length" "4")
2674    (set_attr "type" "arith")])
2675
2676 (define_insn "ashrdi3_media"
2677   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2678         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2679                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2680   "TARGET_SHMEDIA"
2681   "@
2682         shard   %1, %2, %0
2683         shari   %1, %2, %0"
2684   [(set_attr "type" "arith_media")])
2685
2686 (define_expand "ashrdi3"
2687   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2688                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2689                                 (match_operand:DI 2 "immediate_operand" "")))
2690               (clobber (reg:SI T_REG))])]
2691   ""
2692   "
2693 {
2694   if (TARGET_SHMEDIA)
2695     {
2696       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2697       DONE;
2698     }
2699   if (GET_CODE (operands[2]) != CONST_INT
2700       || INTVAL (operands[2]) != 1)
2701     FAIL;
2702 }")
2703
2704 ;; combined left/right shift
2705
2706 (define_split
2707   [(set (match_operand:SI 0 "register_operand" "")
2708         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2709                            (match_operand:SI 2 "const_int_operand" ""))
2710                 (match_operand:SI 3 "const_int_operand" "")))]
2711   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2712   [(use (reg:SI R0_REG))]
2713   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2714    DONE;")
2715
2716 (define_split
2717   [(set (match_operand:SI 0 "register_operand" "")
2718         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2719                            (match_operand:SI 2 "const_int_operand" ""))
2720                 (match_operand:SI 3 "const_int_operand" "")))
2721    (clobber (reg:SI T_REG))]
2722   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2723   [(use (reg:SI R0_REG))]
2724   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2725    DONE;")
2726
2727 (define_insn ""
2728   [(set (match_operand:SI 0 "register_operand" "=r")
2729         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730                            (match_operand:SI 2 "const_int_operand" "n"))
2731                 (match_operand:SI 3 "const_int_operand" "n")))
2732    (clobber (reg:SI T_REG))]
2733   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2734  "#"
2735   [(set (attr "length")
2736         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2737                (const_string "4")
2738                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2739                (const_string "6")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2741                (const_string "8")
2742                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2743                (const_string "10")
2744                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2745                (const_string "12")
2746                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2747                (const_string "14")
2748                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2749                (const_string "16")]
2750               (const_string "18")))
2751    (set_attr "type" "arith")])
2752
2753 (define_insn ""
2754   [(set (match_operand:SI 0 "register_operand" "=z")
2755         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2756                            (match_operand:SI 2 "const_int_operand" "n"))
2757                 (match_operand:SI 3 "const_int_operand" "n")))
2758    (clobber (reg:SI T_REG))]
2759   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2760  "#"
2761   [(set (attr "length")
2762         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2763                (const_string "4")
2764                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2765                (const_string "6")
2766                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2767                (const_string "8")]
2768               (const_string "10")))
2769    (set_attr "type" "arith")])
2770
2771 ;; shift left / and combination with a scratch register: The combine pass
2772 ;; does not accept the individual instructions, even though they are
2773 ;; cheap.  But it needs a precise description so that it is usable after
2774 ;; reload.
2775 (define_insn "and_shl_scratch"
2776   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2777         (lshiftrt:SI
2778          (ashift:SI
2779           (and:SI
2780            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2781                         (match_operand:SI 2 "const_int_operand" "N,n"))
2782            (match_operand:SI 3 "" "0,r"))
2783           (match_operand:SI 4 "const_int_operand" "n,n"))
2784          (match_operand:SI 5 "const_int_operand" "n,n")))
2785    (clobber (reg:SI T_REG))]
2786   "TARGET_SH1"
2787   "#"
2788   [(set (attr "length")
2789         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2790                (const_string "4")
2791                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2792                (const_string "6")
2793                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2794                (const_string "8")
2795                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2796                (const_string "10")]
2797               (const_string "12")))
2798    (set_attr "type" "arith")])
2799
2800 (define_split
2801   [(set (match_operand:SI 0 "register_operand" "")
2802         (lshiftrt:SI
2803          (ashift:SI
2804           (and:SI
2805            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2806                         (match_operand:SI 2 "const_int_operand" ""))
2807            (match_operand:SI 3 "register_operand" ""))
2808           (match_operand:SI 4 "const_int_operand" ""))
2809          (match_operand:SI 5 "const_int_operand" "")))
2810    (clobber (reg:SI T_REG))]
2811   "TARGET_SH1"
2812   [(use (reg:SI R0_REG))]
2813   "
2814 {
2815   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2816
2817   if (INTVAL (operands[2]))
2818     {
2819       gen_shifty_op (LSHIFTRT, operands);
2820     }
2821   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2822   operands[2] = operands[4];
2823   gen_shifty_op (ASHIFT, operands);
2824   if (INTVAL (operands[5]))
2825     {
2826       operands[2] = operands[5];
2827       gen_shifty_op (LSHIFTRT, operands);
2828     }
2829   DONE;
2830 }")
2831
2832 ;; signed left/right shift combination.
2833 (define_split
2834   [(set (match_operand:SI 0 "register_operand" "")
2835         (sign_extract:SI
2836          (ashift:SI (match_operand:SI 1 "register_operand" "")
2837                     (match_operand:SI 2 "const_int_operand" ""))
2838          (match_operand:SI 3 "const_int_operand" "")
2839          (const_int 0)))
2840    (clobber (reg:SI T_REG))]
2841   "TARGET_SH1"
2842   [(use (reg:SI R0_REG))]
2843   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2844    DONE;")
2845
2846 (define_insn "shl_sext_ext"
2847   [(set (match_operand:SI 0 "register_operand" "=r")
2848         (sign_extract:SI
2849          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2850                     (match_operand:SI 2 "const_int_operand" "n"))
2851          (match_operand:SI 3 "const_int_operand" "n")
2852          (const_int 0)))
2853    (clobber (reg:SI T_REG))]
2854   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2855   "#"
2856   [(set (attr "length")
2857         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2858                (const_string "2")
2859                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2860                (const_string "4")
2861                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2862                (const_string "6")
2863                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2864                (const_string "8")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2866                (const_string "10")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2868                (const_string "12")
2869                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2870                (const_string "14")
2871                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2872                (const_string "16")]
2873               (const_string "18")))
2874     (set_attr "type" "arith")])
2875
2876 (define_insn "shl_sext_sub"
2877   [(set (match_operand:SI 0 "register_operand" "=z")
2878         (sign_extract:SI
2879          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2880                     (match_operand:SI 2 "const_int_operand" "n"))
2881          (match_operand:SI 3 "const_int_operand" "n")
2882          (const_int 0)))
2883    (clobber (reg:SI T_REG))]
2884   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2885   "#"
2886   [(set (attr "length")
2887         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2888                (const_string "6")
2889                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2890                (const_string "8")
2891                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2892                (const_string "10")
2893                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2894                (const_string "12")]
2895               (const_string "14")))
2896     (set_attr "type" "arith")])
2897
2898 ;; These patterns are found in expansions of DImode shifts by 16, and
2899 ;; allow the xtrct instruction to be generated from C source.
2900
2901 (define_insn "xtrct_left"
2902   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2904                            (const_int 16))
2905                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2906                              (const_int 16))))]
2907   "TARGET_SH1"
2908   "xtrct        %1,%0"
2909   [(set_attr "type" "arith")])
2910
2911 (define_insn "xtrct_right"
2912   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2914                              (const_int 16))
2915                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2916                            (const_int 16))))]
2917   "TARGET_SH1"
2918   "xtrct        %2,%0"
2919   [(set_attr "type" "arith")])
2920
2921 ;; -------------------------------------------------------------------------
2922 ;; Unary arithmetic
2923 ;; -------------------------------------------------------------------------
2924
2925 (define_insn "negc"
2926   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2927         (neg:SI (plus:SI (reg:SI T_REG)
2928                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2929    (set (reg:SI T_REG)
2930         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2931                (const_int 0)))]
2932   "TARGET_SH1"
2933   "negc %1,%0"
2934   [(set_attr "type" "arith")])
2935
2936 (define_insn "*negdi_media"
2937   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2938         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2939   "TARGET_SHMEDIA"
2940   "sub  r63, %1, %0"
2941   [(set_attr "type" "arith_media")])
2942
2943 (define_expand "negdi2"
2944   [(set (match_operand:DI 0 "arith_reg_operand" "")
2945         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2946   ""
2947   "
2948 {
2949   if (TARGET_SH1)
2950     {
2951       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2952       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2953
2954       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2955       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2956
2957       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2958       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2959
2960       emit_insn (gen_clrt ());
2961       emit_insn (gen_negc (low_dst, low_src));
2962       emit_insn (gen_negc (high_dst, high_src));
2963       DONE;
2964     }
2965 }")
2966
2967 (define_insn "negsi2"
2968   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2969         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2970   "TARGET_SH1"
2971   "neg  %1,%0"
2972   [(set_attr "type" "arith")])
2973
2974 (define_insn "one_cmplsi2"
2975   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2977   "TARGET_SH1"
2978   "not  %1,%0"
2979   [(set_attr "type" "arith")])
2980
2981 (define_expand "one_cmpldi2"
2982   [(set (match_operand:DI 0 "arith_reg_operand" "")
2983         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2984                 (const_int -1)))]
2985   "TARGET_SHMEDIA" "")
2986 \f
2987 ;; -------------------------------------------------------------------------
2988 ;; Zero extension instructions
2989 ;; -------------------------------------------------------------------------
2990
2991 (define_insn "zero_extendsidi2"
2992   [(set (match_operand:DI 0 "register_operand" "=r")
2993         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2994   "TARGET_SHMEDIA"
2995   "addz.l       %1, r63, %0"
2996   [(set_attr "type" "arith_media")])
2997
2998 (define_insn "zero_extendhidi2"
2999   [(set (match_operand:DI 0 "register_operand" "=r,r")
3000         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3001   "TARGET_SHMEDIA"
3002   "@
3003         #
3004         ld%M1.uw        %m1, %0"
3005   [(set_attr "type" "*,load_media")])
3006
3007 (define_split
3008   [(set (match_operand:DI 0 "register_operand" "")
3009         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3010   "TARGET_SHMEDIA && reload_completed"
3011   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3012    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3013   "
3014 {
3015   if (GET_CODE (operands[1]) == TRUNCATE)
3016     operands[1] = XEXP (operands[1], 0);
3017 }")
3018
3019 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3020 ;; reload the entire truncate expression.
3021 (define_insn_and_split "*loaddi_trunc"
3022   [(set (match_operand 0 "int_gpr_dest" "=r")
3023         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3024   "TARGET_SHMEDIA && reload_completed"
3025   "#"
3026   "TARGET_SHMEDIA && reload_completed"
3027   [(set (match_dup 0) (match_dup 1))]
3028   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3029
3030 (define_insn "zero_extendqidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r,r")
3032         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3033   "TARGET_SHMEDIA"
3034   "@
3035         andi    %1, 255, %0
3036         ld%M1.ub        %m1, %0"
3037   [(set_attr "type" "arith_media,load_media")])
3038
3039 (define_expand "zero_extendhisi2"
3040   [(set (match_operand:SI 0 "arith_reg_operand" "")
3041         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3042   ""
3043   "
3044 {
3045   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3046     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3047 }")
3048
3049 (define_insn "*zero_extendhisi2_compact"
3050   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3051         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3052   "TARGET_SH1"
3053   "extu.w       %1,%0"
3054   [(set_attr "type" "arith")])
3055
3056 (define_insn "*zero_extendhisi2_media"
3057   [(set (match_operand:SI 0 "register_operand" "=r,r")
3058         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3059   "TARGET_SHMEDIA"
3060   "@
3061         #
3062         ld%M1.uw        %m1, %0"
3063   [(set_attr "type" "arith_media,load_media")])
3064
3065 (define_split
3066   [(set (match_operand:SI 0 "register_operand" "")
3067         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3068   "TARGET_SHMEDIA && reload_completed"
3069   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3070    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3071   "
3072 {
3073   if (GET_CODE (operands[1]) == TRUNCATE)
3074     operands[1] = XEXP (operands[1], 0);
3075 }")
3076
3077 (define_expand "zero_extendqisi2"
3078   [(set (match_operand:SI 0 "arith_reg_operand" "")
3079         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3080   ""
3081   "
3082 {
3083   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3084     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3085 }")
3086
3087 (define_insn "*zero_extendqisi2_compact"
3088   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3089         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3090   "TARGET_SH1"
3091   "extu.b       %1,%0"
3092   [(set_attr "type" "arith")])
3093
3094 (define_insn "*zero_extendqisi2_media"
3095   [(set (match_operand:SI 0 "register_operand" "=r,r")
3096         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3097   "TARGET_SHMEDIA"
3098   "@
3099         andi    %1, 255, %0
3100         ld%M1.ub        %m1, %0"
3101   [(set_attr "type" "arith_media,load_media")])
3102
3103 (define_insn "zero_extendqihi2"
3104   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3105         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3106   "TARGET_SH1"
3107   "extu.b       %1,%0"
3108   [(set_attr "type" "arith")])
3109
3110 ;; -------------------------------------------------------------------------
3111 ;; Sign extension instructions
3112 ;; -------------------------------------------------------------------------
3113
3114 ;; ??? This should be a define expand.
3115 ;; ??? Or perhaps it should be dropped?
3116
3117 ;; convert_move generates good code for SH[1-4].
3118 (define_insn "extendsidi2"
3119   [(set (match_operand:DI 0 "register_operand" "=r,r")
3120         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3121   "TARGET_SHMEDIA"
3122   "@
3123         add.l   %1, r63, %0
3124         ld%M1.l %m1, %0"
3125   [(set_attr "type" "arith_media,load_media")])
3126
3127 (define_insn "extendhidi2"
3128   [(set (match_operand:DI 0 "register_operand" "=r,r")
3129         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3130   "TARGET_SHMEDIA"
3131   "@
3132         #
3133         ld%M1.w %m1, %0"
3134   [(set_attr "type" "*,load_media")])
3135
3136 (define_split
3137   [(set (match_operand:DI 0 "register_operand" "")
3138         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3139   "TARGET_SHMEDIA && reload_completed"
3140   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3141    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3142   "
3143 {
3144   if (GET_CODE (operands[1]) == TRUNCATE)
3145     operands[1] = XEXP (operands[1], 0);
3146 }")
3147
3148 (define_insn "extendqidi2"
3149   [(set (match_operand:DI 0 "register_operand" "=r,r")
3150         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3151   "TARGET_SHMEDIA"
3152   "@
3153         #
3154         ld%M1.b %m1, %0"
3155   [(set_attr "type" "*,load_media")])
3156
3157 (define_split
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3160   "TARGET_SHMEDIA && reload_completed"
3161   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3162    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3163   "
3164 {
3165   if (GET_CODE (operands[1]) == TRUNCATE)
3166     operands[1] = XEXP (operands[1], 0);
3167 }")
3168
3169 (define_expand "extendhisi2"
3170   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3171         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3172   ""
3173   "")
3174
3175 (define_insn "*extendhisi2_compact"
3176   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3177         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3178   "TARGET_SH1"
3179   "@
3180         exts.w  %1,%0
3181         mov.w   %1,%0"
3182   [(set_attr "type" "arith,load")])
3183
3184 (define_insn "*extendhisi2_media"
3185   [(set (match_operand:SI 0 "register_operand" "=r,r")
3186         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3187   "TARGET_SHMEDIA"
3188   "@
3189         #
3190         ld%M1.w %m1, %0"
3191   [(set_attr "type" "arith_media,load_media")])
3192
3193 (define_split
3194   [(set (match_operand:SI 0 "register_operand" "")
3195         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3196   "TARGET_SHMEDIA && reload_completed"
3197   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3198    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3199   "
3200 {
3201   if (GET_CODE (operands[1]) == TRUNCATE)
3202     operands[1] = XEXP (operands[1], 0);
3203 }")
3204
3205 (define_expand "extendqisi2"
3206   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3207         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3208   ""
3209   "")
3210
3211 (define_insn "*extendqisi2_compact"
3212   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3213         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3214   "TARGET_SH1"
3215   "@
3216         exts.b  %1,%0
3217         mov.b   %1,%0"
3218   [(set_attr "type" "arith,load")])
3219
3220 (define_insn "*extendqisi2_media"
3221   [(set (match_operand:SI 0 "register_operand" "=r,r")
3222         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3223   "TARGET_SHMEDIA"
3224   "@
3225         #
3226         ld%M1.b %m1, %0"
3227   [(set_attr "type" "arith_media,load_media")])
3228
3229 (define_split
3230   [(set (match_operand:SI 0 "register_operand" "")
3231         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3232   "TARGET_SHMEDIA && reload_completed"
3233   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3234    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3235    "
3236 {
3237   if (GET_CODE (operands[1]) == TRUNCATE)
3238     operands[1] = XEXP (operands[1], 0);
3239 }")
3240
3241 (define_insn "extendqihi2"
3242   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3243         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3244   "TARGET_SH1"
3245   "@
3246         exts.b  %1,%0
3247         mov.b   %1,%0"
3248   [(set_attr "type" "arith,load")])
3249
3250 /* It would seem useful to combine the truncXi patterns into the movXi
3251    patterns, but unary operators are ignored when matching constraints,
3252    so we need separate patterns.  */
3253 (define_insn "truncdisi2"
3254   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3255         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3256   "TARGET_SHMEDIA"
3257   "@
3258         add.l   %1, r63, %0
3259         st%M0.l %m0, %1
3260         fst%M0.s        %m0, %T1
3261         fmov.ls %1, %0
3262         fmov.sl %T1, %0
3263         fmov.s  %T1, %0"
3264   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3265
3266
3267 (define_insn "truncdihi2"
3268   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3269         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3270   "TARGET_SHMEDIA"
3271   "@
3272         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3273         st%M0.w %m0, %1"
3274   [(set_attr "type"   "arith_media,store_media")
3275    (set_attr "length" "8,4")])
3276
3277 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3278 ; Because we use zero extension, we can't provide signed QImode compares
3279 ; using a simple compare or conditional banch insn.
3280 (define_insn "truncdiqi2"
3281   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3282         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3283   "TARGET_SHMEDIA"
3284   "@
3285         andi    %1, 255, %0
3286         st%M0.b %m0, %1"
3287   [(set_attr "type"   "arith_media,store")])
3288
3289 ;; -------------------------------------------------------------------------
3290 ;; Move instructions
3291 ;; -------------------------------------------------------------------------
3292
3293 ;; define push and pop so it is easy for sh.c
3294 ;; We can't use push and pop on SHcompact because the stack must always
3295 ;; be 8-byte aligned.
3296
3297 (define_expand "push"
3298   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3299         (match_operand:SI 0 "register_operand" "r,l,x"))]
3300   "TARGET_SH1 && ! TARGET_SH5"
3301   "")
3302
3303 (define_expand "pop"
3304   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3305         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3306   "TARGET_SH1 && ! TARGET_SH5"
3307   "")
3308
3309 (define_expand "push_e"
3310   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3311                    (match_operand:SF 0 "" ""))
3312               (use (reg:PSI FPSCR_REG))
3313               (clobber (scratch:SI))])]
3314   "TARGET_SH1 && ! TARGET_SH5"
3315   "")
3316
3317 (define_insn "push_fpul"
3318   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3319   "TARGET_SH2E && ! TARGET_SH5"
3320   "sts.l        fpul,@-r15"
3321   [(set_attr "type" "store")
3322    (set_attr "late_fp_use" "yes")
3323    (set_attr "hit_stack" "yes")])
3324
3325 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3326 ;; so use that.
3327 (define_expand "push_4"
3328   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3329                    (match_operand:DF 0 "" ""))
3330               (use (reg:PSI FPSCR_REG))
3331               (clobber (scratch:SI))])]
3332   "TARGET_SH1 && ! TARGET_SH5"
3333   "")
3334
3335 (define_expand "pop_e"
3336   [(parallel [(set (match_operand:SF 0 "" "")
3337               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3338               (use (reg:PSI FPSCR_REG))
3339               (clobber (scratch:SI))])]
3340   "TARGET_SH1 && ! TARGET_SH5"
3341   "")
3342
3343 (define_insn "pop_fpul"
3344   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3345   "TARGET_SH2E && ! TARGET_SH5"
3346   "lds.l        @r15+,fpul"
3347   [(set_attr "type" "load")
3348    (set_attr "hit_stack" "yes")])
3349
3350 (define_expand "pop_4"
3351   [(parallel [(set (match_operand:DF 0 "" "")
3352                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3353               (use (reg:PSI FPSCR_REG))
3354               (clobber (scratch:SI))])]
3355   "TARGET_SH1 && ! TARGET_SH5"
3356   "")
3357
3358 (define_expand "push_fpscr"
3359   [(const_int 0)]
3360   "TARGET_SH2E"
3361   "
3362 {
3363   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3364                                                  gen_rtx_PRE_DEC (Pmode,
3365                                                           stack_pointer_rtx)),
3366                                         get_fpscr_rtx ()));
3367   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3368   DONE;
3369 }")
3370
3371 (define_expand "pop_fpscr"
3372   [(const_int 0)]
3373   "TARGET_SH2E"
3374   "
3375 {
3376   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3377                                         gen_rtx_MEM (PSImode,
3378                                                  gen_rtx_POST_INC (Pmode,
3379                                                           stack_pointer_rtx))));
3380   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3381   DONE;
3382 }")
3383
3384 ;; These two patterns can happen as the result of optimization, when
3385 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3386 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3387
3388 (define_insn "clrt"
3389   [(set (reg:SI T_REG) (const_int 0))]
3390   "TARGET_SH1"
3391   "clrt")
3392
3393 (define_insn "sett"
3394   [(set (reg:SI T_REG) (const_int 1))]
3395   "TARGET_SH1"
3396   "sett")
3397
3398 ;; t/r must come after r/r, lest reload will try to reload stuff like
3399 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3400 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3401 (define_insn "movsi_i"
3402   [(set (match_operand:SI 0 "general_movdst_operand"
3403             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3404         (match_operand:SI 1 "general_movsrc_operand"
3405          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3406   "TARGET_SH1
3407    && ! TARGET_SH2E
3408    && (register_operand (operands[0], SImode)
3409        || register_operand (operands[1], SImode))"
3410   "@
3411         mov.l   %1,%0
3412         mov     %1,%0
3413         cmp/pl  %1
3414         mov.l   %1,%0
3415         sts     %1,%0
3416         sts     %1,%0
3417         movt    %0
3418         mov.l   %1,%0
3419         sts.l   %1,%0
3420         sts.l   %1,%0
3421         lds     %1,%0
3422         lds     %1,%0
3423         lds.l   %1,%0
3424         lds.l   %1,%0
3425         fake    %1,%0"
3426   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3427    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3428
3429 ;; t/r must come after r/r, lest reload will try to reload stuff like
3430 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3431 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3432 ;; will require a reload.
3433 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3434 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3435 (define_insn "movsi_ie"
3436   [(set (match_operand:SI 0 "general_movdst_operand"
3437             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3438         (match_operand:SI 1 "general_movsrc_operand"
3439          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3440   "TARGET_SH2E
3441    && (register_operand (operands[0], SImode)
3442        || register_operand (operands[1], SImode))"
3443   "@
3444         mov.l   %1,%0
3445         mov     %1,%0
3446         cmp/pl  %1
3447         mov.l   %1,%0
3448         sts     %1,%0
3449         sts     %1,%0
3450         movt    %0
3451         mov.l   %1,%0
3452         sts.l   %1,%0
3453         sts.l   %1,%0
3454         lds     %1,%0
3455         lds     %1,%0
3456         lds.l   %1,%0
3457         lds.l   %1,%0
3458         lds.l   %1,%0
3459         sts.l   %1,%0
3460         fake    %1,%0
3461         lds     %1,%0
3462         sts     %1,%0
3463         fsts    fpul,%0
3464         flds    %1,fpul
3465         fmov    %1,%0
3466         ! move optimized away"
3467   [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3468    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3469    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3470
3471 (define_insn "movsi_i_lowpart"
3472   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3473         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3474    "TARGET_SH1
3475     && (register_operand (operands[0], SImode)
3476         || register_operand (operands[1], SImode))"
3477   "@
3478         mov.l   %1,%0
3479         mov     %1,%0
3480         mov.l   %1,%0
3481         sts     %1,%0
3482         sts     %1,%0
3483         movt    %0
3484         mov.l   %1,%0
3485         fake    %1,%0"
3486   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3487
3488 (define_insn_and_split "load_ra"
3489   [(set (match_operand:SI 0 "general_movdst_operand" "")
3490         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3491   "TARGET_SH1"
3492   "#"
3493   "&& ! rtx_equal_function_value_matters"
3494   [(set (match_dup 0) (match_dup 1))]
3495   "
3496 {
3497   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3498     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3499 }")
3500
3501 (define_insn "*movsi_media"
3502   [(set (match_operand:SI 0 "general_movdst_operand"
3503                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3504         (match_operand:SI 1 "general_movsrc_operand"
3505          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3506   "TARGET_SHMEDIA_FPU
3507    && (register_operand (operands[0], SImode)
3508        || sh_register_operand (operands[1], SImode))"
3509   "@
3510         add.l   %1, r63, %0
3511         movi    %1, %0
3512         #
3513         ld%M1.l %m1, %0
3514         st%M0.l %m0, %N1
3515         fld%M1.s        %m1, %0
3516         fst%M0.s        %m0, %1
3517         fmov.ls %N1, %0
3518         fmov.sl %1, %0
3519         fmov.s  %1, %0
3520         ptabs   %1, %0
3521         gettr   %1, %0
3522         pt      %1, %0"
3523   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3524    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3525
3526 (define_insn "*movsi_media_nofpu"
3527   [(set (match_operand:SI 0 "general_movdst_operand"
3528                 "=r,r,r,r,m,*b,r,b")
3529         (match_operand:SI 1 "general_movsrc_operand"
3530          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3531   "TARGET_SHMEDIA
3532    && (register_operand (operands[0], SImode)
3533        || sh_register_operand (operands[1], SImode))"
3534   "@
3535         add.l   %1, r63, %0
3536         movi    %1, %0
3537         #
3538         ld%M1.l %m1, %0
3539         st%M0.l %m0, %N1
3540         ptabs   %1, %0
3541         gettr   %1, %0
3542         pt      %1, %0"
3543   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3544    (set_attr "length" "4,4,8,4,4,4,4,12")])
3545
3546 (define_split
3547   [(set (match_operand:SI 0 "arith_reg_operand" "")
3548         (match_operand:SI 1 "immediate_operand" ""))]
3549   "TARGET_SHMEDIA && reload_completed
3550    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3551   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3552   "
3553 {
3554   operands[2] = shallow_copy_rtx (operands[1]);
3555   PUT_MODE (operands[2], DImode);
3556 }")
3557
3558 (define_split
3559   [(set (match_operand:SI 0 "register_operand" "")
3560         (match_operand:SI 1 "immediate_operand" ""))]
3561   "TARGET_SHMEDIA && reload_completed
3562    && ((GET_CODE (operands[1]) == CONST_INT
3563         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3564        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3565   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3566
3567 (define_expand "movsi"
3568   [(set (match_operand:SI 0 "general_movdst_operand" "")
3569         (match_operand:SI 1 "general_movsrc_operand" ""))]
3570   ""
3571   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3572
3573 (define_expand "ic_invalidate_line"
3574   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3575                                 (match_dup 1)] UNSPEC_ICACHE)
3576               (clobber (scratch:SI))])]
3577   "TARGET_HARD_SH4 || TARGET_SH5"
3578   "
3579 {
3580   if (TARGET_SHMEDIA)
3581     {
3582       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3583       DONE;
3584     }
3585   else if (TARGET_SHCOMPACT)
3586     {
3587       operands[1] = function_symbol (\"__ic_invalidate\");
3588       operands[1] = force_reg (Pmode, operands[1]);
3589       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3590       DONE;
3591     }
3592   operands[0] = force_reg (Pmode, operands[0]);
3593   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3594                                                                Pmode)));
3595 }")
3596
3597 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3598 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3599 ;; the requirement *1*00 for associative address writes.  The alignment of
3600 ;; %0 implies that its least significant bit is cleared,
3601 ;; thus we clear the V bit of a matching entry if there is one.
3602 (define_insn "ic_invalidate_line_i"
3603   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3604                      (match_operand:SI 1 "register_operand" "r")]
3605                      UNSPEC_ICACHE)
3606    (clobber (match_scratch:SI 2 "=&r"))]
3607   "TARGET_HARD_SH4"
3608   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3609   [(set_attr "length" "8")
3610    (set_attr "type" "cwb")])
3611
3612 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3613 ;; an add in the code that calculates the address.
3614 (define_insn "ic_invalidate_line_media"
3615   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3616                     UNSPEC_ICACHE)]
3617   "TARGET_SHMEDIA"
3618   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3619   [(set_attr "length" "16")
3620    (set_attr "type" "invalidate_line_media")])
3621
3622 (define_insn "ic_invalidate_line_compact"
3623   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3624                      (match_operand:SI 1 "register_operand" "r")]
3625                     UNSPEC_ICACHE)
3626    (clobber (reg:SI PR_REG))]
3627   "TARGET_SHCOMPACT"
3628   "jsr @%1%#"
3629   [(set_attr "type" "sfunc")
3630    (set_attr "needs_delay_slot" "yes")])
3631
3632 (define_expand "initialize_trampoline"
3633   [(match_operand:SI 0 "" "")
3634    (match_operand:SI 1 "" "")
3635    (match_operand:SI 2 "" "")]
3636   "TARGET_SHCOMPACT"
3637   "
3638 {
3639   rtx sfun, tramp;
3640
3641   tramp = force_reg (Pmode, operands[0]);
3642   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3643   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3644   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3645
3646   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3647   DONE;
3648 }")
3649
3650 (define_insn "initialize_trampoline_compact"
3651   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3652                      (match_operand:SI 1 "register_operand" "r")
3653                      (reg:SI R2_REG) (reg:SI R3_REG)]
3654                     UNSPEC_INIT_TRAMP)
3655
3656    (clobber (reg:SI PR_REG))]
3657   "TARGET_SHCOMPACT"
3658   "jsr @%1%#"
3659   [(set_attr "type" "sfunc")
3660    (set_attr "needs_delay_slot" "yes")])
3661
3662 (define_insn "movqi_i"
3663   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3664         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3665   "TARGET_SH1
3666    && (arith_reg_operand (operands[0], QImode)
3667        || arith_reg_operand (operands[1], QImode))"
3668   "@
3669         mov     %1,%0
3670         mov.b   %1,%0
3671         mov.b   %1,%0
3672         movt    %0
3673         sts     %1,%0
3674         lds     %1,%0"
3675  [(set_attr "type" "move,load,store,move,move,move")])
3676
3677 (define_insn "*movqi_media"
3678   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3679         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3680   "TARGET_SHMEDIA
3681    && (arith_reg_operand (operands[0], QImode)
3682        || arith_reg_or_0_operand (operands[1], QImode))"
3683   "@
3684         add.l   %1, r63, %0
3685         movi    %1, %0
3686         ld%M1.ub        %m1, %0
3687         st%M0.b %m0, %N1"
3688   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3689
3690 (define_expand "movqi"
3691   [(set (match_operand:QI 0 "general_operand" "")
3692         (match_operand:QI 1 "general_operand"  ""))]
3693   ""
3694   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3695
3696 (define_expand "reload_inqi"
3697   [(set (match_operand:SI 2 "" "=&r")
3698         (match_operand:QI 1 "inqhi_operand" ""))
3699    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3700         (truncate:QI (match_dup 3)))]
3701   "TARGET_SHMEDIA"
3702   "
3703 {
3704   rtx inner = XEXP (operands[1], 0);
3705   int regno = REGNO (inner);
3706
3707   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3708   operands[1] = gen_rtx_REG (SImode, regno);
3709   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3710 }")
3711
3712 /* When storing r0, we have to avoid reg+reg addressing.  */
3713 (define_insn "movhi_i"
3714   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3715         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3716   "TARGET_SH1
3717    && (arith_reg_operand (operands[0], HImode)
3718        || arith_reg_operand (operands[1], HImode))
3719    && (GET_CODE (operands[0]) != MEM
3720        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3721        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3722        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3723   "@
3724         mov.w   %1,%0
3725         mov     %1,%0
3726         mov.w   %1,%0
3727         movt    %0
3728         mov.w   %1,%0
3729         sts     %1,%0
3730         lds     %1,%0
3731         fake    %1,%0"
3732   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3733
3734 (define_insn "*movhi_media"
3735   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3736         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3737   "TARGET_SHMEDIA
3738    && (arith_reg_operand (operands[0], HImode)
3739        || arith_reg_or_0_operand (operands[1], HImode))"
3740   "@
3741         add.l   %1, r63, %0
3742         movi    %1, %0
3743         #
3744         ld%M1.w %m1, %0
3745         st%M0.w %m0, %N1"
3746   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3747
3748 (define_split
3749   [(set (match_operand:HI 0 "register_operand" "")
3750         (match_operand:HI 1 "immediate_operand" ""))]
3751   "TARGET_SHMEDIA && reload_completed
3752    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3753   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3754
3755 (define_expand "movhi"
3756   [(set (match_operand:HI 0 "general_movdst_operand" "")
3757         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3758   ""
3759   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3760
3761 (define_expand "reload_inhi"
3762   [(set (match_operand:SI 2 "" "=&r")
3763         (match_operand:HI 1 "inqhi_operand" ""))
3764    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3765         (truncate:HI (match_dup 3)))]
3766   "TARGET_SHMEDIA"
3767   "
3768 {
3769   rtx inner = XEXP (operands[1], 0);
3770   int regno = REGNO (inner);
3771
3772   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3773   operands[1] = gen_rtx_REG (SImode, regno);
3774   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3775 }")
3776
3777 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3778 ;; compiled with -m2 -ml -O3 -funroll-loops
3779 (define_insn "*movdi_i"
3780   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3781         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3782   "TARGET_SH1
3783    && (arith_reg_operand (operands[0], DImode)
3784        || arith_reg_operand (operands[1], DImode))"
3785   "* return output_movedouble (insn, operands, DImode);"
3786   [(set_attr "length" "4")
3787    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3788
3789 ;; If the output is a register and the input is memory or a register, we have
3790 ;; to be careful and see which word needs to be loaded first.
3791
3792 (define_split
3793   [(set (match_operand:DI 0 "general_movdst_operand" "")
3794         (match_operand:DI 1 "general_movsrc_operand" ""))]
3795   "TARGET_SH1 && reload_completed"
3796   [(set (match_dup 2) (match_dup 3))
3797    (set (match_dup 4) (match_dup 5))]
3798   "
3799 {
3800   int regno;
3801
3802   if ((GET_CODE (operands[0]) == MEM
3803        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3804       || (GET_CODE (operands[1]) == MEM
3805           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3806     FAIL;
3807
3808   if (GET_CODE (operands[0]) == REG)
3809     regno = REGNO (operands[0]);
3810   else if (GET_CODE (operands[0]) == SUBREG)
3811     regno = subreg_regno (operands[0]);
3812   else if (GET_CODE (operands[0]) == MEM)
3813     regno = -1;
3814   else
3815     abort ();
3816
3817   if (regno == -1
3818       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3819     {
3820       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3821       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3822       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3823       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3824     }
3825   else
3826     {
3827       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3828       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3829       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3830       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3831     }
3832
3833   if (operands[2] == 0 || operands[3] == 0
3834       || operands[4] == 0 || operands[5] == 0)
3835     FAIL;
3836 }")
3837
3838 (define_insn "*movdi_media"
3839   [(set (match_operand:DI 0 "general_movdst_operand"
3840                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3841         (match_operand:DI 1 "general_movsrc_operand"
3842          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3843   "TARGET_SHMEDIA_FPU
3844    && (register_operand (operands[0], DImode)
3845        || sh_register_operand (operands[1], DImode))"
3846   "@
3847         add     %1, r63, %0
3848         movi    %1, %0
3849         #
3850         ld%M1.q %m1, %0
3851         st%M0.q %m0, %N1
3852         fld%M1.d        %m1, %0
3853         fst%M0.d        %m0, %1
3854         fmov.qd %N1, %0
3855         fmov.dq %1, %0
3856         fmov.d  %1, %0
3857         ptabs   %1, %0
3858         gettr   %1, %0
3859         pt      %1, %0"
3860   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3861    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3862
3863 (define_insn "*movdi_media_nofpu"
3864   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3865         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3866   "TARGET_SHMEDIA
3867    && (register_operand (operands[0], DImode)
3868        || sh_register_operand (operands[1], DImode))"
3869   "@
3870         add     %1, r63, %0
3871         movi    %1, %0
3872         #
3873         ld%M1.q %m1, %0
3874         st%M0.q %m0, %N1
3875         ptabs   %1, %0
3876         gettr   %1, %0
3877         pt      %1, %0"
3878   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3879    (set_attr "length" "4,4,16,4,4,4,4,*")])
3880
3881 (define_split
3882   [(set (match_operand:DI 0 "arith_reg_operand" "")
3883         (match_operand:DI 1 "immediate_operand" ""))]
3884   "TARGET_SHMEDIA && reload_completed
3885    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3886   [(set (match_dup 0) (match_dup 1))]
3887   "
3888 {
3889   rtx insn;
3890
3891   if (TARGET_SHMEDIA64)
3892     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3893   else
3894     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3895
3896   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3897                                         REG_NOTES (insn));
3898
3899   DONE;
3900 }")
3901
3902 (define_expand "movdi_const"
3903   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3904         (const:DI (sign_extend:DI
3905                    (truncate:HI
3906                     (ashiftrt:DI
3907                      (match_operand:DI 1 "immediate_operand" "s")
3908                      (const_int 48))))))
3909    (set (match_dup 0)
3910         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3911                 (zero_extend:DI
3912                  (truncate:HI
3913                   (const:DI
3914                    (sign_extend:DI
3915                     (truncate:HI
3916                      (ashiftrt:SI
3917                       (match_dup 1)
3918                       (const_int 32)))))))))
3919    (set (match_dup 0)
3920         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3921                 (zero_extend:DI
3922                  (truncate:HI
3923                   (const:DI
3924                    (sign_extend:DI
3925                     (truncate:HI
3926                      (ashiftrt:SI
3927                       (match_dup 1)
3928                       (const_int 16)))))))))
3929    (set (match_dup 0)
3930         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3931                 (zero_extend:DI
3932                  (truncate:HI
3933                   (const:DI
3934                    (sign_extend:DI
3935                     (truncate:HI
3936                      (match_dup 1))))))))]
3937   "TARGET_SHMEDIA64 && reload_completed
3938    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3939   "
3940 {
3941   sh_mark_label (operands[1], 4);
3942 }")
3943
3944 (define_expand "movdi_const_32bit"
3945   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3946         (const:DI (sign_extend:DI
3947                    (truncate:HI
3948                     (ashiftrt:DI
3949                      (match_operand:DI 1 "immediate_operand" "s")
3950                      (const_int 16))))))
3951    (set (match_dup 0)
3952         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3953                 (zero_extend:DI
3954                  (truncate:HI
3955                   (const:DI
3956                    (sign_extend:DI
3957                     (truncate:HI
3958                      (match_dup 1))))))))]
3959   "TARGET_SHMEDIA32 && reload_completed
3960    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3961   "
3962 {
3963   sh_mark_label (operands[1], 2);
3964 }")
3965
3966 (define_expand "movdi_const_16bit"
3967   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3968         (const:DI (sign_extend:DI
3969                    (truncate:HI
3970                     (match_operand:DI 1 "immediate_operand" "s")))))]
3971   "TARGET_SHMEDIA && flag_pic && reload_completed
3972    && GET_CODE (operands[1]) == SYMBOL_REF"
3973   "")
3974
3975 (define_split
3976   [(set (match_operand:DI 0 "arith_reg_operand" "")
3977         (match_operand:DI 1 "immediate_operand" ""))]
3978   "TARGET_SHMEDIA && reload_completed
3979    && GET_CODE (operands[1]) == CONST_INT
3980    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3981   [(set (match_dup 0) (match_dup 2))
3982    (match_dup 1)]
3983   "
3984 {
3985   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3986   unsigned HOST_WIDE_INT low = val;
3987   unsigned HOST_WIDE_INT high = val;
3988   unsigned HOST_WIDE_INT sign;
3989   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3990
3991   /* Sign-extend the 16 least-significant bits.  */
3992   low &= 0xffff;
3993   low ^= 0x8000;
3994   low -= 0x8000;
3995
3996   /* Arithmetic shift right the word by 16 bits.  */
3997   high >>= 16;
3998   sign = 1;
3999   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4000   high ^= sign;
4001   high -= sign;
4002   do
4003     {
4004       /* If we can't generate the constant with a two-insn movi / shori
4005          sequence, try some other strategies.  */
4006       if (! CONST_OK_FOR_I16 (high))
4007         {
4008           /* Try constant load / left shift.  We know VAL != 0.  */
4009           val2 = val ^ (val-1);
4010           if (val2 > 0x1ffff)
4011             {
4012               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4013
4014               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4015                   || (! CONST_OK_FOR_I16 (high >> 16)
4016                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4017                 {
4018                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4019                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4020                                                    GEN_INT (trailing_zeroes));
4021                   break;
4022                 }
4023             }
4024           /* Try constant load / right shift.  */
4025           val2 = (val >> 15) + 1;
4026           if (val2 == (val2 & -val2))
4027             {
4028               int shift = 49 - exact_log2 (val2);
4029
4030               val2 = trunc_int_for_mode (val << shift, DImode);
4031               if (CONST_OK_FOR_I16 (val2))
4032                 {
4033                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4034                                                    GEN_INT (shift));