OSDN Git Service

8b295bc85d813c6eab00c6278b355e968d72e47f
[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, 2005, 2006, 2007 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, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, 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_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_SP_SET        40)
154   (UNSPEC_SP_TEST       41)
155   (UNSPEC_MOVUA         42)
156
157   ;; These are used with unspec_volatile.
158   (UNSPECV_BLOCKAGE     0)
159   (UNSPECV_ALIGN        1)
160   (UNSPECV_CONST2       2)
161   (UNSPECV_CONST4       4)
162   (UNSPECV_CONST8       6)
163   (UNSPECV_WINDOW_END   10)
164   (UNSPECV_CONST_END    11)
165   (UNSPECV_EH_RETURN    12)
166 ])
167
168 ;; -------------------------------------------------------------------------
169 ;; Attributes
170 ;; -------------------------------------------------------------------------
171
172 ;; Target CPU.
173
174 (define_attr "cpu"
175  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
176   (const (symbol_ref "sh_cpu_attr")))
177
178 (define_attr "endian" "big,little"
179  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
180                       (const_string "little") (const_string "big"))))
181
182 ;; Indicate if the default fpu mode is single precision.
183 (define_attr "fpu_single" "yes,no"
184   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
185                          (const_string "yes") (const_string "no"))))
186
187 (define_attr "fmovd" "yes,no"
188   (const (if_then_else (symbol_ref "TARGET_FMOVD")
189                        (const_string "yes") (const_string "no"))))
190 ;; pipeline model
191 (define_attr "pipe_model" "sh1,sh4,sh5media"
192   (const
193    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
194           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
195          (const_string "sh1"))))
196
197 ;; cbranch      conditional branch instructions
198 ;; jump         unconditional jumps
199 ;; arith        ordinary arithmetic
200 ;; arith3       a compound insn that behaves similarly to a sequence of
201 ;;              three insns of type arith
202 ;; arith3b      like above, but might end with a redirected branch
203 ;; load         from memory
204 ;; load_si      Likewise, SImode variant for general register.
205 ;; fload        Likewise, but load to fp register.
206 ;; store        to memory
207 ;; fstore       floating point register to memory
208 ;; move         general purpose register to register
209 ;; movi8        8-bit immediate to general purpose register
210 ;; mt_group     other sh4 mt instructions
211 ;; fmove        register to register, floating point
212 ;; smpy         word precision integer multiply
213 ;; dmpy         longword or doublelongword precision integer multiply
214 ;; return       rts
215 ;; pload        load of pr reg, which can't be put into delay slot of rts
216 ;; prset        copy register to pr reg, ditto
217 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
218 ;; prget        copy pr to register, ditto
219 ;; pcload       pc relative load of constant value
220 ;; pcfload      Likewise, but load to fp register.
221 ;; pcload_si    Likewise, SImode variant for general register.
222 ;; rte          return from exception
223 ;; sfunc        special function call with known used registers
224 ;; call         function call
225 ;; fp           floating point
226 ;; fpscr_toggle toggle a bit in the fpscr
227 ;; fdiv         floating point divide (or square root)
228 ;; gp_fpul      move from general purpose register to fpul
229 ;; fpul_gp      move from fpul to general purpose register
230 ;; mac_gp       move from mac[lh] to general purpose register
231 ;; gp_mac       move from general purpose register to mac[lh]
232 ;; mac_mem      move from mac[lh] to memory
233 ;; mem_mac      move from memory to mac[lh]
234 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
235 ;; ftrc_s       fix_truncsfsi2_i4
236 ;; dfdiv        double precision floating point divide (or square root)
237 ;; cwb          ic_invalidate_line_i
238 ;; movua        SH4a unaligned load
239 ;; fsrra        square root reciprocal approximate
240 ;; fsca         sine and cosine approximate
241 ;; tls_load     load TLS related address
242 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
243 ;; cbranch_media SHmedia conditional branch instructions
244 ;; cmp_media    SHmedia compare instructions
245 ;; dfdiv_media  SHmedia double precision divide and square root
246 ;; dfmul_media  SHmedia double precision multiply instruction
247 ;; dfparith_media SHmedia double precision floating point arithmetic
248 ;; dfpconv_media SHmedia double precision floating point conversions
249 ;; dmpy_media   SHmedia longword multiply
250 ;; fcmp_media   SHmedia floating point compare instructions
251 ;; fdiv_media   SHmedia single precision divide and square root
252 ;; fload_media  SHmedia floating point register load instructions
253 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
254 ;; fparith_media SHmedia single precision floating point arithmetic
255 ;; fpconv_media SHmedia single precision floating point conversions
256 ;; fstore_media SHmedia floating point register store instructions
257 ;; gettr_media  SHmedia gettr instruction
258 ;; invalidate_line_media SHmedia invalidate_line sequence
259 ;; jump_media   SHmedia unconditional branch instructions
260 ;; load_media   SHmedia general register load instructions
261 ;; pt_media     SHmedia pt instruction (expanded by assembler)
262 ;; ptabs_media  SHmedia ptabs instruction
263 ;; store_media  SHmedia general register store instructions
264 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
265 ;; mac_media    SHmedia mac-style fixed point operations
266 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
267 ;; atrans_media SHmedia approximate transcendental functions
268 ;; ustore_media SHmedia unaligned stores
269 ;; nil          no-op move, will be deleted.
270
271 (define_attr "type"
272  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
273   (const_string "other"))
274
275 ;; We define a new attribute namely "insn_class".We use
276 ;; this for the DFA based pipeline description.
277 ;;
278 ;; mt_group      SH4 "mt" group instructions.
279 ;;
280 ;; ex_group      SH4 "ex" group instructions.
281 ;;
282 ;; ls_group      SH4 "ls" group instructions.
283 ;;
284
285 (define_attr "insn_class"
286   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
287   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
288          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
289          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
290          (eq_attr "type" "cbranch,jump") (const_string "br_group")
291          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
292            (const_string "fe_group")
293          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
294         (const_string "none")))
295 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
296 ;; so these do not belong in an insn group, although they are modeled
297 ;; with their own define_insn_reservations.
298
299 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300
301 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302
303 ;; Indicate if the fpu mode is set by this instruction
304 ;; "unknown" must have the value as "none" in fp_mode, and means
305 ;; that the instruction/abi has left the processor in an unknown
306 ;; state.
307 ;; "none" means that nothing has changed and no mode is set.
308 ;; This attribute is only used for the Renesas ABI.
309 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310
311 ; If a conditional branch destination is within -252..258 bytes away
312 ; from the instruction it can be 2 bytes long.  Something in the
313 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
314 ; branches are initially assumed to be 16 bytes long.
315 ; In machine_dependent_reorg, we split all branches that are longer than
316 ; 2 bytes.
317
318 ;; The maximum range used for SImode constant pool entries is 1018.  A final
319 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
320 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
321 ;; instruction around the pool table, 2 bytes of alignment before the table,
322 ;; and 30 bytes of alignment after the table.  That gives a maximum total
323 ;; pool size of 1058 bytes.
324 ;; Worst case code/pool content size ratio is 1:2 (using asms).
325 ;; Thus, in the worst case, there is one instruction in front of a maximum
326 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
327 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
328 ;; If we have a forward branch, the initial table will be put after the
329 ;; unconditional branch.
330 ;;
331 ;; ??? We could do much better by keeping track of the actual pcloads within
332 ;; the branch range and in the pcload range in front of the branch range.
333
334 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
335 ;; inside an le.
336 (define_attr "short_cbranch_p" "no,yes"
337   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
338          (const_string "no")
339          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
340          (const_string "yes")
341          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
342          (const_string "no")
343          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
344          (const_string "yes")
345          ] (const_string "no")))
346
347 (define_attr "med_branch_p" "no,yes"
348   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
349               (const_int 1988))
350          (const_string "yes")
351          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
354               (const_int 8186))
355          (const_string "yes")
356          ] (const_string "no")))
357
358 (define_attr "med_cbranch_p" "no,yes"
359   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
360               (const_int 1986))
361          (const_string "yes")
362          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
365                (const_int 8184))
366          (const_string "yes")
367          ] (const_string "no")))
368
369 (define_attr "braf_branch_p" "no,yes"
370   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
371          (const_string "no")
372          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
373               (const_int 20660))
374          (const_string "yes")
375          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
378               (const_int 65530))
379          (const_string "yes")
380          ] (const_string "no")))
381
382 (define_attr "braf_cbranch_p" "no,yes"
383   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384          (const_string "no")
385          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
386               (const_int 20658))
387          (const_string "yes")
388          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389          (const_string "no")
390          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
391               (const_int 65528))
392          (const_string "yes")
393          ] (const_string "no")))
394
395 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
396 ; For wider ranges, we need a combination of a code and a data part.
397 ; If we can get a scratch register for a long range jump, the code
398 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
399 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
400 ; long; otherwise, it must be 6 bytes long.
401
402 ; All other instructions are two bytes long by default.
403
404 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
405 ;; but getattrtab doesn't understand this.
406 (define_attr "length" ""
407   (cond [(eq_attr "type" "cbranch")
408          (cond [(eq_attr "short_cbranch_p" "yes")
409                 (const_int 2)
410                 (eq_attr "med_cbranch_p" "yes")
411                 (const_int 6)
412                 (eq_attr "braf_cbranch_p" "yes")
413                 (const_int 12)
414 ;; ??? using pc is not computed transitively.
415                 (ne (match_dup 0) (match_dup 0))
416                 (const_int 14)
417                 (ne (symbol_ref ("flag_pic")) (const_int 0))
418                 (const_int 24)
419                 ] (const_int 16))
420          (eq_attr "type" "jump")
421          (cond [(eq_attr "med_branch_p" "yes")
422                 (const_int 2)
423                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
424                          (const_int 0))
425                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
426                               (symbol_ref "INSN"))
427                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
428                               (symbol_ref "code_for_indirect_jump_scratch"))))
429                 (cond [(eq_attr "braf_branch_p" "yes")
430                        (const_int 6)
431                        (eq (symbol_ref "flag_pic") (const_int 0))
432                        (const_int 10)
433                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
434                        (const_int 10)] (const_int 18))
435                 (eq_attr "braf_branch_p" "yes")
436                 (const_int 10)
437 ;; ??? using pc is not computed transitively.
438                 (ne (match_dup 0) (match_dup 0))
439                 (const_int 12)
440                 (ne (symbol_ref ("flag_pic")) (const_int 0))
441                 (const_int 22)
442                 ] (const_int 14))
443          (eq_attr "type" "pt_media")
444          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
445                        (const_int 20) (const_int 12))
446          (and (eq_attr "type" "jump_media")
447               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
448          (const_int 8)
449          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
450                          (const_int 4)
451                          (const_int 2))))
452
453 ;; DFA descriptions for the pipelines
454
455 (include "sh1.md")
456 (include "shmedia.md")
457 (include "sh4.md")
458
459 (include "predicates.md")
460 (include "constraints.md")
461
462 ;; Definitions for filling delay slots
463
464 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465
466 (define_attr "banked" "yes,no" 
467         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
468                    (const_int 1))
469                (const_string "yes")]
470               (const_string "no")))
471
472 ;; ??? This should be (nil) instead of (const_int 0)
473 (define_attr "hit_stack" "yes,no"
474         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
475                    (const_int 0))
476                (const_string "no")]
477               (const_string "yes")))
478
479 (define_attr "interrupt_function" "no,yes"
480   (const (symbol_ref "current_function_interrupt")))
481
482 (define_attr "in_delay_slot" "yes,no"
483   (cond [(eq_attr "type" "cbranch") (const_string "no")
484          (eq_attr "type" "pcload,pcload_si") (const_string "no")
485          (eq_attr "needs_delay_slot" "yes") (const_string "no")
486          (eq_attr "length" "2") (const_string "yes")
487          ] (const_string "no")))
488
489 (define_attr "cond_delay_slot" "yes,no"
490   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
491          ] (const_string "no")))
492
493 (define_attr "is_sfunc" ""
494   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
495
496 (define_attr "is_mac_media" ""
497   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
498
499 (define_attr "branch_zero" "yes,no"
500   (cond [(eq_attr "type" "!cbranch") (const_string "no")
501          (ne (symbol_ref "(next_active_insn (insn)\
502                            == (prev_active_insn\
503                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
504                           && get_attr_length (next_active_insn (insn)) == 2")
505              (const_int 0))
506          (const_string "yes")]
507         (const_string "no")))
508
509 ;; SH4 Double-precision computation with double-precision result -
510 ;; the two halves are ready at different times.
511 (define_attr "dfp_comp" "yes,no"
512   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
513         (const_string "no")))
514
515 ;; Insns for which the latency of a preceding fp insn is decreased by one.
516 (define_attr "late_fp_use" "yes,no" (const_string "no"))
517 ;; And feeding insns for which this relevant.
518 (define_attr "any_fp_comp" "yes,no"
519   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
520          (const_string "yes")]
521         (const_string "no")))
522
523 (define_attr "any_int_load" "yes,no"
524   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
525          (const_string "yes")]
526         (const_string "no")))
527
528 (define_attr "highpart" "user, ignore, extend, depend, must_split"
529   (const_string "user"))
530
531 (define_delay
532   (eq_attr "needs_delay_slot" "yes")
533   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
534
535 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
536 ;; and thus we can't put a pop instruction in its delay slot.
537 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
538 ;; instruction can go in the delay slot.
539
540 ;; Since a normal return (rts) implicitly uses the PR register,
541 ;; we can't allow PR register loads in an rts delay slot.
542
543 (define_delay
544   (eq_attr "type" "return")
545   [(and (eq_attr "in_delay_slot" "yes")
546         (ior (and (eq_attr "interrupt_function" "no")
547                   (eq_attr "type" "!pload,prset"))
548              (and (eq_attr "interrupt_function" "yes")
549                   (ior
550                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
551                    (eq_attr "hit_stack" "no")
552                    (eq_attr "banked" "no"))))) (nil) (nil)])
553
554 ;; Since a call implicitly uses the PR register, we can't allow
555 ;; a PR register store in a jsr delay slot.
556
557 (define_delay
558   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
559   [(and (eq_attr "in_delay_slot" "yes")
560         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
561
562 ;; Say that we have annulled true branches, since this gives smaller and
563 ;; faster code when branches are predicted as not taken.
564
565 ;; ??? The non-annulled condition should really be "in_delay_slot",
566 ;; but insns that can be filled in non-annulled get priority over insns
567 ;; that can only be filled in anulled.
568
569 (define_delay
570   (and (eq_attr "type" "cbranch")
571        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
572   ;; SH2e has a hardware bug that pretty much prohibits the use of
573   ;; annuled delay slots.
574   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
575                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
576 \f
577 ;; -------------------------------------------------------------------------
578 ;; SImode signed integer comparisons
579 ;; -------------------------------------------------------------------------
580
581 (define_insn ""
582   [(set (reg:SI T_REG)
583         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
584                        (match_operand:SI 1 "arith_operand" "K08,r"))
585                (const_int 0)))]
586   "TARGET_SH1"
587   "tst  %1,%0"
588   [(set_attr "type" "mt_group")])
589
590 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
591 ;; That would still allow reload to create cmpi instructions, but would
592 ;; perhaps allow forcing the constant into a register when that is better.
593 ;; Probably should use r0 for mem/imm compares, but force constant into a
594 ;; register for pseudo/imm compares.
595
596 (define_insn "cmpeqsi_t"
597   [(set (reg:SI T_REG)
598         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
599                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
600   "TARGET_SH1"
601   "@
602         tst     %0,%0
603         cmp/eq  %1,%0
604         cmp/eq  %1,%0"
605    [(set_attr "type" "mt_group")])
606
607 (define_insn "cmpgtsi_t"
608   [(set (reg:SI T_REG)
609         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
610                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
611   "TARGET_SH1"
612   "@
613         cmp/gt  %1,%0
614         cmp/pl  %0"
615    [(set_attr "type" "mt_group")])
616
617 (define_insn "cmpgesi_t"
618   [(set (reg:SI T_REG)
619         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
621   "TARGET_SH1"
622   "@
623         cmp/ge  %1,%0
624         cmp/pz  %0"
625    [(set_attr "type" "mt_group")])
626
627 ;; -------------------------------------------------------------------------
628 ;; SImode compare and branch
629 ;; -------------------------------------------------------------------------
630
631 (define_expand "cbranchsi4"
632   [(set (pc)
633         (if_then_else (match_operator 0 "comparison_operator"
634                         [(match_operand:SI 1 "arith_operand" "")
635                          (match_operand:SI 2 "arith_operand" "")])
636                       (label_ref (match_operand 3 "" ""))
637                       (pc)))
638    (clobber (reg:SI T_REG))]
639   "TARGET_CBRANCHDI4"
640   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
641
642 ;; -------------------------------------------------------------------------
643 ;; SImode unsigned integer comparisons
644 ;; -------------------------------------------------------------------------
645
646 (define_insn_and_split "cmpgeusi_t"
647   [(set (reg:SI T_REG)
648         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
649                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
650   "TARGET_SH1"
651   "cmp/hs       %1,%0"
652   "&& operands[0] == CONST0_RTX (SImode)"
653   [(pc)]
654   "
655 {
656   emit_insn (gen_sett ());
657   DONE;
658 }"
659    [(set_attr "type" "mt_group")])
660
661 (define_insn "cmpgtusi_t"
662   [(set (reg:SI T_REG)
663         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
664                 (match_operand:SI 1 "arith_reg_operand" "r")))]
665   "TARGET_SH1"
666   "cmp/hi       %1,%0"
667    [(set_attr "type" "mt_group")])
668
669 ;; We save the compare operands in the cmpxx patterns and use them when
670 ;; we generate the branch.
671
672 (define_expand "cmpsi"
673   [(set (reg:SI T_REG)
674         (compare (match_operand:SI 0 "cmpsi_operand" "")
675                  (match_operand:SI 1 "arith_operand" "")))]
676   "TARGET_SH1 || TARGET_SHMEDIA"
677   "
678 {
679   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
680       && GET_CODE (operands[1]) != CONST_INT)
681     operands[0] = copy_to_mode_reg (SImode, operands[0]);
682   sh_compare_op0 = operands[0];
683   sh_compare_op1 = operands[1];
684   DONE;
685 }")
686 \f
687 ;; -------------------------------------------------------------------------
688 ;; DImode compare and branch
689 ;; -------------------------------------------------------------------------
690
691
692 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693 ;; Therefore, we aim to have a set of three branches that go straight to the
694 ;; destination, i.e. only one of them is taken at any one time.
695 ;; This mechanism should also be slightly better for the sh4-200.
696
697 (define_expand "cbranchdi4"
698   [(set (pc)
699         (if_then_else (match_operator 0 "comparison_operator"
700                         [(match_operand:DI 1 "arith_operand" "")
701                          (match_operand:DI 2 "arith_operand" "")])
702                       (label_ref (match_operand 3 "" ""))
703                       (pc)))
704    (clobber (match_dup 4))
705    (clobber (reg:SI T_REG))]
706   "TARGET_CBRANCHDI4"
707   "
708 {
709   enum rtx_code comparison;
710
711   if (TARGET_EXPAND_CBRANCHDI4)
712     {
713       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
714         DONE;
715     }
716   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
717   if (comparison != GET_CODE (operands[0]))
718     operands[0]
719       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
720    operands[4] = gen_rtx_SCRATCH (SImode);
721 }")
722
723 (define_insn_and_split "cbranchdi4_i"
724   [(set (pc)
725         (if_then_else (match_operator 0 "comparison_operator"
726                         [(match_operand:DI 1 "arith_operand" "r,r")
727                          (match_operand:DI 2 "arith_operand" "rN,i")])
728                       (label_ref (match_operand 3 "" ""))
729                       (pc)))
730    (clobber (match_scratch:SI 4 "=X,&r"))
731    (clobber (reg:SI T_REG))]
732   "TARGET_CBRANCHDI4"
733   "#"
734   "&& reload_completed"
735   [(pc)]
736   "
737 {
738   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
739     FAIL;
740   DONE;
741 }")
742
743 ;; -------------------------------------------------------------------------
744 ;; DImode signed integer comparisons
745 ;; -------------------------------------------------------------------------
746
747 (define_insn ""
748   [(set (reg:SI T_REG)
749         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
750                        (match_operand:DI 1 "arith_operand" "r"))
751                (const_int 0)))]
752   "TARGET_SH1"
753   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
754                                  insn, operands);"
755   [(set_attr "length" "6")
756    (set_attr "type" "arith3b")])
757
758 (define_insn "cmpeqdi_t"
759   [(set (reg:SI T_REG)
760         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
761                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
762   "TARGET_SH1"
763   "@
764         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
765         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
766   [(set_attr "length" "6")
767    (set_attr "type" "arith3b")])
768
769 (define_split
770   [(set (reg:SI T_REG)
771         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
772                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
773 ;; If we applied this split when not optimizing, it would only be
774 ;; applied during the machine-dependent reorg, when no new basic blocks
775 ;; may be created.
776   "TARGET_SH1 && reload_completed && optimize"
777   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
778    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
779                            (label_ref (match_dup 6))
780                            (pc)))
781    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
782    (match_dup 6)]
783   "
784 {
785   operands[2]
786     = gen_rtx_REG (SImode,
787                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
788   operands[3]
789     = (operands[1] == const0_rtx
790        ? const0_rtx
791        : gen_rtx_REG (SImode,
792                       true_regnum (operands[1])
793                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
794   operands[4] = gen_lowpart (SImode, operands[0]);
795   operands[5] = gen_lowpart (SImode, operands[1]);
796   operands[6] = gen_label_rtx ();
797 }")
798
799 (define_insn "cmpgtdi_t"
800   [(set (reg:SI T_REG)
801         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
802                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
803   "TARGET_SH2"
804   "@
805         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
806         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
807   [(set_attr "length" "8")
808    (set_attr "type" "arith3")])
809
810 (define_insn "cmpgedi_t"
811   [(set (reg:SI T_REG)
812         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
813                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
814   "TARGET_SH2"
815   "@
816         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
817         cmp/pz\\t%S0"
818   [(set_attr "length" "8,2")
819    (set_attr "type" "arith3,mt_group")])
820 \f
821 ;; -------------------------------------------------------------------------
822 ;; DImode unsigned integer comparisons
823 ;; -------------------------------------------------------------------------
824
825 (define_insn "cmpgeudi_t"
826   [(set (reg:SI T_REG)
827         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
828                 (match_operand:DI 1 "arith_reg_operand" "r")))]
829   "TARGET_SH2"
830   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
831   [(set_attr "length" "8")
832    (set_attr "type" "arith3")])
833
834 (define_insn "cmpgtudi_t"
835   [(set (reg:SI T_REG)
836         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
837                 (match_operand:DI 1 "arith_reg_operand" "r")))]
838   "TARGET_SH2"
839   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
840   [(set_attr "length" "8")
841    (set_attr "type" "arith3")])
842
843 (define_insn "cmpeqsi_media"
844   [(set (match_operand:SI 0 "register_operand" "=r")
845         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
846                (match_operand:SI 2 "cmp_operand" "Nr")))]
847   "TARGET_SHMEDIA"
848   "cmpeq        %1, %N2, %0"
849   [(set_attr "type" "cmp_media")])
850
851 (define_insn "cmpeqdi_media"
852   [(set (match_operand:SI 0 "register_operand" "=r")
853         (eq:SI (match_operand:DI 1 "register_operand" "%r")
854                (match_operand:DI 2 "cmp_operand" "Nr")))]
855   "TARGET_SHMEDIA"
856   "cmpeq        %1, %N2, %0"
857   [(set_attr "type" "cmp_media")])
858
859 (define_insn "cmpgtsi_media"
860   [(set (match_operand:SI 0 "register_operand" "=r")
861         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
862                (match_operand:SI 2 "cmp_operand" "rN")))]
863   "TARGET_SHMEDIA"
864   "cmpgt        %N1, %N2, %0"
865   [(set_attr "type" "cmp_media")])
866
867 (define_insn "cmpgtdi_media"
868   [(set (match_operand:SI 0 "register_operand" "=r")
869         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
870                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
871   "TARGET_SHMEDIA"
872   "cmpgt        %N1, %N2, %0"
873   [(set_attr "type" "cmp_media")])
874
875 (define_insn "cmpgtusi_media"
876   [(set (match_operand:SI 0 "register_operand" "=r")
877         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
878                 (match_operand:SI 2 "cmp_operand" "rN")))]
879   "TARGET_SHMEDIA"
880   "cmpgtu       %N1, %N2, %0"
881   [(set_attr "type" "cmp_media")])
882
883 (define_insn "cmpgtudi_media"
884   [(set (match_operand:SI 0 "register_operand" "=r")
885         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
886                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
887   "TARGET_SHMEDIA"
888   "cmpgtu       %N1, %N2, %0"
889   [(set_attr "type" "cmp_media")])
890
891 ; These two patterns are for combine.
892 (define_insn "*cmpne0sisi_media"
893   [(set (match_operand:SI 0 "register_operand" "=r")
894         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
895   "TARGET_SHMEDIA"
896   "cmpgtu       %1,r63,%0"
897   [(set_attr "type" "cmp_media")])
898
899 ;; We save the compare operands in the cmpxx patterns and use them when
900 ;; we generate the branch.
901
902 (define_expand "cmpdi"
903   [(set (reg:SI T_REG)
904         (compare (match_operand:DI 0 "arith_operand" "")
905                  (match_operand:DI 1 "arith_operand" "")))]
906   "TARGET_SH2 || TARGET_SHMEDIA"
907   "
908 {
909   sh_compare_op0 = operands[0];
910   sh_compare_op1 = operands[1];
911   DONE;
912 }")
913 ;; -------------------------------------------------------------------------
914 ;; Conditional move instructions
915 ;; -------------------------------------------------------------------------
916
917 ;; The insn names may seem reversed, but note that cmveq performs the move
918 ;; if op1 == 0, and cmvne does it if op1 != 0.
919
920 (define_insn "movdicc_false"
921   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
922         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
923                              (const_int 0))
924          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
925          (match_operand:DI 3 "arith_reg_operand" "0")))]
926   "TARGET_SHMEDIA"
927   "cmveq        %1, %N2, %0"
928   [(set_attr "type" "arith_media")])
929
930 (define_insn "movdicc_true"
931   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
932         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
933                              (const_int 0))
934          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
935          (match_operand:DI 3 "arith_reg_operand" "0")))]
936   "TARGET_SHMEDIA"
937   "cmvne        %1, %N2, %0"
938   [(set_attr "type" "arith_media")])
939
940 (define_peephole2
941   [(set (match_operand:DI 0 "arith_reg_dest" "")
942         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
943                            [(match_operand:DI 1 "arith_reg_operand" "")
944                             (const_int 0)])
945          (match_operand:DI 2 "arith_reg_dest" "")
946          (match_dup 0)))
947    (set (match_dup 2) (match_dup 0))]
948   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
949   [(set (match_dup 2)
950         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
951   "
952 {
953   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
954                                 VOIDmode, operands[1], CONST0_RTX (DImode));
955 }")
956
957 (define_peephole2
958   [(set (match_operand:DI 0 "general_movdst_operand" "")
959         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
960    (set (match_operand:DI 2 "arith_reg_dest" "")
961         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
962                            [(match_operand:DI 3 "arith_reg_operand" "")
963                             (const_int 0)])
964          (match_dup 0)
965          (match_dup 2)))]
966   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
967   [(set (match_dup 2)
968         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
969   "")
970
971 (define_expand "movdicc"
972   [(set (match_operand:DI 0 "register_operand" "")
973         (if_then_else:DI (match_operand 1 "comparison_operator" "")
974                          (match_operand:DI 2 "register_operand" "")
975                          (match_operand:DI 3 "register_operand" "")))]
976   "TARGET_SHMEDIA"
977   "
978 {
979   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
980       && GET_MODE (sh_compare_op0) == DImode
981       && sh_compare_op1 == const0_rtx)
982     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
983                                   sh_compare_op0, sh_compare_op1);
984   else
985     {
986       rtx tmp;
987
988       if (no_new_pseudos)
989         FAIL;
990
991       tmp = gen_reg_rtx (DImode);
992
993       switch (GET_CODE (operands[1]))
994         {
995         case EQ:
996           emit_insn (gen_seq (tmp));
997           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
998           break;
999
1000         case NE:
1001           emit_insn (gen_seq (tmp));
1002           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1003           break;
1004
1005         case GT:
1006           emit_insn (gen_sgt (tmp));
1007           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1008           break;
1009
1010         case LT:
1011           emit_insn (gen_slt (tmp));
1012           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1013           break;
1014
1015         case GE:
1016           emit_insn (gen_slt (tmp));
1017           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1018           break;
1019
1020         case LE:
1021           emit_insn (gen_sgt (tmp));
1022           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1023           break;
1024
1025         case GTU:
1026           emit_insn (gen_sgtu (tmp));
1027           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1028           break;
1029
1030         case LTU:
1031           emit_insn (gen_sltu (tmp));
1032           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1033           break;
1034
1035         case GEU:
1036           emit_insn (gen_sltu (tmp));
1037           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1038           break;
1039
1040         case LEU:
1041           emit_insn (gen_sgtu (tmp));
1042           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1043           break;
1044
1045         case UNORDERED:
1046           emit_insn (gen_sunordered (tmp));
1047           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1048           break;
1049
1050         case ORDERED:
1051           emit_insn (gen_sunordered (tmp));
1052           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1053           break;
1054
1055         case UNEQ:
1056         case UNGE:
1057         case UNGT:
1058         case UNLE:
1059         case UNLT:
1060         case LTGT:
1061           FAIL;
1062
1063         default:
1064           gcc_unreachable ();
1065         }
1066     }
1067 }")
1068
1069 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1070 ;; SImode to DImode.
1071 (define_insn "movsicc_false"
1072   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1073         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1074                           (const_int 0))
1075          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1076          (match_operand:SI 3 "arith_reg_operand" "0")))]
1077   "TARGET_SHMEDIA"
1078   "cmveq        %1, %N2, %0"
1079   [(set_attr "type" "arith_media")])
1080
1081 (define_insn "movsicc_true"
1082   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1083         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1084                           (const_int 0))
1085          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1086          (match_operand:SI 3 "arith_reg_operand" "0")))]
1087   "TARGET_SHMEDIA"
1088   "cmvne        %1, %N2, %0"
1089   [(set_attr "type" "arith_media")])
1090
1091 (define_peephole2
1092   [(set (match_operand:SI 0 "arith_reg_dest" "")
1093         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1094                            [(match_operand:SI 1 "arith_reg_operand" "")
1095                             (const_int 0)])
1096          (match_operand:SI 2 "arith_reg_dest" "")
1097          (match_dup 0)))
1098    (set (match_dup 2) (match_dup 0))]
1099   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1100   [(set (match_dup 2)
1101         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1102   "
1103 {
1104   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1105                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1106 }")
1107
1108 (define_peephole2
1109   [(set (match_operand:SI 0 "general_movdst_operand" "")
1110         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1111    (set (match_operand:SI 2 "arith_reg_dest" "")
1112         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1113                            [(match_operand:SI 3 "arith_reg_operand" "")
1114                             (const_int 0)])
1115          (match_dup 0)
1116          (match_dup 2)))]
1117   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1118    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1119   [(set (match_dup 2)
1120         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1121   "
1122 {
1123   replace_rtx (operands[4], operands[0], operands[1]);
1124 }")
1125
1126 (define_peephole2
1127   [(set (match_operand 0 "any_register_operand" "")
1128         (match_operand 1 "any_register_operand" ""))
1129    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1130    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1131   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1132     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1133    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1134    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1135    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1136    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1137    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1138    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1139    && (REGNO_REG_CLASS (REGNO (operands[0]))
1140        == REGNO_REG_CLASS (REGNO (operands[2])))
1141    && (REGNO_REG_CLASS (REGNO (operands[1]))
1142        == REGNO_REG_CLASS (REGNO (operands[0])))"
1143   [(set (match_dup 0) (match_dup 3))
1144    (set (match_dup 4) (match_dup 5))]
1145   "
1146 {
1147   rtx set1, set2;
1148   rtx replacements[4];
1149
1150   /* We want to replace occurrences of operands[0] with operands[1] and
1151      operands[2] with operands[0] in operands[4]/operands[5].
1152      Doing just two replace_rtx calls naively would result in the second
1153      replacement undoing all that the first did if operands[1] and operands[2]
1154      are identical, so we must do this simultaneously.  */
1155   replacements[0] = operands[0];
1156   replacements[1] = operands[1];
1157   replacements[2] = operands[2];
1158   replacements[3] = operands[0];
1159   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1160       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1161       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1162     FAIL;
1163
1164   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1165   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1166   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1167   /* The operands array is aliased to recog_data.operand, which gets
1168      clobbered by extract_insn, so finish with it now.  */
1169   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1170   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1171   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1172      always uses emit_insn.  */
1173   /* Check that we don't violate matching constraints or earlyclobbers.  */
1174   extract_insn (emit_insn (set1));
1175   if (! constrain_operands (1))
1176     goto failure;
1177   extract_insn (emit (set2));
1178   if (! constrain_operands (1))
1179     {
1180       rtx tmp;
1181     failure:
1182       tmp = replacements[0];
1183       replacements[0] = replacements[1];
1184       replacements[1] = tmp;
1185       tmp = replacements[2];
1186       replacements[2] = replacements[3];
1187       replacements[3] = tmp;
1188       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1189       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1190       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1191       FAIL;
1192     }
1193   DONE;
1194 }")
1195
1196 ;; The register allocator is rather clumsy in handling multi-way conditional
1197 ;; moves, so allow the combiner to make them, and we split them up after
1198 ;; reload.  */
1199 (define_insn_and_split "*movsicc_umin"
1200   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1201         (umin:SI (if_then_else:SI
1202                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1203                        (const_int 0))
1204                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1205                    (match_operand:SI 3 "register_operand" "0"))
1206                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1207    (clobber (match_scratch:SI 5 "=&r"))]
1208   "TARGET_SHMEDIA && no_new_pseudos"
1209   "#"
1210   "TARGET_SHMEDIA && reload_completed"
1211   [(pc)]
1212   "
1213 {
1214   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1215                                 operands[3]));
1216   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1217   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1218                                 operands[0]));
1219   DONE;
1220 }")
1221
1222 (define_insn "*movsicc_t_false"
1223   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1224         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1225                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1226                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1227   "TARGET_PRETEND_CMOVE
1228    && (arith_reg_operand (operands[1], SImode)
1229        || (immediate_operand (operands[1], SImode)
1230            && satisfies_constraint_I08 (operands[1])))"
1231   "bt 0f\;mov %1,%0\\n0:"
1232   [(set_attr "type" "mt_group,arith") ;; poor approximation
1233    (set_attr "length" "4")])
1234
1235 (define_insn "*movsicc_t_true"
1236   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1237         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1238                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1239                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1240   "TARGET_PRETEND_CMOVE
1241    && (arith_reg_operand (operands[1], SImode)
1242        || (immediate_operand (operands[1], SImode)
1243            && satisfies_constraint_I08 (operands[1])))"
1244   "bf 0f\;mov %1,%0\\n0:"
1245   [(set_attr "type" "mt_group,arith") ;; poor approximation
1246    (set_attr "length" "4")])
1247
1248 (define_expand "movsicc"
1249   [(set (match_operand:SI 0 "arith_reg_dest" "")
1250         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1251                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1252                          (match_operand:SI 3 "arith_reg_operand" "")))]
1253   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1254   "
1255 {
1256   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1257       && GET_MODE (sh_compare_op0) == SImode
1258       && (TARGET_SHMEDIA
1259           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1260       && sh_compare_op1 == const0_rtx)
1261     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1262                                   sh_compare_op0, sh_compare_op1);
1263   else if (TARGET_PRETEND_CMOVE)
1264     {
1265       enum rtx_code code = GET_CODE (operands[1]);
1266       enum rtx_code new_code = code;
1267       rtx tmp;
1268
1269       if (! currently_expanding_to_rtl)
1270         FAIL;
1271       switch (code)
1272         {
1273         case LT: case LE: case LEU: case LTU:
1274           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1275             break;
1276         case NE:
1277           new_code = reverse_condition (code);
1278           break;
1279         case EQ: case GT: case GE: case GEU: case GTU:
1280           break;
1281         default:
1282           FAIL;
1283         }
1284       tmp = prepare_scc_operands (new_code);
1285       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1286                                     tmp, const0_rtx);
1287     }
1288   else
1289     {
1290       rtx tmp;
1291
1292       if (no_new_pseudos)
1293         FAIL;
1294
1295       tmp = gen_reg_rtx (SImode);
1296
1297       switch (GET_CODE (operands[1]))
1298         {
1299         case EQ:
1300           emit_insn (gen_seq (tmp));
1301           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1302           break;
1303
1304         case NE:
1305           emit_insn (gen_seq (tmp));
1306           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1307           break;
1308
1309         case GT:
1310           emit_insn (gen_sgt (tmp));
1311           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1312           break;
1313
1314         case LT:
1315           emit_insn (gen_slt (tmp));
1316           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1317           break;
1318
1319         case GE:
1320           emit_insn (gen_slt (tmp));
1321           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1322           break;
1323
1324         case LE:
1325           emit_insn (gen_sgt (tmp));
1326           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1327           break;
1328
1329         case GTU:
1330           emit_insn (gen_sgtu (tmp));
1331           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1332           break;
1333
1334         case LTU:
1335           emit_insn (gen_sltu (tmp));
1336           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1337           break;
1338
1339         case GEU:
1340           emit_insn (gen_sltu (tmp));
1341           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1342           break;
1343
1344         case LEU:
1345           emit_insn (gen_sgtu (tmp));
1346           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1347           break;
1348
1349         case UNORDERED:
1350           emit_insn (gen_sunordered (tmp));
1351           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1352           break;
1353
1354         case ORDERED:
1355           emit_insn (gen_sunordered (tmp));
1356           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1357           break;
1358
1359         case UNEQ:
1360         case UNGE:
1361         case UNGT:
1362         case UNLE:
1363         case UNLT:
1364         case LTGT:
1365           FAIL;
1366
1367         default:
1368           abort ();
1369         }
1370     }
1371 }")
1372
1373 (define_expand "movqicc"
1374   [(set (match_operand:QI 0 "register_operand" "")
1375         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1376                          (match_operand:QI 2 "register_operand" "")
1377                          (match_operand:QI 3 "register_operand" "")))]
1378   "TARGET_SHMEDIA"
1379   "
1380 {
1381   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1382   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1383   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1384   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1385   DONE;
1386 }")
1387 \f
1388 ;; -------------------------------------------------------------------------
1389 ;; Addition instructions
1390 ;; -------------------------------------------------------------------------
1391
1392 (define_expand "adddi3"
1393   [(set (match_operand:DI 0 "arith_reg_operand" "")
1394         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1395                  (match_operand:DI 2 "arith_operand" "")))]
1396   ""
1397   "
1398 {
1399   if (TARGET_SH1)
1400     {
1401       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1402         FAIL;
1403       operands[2] = force_reg (DImode, operands[2]);
1404       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1405       DONE;
1406     }
1407 }")
1408
1409 (define_insn "*adddi3_media"
1410   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1411         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1412                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1413   "TARGET_SHMEDIA"
1414   "@
1415         add     %1, %2, %0
1416         addi    %1, %2, %0"
1417   [(set_attr "type" "arith_media")])
1418
1419 (define_insn "*adddisi3_media"
1420   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1421         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1422                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1423   "TARGET_SHMEDIA"
1424   "@
1425         add.l   %1, %2, %0
1426         addi.l  %1, %2, %0"
1427   [(set_attr "type" "arith_media")
1428    (set_attr "highpart" "ignore")])
1429
1430 (define_insn "adddi3z_media"
1431   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1432         (zero_extend:DI
1433          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1434                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1435   "TARGET_SHMEDIA"
1436   "addz.l       %1, %N2, %0"
1437   [(set_attr "type" "arith_media")
1438    (set_attr "highpart" "ignore")])
1439
1440 (define_insn "adddi3_compact"
1441   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1442         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1443                  (match_operand:DI 2 "arith_reg_operand" "r")))
1444    (clobber (reg:SI T_REG))]
1445   "TARGET_SH1"
1446   "#"
1447   [(set_attr "length" "6")])
1448
1449 (define_split
1450   [(set (match_operand:DI 0 "arith_reg_dest" "")
1451         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1452                  (match_operand:DI 2 "arith_reg_operand" "")))
1453    (clobber (reg:SI T_REG))]
1454   "TARGET_SH1 && reload_completed"
1455   [(const_int 0)]
1456   "
1457 {
1458   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1459   high0 = gen_rtx_REG (SImode,
1460                        true_regnum (operands[0])
1461                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1462   high2 = gen_rtx_REG (SImode,
1463                        true_regnum (operands[2])
1464                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1465   emit_insn (gen_clrt ());
1466   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1467   emit_insn (gen_addc1 (high0, high0, high2));
1468   DONE;
1469 }")
1470
1471 (define_insn "addc"
1472   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1473         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1474                           (match_operand:SI 2 "arith_reg_operand" "r"))
1475                  (reg:SI T_REG)))
1476    (set (reg:SI T_REG)
1477         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1478   "TARGET_SH1"
1479   "addc %2,%0"
1480   [(set_attr "type" "arith")])
1481
1482 (define_insn "addc1"
1483   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1484         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1485                           (match_operand:SI 2 "arith_reg_operand" "r"))
1486                  (reg:SI T_REG)))
1487    (clobber (reg:SI T_REG))]
1488   "TARGET_SH1"
1489   "addc %2,%0"
1490   [(set_attr "type" "arith")])
1491
1492 (define_expand "addsi3"
1493   [(set (match_operand:SI 0 "arith_reg_operand" "")
1494         (plus:SI (match_operand:SI 1 "arith_operand" "")
1495                  (match_operand:SI 2 "arith_operand" "")))]
1496   ""
1497   "
1498 {
1499   if (TARGET_SHMEDIA)
1500     operands[1] = force_reg (SImode, operands[1]);
1501 }")
1502
1503 (define_insn "addsi3_media"
1504   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1505         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1506                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1507   "TARGET_SHMEDIA"
1508   "@
1509         add.l   %1, %2, %0
1510         addi.l  %1, %2, %0"
1511   [(set_attr "type" "arith_media")
1512    (set_attr "highpart" "ignore")])
1513
1514 (define_insn "addsidi3_media"
1515   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1516         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1517                                   "%r,r")
1518                                  (match_operand:SI 2 "arith_operand"
1519                                   "r,I10"))))]
1520   "TARGET_SHMEDIA"
1521   "@
1522         add.l   %1, %2, %0
1523         addi.l  %1, %2, %0"
1524   [(set_attr "type" "arith_media")
1525    (set_attr "highpart" "ignore")])
1526
1527 (define_insn "*addsi3_compact"
1528   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1529         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1530                  (match_operand:SI 2 "arith_operand" "rI08")))]
1531   "TARGET_SH1"
1532   "add  %2,%0"
1533   [(set_attr "type" "arith")])
1534
1535 ;; -------------------------------------------------------------------------
1536 ;; Subtraction instructions
1537 ;; -------------------------------------------------------------------------
1538
1539 (define_expand "subdi3"
1540   [(set (match_operand:DI 0 "arith_reg_operand" "")
1541         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1542                   (match_operand:DI 2 "arith_reg_operand" "")))]
1543   ""
1544   "
1545 {
1546   if (TARGET_SH1)
1547     {
1548       operands[1] = force_reg (DImode, operands[1]);
1549       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1550       DONE;
1551     }
1552 }")
1553
1554 (define_insn "*subdi3_media"
1555   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1556         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1557                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1558   "TARGET_SHMEDIA"
1559   "sub  %N1, %2, %0"
1560   [(set_attr "type" "arith_media")])
1561   
1562 (define_insn "subdisi3_media"
1563   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1564         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1565                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1566   "TARGET_SHMEDIA"
1567   "sub.l        %N1, %2, %0"
1568   [(set_attr "type" "arith_media")
1569    (set_attr "highpart" "ignore")])
1570
1571 (define_insn "subdi3_compact"
1572   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1573         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1574                  (match_operand:DI 2 "arith_reg_operand" "r")))
1575    (clobber (reg:SI T_REG))]
1576   "TARGET_SH1"
1577   "#"
1578   [(set_attr "length" "6")])
1579
1580 (define_split
1581   [(set (match_operand:DI 0 "arith_reg_dest" "")
1582         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1583                   (match_operand:DI 2 "arith_reg_operand" "")))
1584    (clobber (reg:SI T_REG))]
1585   "TARGET_SH1 && reload_completed"
1586   [(const_int 0)]
1587   "
1588 {
1589   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1590   high0 = gen_rtx_REG (SImode,
1591                        true_regnum (operands[0])
1592                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1593   high2 = gen_rtx_REG (SImode,
1594                        true_regnum (operands[2])
1595                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1596   emit_insn (gen_clrt ());
1597   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1598   emit_insn (gen_subc1 (high0, high0, high2));
1599   DONE;
1600 }")
1601
1602 (define_insn "subc"
1603   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1604         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1605                             (match_operand:SI 2 "arith_reg_operand" "r"))
1606                   (reg:SI T_REG)))
1607    (set (reg:SI T_REG)
1608         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1609                           (reg:SI T_REG))
1610                 (match_dup 1)))]
1611   "TARGET_SH1"
1612   "subc %2,%0"
1613   [(set_attr "type" "arith")])
1614
1615 (define_insn "subc1"
1616   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1617         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1618                             (match_operand:SI 2 "arith_reg_operand" "r"))
1619                   (reg:SI T_REG)))
1620    (clobber (reg:SI T_REG))]
1621   "TARGET_SH1"
1622   "subc %2,%0"
1623   [(set_attr "type" "arith")])
1624
1625 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1626 ;; pattern for this case.  This helps multimedia applications that compute
1627 ;; the sum of absolute differences.
1628 (define_insn "mov_neg_si_t"
1629   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1630   "TARGET_SH1"
1631   "subc %0,%0"
1632   [(set_attr "type" "arith")])
1633
1634 (define_insn "*subsi3_internal"
1635   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1636         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1637                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1638   "TARGET_SH1"
1639   "sub  %2,%0"
1640   [(set_attr "type" "arith")])
1641
1642 (define_insn_and_split "*subsi3_media"
1643   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1644         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1645                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1646   "TARGET_SHMEDIA
1647    && (operands[1] != constm1_rtx
1648        || (GET_CODE (operands[2]) != TRUNCATE
1649            && GET_CODE (operands[2]) != SUBREG))"
1650   "sub.l        %N1, %2, %0"
1651   "operands[1] == constm1_rtx"
1652   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1653   ""
1654   [(set_attr "type" "arith_media")
1655    (set_attr "highpart" "ignore")])
1656
1657 (define_split
1658   [(set (match_operand:SI 0 "arith_reg_dest" "")
1659         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1660                                                        "general_extend_operand"
1661                                                        "") 0)) 0)))]
1662   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1663   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1664    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1665   "")
1666
1667 (define_split
1668   [(set (match_operand:SI 0 "arith_reg_dest" "")
1669         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1670                                                        "general_extend_operand"
1671                                                        "") 0)) 3)))]
1672   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1673   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1674    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1675   "")
1676 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1677 ;; will sometimes save one instruction.  Otherwise we might get
1678 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1679 ;; are the same.
1680
1681 (define_expand "subsi3"
1682   [(set (match_operand:SI 0 "arith_reg_operand" "")
1683         (minus:SI (match_operand:SI 1 "arith_operand" "")
1684                   (match_operand:SI 2 "arith_reg_operand" "")))]
1685   ""
1686   "
1687 {
1688   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1689     {
1690       emit_insn (gen_negsi2 (operands[0], operands[2]));
1691       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1692       DONE;
1693     }
1694   if (TARGET_SHMEDIA)
1695     {
1696       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1697         FAIL;
1698       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1699         operands[1] = force_reg (SImode, operands[1]);
1700     }
1701 }")
1702 \f
1703 ;; -------------------------------------------------------------------------
1704 ;; Division instructions
1705 ;; -------------------------------------------------------------------------
1706
1707 ;; We take advantage of the library routines which don't clobber as many
1708 ;; registers as a normal function call would.
1709
1710 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1711 ;; also has an effect on the register that holds the address of the sfunc.
1712 ;; To make this work, we have an extra dummy insn that shows the use
1713 ;; of this register for reorg.
1714
1715 (define_insn "use_sfunc_addr"
1716   [(set (reg:SI PR_REG)
1717         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1718   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1719   ""
1720   [(set_attr "length" "0")])
1721
1722 (define_insn "udivsi3_sh2a"
1723   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1724         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1725                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1726   "TARGET_SH2A"
1727   "divu %2,%1"
1728   [(set_attr "type" "arith")
1729    (set_attr "in_delay_slot" "no")])
1730
1731 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1732 ;; hard register 0.  If we used hard register 0, then the next instruction
1733 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1734 ;; gets allocated to a stack slot that needs its address reloaded, then
1735 ;; there is nothing to prevent reload from using r0 to reload the address.
1736 ;; This reload would clobber the value in r0 we are trying to store.
1737 ;; If we let reload allocate r0, then this problem can never happen.
1738
1739 (define_insn "udivsi3_i1"
1740   [(set (match_operand:SI 0 "register_operand" "=z")
1741         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1742    (clobber (reg:SI T_REG))
1743    (clobber (reg:SI PR_REG))
1744    (clobber (reg:SI R4_REG))
1745    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1746   "TARGET_SH1 && ! TARGET_SH4"
1747   "jsr  @%1%#"
1748   [(set_attr "type" "sfunc")
1749    (set_attr "needs_delay_slot" "yes")])
1750
1751 ; Since shmedia-nofpu code could be linked against shcompact code, and
1752 ; the udivsi3 libcall has the same name, we must consider all registers
1753 ; clobbered that are in the union of the registers clobbered by the
1754 ; shmedia and the shcompact implementation.  Note, if the shcompact
1755 ; implementation actually used shcompact code, we'd need to clobber
1756 ; also r23 and fr23.
1757 (define_insn "udivsi3_i1_media"
1758   [(set (match_operand:SI 0 "register_operand" "=z")
1759         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760    (clobber (reg:SI T_MEDIA_REG))
1761    (clobber (reg:SI PR_MEDIA_REG))
1762    (clobber (reg:SI R20_REG))
1763    (clobber (reg:SI R21_REG))
1764    (clobber (reg:SI R22_REG))
1765    (clobber (reg:DI TR0_REG))
1766    (clobber (reg:DI TR1_REG))
1767    (clobber (reg:DI TR2_REG))
1768    (use (match_operand 1 "target_operand" "b"))]
1769   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1770   "blink        %1, r18"
1771   [(set_attr "type" "sfunc")
1772    (set_attr "needs_delay_slot" "yes")])
1773
1774 (define_expand "udivsi3_i4_media"
1775   [(set (match_dup 3)
1776         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1777    (set (match_dup 4)
1778         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779    (set (match_dup 5) (float:DF (match_dup 3)))
1780    (set (match_dup 6) (float:DF (match_dup 4)))
1781    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782    (set (match_dup 8) (fix:DI (match_dup 7)))
1783    (set (match_operand:SI 0 "register_operand" "")
1784         (truncate:SI (match_dup 8)))]
1785   "TARGET_SHMEDIA_FPU"
1786   "
1787 {
1788   operands[3] = gen_reg_rtx (DImode);
1789   operands[4] = gen_reg_rtx (DImode);
1790   operands[5] = gen_reg_rtx (DFmode);
1791   operands[6] = gen_reg_rtx (DFmode);
1792   operands[7] = gen_reg_rtx (DFmode);
1793   operands[8] = gen_reg_rtx (DImode);
1794 }")
1795
1796 (define_insn "udivsi3_i4"
1797   [(set (match_operand:SI 0 "register_operand" "=y")
1798         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799    (clobber (reg:SI T_REG))
1800    (clobber (reg:SI PR_REG))
1801    (clobber (reg:DF DR0_REG))
1802    (clobber (reg:DF DR2_REG))
1803    (clobber (reg:DF DR4_REG))
1804    (clobber (reg:SI R0_REG))
1805    (clobber (reg:SI R1_REG))
1806    (clobber (reg:SI R4_REG))
1807    (clobber (reg:SI R5_REG))
1808    (use (reg:PSI FPSCR_REG))
1809    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1811   "jsr  @%1%#"
1812   [(set_attr "type" "sfunc")
1813    (set_attr "fp_mode" "double")
1814    (set_attr "needs_delay_slot" "yes")])
1815
1816 (define_insn "udivsi3_i4_single"
1817   [(set (match_operand:SI 0 "register_operand" "=y")
1818         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819    (clobber (reg:SI T_REG))
1820    (clobber (reg:SI PR_REG))
1821    (clobber (reg:DF DR0_REG))
1822    (clobber (reg:DF DR2_REG))
1823    (clobber (reg:DF DR4_REG))
1824    (clobber (reg:SI R0_REG))
1825    (clobber (reg:SI R1_REG))
1826    (clobber (reg:SI R4_REG))
1827    (clobber (reg:SI R5_REG))
1828    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1830   "jsr  @%1%#"
1831   [(set_attr "type" "sfunc")
1832    (set_attr "needs_delay_slot" "yes")])
1833
1834 (define_insn "udivsi3_i4_int"
1835   [(set (match_operand:SI 0 "register_operand" "=z")
1836         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837    (clobber (reg:SI T_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI PR_REG))
1840    (clobber (reg:SI MACH_REG))
1841    (clobber (reg:SI MACL_REG))
1842    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843   "TARGET_SH1"
1844   "jsr  @%1%#"
1845   [(set_attr "type" "sfunc")
1846    (set_attr "needs_delay_slot" "yes")])
1847
1848
1849 (define_expand "udivsi3"
1850   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853    (parallel [(set (match_operand:SI 0 "register_operand" "")
1854                    (udiv:SI (reg:SI R4_REG)
1855                             (reg:SI R5_REG)))
1856               (clobber (reg:SI T_REG))
1857               (clobber (reg:SI PR_REG))
1858               (clobber (reg:SI R4_REG))
1859               (use (match_dup 3))])]
1860   ""
1861   "
1862 {
1863   rtx last;
1864
1865   operands[3] = gen_reg_rtx (Pmode);
1866   /* Emit the move of the address to a pseudo outside of the libcall.  */
1867   if (TARGET_DIVIDE_CALL_TABLE)
1868     {
1869       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870          that causes problems when the divide code is supposed to come from a
1871          separate library.  Division by zero is undefined, so dividing 1 can be
1872          implemented by comparing with the divisor.  */
1873       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1874         {
1875           emit_insn (gen_cmpsi (operands[1], operands[2]));
1876           emit_insn (gen_sgeu (operands[0]));
1877           DONE;
1878         }
1879       else if (operands[2] == const0_rtx)
1880         {
1881           emit_move_insn (operands[0], operands[2]);
1882           DONE;
1883         }
1884       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1886     }
1887   else if (TARGET_DIVIDE_CALL_FP)
1888     {
1889       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890       if (TARGET_FPU_SINGLE)
1891         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1892       else
1893         last = gen_udivsi3_i4 (operands[0], operands[3]);
1894     }
1895   else if (TARGET_SHMEDIA_FPU)
1896     {
1897       operands[1] = force_reg (SImode, operands[1]);
1898       operands[2] = force_reg (SImode, operands[2]);
1899       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1900       DONE;
1901     }
1902   else if (TARGET_SH2A)
1903     {
1904       operands[1] = force_reg (SImode, operands[1]);
1905       operands[2] = force_reg (SImode, operands[2]);
1906       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1907       DONE;
1908     }
1909   else if (TARGET_SH5)
1910     {
1911       function_symbol (operands[3],
1912                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1913                        SFUNC_STATIC);
1914
1915       if (TARGET_SHMEDIA)
1916         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917       else if (TARGET_FPU_ANY)
1918         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1919       else
1920         last = gen_udivsi3_i1 (operands[0], operands[3]);
1921     }
1922   else
1923     {
1924       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925       last = gen_udivsi3_i1 (operands[0], operands[3]);
1926     }
1927   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1929   emit_insn (last);
1930   DONE;
1931 }")
1932
1933 (define_insn "divsi3_sh2a"
1934   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1937   "TARGET_SH2A"
1938   "divs %2,%1"
1939   [(set_attr "type" "arith")
1940    (set_attr "in_delay_slot" "no")])
1941
1942 (define_insn "divsi3_i1"
1943   [(set (match_operand:SI 0 "register_operand" "=z")
1944         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945    (clobber (reg:SI T_REG))
1946    (clobber (reg:SI PR_REG))
1947    (clobber (reg:SI R1_REG))
1948    (clobber (reg:SI R2_REG))
1949    (clobber (reg:SI R3_REG))
1950    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951   "TARGET_SH1 && ! TARGET_SH4"
1952   "jsr  @%1%#"
1953   [(set_attr "type" "sfunc")
1954    (set_attr "needs_delay_slot" "yes")])
1955
1956 (define_insn "divsi3_i1_media"
1957   [(set (match_operand:SI 0 "register_operand" "=z")
1958         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959    (clobber (reg:SI T_MEDIA_REG))
1960    (clobber (reg:SI PR_MEDIA_REG))
1961    (clobber (reg:SI R1_REG))
1962    (clobber (reg:SI R20_REG))
1963    (clobber (reg:SI R21_REG))
1964    (clobber (reg:SI TR0_REG))
1965    (use (match_operand 1 "target_operand" "b"))]
1966   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1967   "blink        %1, r18"
1968   [(set_attr "type" "sfunc")])
1969
1970 (define_insn "divsi3_media_2"
1971   [(set (match_operand:SI 0 "register_operand" "=z")
1972         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973    (clobber (reg:SI T_MEDIA_REG))
1974    (clobber (reg:SI PR_MEDIA_REG))
1975    (clobber (reg:SI R1_REG))
1976    (clobber (reg:SI R21_REG))
1977    (clobber (reg:SI TR0_REG))
1978    (use (reg:SI R20_REG))
1979    (use (match_operand 1 "target_operand" "b"))]
1980   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1981   "blink        %1, r18"
1982   [(set_attr "type" "sfunc")])
1983
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988   [(set (match_operand:SI 0 "register_operand" "=r")
1989         (div:SI (match_operand:SI 1 "register_operand" "r")
1990                 (match_operand:SI 2 "register_operand" "r")))
1991    (clobber (reg:SI R4_REG))
1992    (clobber (reg:SI R5_REG))
1993    (clobber (reg:SI T_MEDIA_REG))
1994    (clobber (reg:SI PR_MEDIA_REG))
1995    (clobber (reg:SI R1_REG))
1996    (clobber (reg:SI R21_REG))
1997    (clobber (reg:SI TR0_REG))
1998    (clobber (reg:SI R20_REG))
1999    (use (match_operand:SI 3 "register_operand" "r"))]
2000   "TARGET_SHMEDIA"
2001   "#"
2002   "&& (high_life_started || reload_completed)"
2003   [(set (match_dup 0) (match_dup 3))]
2004   ""
2005   [(set_attr "highpart" "must_split")])
2006
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009   [(set (match_operand:SI 0 "register_operand" "=z")
2010         (div:SI (match_operand:SI 1 "register_operand" "r")
2011                 (match_operand:SI 2 "register_operand" "r")))
2012    (clobber (reg:SI R4_REG))
2013    (clobber (reg:SI R5_REG))
2014    (clobber (reg:SI T_MEDIA_REG))
2015    (clobber (reg:SI PR_MEDIA_REG))
2016    (clobber (reg:SI R1_REG))
2017    (clobber (reg:SI R21_REG))
2018    (clobber (reg:SI TR0_REG))
2019    (clobber (reg:SI R20_REG))
2020    (use (unspec:SI [(match_dup 1)
2021                     (match_operand:SI 3 "" "")
2022                     (unspec:SI [(match_operand:SI 4 "" "")
2023                                 (match_dup 3)
2024                                 (match_operand:DI 5 "" "")]
2025                      UNSPEC_DIV_INV_M2)
2026                     (match_operand:DI 6 "" "")
2027                     (const_int 0)
2028                     (const_int 0)]
2029          UNSPEC_DIV_INV_M3))]
2030   "TARGET_SHMEDIA"
2031   "#"
2032   "&& (high_life_started || reload_completed)"
2033   [(pc)]
2034   "
2035 {
2036   const char *name = sh_divsi3_libfunc;
2037   enum sh_function_kind kind = SFUNC_GOT;
2038   rtx sym;
2039
2040   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042   while (TARGET_DIVIDE_INV_CALL2)
2043     {
2044       rtx x = operands[3];
2045
2046       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2047         break;
2048       x = XVECEXP (x, 0, 0);
2049       name = \"__sdivsi3_2\";
2050       kind = SFUNC_STATIC;
2051       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2052       break;
2053     }
2054   sym = function_symbol (NULL, name, kind);
2055   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2056   DONE;
2057 }"
2058   [(set_attr "highpart" "must_split")])
2059
2060 (define_expand "divsi3_i4_media"
2061   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064    (set (match_operand:SI 0 "register_operand" "=r")
2065         (fix:SI (match_dup 5)))]
2066   "TARGET_SHMEDIA_FPU"
2067   "
2068 {
2069   operands[3] = gen_reg_rtx (DFmode);
2070   operands[4] = gen_reg_rtx (DFmode);
2071   operands[5] = gen_reg_rtx (DFmode);
2072 }")
2073
2074 (define_insn "divsi3_i4"
2075   [(set (match_operand:SI 0 "register_operand" "=y")
2076         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077    (clobber (reg:SI PR_REG))
2078    (clobber (reg:DF DR0_REG))
2079    (clobber (reg:DF DR2_REG))
2080    (use (reg:PSI FPSCR_REG))
2081    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2083   "jsr  @%1%#"
2084   [(set_attr "type" "sfunc")
2085    (set_attr "fp_mode" "double")
2086    (set_attr "needs_delay_slot" "yes")])
2087
2088 (define_insn "divsi3_i4_single"
2089   [(set (match_operand:SI 0 "register_operand" "=y")
2090         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091    (clobber (reg:SI PR_REG))
2092    (clobber (reg:DF DR0_REG))
2093    (clobber (reg:DF DR2_REG))
2094    (clobber (reg:SI R2_REG))
2095    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2097   "jsr  @%1%#"
2098   [(set_attr "type" "sfunc")
2099    (set_attr "needs_delay_slot" "yes")])
2100
2101 (define_insn "divsi3_i4_int"
2102   [(set (match_operand:SI 0 "register_operand" "=z")
2103         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104    (clobber (reg:SI T_REG))
2105    (clobber (reg:SI PR_REG))
2106    (clobber (reg:SI R1_REG))
2107    (clobber (reg:SI MACH_REG))
2108    (clobber (reg:SI MACL_REG))
2109    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110   "TARGET_SH1"
2111   "jsr  @%1%#"
2112   [(set_attr "type" "sfunc")
2113    (set_attr "needs_delay_slot" "yes")])
2114
2115 (define_expand "divsi3"
2116   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119    (parallel [(set (match_operand:SI 0 "register_operand" "")
2120                    (div:SI (reg:SI R4_REG)
2121                            (reg:SI R5_REG)))
2122               (clobber (reg:SI T_REG))
2123               (clobber (reg:SI PR_REG))
2124               (clobber (reg:SI R1_REG))
2125               (clobber (reg:SI R2_REG))
2126               (clobber (reg:SI R3_REG))
2127               (use (match_dup 3))])]
2128   ""
2129   "
2130 {
2131   rtx last;
2132
2133   operands[3] = gen_reg_rtx (Pmode);
2134   /* Emit the move of the address to a pseudo outside of the libcall.  */
2135   if (TARGET_DIVIDE_CALL_TABLE)
2136     {
2137       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138       last = gen_divsi3_i4_int (operands[0], operands[3]);
2139     }
2140   else if (TARGET_DIVIDE_CALL_FP)
2141     {
2142       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143       if (TARGET_FPU_SINGLE)
2144         last = gen_divsi3_i4_single (operands[0], operands[3]);
2145       else
2146         last = gen_divsi3_i4 (operands[0], operands[3]);
2147     }
2148   else if (TARGET_SH2A)
2149     {
2150       operands[1] = force_reg (SImode, operands[1]);
2151       operands[2] = force_reg (SImode, operands[2]);
2152       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2153       DONE;
2154     }
2155   else if (TARGET_DIVIDE_INV)
2156     {
2157       rtx dividend = operands[1];
2158       rtx divisor = operands[2];
2159       rtx tab_base;
2160       rtx nsb_res = gen_reg_rtx (DImode);
2161       rtx norm64 = gen_reg_rtx (DImode);
2162       rtx tab_ix = gen_reg_rtx (DImode);
2163       rtx norm32 = gen_reg_rtx (SImode);
2164       rtx i92 = force_reg (DImode, GEN_INT (92));
2165       rtx scratch0a = gen_reg_rtx (DImode);
2166       rtx scratch0b = gen_reg_rtx (DImode);
2167       rtx inv0 = gen_reg_rtx (SImode);
2168       rtx scratch1a = gen_reg_rtx (DImode);
2169       rtx scratch1b = gen_reg_rtx (DImode);
2170       rtx shift = gen_reg_rtx (DImode);
2171       rtx i2p27, i43;
2172       rtx inv1 = gen_reg_rtx (SImode);
2173       rtx scratch2a = gen_reg_rtx (DImode);
2174       rtx scratch2b = gen_reg_rtx (SImode);
2175       rtx inv2 = gen_reg_rtx (SImode);
2176       rtx scratch3a = gen_reg_rtx (DImode);
2177       rtx scratch3b = gen_reg_rtx (DImode);
2178       rtx scratch3c = gen_reg_rtx (DImode);
2179       rtx scratch3d = gen_reg_rtx (SImode);
2180       rtx scratch3e = gen_reg_rtx (DImode);
2181       rtx result = gen_reg_rtx (SImode);
2182
2183       if (! arith_reg_or_0_operand (dividend, SImode))
2184         dividend = force_reg (SImode, dividend);
2185       if (! arith_reg_operand (divisor, SImode))
2186         divisor = force_reg (SImode, divisor);
2187       if (flag_pic && Pmode != DImode)
2188         {
2189           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190           tab_base = gen_datalabel_ref (tab_base);
2191           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2192         }
2193       else
2194         {
2195           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196           tab_base = gen_datalabel_ref (tab_base);
2197           tab_base = force_reg (DImode, tab_base);
2198         }
2199       if (TARGET_DIVIDE_INV20U)
2200         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2201       else
2202         i2p27 = GEN_INT (0);
2203       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204         i43 = force_reg (DImode, GEN_INT (43));
2205       else
2206         i43 = GEN_INT (0);
2207       emit_insn (gen_nsbdi (nsb_res,
2208                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209       emit_insn (gen_ashldi3_media (norm64,
2210                                     gen_rtx_SUBREG (DImode, divisor, 0),
2211                                     nsb_res));
2212       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215                                    inv0, scratch0a, scratch0b,
2216                                    scratch1a, scratch1b));
2217       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2219                                    scratch2a));
2220       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2221                                    i2p27, i43,
2222                                    scratch3a, scratch3b, scratch3c,
2223                                    scratch2a, scratch2b, scratch3d, scratch3e));
2224       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226       else if (TARGET_DIVIDE_INV_FP)
2227         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230                                      gen_reg_rtx (DFmode)));
2231       else
2232         emit_move_insn (operands[0], result);
2233       DONE;
2234     }
2235   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2236     {
2237       operands[1] = force_reg (SImode, operands[1]);
2238       operands[2] = force_reg (SImode, operands[2]);
2239       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2240       DONE;
2241     }
2242   else if (TARGET_SH5)
2243     {
2244       if (TARGET_DIVIDE_CALL2)
2245         {
2246           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247           tab_base = gen_datalabel_ref (tab_base);
2248           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2249         }
2250       if (TARGET_FPU_ANY && TARGET_SH1)
2251         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252       else if (TARGET_DIVIDE_CALL2)
2253         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2254       else
2255         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2256
2257       if (TARGET_SHMEDIA)
2258         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259                 (operands[0], operands[3]));
2260       else if (TARGET_FPU_ANY)
2261         last = gen_divsi3_i4_single (operands[0], operands[3]);
2262       else
2263         last = gen_divsi3_i1 (operands[0], operands[3]);
2264     }
2265   else
2266     {
2267       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268       last = gen_divsi3_i1 (operands[0], operands[3]);
2269     }
2270   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2272   emit_insn (last);
2273   DONE;
2274 }")
2275
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload.  See PR27117.
2280
2281 (define_insn "divsi_inv_qitable"
2282   [(set (match_operand:DI 0 "register_operand" "=r")
2283         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284                                     (match_operand:DI 2 "register_operand" "r")]
2285                          UNSPEC_DIV_INV_TABLE)))]
2286   "TARGET_SHMEDIA"
2287   "@
2288         ldx.ub  %1, %2, %0"
2289   [(set_attr "type" "load_media")
2290    (set_attr "highpart" "user")])
2291
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294   [(set (match_operand:DI 0 "register_operand" "=r")
2295         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296                                     (match_operand:DI 2 "register_operand" "r")]
2297                          UNSPEC_DIV_INV_TABLE)))]
2298   "TARGET_SHMEDIA"
2299   "@
2300         ldx.w   %1, %2, %0"
2301   [(set_attr "type" "load_media")
2302    (set_attr "highpart" "user")])
2303
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307   [(set (match_operand:SI 0 "register_operand" "=r")
2308         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309                     (match_operand:DI 2 "register_operand" "r")
2310                     (match_operand:SI 3 "register_operand" "r")]
2311          UNSPEC_DIV_INV_M0))
2312    (clobber (match_operand:DI 4 "register_operand" "=r"))
2313    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2314   "TARGET_SHMEDIA"
2315   "
2316 {
2317 /*
2318 tab_base: r20
2319 tab_ix: r21
2320 norm32: r25
2321  ldx.ub r20, r21, r19 // u0.8
2322  shlli r21, 1, r21
2323  muls.l r25, r19, r19 // s2.38
2324  ldx.w r20, r21, r21  // s2.14
2325  shari r19, 24, r19   // truncate to s2.14
2326  sub r21, r19, r19    // some 11 bit inverse in s1.14
2327 */
2328
2329   rtx inv0 = operands[0];
2330   rtx tab_base = operands[1];
2331   rtx tab_ix = operands[2];
2332   rtx norm32 = operands[3];
2333   rtx scratch0 = operands[4];
2334   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335   rtx scratch1 = operands[5];
2336
2337   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2343   DONE;
2344 }")
2345
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348   [(set (match_operand:SI 0 "register_operand" "=r")
2349         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350                     (match_operand:DI 2 "register_operand" "r")
2351                     (match_operand:SI 3 "register_operand" "r")]
2352          UNSPEC_DIV_INV_M1))
2353    (clobber (match_operand:SI 4 "register_operand" "=r"))
2354    (clobber (match_operand:DI 5 "register_operand" "=r"))
2355    (clobber (match_operand:DI 6 "register_operand" "=r"))
2356    (clobber (match_operand:DI 7 "register_operand" "=r"))
2357    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2358   "TARGET_SHMEDIA"
2359   "#"
2360   "&& no_new_pseudos"
2361   [(pc)]
2362   "
2363 {
2364 /* inv0: r19
2365  muls.l r19, r19, r18 // u0.28
2366  muls.l r25, r18, r18 // s2.58
2367  shlli r19, 45, r0    // multiply by two and convert to s2.58
2368  sub r0, r18, r18
2369  shari r18, 28, r18   // some 18 bit inverse in s1.30
2370 */
2371
2372   rtx inv1 = operands[0];
2373   rtx tab_base = operands[1];
2374   rtx tab_ix = operands[2];
2375   rtx norm32 = operands[3];
2376   rtx inv0 = operands[4];
2377   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378   rtx scratch0a = operands[5];
2379   rtx scratch0b = operands[6];
2380   rtx scratch0 = operands[7];
2381   rtx scratch1 = operands[8];
2382   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2383
2384   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385                                scratch0a, scratch0b));
2386   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2391   DONE;
2392 }")
2393
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396   [(set (match_operand:SI 0 "register_operand" "=r")
2397         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398                     (match_operand:SI 2 "register_operand" "r")
2399                     (match_operand:DI 3 "register_operand" "r")]
2400          UNSPEC_DIV_INV_M2))
2401    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2402   "TARGET_SHMEDIA"
2403   "#"
2404   "&& no_new_pseudos"
2405   [(pc)]
2406   "
2407 {
2408 /*
2409  muls.l r18, r25, r0  // s2.60
2410  shari r0, 16, r0     // s-16.44
2411   sub
2412  muls.l r0, r18, r19  // s-16.74
2413  shari r19, 30, r19   // s-16.44
2414 */
2415   rtx inv2 = operands[0];
2416   rtx norm32 = operands[1];
2417   rtx inv1 = operands[2];
2418   rtx i92 = operands[3];
2419   rtx scratch0 = operands[4];
2420   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2421
2422   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2427   DONE;
2428 }")
2429
2430 (define_insn_and_split "divsi_inv_m3"
2431   [(set (match_operand:SI 0 "register_operand" "=r")
2432         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2438          UNSPEC_DIV_INV_M3))
2439    (clobber (match_operand:DI 7 "register_operand" "=r"))
2440    (clobber (match_operand:DI 8 "register_operand" "=r"))
2441    (clobber (match_operand:DI 9 "register_operand" "=r"))
2442    (clobber (match_operand:DI 10 "register_operand" "=r"))
2443    (clobber (match_operand:SI 11 "register_operand" "=r"))
2444    (clobber (match_operand:SI 12 "register_operand" "=r"))
2445    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2446   "TARGET_SHMEDIA"
2447   "#"
2448   "&& no_new_pseudos"
2449   [(pc)]
2450   "
2451 {
2452 /*
2453   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2454   r0: scratch0  r19: scratch1 r21: scratch2
2455
2456   muls.l r18, r4, r25 // s32.30
2457  muls.l r19, r4, r19  // s15.30
2458  shari r25, 63, r21
2459   shari r19, 14, r19  // s18.-14
2460  sub r25, r19, r0
2461  shard r0, r1, r0
2462  sub r0, r21, r0
2463 */
2464
2465   rtx result = operands[0];
2466   rtx dividend = operands[1];
2467   rtx inv1 = operands[2];
2468   rtx inv2 = operands[3];
2469   rtx shift = operands[4];
2470   rtx scratch0 = operands[7];
2471   rtx scratch1 = operands[8];
2472   rtx scratch2 = operands[9];
2473
2474   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2481   DONE;
2482 }")
2483
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488   [(set (match_operand:SI 0 "register_operand" "=r")
2489         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491                                 (match_operand:DI 3 "register_operand" "r")
2492                                 (match_operand:SI 4 "register_operand" "r")]
2493                      UNSPEC_DIV_INV_M1)
2494                     (unspec:SI [(match_dup 4)
2495                                 (unspec:SI [(match_dup 2)
2496                                             (match_dup 3)
2497                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2498                                 (match_operand:SI 5 "" "")]
2499                      UNSPEC_DIV_INV_M2)
2500                     (match_operand:DI 6 "register_operand" "r")
2501                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2503          UNSPEC_DIV_INV_M3))
2504    (clobber (match_operand:DI 9 "register_operand" "=r"))
2505    (clobber (match_operand:DI 10 "register_operand" "=r"))
2506    (clobber (match_operand:DI 11 "register_operand" "=r"))
2507    (clobber (match_operand:DI 12 "register_operand" "=r"))
2508    (clobber (match_operand:SI 13 "register_operand" "=r"))
2509    (clobber (match_operand:SI 14 "register_operand" "=r"))
2510    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2511   "TARGET_SHMEDIA
2512    && (TARGET_DIVIDE_INV_MINLAT
2513        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2514   "#"
2515   "&& no_new_pseudos"
2516   [(pc)]
2517   "
2518 {
2519   rtx result = operands[0];
2520   rtx dividend = operands[1];
2521   rtx tab_base = operands[2];
2522   rtx tab_ix = operands[3];
2523   rtx norm32 = operands[4];
2524   /* rtx i92 = operands[5]; */
2525   rtx shift = operands[6];
2526   rtx i2p27 = operands[7];
2527   rtx i43 = operands[8];
2528   rtx scratch0 = operands[9];
2529   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530   rtx scratch1 = operands[10];
2531   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532   rtx scratch2 = operands[11];
2533   rtx scratch3 = operands[12];
2534   rtx scratch4 = operands[13];
2535   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536   rtx scratch5 = operands[14];
2537   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538   rtx scratch6 = operands[15];
2539
2540   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541                                scratch0, scratch1));
2542   /* inv0 == scratch4 */
2543   if (! TARGET_DIVIDE_INV20U)
2544     {
2545       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2546       i2p27 = scratch0;
2547       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2548     }
2549   else
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2553     }
2554   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557   /* inv1 == scratch4 */
2558
2559   if (TARGET_DIVIDE_INV_MINLAT)
2560     {
2561       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2572     }
2573   else
2574     {
2575       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2577       emit_insn (gen_nsbdi (scratch6,
2578                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581       emit_insn (gen_divsi_inv20 (scratch2,
2582                                   norm32, scratch4, dividend,
2583                                   scratch6, scratch3, i43,
2584                                   /* scratch0 may be shared with i2p27.  */
2585                                   scratch0, scratch1, scratch5,
2586                                   label, label, i2p27));
2587     }
2588   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2590   DONE;
2591 }")
2592
2593 (define_insn "divsi_inv20"
2594   [(set (match_operand:DI 0 "register_operand" "=&r")
2595         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596                     (match_operand:SI 2 "register_operand" "r")
2597                     (match_operand:SI 3 "register_operand" "r")
2598                     (match_operand:DI 4 "register_operand" "r")
2599                     (match_operand:DI 5 "register_operand" "r")
2600                     (match_operand:DI 6 "register_operand" "r")
2601                     (match_operand:DI 12 "register_operand" "r")
2602                     (match_operand 10 "target_operand" "b")
2603                     (match_operand 11 "immediate_operand" "i")]
2604          UNSPEC_DIV_INV20))
2605    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2608   "TARGET_SHMEDIA
2609    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2610   "*
2611 {
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615              %10 label (tr), %11 label (imm)
2616
2617  muls.l inv1, norm32, scratch0  // s2.60
2618   muls.l inv1, dividend, result // s32.30
2619   xor i2p27, result_sign, round_scratch
2620  bge/u dividend_nsb, i43, tr.. (label)
2621  shari scratch0, 16, scratch0   // s-16.44
2622  muls.l sratch0_si, inv1, scratch0 // s-16.74
2623   sub result, round_scratch, result
2624   shari dividend, 14, scratch1   // s19.-14
2625  shari scratch0, 30, scratch0   // s-16.44
2626  muls.l scratch0, scratch1, round_scratch // s15.30
2627 label:
2628  sub result, round_scratch, result */
2629
2630   int likely = TARGET_DIVIDE_INV20L;
2631
2632   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634   output_asm_insn (likely
2635                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636                    : \"bge/u\t%4, %6, %10\", operands);
2637   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2640   return (likely
2641           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2643 }")
2644
2645 (define_insn_and_split "divsi_inv_fp"
2646   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648                 (match_operand:SI 2 "register_operand" "rf")))
2649    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650    (clobber (match_operand:SI 4 "register_operand" "=r"))
2651    (clobber (match_operand:SI 5 "register_operand" "=r"))
2652    (clobber (match_operand:DF 6 "register_operand" "=r"))
2653    (clobber (match_operand:DF 7 "register_operand" "=r"))
2654    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655   "TARGET_SHMEDIA_FPU"
2656   "#"
2657   "&& (high_life_started || reload_completed)"
2658   [(set (match_dup 0) (match_dup 3))]
2659   ""
2660   [(set_attr "highpart" "must_split")])
2661
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666   [(set (match_operand:SI 0 "register_operand" "=f")
2667         (div:SI (match_operand:SI 1 "register_operand" "f")
2668                 (match_operand:SI 2 "register_operand" "f")))
2669    (use (unspec:SI [(match_dup 1)
2670                     (match_operand:SI 3 "" "")
2671                     (unspec:SI [(match_operand:SI 4 "" "")
2672                                 (match_dup 3)
2673                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674                     (match_operand:DI 6 "" "")
2675                     (const_int 0)
2676                     (const_int 0)] UNSPEC_DIV_INV_M3))
2677    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2683   "#"
2684   "&& 1"
2685   [(set (match_dup 9) (float:DF (match_dup 1)))
2686    (set (match_dup 10) (float:DF (match_dup 2)))
2687    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2688    (set (match_dup 8)
2689         (fix:SI (match_dup 11)))
2690    (set (match_dup 0) (match_dup 8))]
2691   "
2692 {
2693   if (! fp_arith_reg_operand (operands[1], SImode))
2694     {
2695       emit_move_insn (operands[7], operands[1]);
2696       operands[1] = operands[7];
2697     }
2698   if (! fp_arith_reg_operand (operands[2], SImode))
2699     {
2700       emit_move_insn (operands[8], operands[2]);
2701       operands[2] = operands[8];
2702     }
2703 }"
2704   [(set_attr "highpart" "must_split")])
2705 \f
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2709
2710 (define_insn "umulhisi3_i"
2711   [(set (reg:SI MACL_REG)
2712         (mult:SI (zero_extend:SI
2713                   (match_operand:HI 0 "arith_reg_operand" "r"))
2714                  (zero_extend:SI
2715                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716   "TARGET_SH1"
2717   "mulu.w       %1,%0"
2718   [(set_attr "type" "smpy")])
2719
2720 (define_insn "mulhisi3_i"
2721   [(set (reg:SI MACL_REG)
2722         (mult:SI (sign_extend:SI
2723                   (match_operand:HI 0 "arith_reg_operand" "r"))
2724                  (sign_extend:SI
2725                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2726   "TARGET_SH1"
2727   "muls.w       %1,%0"
2728   [(set_attr "type" "smpy")])
2729
2730 (define_expand "mulhisi3"
2731   [(set (reg:SI MACL_REG)
2732         (mult:SI (sign_extend:SI
2733                   (match_operand:HI 1 "arith_reg_operand" ""))
2734                  (sign_extend:SI
2735                   (match_operand:HI 2 "arith_reg_operand" ""))))
2736    (set (match_operand:SI 0 "arith_reg_operand" "")
2737         (reg:SI MACL_REG))]
2738   "TARGET_SH1"
2739   "
2740 {
2741   rtx insn, macl;
2742
2743   macl = gen_rtx_REG (SImode, MACL_REG);
2744   start_sequence ();
2745   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746   insn = get_insns ();  
2747   end_sequence ();
2748   /* expand_binop can't find a suitable code in umul_widen_optab to
2749      make a REG_EQUAL note from, so make one here.
2750      See also smulsi3_highpart.
2751      ??? Alternatively, we could put this at the calling site of expand_binop,
2752      i.e. expand_expr.  */
2753   /* Use emit_libcall_block for loop invariant code motion and to make
2754      a REG_EQUAL note.  */
2755   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2756
2757   DONE;
2758 }")
2759
2760 (define_expand "umulhisi3"
2761   [(set (reg:SI MACL_REG)
2762         (mult:SI (zero_extend:SI
2763                   (match_operand:HI 1 "arith_reg_operand" ""))
2764                  (zero_extend:SI
2765                   (match_operand:HI 2 "arith_reg_operand" ""))))
2766    (set (match_operand:SI 0 "arith_reg_operand" "")
2767         (reg:SI MACL_REG))]
2768   "TARGET_SH1"
2769   "
2770 {
2771   rtx insn, macl;
2772
2773   macl = gen_rtx_REG (SImode, MACL_REG);
2774   start_sequence ();
2775   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776   insn = get_insns ();  
2777   end_sequence ();
2778   /* expand_binop can't find a suitable code in umul_widen_optab to
2779      make a REG_EQUAL note from, so make one here.
2780      See also smulsi3_highpart.
2781      ??? Alternatively, we could put this at the calling site of expand_binop,
2782      i.e. expand_expr.  */
2783   /* Use emit_libcall_block for loop invariant code motion and to make
2784      a REG_EQUAL note.  */
2785   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2786
2787   DONE;
2788 }")
2789
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2792
2793 (define_insn ""
2794   [(set (match_operand:SI 1 "register_operand" "=z")
2795         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796    (clobber (reg:SI MACL_REG))
2797    (clobber (reg:SI T_REG))
2798    (clobber (reg:SI PR_REG))
2799    (clobber (reg:SI R3_REG))
2800    (clobber (reg:SI R2_REG))
2801    (clobber (reg:SI R1_REG))
2802    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2803   "TARGET_SH1"
2804   "jsr  @%0%#"
2805   [(set_attr "type" "sfunc")
2806    (set_attr "needs_delay_slot" "yes")])
2807
2808 (define_expand "mulsi3_call"
2809   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811    (parallel[(set (match_operand:SI 0 "register_operand" "")
2812                   (mult:SI (reg:SI R4_REG)
2813                            (reg:SI R5_REG)))
2814              (clobber (reg:SI MACL_REG))
2815              (clobber (reg:SI T_REG))
2816              (clobber (reg:SI PR_REG))
2817              (clobber (reg:SI R3_REG))
2818              (clobber (reg:SI R2_REG))
2819              (clobber (reg:SI R1_REG))
2820              (use (match_operand:SI 3 "register_operand" ""))])]
2821   "TARGET_SH1"
2822   "")
2823
2824 (define_insn "mul_r"
2825   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2828   "TARGET_SH2A"
2829   "mulr %2,%0"
2830   [(set_attr "type" "dmpy")])
2831
2832 (define_insn "mul_l"
2833   [(set (reg:SI MACL_REG)
2834         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2836   "TARGET_SH2"
2837   "mul.l        %1,%0"
2838   [(set_attr "type" "dmpy")])
2839
2840 (define_expand "mulsi3"
2841   [(set (reg:SI MACL_REG)
2842         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2843                   (match_operand:SI 2 "arith_reg_operand" "")))
2844    (set (match_operand:SI 0 "arith_reg_operand" "")
2845         (reg:SI MACL_REG))]
2846   "TARGET_SH1"
2847   "
2848 {
2849   if (!TARGET_SH2)
2850     {
2851       /* The address must be set outside the libcall,
2852          since it goes into a pseudo.  */
2853       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854       rtx addr = force_reg (SImode, sym);
2855       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2856                                    operands[2], addr);
2857       emit_insn (insns);
2858     }
2859   else
2860     {
2861       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2862
2863       emit_insn (gen_mul_l (operands[1], operands[2]));
2864       /* consec_sets_giv can only recognize the first insn that sets a
2865          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2866          note.  */
2867       emit_insn (gen_movsi_i ((operands[0]), macl));
2868     }
2869   DONE;
2870 }")
2871
2872 (define_insn "mulsidi3_i"
2873   [(set (reg:SI MACH_REG)
2874         (truncate:SI
2875          (lshiftrt:DI
2876           (mult:DI
2877            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2879           (const_int 32))))
2880    (set (reg:SI MACL_REG)
2881         (mult:SI (match_dup 0)
2882                  (match_dup 1)))]
2883   "TARGET_SH2"
2884   "dmuls.l      %1,%0"
2885   [(set_attr "type" "dmpy")])
2886
2887 (define_expand "mulsidi3"
2888   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891   "TARGET_SH2 || TARGET_SHMEDIA"
2892   "
2893 {
2894   if (TARGET_SH2)
2895     {
2896        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2897                                         operands[2]));
2898        DONE;
2899     }
2900 }")
2901
2902 (define_insn "mulsidi3_media"
2903   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2906   "TARGET_SHMEDIA"
2907   "muls.l       %1, %2, %0"
2908   [(set_attr "type" "dmpy_media")
2909    (set_attr "highpart" "ignore")])
2910
2911 (define_insn "mulsidi3_compact"
2912   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913         (mult:DI
2914          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916    (clobber (reg:SI MACH_REG))
2917    (clobber (reg:SI MACL_REG))]
2918   "TARGET_SH2"
2919   "#")
2920
2921 (define_split
2922   [(set (match_operand:DI 0 "arith_reg_dest" "")
2923         (mult:DI
2924          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926    (clobber (reg:SI MACH_REG))
2927    (clobber (reg:SI MACL_REG))]
2928   "TARGET_SH2"
2929   [(const_int 0)]
2930   "
2931 {
2932   rtx low_dst = gen_lowpart (SImode, operands[0]);
2933   rtx high_dst = gen_highpart (SImode, operands[0]);
2934
2935   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2936
2937   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939   /* We need something to tag the possible REG_EQUAL notes on to.  */
2940   emit_move_insn (operands[0], operands[0]);
2941   DONE;
2942 }")
2943
2944 (define_insn "umulsidi3_i"
2945   [(set (reg:SI MACH_REG)
2946         (truncate:SI
2947          (lshiftrt:DI
2948           (mult:DI
2949            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2951           (const_int 32))))
2952    (set (reg:SI MACL_REG)
2953         (mult:SI (match_dup 0)
2954                  (match_dup 1)))]
2955   "TARGET_SH2"
2956   "dmulu.l      %1,%0"
2957   [(set_attr "type" "dmpy")])
2958
2959 (define_expand "umulsidi3"
2960   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963   "TARGET_SH2 || TARGET_SHMEDIA"
2964   "
2965 {
2966   if (TARGET_SH2)
2967     {
2968        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2969                                          operands[2]));
2970        DONE;
2971     }
2972 }")
2973
2974 (define_insn "umulsidi3_media"
2975   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2978   "TARGET_SHMEDIA"
2979   "mulu.l       %1, %2, %0"
2980   [(set_attr "type" "dmpy_media")
2981    (set_attr "highpart" "ignore")])
2982
2983 (define_insn "umulsidi3_compact"
2984   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985         (mult:DI
2986          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988    (clobber (reg:SI MACH_REG))
2989    (clobber (reg:SI MACL_REG))]
2990   "TARGET_SH2"
2991   "#")
2992
2993 (define_split
2994   [(set (match_operand:DI 0 "arith_reg_dest" "")
2995         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997    (clobber (reg:SI MACH_REG))
2998    (clobber (reg:SI MACL_REG))]
2999   "TARGET_SH2"
3000   [(const_int 0)]
3001   "
3002 {
3003   rtx low_dst = gen_lowpart (SImode, operands[0]);
3004   rtx high_dst = gen_highpart (SImode, operands[0]);
3005
3006   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3007
3008   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010   /* We need something to tag the possible REG_EQUAL notes on to.  */
3011   emit_move_insn (operands[0], operands[0]);
3012   DONE;
3013 }")
3014
3015 (define_insn "smulsi3_highpart_i"
3016   [(set (reg:SI MACH_REG)
3017         (truncate:SI
3018          (lshiftrt:DI
3019           (mult:DI
3020            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3022           (const_int 32))))
3023    (clobber (reg:SI MACL_REG))]
3024   "TARGET_SH2"
3025   "dmuls.l      %1,%0"
3026   [(set_attr "type" "dmpy")])
3027
3028 (define_expand "smulsi3_highpart"
3029   [(parallel
3030     [(set (reg:SI MACH_REG)
3031           (truncate:SI
3032            (lshiftrt:DI
3033             (mult:DI
3034              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3036             (const_int 32))))
3037     (clobber (reg:SI MACL_REG))])
3038    (set (match_operand:SI 0 "arith_reg_operand" "")
3039         (reg:SI MACH_REG))]
3040   "TARGET_SH2"
3041   "
3042 {
3043   rtx insn, mach;
3044
3045   mach = gen_rtx_REG (SImode, MACH_REG);
3046   start_sequence ();
3047   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048   insn = get_insns ();  
3049   end_sequence ();
3050   /* expand_binop can't find a suitable code in mul_highpart_optab to
3051      make a REG_EQUAL note from, so make one here.
3052      See also {,u}mulhisi.
3053      ??? Alternatively, we could put this at the calling site of expand_binop,
3054      i.e. expand_mult_highpart.  */
3055   /* Use emit_libcall_block for loop invariant code motion and to make
3056      a REG_EQUAL note.  */
3057   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3058
3059   DONE;
3060 }")
3061
3062 (define_insn "umulsi3_highpart_i"
3063   [(set (reg:SI MACH_REG)
3064         (truncate:SI
3065          (lshiftrt:DI
3066           (mult:DI
3067            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3069           (const_int 32))))
3070    (clobber (reg:SI MACL_REG))]
3071   "TARGET_SH2"
3072   "dmulu.l      %1,%0"
3073   [(set_attr "type" "dmpy")])
3074
3075 (define_expand "umulsi3_highpart"
3076   [(parallel
3077     [(set (reg:SI MACH_REG)
3078           (truncate:SI
3079            (lshiftrt:DI
3080             (mult:DI
3081              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3083             (const_int 32))))
3084     (clobber (reg:SI MACL_REG))])
3085    (set (match_operand:SI 0 "arith_reg_operand" "")
3086         (reg:SI MACH_REG))]
3087   "TARGET_SH2"
3088   "
3089 {
3090   rtx insn, mach;
3091
3092   mach = gen_rtx_REG (SImode, MACH_REG);
3093   start_sequence ();
3094   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095   insn = get_insns ();  
3096   end_sequence ();
3097   /* Use emit_libcall_block for loop invariant code motion and to make
3098      a REG_EQUAL note.  */
3099   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3100
3101   DONE;
3102 }")
3103
3104 (define_insn_and_split "muldi3"
3105   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107                  (match_operand:DI 2 "arith_reg_operand" "r")))
3108    (clobber (match_scratch:DI 3 "=&r"))
3109    (clobber (match_scratch:DI 4 "=r"))]
3110   "TARGET_SHMEDIA"
3111   "#"
3112   "reload_completed"
3113   [(const_int 0)]
3114   "
3115 {
3116   rtx op3_v2si, op2_v2si;
3117
3118   op3_v2si = operands[3];
3119   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3120     {
3121       op3_v2si = XEXP (op3_v2si, 0);
3122       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3123     }
3124   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125   op2_v2si = operands[2];
3126   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3127     {
3128       op2_v2si = XEXP (op2_v2si, 0);
3129       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3130     }
3131   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134   emit_insn (gen_umulsidi3_media (operands[4],
3135                                  sh_gen_truncate (SImode, operands[1], 0),
3136                                  sh_gen_truncate (SImode, operands[2], 0)));
3137   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3141   DONE;
3142 }")
3143
3144 \f
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3148
3149 (define_insn "*andsi3_compact"
3150   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3153   "TARGET_SH1"
3154   "and  %2,%0"
3155   [(set_attr "type" "arith")])
3156
3157 (define_insn "*andsi3_media"
3158   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3161   "TARGET_SHMEDIA"
3162   "@
3163         and     %1, %2, %0
3164         andi    %1, %2, %0"
3165   [(set_attr "type" "arith_media")])
3166
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3169
3170 (define_expand "andsi3"
3171   [(set (match_operand:SI 0 "arith_reg_operand" "")
3172         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173                 (match_operand:SI 2 "logical_operand" "")))]
3174   ""
3175   "
3176 {
3177   if (TARGET_SH1
3178       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3179     {
3180       emit_insn (gen_zero_extendqisi2 (operands[0],
3181                                        gen_lowpart (QImode, operands[1])));
3182       DONE;
3183     }
3184 }")
3185
3186 (define_insn_and_split "anddi3"
3187   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3190   "TARGET_SHMEDIA"
3191   "@
3192         and     %1, %2, %0
3193         andi    %1, %2, %0
3194         #"
3195   "reload_completed
3196    && ! logical_operand (operands[2], DImode)"
3197   [(const_int 0)]
3198   "
3199 {
3200   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3202   else
3203     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3204   DONE;
3205 }"
3206   [(set_attr "type" "arith_media")])
3207
3208 (define_insn "andcsi3"
3209   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3212   "TARGET_SHMEDIA"
3213   "andc %1,%2,%0"
3214   [(set_attr "type" "arith_media")])
3215
3216 (define_insn "andcdi3"
3217   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3220   "TARGET_SHMEDIA"
3221   "andc %1,%2,%0"
3222   [(set_attr "type" "arith_media")])
3223
3224 (define_expand "iorsi3"
3225   [(set (match_operand:SI 0 "arith_reg_operand" "")
3226         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227                 (match_operand:SI 2 "logical_operand" "")))]
3228   ""
3229   "")
3230
3231 (define_insn "*iorsi3_compact"
3232   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3235   "TARGET_SH1"
3236   "or   %2,%0"
3237   [(set_attr "type" "arith")])
3238
3239 (define_insn "*iorsi3_media"
3240   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3243   "TARGET_SHMEDIA"
3244   "@
3245         or      %1, %2, %0
3246         ori     %1, %2, %0"
3247   [(set_attr "type" "arith_media")])
3248
3249 (define_insn "iordi3"
3250   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3253   "TARGET_SHMEDIA"
3254   "@
3255         or      %1, %2, %0
3256         ori     %1, %2, %0"
3257   [(set_attr "type" "arith_media")])
3258
3259 (define_insn_and_split "*logical_sidi3"
3260   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3264   "TARGET_SHMEDIA"
3265   "#"
3266   "&& reload_completed"
3267   [(set (match_dup 0) (match_dup 3))]
3268   "
3269 {
3270   operands[3]
3271     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3274 }")
3275
3276 (define_insn_and_split "*logical_sidisi3"
3277   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278         (truncate:SI (sign_extend:DI
3279                         (match_operator:SI 3 "logical_operator"
3280                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3282   "TARGET_SHMEDIA"
3283   "#"
3284   "&& 1"
3285   [(set (match_dup 0) (match_dup 3))])
3286
3287 (define_insn_and_split "*logical_sidi3_2"
3288   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289         (sign_extend:DI (truncate:SI (sign_extend:DI
3290                         (match_operator:SI 3 "logical_operator"
3291                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3293   "TARGET_SHMEDIA"
3294   "#"
3295   "&& 1"
3296   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3297
3298 (define_expand "xorsi3"
3299   [(set (match_operand:SI 0 "arith_reg_operand" "")
3300         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301                 (match_operand:SI 2 "xor_operand" "")))]
3302   ""
3303   "")
3304
3305 (define_insn "*xorsi3_compact"
3306   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3309   "TARGET_SH1"
3310   "xor  %2,%0"
3311   [(set_attr "type" "arith")])
3312
3313 (define_insn "*xorsi3_media"
3314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3317   "TARGET_SHMEDIA"
3318   "@
3319         xor     %1, %2, %0
3320         xori    %1, %2, %0"
3321   [(set_attr "type" "arith_media")])
3322
3323 (define_insn "xordi3"
3324   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3327   "TARGET_SHMEDIA"
3328   "@
3329         xor     %1, %2, %0
3330         xori    %1, %2, %0"
3331   [(set_attr "type" "arith_media")])
3332
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3335 (define_split
3336   [(set (match_operand:DI 0 "arith_reg_dest" "")
3337         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338                           [(match_operand 1 "any_register_operand" "")
3339                            (match_operand 2 "any_register_operand" "")])))]
3340   "TARGET_SHMEDIA"
3341   [(set (match_dup 5) (match_dup 4))
3342    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3343 "
3344 {
3345   enum machine_mode inmode = GET_MODE (operands[1]);
3346   int offset = 0;
3347
3348   if (GET_CODE (operands[0]) == SUBREG)
3349     {
3350       offset = SUBREG_BYTE (operands[0]);
3351       operands[0] = SUBREG_REG (operands[0]);
3352     }
3353   gcc_assert (GET_CODE (operands[0]) == REG);
3354   if (! TARGET_LITTLE_ENDIAN)
3355     offset += 8 - GET_MODE_SIZE (inmode);
3356   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3357 }")
3358 \f
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3362
3363 (define_expand "rotldi3"
3364   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3367   "TARGET_SHMEDIA"
3368   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3369
3370 (define_insn "rotldi3_mextr"
3371   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3374   "TARGET_SHMEDIA"
3375   "*
3376 {
3377   static char templ[16];
3378
3379   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380            8 - (int) (INTVAL (operands[2]) >> 3));
3381   return templ;
3382 }"
3383   [(set_attr "type" "arith_media")])
3384
3385 (define_expand "rotrdi3"
3386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3389   "TARGET_SHMEDIA"
3390   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3391
3392 (define_insn "rotrdi3_mextr"
3393   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3396   "TARGET_SHMEDIA"
3397   "*
3398 {
3399   static char templ[16];
3400
3401   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3402   return templ;
3403 }"
3404   [(set_attr "type" "arith_media")])
3405
3406 (define_split
3407   [(set (match_operand:DI 0 "arith_reg_dest" "")
3408         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409                                          "ua_address_operand" "")))
3410                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3411                            (const_int 8))))
3412    (clobber (match_operand:DI 3 "register_operand" ""))]
3413   "TARGET_SHMEDIA"
3414   [(match_dup 4) (match_dup 5)]
3415   "
3416 {
3417   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418                  (operands[3], operands[1]));
3419   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3420                               GEN_INT (56), GEN_INT (8));
3421 }")
3422
3423 (define_insn "rotlsi3_1"
3424   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3425         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3426                    (const_int 1)))
3427    (set (reg:SI T_REG)
3428         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3429   "TARGET_SH1"
3430   "rotl %0"
3431   [(set_attr "type" "arith")])
3432
3433 (define_insn "rotlsi3_31"
3434   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3436                    (const_int 31)))
3437    (clobber (reg:SI T_REG))]
3438   "TARGET_SH1"
3439   "rotr %0"
3440   [(set_attr "type" "arith")])
3441
3442 (define_insn "rotlsi3_16"
3443   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3444         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3445                    (const_int 16)))]
3446   "TARGET_SH1"
3447   "swap.w       %1,%0"
3448   [(set_attr "type" "arith")])
3449
3450 (define_expand "rotlsi3"
3451   [(set (match_operand:SI 0 "arith_reg_dest" "")
3452         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3453                    (match_operand:SI 2 "immediate_operand" "")))]
3454   "TARGET_SH1"
3455   "
3456 {
3457   static const char rot_tab[] = {
3458     000, 000, 000, 000, 000, 000, 010, 001,
3459     001, 001, 011, 013, 003, 003, 003, 003,
3460     003, 003, 003, 003, 003, 013, 012, 002,
3461     002, 002, 010, 000, 000, 000, 000, 000,
3462   };
3463
3464   int count, choice;
3465
3466   if (GET_CODE (operands[2]) != CONST_INT)
3467     FAIL;
3468   count = INTVAL (operands[2]);
3469   choice = rot_tab[count];
3470   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3471     FAIL;
3472   choice &= 7;
3473   switch (choice)
3474     {
3475     case 0:
3476       emit_move_insn (operands[0], operands[1]);
3477       count -= (count & 16) * 2;
3478       break;
3479     case 3:
3480      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3481      count -= 16;
3482      break;
3483     case 1:
3484     case 2:
3485       {
3486         rtx parts[2];
3487         parts[0] = gen_reg_rtx (SImode);
3488         parts[1] = gen_reg_rtx (SImode);
3489         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3490         emit_move_insn (parts[choice-1], operands[1]);
3491         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3492         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3493         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3494         count = (count & ~16) - 8;
3495       }
3496     }
3497
3498   for (; count > 0; count--)
3499     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3500   for (; count < 0; count++)
3501     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3502
3503   DONE;
3504 }")
3505
3506 (define_insn "*rotlhi3_8"
3507   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3508         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3509                    (const_int 8)))]
3510   "TARGET_SH1"
3511   "swap.b       %1,%0"
3512   [(set_attr "type" "arith")])
3513
3514 (define_expand "rotlhi3"
3515   [(set (match_operand:HI 0 "arith_reg_operand" "")
3516         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3517                    (match_operand:HI 2 "immediate_operand" "")))]
3518   "TARGET_SH1"
3519   "
3520 {
3521   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3522     FAIL;
3523 }")
3524
3525 ;;
3526 ;; shift left
3527
3528 (define_insn "ashlsi3_sh2a"
3529   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3532   "TARGET_SH2A"
3533   "shad %2,%0"
3534   [(set_attr "type" "arith")
3535    (set_attr "length" "4")])
3536
3537 ;; This pattern is used by init_expmed for computing the costs of shift
3538 ;; insns.
3539
3540 (define_insn_and_split "ashlsi3_std"
3541   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3542         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3543                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3544    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3545   "TARGET_SH3
3546    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3547   "@
3548    shld %2,%0
3549    add  %0,%0
3550    shll%O2      %0
3551    #"
3552   "TARGET_SH3
3553    && reload_completed
3554    && GET_CODE (operands[2]) == CONST_INT
3555    && ! satisfies_constraint_P27 (operands[2])"
3556   [(set (match_dup 3) (match_dup 2))
3557    (parallel
3558     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3559      (clobber (match_dup 4))])]
3560   "operands[4] = gen_rtx_SCRATCH (SImode);"
3561   [(set_attr "length" "*,*,*,4")
3562    (set_attr "type" "dyn_shift,arith,arith,arith")])
3563
3564 (define_insn "ashlhi3_k"
3565   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3566         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3567                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3568   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3569   "@
3570         add     %0,%0
3571         shll%O2 %0"
3572   [(set_attr "type" "arith")])
3573
3574 (define_insn "ashlsi3_n"
3575   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577                    (match_operand:SI 2 "const_int_operand" "n")))
3578    (clobber (reg:SI T_REG))]
3579   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3580   "#"
3581   [(set (attr "length")
3582         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3583                (const_string "2")
3584                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3585                (const_string "4")
3586                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3587                (const_string "6")]
3588               (const_string "8")))
3589    (set_attr "type" "arith")])
3590
3591 (define_split
3592   [(set (match_operand:SI 0 "arith_reg_dest" "")
3593         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3594                    (match_operand:SI 2 "const_int_operand" "")))
3595    (clobber (reg:SI T_REG))]
3596   "TARGET_SH1 && reload_completed"
3597   [(use (reg:SI R0_REG))]
3598   "
3599 {
3600   gen_shifty_op (ASHIFT, operands);
3601   DONE;
3602 }")
3603
3604 (define_insn "ashlsi3_media"
3605   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3606         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3607                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3608   "TARGET_SHMEDIA"
3609   "@
3610         shlld.l %1, %2, %0
3611         shlli.l %1, %2, %0"
3612   [(set_attr "type" "arith_media")
3613    (set_attr "highpart" "ignore")])
3614
3615 (define_expand "ashlsi3"
3616   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3617                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3618                               (match_operand:SI 2 "nonmemory_operand" "")))
3619               (clobber (reg:SI T_REG))])]
3620   ""
3621   "
3622 {
3623   if (TARGET_SHMEDIA)
3624     {
3625       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3626       DONE;
3627     }
3628   if (GET_CODE (operands[2]) == CONST_INT
3629       && sh_dynamicalize_shift_p (operands[2]))
3630     operands[2] = force_reg (SImode, operands[2]);
3631   if (TARGET_SH3)
3632     {
3633       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3634       DONE;
3635     }
3636   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3637     FAIL;
3638 }")
3639
3640 (define_insn "*ashlhi3_n"
3641   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3642         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3643                    (match_operand:HI 2 "const_int_operand" "n")))
3644    (clobber (reg:SI T_REG))]
3645   "TARGET_SH1"
3646   "#"
3647   [(set (attr "length")
3648         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3649                (const_string "2")
3650                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3651                (const_string "4")]
3652               (const_string "6")))
3653    (set_attr "type" "arith")])
3654
3655 (define_expand "ashlhi3"
3656   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3657                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3658                               (match_operand:SI 2 "nonmemory_operand" "")))
3659               (clobber (reg:SI T_REG))])]
3660   "TARGET_SH1"
3661   "
3662 {
3663   if (GET_CODE (operands[2]) != CONST_INT)
3664     FAIL;
3665   /* It may be possible to call gen_ashlhi3 directly with more generic
3666      operands.  Make sure operands[1] is a HImode register here.  */
3667   if (!arith_reg_operand (operands[1], HImode))
3668     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3669 }")
3670
3671 (define_split
3672   [(set (match_operand:HI 0 "arith_reg_dest" "")
3673         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3674                    (match_operand:HI 2 "const_int_operand" "")))
3675    (clobber (reg:SI T_REG))]
3676   "TARGET_SH1 && reload_completed"
3677   [(use (reg:SI R0_REG))]
3678   "
3679 {
3680   gen_shifty_hi_op (ASHIFT, operands);
3681   DONE;
3682 }")
3683
3684 ;
3685 ; arithmetic shift right
3686 ;
3687
3688 (define_insn "ashrsi3_sh2a"
3689   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692   "TARGET_SH2A"
3693   "shad %2,%0"
3694   [(set_attr "type" "dyn_shift")
3695    (set_attr "length" "4")])
3696
3697 (define_insn "ashrsi3_k"
3698   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3700                      (match_operand:SI 2 "const_int_operand" "M")))
3701    (clobber (reg:SI T_REG))]
3702   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3703   "shar %0"
3704   [(set_attr "type" "arith")])
3705
3706 ;; We can't do HImode right shifts correctly unless we start out with an
3707 ;; explicit zero / sign extension; doing that would result in worse overall
3708 ;; code, so just let the machine independent code widen the mode.
3709 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3710
3711
3712 ;; ??? This should be a define expand.
3713
3714 (define_insn "ashrsi2_16"
3715   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3716         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3717                      (const_int 16)))]
3718   "TARGET_SH1"
3719   "#"
3720   [(set_attr "length" "4")])
3721
3722 (define_split
3723   [(set (match_operand:SI 0 "arith_reg_dest" "")
3724         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3725                      (const_int 16)))]
3726   "TARGET_SH1"
3727   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3728    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3729   "operands[2] = gen_lowpart (HImode, operands[0]);")
3730
3731 ;; ??? This should be a define expand.
3732
3733 (define_insn "ashrsi2_31"
3734   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3736                      (const_int 31)))
3737    (clobber (reg:SI T_REG))]
3738   "TARGET_SH1"
3739   "#"
3740   [(set_attr "length" "4")])
3741
3742 (define_split
3743   [(set (match_operand:SI 0 "arith_reg_dest" "")
3744         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3745                      (const_int 31)))
3746    (clobber (reg:SI T_REG))]
3747   "TARGET_SH1"
3748   [(const_int 0)]
3749   "
3750 {
3751   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3752   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3753   DONE;
3754 }")
3755
3756 (define_peephole2
3757   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3758    (set (reg:SI T_REG)
3759         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3760   "TARGET_SH1
3761    && peep2_reg_dead_p (2, operands[0])
3762    && peep2_reg_dead_p (2, operands[1])"
3763   [(const_int 0)]
3764   "
3765 {
3766   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3767   DONE;
3768 }")
3769
3770 (define_insn "ashlsi_c"
3771   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3773    (set (reg:SI T_REG)
3774         (lt:SI (match_dup 1) (const_int 0)))]
3775   "TARGET_SH1"
3776   "shll %0"
3777   [(set_attr "type" "arith")])
3778
3779 (define_insn "*ashlsi_c_void"
3780   [(set (reg:SI T_REG)
3781         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3782    (clobber (match_scratch:SI 1 "=0"))]
3783   "TARGET_SH1 && cse_not_expected"
3784   "shll %0"
3785   [(set_attr "type" "arith")])
3786
3787 (define_insn "ashrsi3_d"
3788   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3789         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3790                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3791   "TARGET_SH3"
3792   "shad %2,%0"
3793   [(set_attr "type" "dyn_shift")])
3794
3795 (define_insn "ashrsi3_n"
3796   [(set (reg:SI R4_REG)
3797         (ashiftrt:SI (reg:SI R4_REG)
3798                      (match_operand:SI 0 "const_int_operand" "i")))
3799    (clobber (reg:SI T_REG))
3800    (clobber (reg:SI PR_REG))
3801    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3802   "TARGET_SH1"
3803   "jsr  @%1%#"
3804   [(set_attr "type" "sfunc")
3805    (set_attr "needs_delay_slot" "yes")])
3806
3807 (define_insn "ashrsi3_media"
3808   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3809         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3810                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3811   "TARGET_SHMEDIA"
3812   "@
3813         shard.l %1, %2, %0
3814         shari.l %1, %2, %0"
3815   [(set_attr "type" "arith_media")
3816    (set_attr "highpart" "ignore")])
3817
3818 (define_expand "ashrsi3"
3819   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3820                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3821                                 (match_operand:SI 2 "nonmemory_operand" "")))
3822               (clobber (reg:SI T_REG))])]
3823   ""
3824   "
3825 {
3826   if (TARGET_SHMEDIA)
3827     {
3828       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3829       DONE;
3830     }
3831   if (expand_ashiftrt (operands))
3832     DONE;
3833   else
3834     FAIL;
3835 }")
3836
3837 ;; logical shift right
3838
3839 (define_insn "lshrsi3_sh2a"
3840   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3841         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3842                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3843   "TARGET_SH2A"
3844   "shld %2,%0"
3845   [(set_attr "type" "dyn_shift")
3846    (set_attr "length" "4")])
3847
3848 (define_insn "lshrsi3_d"
3849   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3850         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3851                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3852   "TARGET_SH3"
3853   "shld %2,%0"
3854   [(set_attr "type" "dyn_shift")])
3855
3856 ;;  Only the single bit shift clobbers the T bit.
3857
3858 (define_insn "lshrsi3_m"
3859   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3860         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3861                      (match_operand:SI 2 "const_int_operand" "M")))
3862    (clobber (reg:SI T_REG))]
3863   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3864   "shlr %0"
3865   [(set_attr "type" "arith")])
3866
3867 (define_insn "lshrsi3_k"
3868   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3869         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3870                      (match_operand:SI 2 "const_int_operand" "P27")))]
3871   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3872    && ! satisfies_constraint_M (operands[2])"
3873   "shlr%O2      %0"
3874   [(set_attr "type" "arith")])
3875
3876 (define_insn "lshrsi3_n"
3877   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879                      (match_operand:SI 2 "const_int_operand" "n")))
3880    (clobber (reg:SI T_REG))]
3881   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3882   "#"
3883   [(set (attr "length")
3884         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3885                (const_string "2")
3886                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3887                (const_string "4")
3888                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3889                (const_string "6")]
3890               (const_string "8")))
3891    (set_attr "type" "arith")])
3892
3893 (define_split
3894   [(set (match_operand:SI 0 "arith_reg_dest" "")
3895         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3896                      (match_operand:SI 2 "const_int_operand" "")))
3897    (clobber (reg:SI T_REG))]
3898   "TARGET_SH1 && reload_completed"
3899   [(use (reg:SI R0_REG))]
3900   "
3901 {
3902   gen_shifty_op (LSHIFTRT, operands);
3903   DONE;
3904 }")
3905
3906 (define_insn "lshrsi3_media"
3907   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3909                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3910   "TARGET_SHMEDIA"
3911   "@
3912         shlrd.l %1, %2, %0
3913         shlri.l %1, %2, %0"
3914   [(set_attr "type" "arith_media")
3915    (set_attr "highpart" "ignore")])
3916
3917 (define_expand "lshrsi3"
3918   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3919                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3920                                 (match_operand:SI 2 "nonmemory_operand" "")))
3921               (clobber (reg:SI T_REG))])]
3922   ""
3923   "
3924 {
3925   if (TARGET_SHMEDIA)
3926     {
3927       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3928       DONE;
3929     }
3930   if (GET_CODE (operands[2]) == CONST_INT
3931       && sh_dynamicalize_shift_p (operands[2]))
3932     operands[2] = force_reg (SImode, operands[2]);
3933   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3934     {
3935       rtx count = copy_to_mode_reg (SImode, operands[2]);
3936       emit_insn (gen_negsi2 (count, count));
3937       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3938       DONE;
3939     }
3940   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3941     FAIL;
3942 }")
3943
3944 ;; ??? This should be a define expand.
3945
3946 (define_insn "ashldi3_k"
3947   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3949                    (const_int 1)))
3950    (clobber (reg:SI T_REG))]
3951   "TARGET_SH1"
3952   "shll %R0\;rotcl      %S0"
3953   [(set_attr "length" "4")
3954    (set_attr "type" "arith")])
3955
3956 (define_insn "ashldi3_media"
3957   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3958         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3960   "TARGET_SHMEDIA"
3961   "@
3962         shlld   %1, %2, %0
3963         shlli   %1, %2, %0"
3964   [(set_attr "type" "arith_media")])
3965
3966 (define_insn "*ashldisi3_media"
3967   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3968         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3969                    (match_operand:DI 2 "const_int_operand" "n")))]
3970   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3971   "shlli.l      %1, %2, %0"
3972   [(set_attr "type" "arith_media")
3973    (set_attr "highpart" "ignore")])
3974
3975 (define_expand "ashldi3"
3976   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3977                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3978                               (match_operand:DI 2 "immediate_operand" "")))
3979               (clobber (reg:SI T_REG))])]
3980   ""
3981   "
3982 {
3983   if (TARGET_SHMEDIA)
3984     {
3985       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3986       DONE;
3987     }
3988   if (GET_CODE (operands[2]) != CONST_INT
3989       || INTVAL (operands[2]) != 1)
3990     FAIL;
3991 }")
3992
3993 ;; ??? This should be a define expand.
3994
3995 (define_insn "lshrdi3_k"
3996   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3997         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3998                      (const_int 1)))
3999    (clobber (reg:SI T_REG))]
4000   "TARGET_SH1"
4001   "shlr %S0\;rotcr      %R0"
4002   [(set_attr "length" "4")
4003    (set_attr "type" "arith")])
4004
4005 (define_insn "lshrdi3_media"
4006   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4007         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4008                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4009   "TARGET_SHMEDIA
4010    && (arith_reg_dest (operands[0], DImode)
4011        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4012   "@
4013         shlrd   %1, %2, %0
4014         shlri   %1, %2, %0"
4015   [(set_attr "type" "arith_media")])
4016
4017 (define_insn "*lshrdisi3_media"
4018   [(set (subreg:DI (match_operand:SI 0