OSDN Git Service

f62b3b9594af07775a8bb791e9bf234a6069acb1
[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 3, 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 COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
26
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
29
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
31
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
34
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
37
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
42 ;; Special constraints for SH machine description:
43 ;;
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
48 ;;
49 ;; Special formats used for outputting SH instructions:
50 ;;
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
58 ;;
59 ;; Special predicates:
60 ;;
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
66
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
70
71 (define_constants [
72   (AP_REG       145)
73   (PR_REG       146)
74   (T_REG        147)
75   (GBR_REG      144)
76   (MACH_REG     148)
77   (MACL_REG     149)
78   (FPUL_REG     150)
79   (RAP_REG      152)
80
81   (FPSCR_REG    151)
82
83   (PIC_REG      12)
84   (FP_REG       14)
85   (SP_REG       15)
86
87   (PR_MEDIA_REG 18)
88   (T_MEDIA_REG  19)
89
90   (R0_REG       0)
91   (R1_REG       1)
92   (R2_REG       2)
93   (R3_REG       3)
94   (R4_REG       4)
95   (R5_REG       5)
96   (R6_REG       6)
97   (R7_REG       7)
98   (R8_REG       8)
99   (R9_REG       9)
100   (R10_REG      10)
101   (R20_REG      20)
102   (R21_REG      21)
103   (R22_REG      22)
104   (R23_REG      23)
105
106   (DR0_REG      64)
107   (DR2_REG      66)
108   (DR4_REG      68)
109   (FR23_REG     87)
110
111   (TR0_REG      128)
112   (TR1_REG      129)
113   (TR2_REG      130)
114
115   (XD0_REG      136)
116
117   ;; These are used with unspec.
118   (UNSPEC_COMPACT_ARGS  0)
119   (UNSPEC_MOVA          1)
120   (UNSPEC_CASESI        2)
121   (UNSPEC_DATALABEL     3)
122   (UNSPEC_BBR           4)
123   (UNSPEC_SFUNC         5)
124   (UNSPEC_PIC           6)
125   (UNSPEC_GOT           7)
126   (UNSPEC_GOTOFF        8)
127   (UNSPEC_PLT           9)
128   (UNSPEC_CALLER        10)
129   (UNSPEC_GOTPLT        11)
130   (UNSPEC_ICACHE        12)
131   (UNSPEC_INIT_TRAMP    13)
132   (UNSPEC_FCOSA         14)
133   (UNSPEC_FSRRA         15)
134   (UNSPEC_FSINA         16)
135   (UNSPEC_NSB           17)
136   (UNSPEC_ALLOCO        18)
137   (UNSPEC_TLSGD         20)
138   (UNSPEC_TLSLDM        21)
139   (UNSPEC_TLSIE         22)
140   (UNSPEC_DTPOFF        23)
141   (UNSPEC_GOTTPOFF      24)
142   (UNSPEC_TPOFF         25)
143   (UNSPEC_RA            26)
144   (UNSPEC_DIV_INV_M0    30)
145   (UNSPEC_DIV_INV_M1    31)
146   (UNSPEC_DIV_INV_M2    32)
147   (UNSPEC_DIV_INV_M3    33)
148   (UNSPEC_DIV_INV20     34)
149   (UNSPEC_DIV_INV_TABLE 37)
150   (UNSPEC_ASHIFTRT      35)
151   (UNSPEC_THUNK         36)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
155
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
164   (UNSPECV_EH_RETURN    12)
165 ])
166
167 ;; -------------------------------------------------------------------------
168 ;; Attributes
169 ;; -------------------------------------------------------------------------
170
171 ;; Target CPU.
172
173 (define_attr "cpu"
174  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175   (const (symbol_ref "sh_cpu_attr")))
176
177 (define_attr "endian" "big,little"
178  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179                       (const_string "little") (const_string "big"))))
180
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184                          (const_string "yes") (const_string "no"))))
185
186 (define_attr "fmovd" "yes,no"
187   (const (if_then_else (symbol_ref "TARGET_FMOVD")
188                        (const_string "yes") (const_string "no"))))
189 ;; pipeline model
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
191   (const
192    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194          (const_string "sh1"))))
195
196 ;; cbranch      conditional branch instructions
197 ;; jump         unconditional jumps
198 ;; arith        ordinary arithmetic
199 ;; arith3       a compound insn that behaves similarly to a sequence of
200 ;;              three insns of type arith
201 ;; arith3b      like above, but might end with a redirected branch
202 ;; load         from memory
203 ;; load_si      Likewise, SImode variant for general register.
204 ;; fload        Likewise, but load to fp register.
205 ;; store        to memory
206 ;; fstore       floating point register to memory
207 ;; move         general purpose register to register
208 ;; movi8        8-bit immediate to general purpose register
209 ;; mt_group     other sh4 mt instructions
210 ;; fmove        register to register, floating point
211 ;; smpy         word precision integer multiply
212 ;; dmpy         longword or doublelongword precision integer multiply
213 ;; return       rts
214 ;; pload        load of pr reg, which can't be put into delay slot of rts
215 ;; prset        copy register to pr reg, ditto
216 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
217 ;; prget        copy pr to register, ditto
218 ;; pcload       pc relative load of constant value
219 ;; pcfload      Likewise, but load to fp register.
220 ;; pcload_si    Likewise, SImode variant for general register.
221 ;; rte          return from exception
222 ;; sfunc        special function call with known used registers
223 ;; call         function call
224 ;; fp           floating point
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv         floating point divide (or square root)
227 ;; gp_fpul      move from general purpose register to fpul
228 ;; fpul_gp      move from fpul to general purpose register
229 ;; mac_gp       move from mac[lh] to general purpose register
230 ;; gp_mac       move from general purpose register to mac[lh]
231 ;; mac_mem      move from mac[lh] to memory
232 ;; mem_mac      move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s       fix_truncsfsi2_i4
235 ;; dfdiv        double precision floating point divide (or square root)
236 ;; cwb          ic_invalidate_line_i
237 ;; movua        SH4a unaligned load
238 ;; fsrra        square root reciprocal approximate
239 ;; fsca         sine and cosine approximate
240 ;; tls_load     load TLS related address
241 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media    SHmedia compare instructions
244 ;; dfdiv_media  SHmedia double precision divide and square root
245 ;; dfmul_media  SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media   SHmedia longword multiply
249 ;; fcmp_media   SHmedia floating point compare instructions
250 ;; fdiv_media   SHmedia single precision divide and square root
251 ;; fload_media  SHmedia floating point register load instructions
252 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media  SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media   SHmedia unconditional branch instructions
259 ;; load_media   SHmedia general register load instructions
260 ;; pt_media     SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media  SHmedia ptabs instruction
262 ;; store_media  SHmedia general register store instructions
263 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media    SHmedia mac-style fixed point operations
265 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil          no-op move, will be deleted.
269
270 (define_attr "type"
271  "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"
272   (const_string "other"))
273
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
276 ;;
277 ;; mt_group      SH4 "mt" group instructions.
278 ;;
279 ;; ex_group      SH4 "ex" group instructions.
280 ;;
281 ;; ls_group      SH4 "ls" group instructions.
282 ;;
283
284 (define_attr "insn_class"
285   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289          (eq_attr "type" "cbranch,jump") (const_string "br_group")
290          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291            (const_string "fe_group")
292          (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")]
293         (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
297
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
299
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
301
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
305 ;; state.
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
309
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long.  Something in the
312 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
315 ; 2 bytes.
316
317 ;; The maximum range used for SImode constant pool entries is 1018.  A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table.  That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
329 ;;
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
332
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
334 ;; inside an le.
335 (define_attr "short_cbranch_p" "no,yes"
336   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
337          (const_string "no")
338          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
339          (const_string "yes")
340          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
341          (const_string "no")
342          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
343          (const_string "yes")
344          ] (const_string "no")))
345
346 (define_attr "med_branch_p" "no,yes"
347   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
348               (const_int 1988))
349          (const_string "yes")
350          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
351          (const_string "no")
352          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
353               (const_int 8186))
354          (const_string "yes")
355          ] (const_string "no")))
356
357 (define_attr "med_cbranch_p" "no,yes"
358   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
359               (const_int 1986))
360          (const_string "yes")
361          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
364                (const_int 8184))
365          (const_string "yes")
366          ] (const_string "no")))
367
368 (define_attr "braf_branch_p" "no,yes"
369   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
370          (const_string "no")
371          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
372               (const_int 20660))
373          (const_string "yes")
374          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
377               (const_int 65530))
378          (const_string "yes")
379          ] (const_string "no")))
380
381 (define_attr "braf_cbranch_p" "no,yes"
382   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
385               (const_int 20658))
386          (const_string "yes")
387          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
390               (const_int 65528))
391          (const_string "yes")
392          ] (const_string "no")))
393
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
400
401 ; All other instructions are two bytes long by default.
402
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406   (cond [(eq_attr "type" "cbranch")
407          (cond [(eq_attr "short_cbranch_p" "yes")
408                 (const_int 2)
409                 (eq_attr "med_cbranch_p" "yes")
410                 (const_int 6)
411                 (eq_attr "braf_cbranch_p" "yes")
412                 (const_int 12)
413 ;; ??? using pc is not computed transitively.
414                 (ne (match_dup 0) (match_dup 0))
415                 (const_int 14)
416                 (ne (symbol_ref ("flag_pic")) (const_int 0))
417                 (const_int 24)
418                 ] (const_int 16))
419          (eq_attr "type" "jump")
420          (cond [(eq_attr "med_branch_p" "yes")
421                 (const_int 2)
422                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
423                          (const_int 0))
424                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
425                               (symbol_ref "INSN"))
426                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427                               (symbol_ref "code_for_indirect_jump_scratch"))))
428                 (cond [(eq_attr "braf_branch_p" "yes")
429                        (const_int 6)
430                        (eq (symbol_ref "flag_pic") (const_int 0))
431                        (const_int 10)
432                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
433                        (const_int 10)] (const_int 18))
434                 (eq_attr "braf_branch_p" "yes")
435                 (const_int 10)
436 ;; ??? using pc is not computed transitively.
437                 (ne (match_dup 0) (match_dup 0))
438                 (const_int 12)
439                 (ne (symbol_ref ("flag_pic")) (const_int 0))
440                 (const_int 22)
441                 ] (const_int 14))
442          (eq_attr "type" "pt_media")
443          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444                        (const_int 20) (const_int 12))
445          (and (eq_attr "type" "jump_media")
446               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
447          (const_int 8)
448          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
449                          (const_int 4)
450                          (const_int 2))))
451
452 ;; DFA descriptions for the pipelines
453
454 (include "sh1.md")
455 (include "shmedia.md")
456 (include "sh4.md")
457
458 (include "predicates.md")
459 (include "constraints.md")
460
461 ;; Definitions for filling delay slots
462
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
464
465 (define_attr "banked" "yes,no" 
466         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
467                    (const_int 1))
468                (const_string "yes")]
469               (const_string "no")))
470
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
474                    (const_int 0))
475                (const_string "no")]
476               (const_string "yes")))
477
478 (define_attr "interrupt_function" "no,yes"
479   (const (symbol_ref "current_function_interrupt")))
480
481 (define_attr "in_delay_slot" "yes,no"
482   (cond [(eq_attr "type" "cbranch") (const_string "no")
483          (eq_attr "type" "pcload,pcload_si") (const_string "no")
484          (eq_attr "needs_delay_slot" "yes") (const_string "no")
485          (eq_attr "length" "2") (const_string "yes")
486          ] (const_string "no")))
487
488 (define_attr "cond_delay_slot" "yes,no"
489   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490          ] (const_string "no")))
491
492 (define_attr "is_sfunc" ""
493   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
494
495 (define_attr "is_mac_media" ""
496   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
497
498 (define_attr "branch_zero" "yes,no"
499   (cond [(eq_attr "type" "!cbranch") (const_string "no")
500          (ne (symbol_ref "(next_active_insn (insn)\
501                            == (prev_active_insn\
502                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503                           && get_attr_length (next_active_insn (insn)) == 2")
504              (const_int 0))
505          (const_string "yes")]
506         (const_string "no")))
507
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512         (const_string "no")))
513
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519          (const_string "yes")]
520         (const_string "no")))
521
522 (define_attr "any_int_load" "yes,no"
523   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524          (const_string "yes")]
525         (const_string "no")))
526
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528   (const_string "user"))
529
530 (define_delay
531   (eq_attr "needs_delay_slot" "yes")
532   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
533
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
538
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
541
542 (define_delay
543   (eq_attr "type" "return")
544   [(and (eq_attr "in_delay_slot" "yes")
545         (ior (and (eq_attr "interrupt_function" "no")
546                   (eq_attr "type" "!pload,prset"))
547              (and (eq_attr "interrupt_function" "yes")
548                   (ior
549                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
550                    (eq_attr "hit_stack" "no")
551                    (eq_attr "banked" "no"))))) (nil) (nil)])
552
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
555
556 (define_delay
557   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558   [(and (eq_attr "in_delay_slot" "yes")
559         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
560
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
563
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
567
568 (define_delay
569   (and (eq_attr "type" "cbranch")
570        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571   ;; SH2e has a hardware bug that pretty much prohibits the use of
572   ;; annuled delay slots.
573   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
575 \f
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
579
580 (define_insn ""
581   [(set (reg:SI T_REG)
582         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583                        (match_operand:SI 1 "arith_operand" "K08,r"))
584                (const_int 0)))]
585   "TARGET_SH1"
586   "tst  %1,%0"
587   [(set_attr "type" "mt_group")])
588
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
594
595 (define_insn "cmpeqsi_t"
596   [(set (reg:SI T_REG)
597         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
599   "TARGET_SH1"
600   "@
601         tst     %0,%0
602         cmp/eq  %1,%0
603         cmp/eq  %1,%0"
604    [(set_attr "type" "mt_group")])
605
606 (define_insn "cmpgtsi_t"
607   [(set (reg:SI T_REG)
608         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
610   "TARGET_SH1"
611   "@
612         cmp/gt  %1,%0
613         cmp/pl  %0"
614    [(set_attr "type" "mt_group")])
615
616 (define_insn "cmpgesi_t"
617   [(set (reg:SI T_REG)
618         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
620   "TARGET_SH1"
621   "@
622         cmp/ge  %1,%0
623         cmp/pz  %0"
624    [(set_attr "type" "mt_group")])
625
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
629
630 (define_expand "cbranchsi4"
631   [(set (pc)
632         (if_then_else (match_operator 0 "comparison_operator"
633                         [(match_operand:SI 1 "arith_operand" "")
634                          (match_operand:SI 2 "arith_operand" "")])
635                       (label_ref (match_operand 3 "" ""))
636                       (pc)))
637    (clobber (reg:SI T_REG))]
638   "TARGET_CBRANCHDI4"
639   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
640
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
644
645 (define_insn_and_split "cmpgeusi_t"
646   [(set (reg:SI T_REG)
647         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
649   "TARGET_SH1"
650   "cmp/hs       %1,%0"
651   "&& operands[1] == CONST0_RTX (SImode)"
652   [(pc)]
653   "
654 {
655   emit_insn (gen_sett ());
656   DONE;
657 }"
658    [(set_attr "type" "mt_group")])
659
660 (define_insn "cmpgtusi_t"
661   [(set (reg:SI T_REG)
662         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663                 (match_operand:SI 1 "arith_reg_operand" "r")))]
664   "TARGET_SH1"
665   "cmp/hi       %1,%0"
666    [(set_attr "type" "mt_group")])
667
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
670
671 (define_expand "cmpsi"
672   [(set (reg:SI T_REG)
673         (compare (match_operand:SI 0 "cmpsi_operand" "")
674                  (match_operand:SI 1 "arith_operand" "")))]
675   "TARGET_SH1 || TARGET_SHMEDIA"
676   "
677 {
678   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679       && GET_CODE (operands[1]) != CONST_INT)
680     operands[0] = copy_to_mode_reg (SImode, operands[0]);
681   sh_compare_op0 = operands[0];
682   sh_compare_op1 = operands[1];
683   DONE;
684 }")
685 \f
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
689
690
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
695
696 (define_expand "cbranchdi4"
697   [(set (pc)
698         (if_then_else (match_operator 0 "comparison_operator"
699                         [(match_operand:DI 1 "arith_operand" "")
700                          (match_operand:DI 2 "arith_operand" "")])
701                       (label_ref (match_operand 3 "" ""))
702                       (pc)))
703    (clobber (match_dup 4))
704    (clobber (reg:SI T_REG))]
705   "TARGET_CBRANCHDI4"
706   "
707 {
708   enum rtx_code comparison;
709
710   if (TARGET_EXPAND_CBRANCHDI4)
711     {
712       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
713         DONE;
714     }
715   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716   if (comparison != GET_CODE (operands[0]))
717     operands[0]
718       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719    operands[4] = gen_rtx_SCRATCH (SImode);
720 }")
721
722 (define_insn_and_split "cbranchdi4_i"
723   [(set (pc)
724         (if_then_else (match_operator 0 "comparison_operator"
725                         [(match_operand:DI 1 "arith_operand" "r,r")
726                          (match_operand:DI 2 "arith_operand" "rN,i")])
727                       (label_ref (match_operand 3 "" ""))
728                       (pc)))
729    (clobber (match_scratch:SI 4 "=X,&r"))
730    (clobber (reg:SI T_REG))]
731   "TARGET_CBRANCHDI4"
732   "#"
733   "&& reload_completed"
734   [(pc)]
735   "
736 {
737   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
738     FAIL;
739   DONE;
740 }")
741
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
745
746 (define_insn ""
747   [(set (reg:SI T_REG)
748         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749                        (match_operand:DI 1 "arith_operand" "r"))
750                (const_int 0)))]
751   "TARGET_SH1"
752   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
753                                  insn, operands);"
754   [(set_attr "length" "6")
755    (set_attr "type" "arith3b")])
756
757 (define_insn "cmpeqdi_t"
758   [(set (reg:SI T_REG)
759         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
761   "TARGET_SH1"
762   "@
763         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
764         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765   [(set_attr "length" "6")
766    (set_attr "type" "arith3b")])
767
768 (define_split
769   [(set (reg:SI T_REG)
770         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
774 ;; may be created.
775   "TARGET_SH1 && reload_completed && optimize"
776   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778                            (label_ref (match_dup 6))
779                            (pc)))
780    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
781    (match_dup 6)]
782   "
783 {
784   operands[2]
785     = gen_rtx_REG (SImode,
786                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
787   operands[3]
788     = (operands[1] == const0_rtx
789        ? const0_rtx
790        : gen_rtx_REG (SImode,
791                       true_regnum (operands[1])
792                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793   operands[4] = gen_lowpart (SImode, operands[0]);
794   operands[5] = gen_lowpart (SImode, operands[1]);
795   operands[6] = gen_label_rtx ();
796 }")
797
798 (define_insn "cmpgtdi_t"
799   [(set (reg:SI T_REG)
800         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
802   "TARGET_SH2"
803   "@
804         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806   [(set_attr "length" "8")
807    (set_attr "type" "arith3")])
808
809 (define_insn "cmpgedi_t"
810   [(set (reg:SI T_REG)
811         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
813   "TARGET_SH2"
814   "@
815         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
816         cmp/pz\\t%S0"
817   [(set_attr "length" "8,2")
818    (set_attr "type" "arith3,mt_group")])
819 \f
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
823
824 (define_insn "cmpgeudi_t"
825   [(set (reg:SI T_REG)
826         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827                 (match_operand:DI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH2"
829   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830   [(set_attr "length" "8")
831    (set_attr "type" "arith3")])
832
833 (define_insn "cmpgtudi_t"
834   [(set (reg:SI T_REG)
835         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836                 (match_operand:DI 1 "arith_reg_operand" "r")))]
837   "TARGET_SH2"
838   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839   [(set_attr "length" "8")
840    (set_attr "type" "arith3")])
841
842 (define_insn "cmpeqsi_media"
843   [(set (match_operand:SI 0 "register_operand" "=r")
844         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845                (match_operand:SI 2 "cmp_operand" "Nr")))]
846   "TARGET_SHMEDIA"
847   "cmpeq        %1, %N2, %0"
848   [(set_attr "type" "cmp_media")])
849
850 (define_insn "cmpeqdi_media"
851   [(set (match_operand:SI 0 "register_operand" "=r")
852         (eq:SI (match_operand:DI 1 "register_operand" "%r")
853                (match_operand:DI 2 "cmp_operand" "Nr")))]
854   "TARGET_SHMEDIA"
855   "cmpeq        %1, %N2, %0"
856   [(set_attr "type" "cmp_media")])
857
858 (define_insn "cmpgtsi_media"
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861                (match_operand:SI 2 "cmp_operand" "rN")))]
862   "TARGET_SHMEDIA"
863   "cmpgt        %N1, %N2, %0"
864   [(set_attr "type" "cmp_media")])
865
866 (define_insn "cmpgtdi_media"
867   [(set (match_operand:SI 0 "register_operand" "=r")
868         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
870   "TARGET_SHMEDIA"
871   "cmpgt        %N1, %N2, %0"
872   [(set_attr "type" "cmp_media")])
873
874 (define_insn "cmpgtusi_media"
875   [(set (match_operand:SI 0 "register_operand" "=r")
876         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877                 (match_operand:SI 2 "cmp_operand" "rN")))]
878   "TARGET_SHMEDIA"
879   "cmpgtu       %N1, %N2, %0"
880   [(set_attr "type" "cmp_media")])
881
882 (define_insn "cmpgtudi_media"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886   "TARGET_SHMEDIA"
887   "cmpgtu       %N1, %N2, %0"
888   [(set_attr "type" "cmp_media")])
889
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
894   "TARGET_SHMEDIA"
895   "cmpgtu       %1,r63,%0"
896   [(set_attr "type" "cmp_media")])
897
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
900
901 (define_expand "cmpdi"
902   [(set (reg:SI T_REG)
903         (compare (match_operand:DI 0 "arith_operand" "")
904                  (match_operand:DI 1 "arith_operand" "")))]
905   "TARGET_SH2 || TARGET_SHMEDIA"
906   "
907 {
908   sh_compare_op0 = operands[0];
909   sh_compare_op1 = operands[1];
910   DONE;
911 }")
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
915
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
918
919 (define_insn "movdicc_false"
920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
922                              (const_int 0))
923          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924          (match_operand:DI 3 "arith_reg_operand" "0")))]
925   "TARGET_SHMEDIA"
926   "cmveq        %1, %N2, %0"
927   [(set_attr "type" "arith_media")])
928
929 (define_insn "movdicc_true"
930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
932                              (const_int 0))
933          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934          (match_operand:DI 3 "arith_reg_operand" "0")))]
935   "TARGET_SHMEDIA"
936   "cmvne        %1, %N2, %0"
937   [(set_attr "type" "arith_media")])
938
939 (define_peephole2
940   [(set (match_operand:DI 0 "arith_reg_dest" "")
941         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942                            [(match_operand:DI 1 "arith_reg_operand" "")
943                             (const_int 0)])
944          (match_operand:DI 2 "arith_reg_dest" "")
945          (match_dup 0)))
946    (set (match_dup 2) (match_dup 0))]
947   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
948   [(set (match_dup 2)
949         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
950   "
951 {
952   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953                                 VOIDmode, operands[1], CONST0_RTX (DImode));
954 }")
955
956 (define_peephole2
957   [(set (match_operand:DI 0 "general_movdst_operand" "")
958         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959    (set (match_operand:DI 2 "arith_reg_dest" "")
960         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961                            [(match_operand:DI 3 "arith_reg_operand" "")
962                             (const_int 0)])
963          (match_dup 0)
964          (match_dup 2)))]
965   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
966   [(set (match_dup 2)
967         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
968   "")
969
970 (define_expand "movdicc"
971   [(set (match_operand:DI 0 "register_operand" "")
972         (if_then_else:DI (match_operand 1 "comparison_operator" "")
973                          (match_operand:DI 2 "register_operand" "")
974                          (match_operand:DI 3 "register_operand" "")))]
975   "TARGET_SHMEDIA"
976   "
977 {
978   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979       && GET_MODE (sh_compare_op0) == DImode
980       && sh_compare_op1 == const0_rtx)
981     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982                                   sh_compare_op0, sh_compare_op1);
983   else
984     {
985       rtx tmp;
986
987       if (!can_create_pseudo_p ())
988         FAIL;
989
990       tmp = gen_reg_rtx (DImode);
991
992       switch (GET_CODE (operands[1]))
993         {
994         case EQ:
995           emit_insn (gen_seq (tmp));
996           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997           break;
998
999         case NE:
1000           emit_insn (gen_seq (tmp));
1001           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002           break;
1003
1004         case GT:
1005           emit_insn (gen_sgt (tmp));
1006           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1007           break;
1008
1009         case LT:
1010           emit_insn (gen_slt (tmp));
1011           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012           break;
1013
1014         case GE:
1015           emit_insn (gen_slt (tmp));
1016           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1017           break;
1018
1019         case LE:
1020           emit_insn (gen_sgt (tmp));
1021           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1022           break;
1023
1024         case GTU:
1025           emit_insn (gen_sgtu (tmp));
1026           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1027           break;
1028
1029         case LTU:
1030           emit_insn (gen_sltu (tmp));
1031           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1032           break;
1033
1034         case GEU:
1035           emit_insn (gen_sltu (tmp));
1036           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1037           break;
1038
1039         case LEU:
1040           emit_insn (gen_sgtu (tmp));
1041           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1042           break;
1043
1044         case UNORDERED:
1045           emit_insn (gen_sunordered (tmp));
1046           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1047           break;
1048
1049         case ORDERED:
1050           emit_insn (gen_sunordered (tmp));
1051           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1052           break;
1053
1054         case UNEQ:
1055         case UNGE:
1056         case UNGT:
1057         case UNLE:
1058         case UNLT:
1059         case LTGT:
1060           FAIL;
1061
1062         default:
1063           gcc_unreachable ();
1064         }
1065     }
1066 }")
1067
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1073                           (const_int 0))
1074          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075          (match_operand:SI 3 "arith_reg_operand" "0")))]
1076   "TARGET_SHMEDIA"
1077   "cmveq        %1, %N2, %0"
1078   [(set_attr "type" "arith_media")])
1079
1080 (define_insn "movsicc_true"
1081   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1083                           (const_int 0))
1084          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085          (match_operand:SI 3 "arith_reg_operand" "0")))]
1086   "TARGET_SHMEDIA"
1087   "cmvne        %1, %N2, %0"
1088   [(set_attr "type" "arith_media")])
1089
1090 (define_peephole2
1091   [(set (match_operand:SI 0 "arith_reg_dest" "")
1092         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093                            [(match_operand:SI 1 "arith_reg_operand" "")
1094                             (const_int 0)])
1095          (match_operand:SI 2 "arith_reg_dest" "")
1096          (match_dup 0)))
1097    (set (match_dup 2) (match_dup 0))]
1098   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1099   [(set (match_dup 2)
1100         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1101   "
1102 {
1103   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1105 }")
1106
1107 (define_peephole2
1108   [(set (match_operand:SI 0 "general_movdst_operand" "")
1109         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110    (set (match_operand:SI 2 "arith_reg_dest" "")
1111         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112                            [(match_operand:SI 3 "arith_reg_operand" "")
1113                             (const_int 0)])
1114          (match_dup 0)
1115          (match_dup 2)))]
1116   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1118   [(set (match_dup 2)
1119         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1120   "
1121 {
1122   replace_rtx (operands[4], operands[0], operands[1]);
1123 }")
1124
1125 (define_peephole2
1126   [(set (match_operand 0 "any_register_operand" "")
1127         (match_operand 1 "any_register_operand" ""))
1128    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138    && (REGNO_REG_CLASS (REGNO (operands[0]))
1139        == REGNO_REG_CLASS (REGNO (operands[2])))
1140    && (REGNO_REG_CLASS (REGNO (operands[1]))
1141        == REGNO_REG_CLASS (REGNO (operands[0])))"
1142   [(set (match_dup 0) (match_dup 3))
1143    (set (match_dup 4) (match_dup 5))]
1144   "
1145 {
1146   rtx set1, set2;
1147   rtx replacements[4];
1148
1149   /* We want to replace occurrences of operands[0] with operands[1] and
1150      operands[2] with operands[0] in operands[4]/operands[5].
1151      Doing just two replace_rtx calls naively would result in the second
1152      replacement undoing all that the first did if operands[1] and operands[2]
1153      are identical, so we must do this simultaneously.  */
1154   replacements[0] = operands[0];
1155   replacements[1] = operands[1];
1156   replacements[2] = operands[2];
1157   replacements[3] = operands[0];
1158   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1161     FAIL;
1162
1163   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166   /* The operands array is aliased to recog_data.operand, which gets
1167      clobbered by extract_insn, so finish with it now.  */
1168   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171      always uses emit_insn.  */
1172   /* Check that we don't violate matching constraints or earlyclobbers.  */
1173   extract_insn (emit_insn (set1));
1174   if (! constrain_operands (1))
1175     goto failure;
1176   extract_insn (emit (set2));
1177   if (! constrain_operands (1))
1178     {
1179       rtx tmp;
1180     failure:
1181       tmp = replacements[0];
1182       replacements[0] = replacements[1];
1183       replacements[1] = tmp;
1184       tmp = replacements[2];
1185       replacements[2] = replacements[3];
1186       replacements[3] = tmp;
1187       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1188       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1189       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1190       FAIL;
1191     }
1192   DONE;
1193 }")
1194
1195 ;; The register allocator is rather clumsy in handling multi-way conditional
1196 ;; moves, so allow the combiner to make them, and we split them up after
1197 ;; reload.  */
1198 (define_insn_and_split "*movsicc_umin"
1199   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1200         (umin:SI (if_then_else:SI
1201                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1202                        (const_int 0))
1203                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1204                    (match_operand:SI 3 "register_operand" "0"))
1205                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1206    (clobber (match_scratch:SI 5 "=&r"))]
1207   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1208   "#"
1209   "TARGET_SHMEDIA && reload_completed"
1210   [(pc)]
1211   "
1212 {
1213   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1214                                 operands[3]));
1215   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1216   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1217                                 operands[0]));
1218   DONE;
1219 }")
1220
1221 (define_insn "*movsicc_t_false"
1222   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1223         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1224                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1225                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1226   "TARGET_PRETEND_CMOVE
1227    && (arith_reg_operand (operands[1], SImode)
1228        || (immediate_operand (operands[1], SImode)
1229            && satisfies_constraint_I08 (operands[1])))"
1230   "bt 0f\;mov %1,%0\\n0:"
1231   [(set_attr "type" "mt_group,arith") ;; poor approximation
1232    (set_attr "length" "4")])
1233
1234 (define_insn "*movsicc_t_true"
1235   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1236         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1237                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1238                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1239   "TARGET_PRETEND_CMOVE
1240    && (arith_reg_operand (operands[1], SImode)
1241        || (immediate_operand (operands[1], SImode)
1242            && satisfies_constraint_I08 (operands[1])))"
1243   "bf 0f\;mov %1,%0\\n0:"
1244   [(set_attr "type" "mt_group,arith") ;; poor approximation
1245    (set_attr "length" "4")])
1246
1247 (define_expand "movsicc"
1248   [(set (match_operand:SI 0 "arith_reg_dest" "")
1249         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1250                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1251                          (match_operand:SI 3 "arith_reg_operand" "")))]
1252   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1253   "
1254 {
1255   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1256       && GET_MODE (sh_compare_op0) == SImode
1257       && (TARGET_SHMEDIA
1258           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1259       && sh_compare_op1 == const0_rtx)
1260     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1261                                   sh_compare_op0, sh_compare_op1);
1262   else if (TARGET_PRETEND_CMOVE)
1263     {
1264       enum rtx_code code = GET_CODE (operands[1]);
1265       enum rtx_code new_code = code;
1266       rtx tmp;
1267
1268       if (! currently_expanding_to_rtl)
1269         FAIL;
1270       switch (code)
1271         {
1272         case LT: case LE: case LEU: case LTU:
1273           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1274             break;
1275         case NE:
1276           new_code = reverse_condition (code);
1277           break;
1278         case EQ: case GT: case GE: case GEU: case GTU:
1279           break;
1280         default:
1281           FAIL;
1282         }
1283       tmp = prepare_scc_operands (new_code);
1284       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1285                                     tmp, const0_rtx);
1286     }
1287   else
1288     {
1289       rtx tmp;
1290
1291       if (!can_create_pseudo_p ())
1292         FAIL;
1293
1294       tmp = gen_reg_rtx (SImode);
1295
1296       switch (GET_CODE (operands[1]))
1297         {
1298         case EQ:
1299           emit_insn (gen_seq (tmp));
1300           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1301           break;
1302
1303         case NE:
1304           emit_insn (gen_seq (tmp));
1305           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1306           break;
1307
1308         case GT:
1309           emit_insn (gen_sgt (tmp));
1310           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1311           break;
1312
1313         case LT:
1314           emit_insn (gen_slt (tmp));
1315           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1316           break;
1317
1318         case GE:
1319           emit_insn (gen_slt (tmp));
1320           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1321           break;
1322
1323         case LE:
1324           emit_insn (gen_sgt (tmp));
1325           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1326           break;
1327
1328         case GTU:
1329           emit_insn (gen_sgtu (tmp));
1330           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1331           break;
1332
1333         case LTU:
1334           emit_insn (gen_sltu (tmp));
1335           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1336           break;
1337
1338         case GEU:
1339           emit_insn (gen_sltu (tmp));
1340           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1341           break;
1342
1343         case LEU:
1344           emit_insn (gen_sgtu (tmp));
1345           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1346           break;
1347
1348         case UNORDERED:
1349           emit_insn (gen_sunordered (tmp));
1350           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1351           break;
1352
1353         case ORDERED:
1354           emit_insn (gen_sunordered (tmp));
1355           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1356           break;
1357
1358         case UNEQ:
1359         case UNGE:
1360         case UNGT:
1361         case UNLE:
1362         case UNLT:
1363         case LTGT:
1364           FAIL;
1365
1366         default:
1367           abort ();
1368         }
1369     }
1370 }")
1371
1372 (define_expand "movqicc"
1373   [(set (match_operand:QI 0 "register_operand" "")
1374         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375                          (match_operand:QI 2 "register_operand" "")
1376                          (match_operand:QI 3 "register_operand" "")))]
1377   "TARGET_SHMEDIA"
1378   "
1379 {
1380   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1381   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1382   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1383   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1384   DONE;
1385 }")
1386 \f
1387 ;; -------------------------------------------------------------------------
1388 ;; Addition instructions
1389 ;; -------------------------------------------------------------------------
1390
1391 (define_expand "adddi3"
1392   [(set (match_operand:DI 0 "arith_reg_operand" "")
1393         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1394                  (match_operand:DI 2 "arith_operand" "")))]
1395   ""
1396   "
1397 {
1398   if (TARGET_SH1)
1399     {
1400       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1401         FAIL;
1402       operands[2] = force_reg (DImode, operands[2]);
1403       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1404       DONE;
1405     }
1406 }")
1407
1408 (define_insn "*adddi3_media"
1409   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1410         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1411                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1412   "TARGET_SHMEDIA"
1413   "@
1414         add     %1, %2, %0
1415         addi    %1, %2, %0"
1416   [(set_attr "type" "arith_media")])
1417
1418 (define_insn "*adddisi3_media"
1419   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1420         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1422   "TARGET_SHMEDIA"
1423   "@
1424         add.l   %1, %2, %0
1425         addi.l  %1, %2, %0"
1426   [(set_attr "type" "arith_media")
1427    (set_attr "highpart" "ignore")])
1428
1429 (define_insn "adddi3z_media"
1430   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1431         (zero_extend:DI
1432          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1433                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1434   "TARGET_SHMEDIA"
1435   "addz.l       %1, %N2, %0"
1436   [(set_attr "type" "arith_media")
1437    (set_attr "highpart" "ignore")])
1438
1439 (define_insn "adddi3_compact"
1440   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1441         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1442                  (match_operand:DI 2 "arith_reg_operand" "r")))
1443    (clobber (reg:SI T_REG))]
1444   "TARGET_SH1"
1445   "#"
1446   [(set_attr "length" "6")])
1447
1448 (define_split
1449   [(set (match_operand:DI 0 "arith_reg_dest" "")
1450         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1451                  (match_operand:DI 2 "arith_reg_operand" "")))
1452    (clobber (reg:SI T_REG))]
1453   "TARGET_SH1 && reload_completed"
1454   [(const_int 0)]
1455   "
1456 {
1457   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1458   high0 = gen_rtx_REG (SImode,
1459                        true_regnum (operands[0])
1460                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461   high2 = gen_rtx_REG (SImode,
1462                        true_regnum (operands[2])
1463                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464   emit_insn (gen_clrt ());
1465   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1466   emit_insn (gen_addc1 (high0, high0, high2));
1467   DONE;
1468 }")
1469
1470 (define_insn "addc"
1471   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1472         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1473                           (match_operand:SI 2 "arith_reg_operand" "r"))
1474                  (reg:SI T_REG)))
1475    (set (reg:SI T_REG)
1476         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1477   "TARGET_SH1"
1478   "addc %2,%0"
1479   [(set_attr "type" "arith")])
1480
1481 (define_insn "addc1"
1482   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1483         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1484                           (match_operand:SI 2 "arith_reg_operand" "r"))
1485                  (reg:SI T_REG)))
1486    (clobber (reg:SI T_REG))]
1487   "TARGET_SH1"
1488   "addc %2,%0"
1489   [(set_attr "type" "arith")])
1490
1491 (define_expand "addsi3"
1492   [(set (match_operand:SI 0 "arith_reg_operand" "")
1493         (plus:SI (match_operand:SI 1 "arith_operand" "")
1494                  (match_operand:SI 2 "arith_operand" "")))]
1495   ""
1496   "
1497 {
1498   if (TARGET_SHMEDIA)
1499     operands[1] = force_reg (SImode, operands[1]);
1500 }")
1501
1502 (define_insn "addsi3_media"
1503   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1504         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1505                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1506   "TARGET_SHMEDIA"
1507   "@
1508         add.l   %1, %2, %0
1509         addi.l  %1, %2, %0"
1510   [(set_attr "type" "arith_media")
1511    (set_attr "highpart" "ignore")])
1512
1513 (define_insn "addsidi3_media"
1514   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1515         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1516                                   "%r,r")
1517                                  (match_operand:SI 2 "arith_operand"
1518                                   "r,I10"))))]
1519   "TARGET_SHMEDIA"
1520   "@
1521         add.l   %1, %2, %0
1522         addi.l  %1, %2, %0"
1523   [(set_attr "type" "arith_media")
1524    (set_attr "highpart" "ignore")])
1525
1526 (define_insn "*addsi3_compact"
1527   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1528         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1529                  (match_operand:SI 2 "arith_operand" "rI08")))]
1530   "TARGET_SH1"
1531   "add  %2,%0"
1532   [(set_attr "type" "arith")])
1533
1534 ;; -------------------------------------------------------------------------
1535 ;; Subtraction instructions
1536 ;; -------------------------------------------------------------------------
1537
1538 (define_expand "subdi3"
1539   [(set (match_operand:DI 0 "arith_reg_operand" "")
1540         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1541                   (match_operand:DI 2 "arith_reg_operand" "")))]
1542   ""
1543   "
1544 {
1545   if (TARGET_SH1)
1546     {
1547       operands[1] = force_reg (DImode, operands[1]);
1548       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1549       DONE;
1550     }
1551 }")
1552
1553 (define_insn "*subdi3_media"
1554   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1555         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1556                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1557   "TARGET_SHMEDIA"
1558   "sub  %N1, %2, %0"
1559   [(set_attr "type" "arith_media")])
1560   
1561 (define_insn "subdisi3_media"
1562   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1563         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1564                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1565   "TARGET_SHMEDIA"
1566   "sub.l        %N1, %2, %0"
1567   [(set_attr "type" "arith_media")
1568    (set_attr "highpart" "ignore")])
1569
1570 (define_insn "subdi3_compact"
1571   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1572         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1573                  (match_operand:DI 2 "arith_reg_operand" "r")))
1574    (clobber (reg:SI T_REG))]
1575   "TARGET_SH1"
1576   "#"
1577   [(set_attr "length" "6")])
1578
1579 (define_split
1580   [(set (match_operand:DI 0 "arith_reg_dest" "")
1581         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1582                   (match_operand:DI 2 "arith_reg_operand" "")))
1583    (clobber (reg:SI T_REG))]
1584   "TARGET_SH1 && reload_completed"
1585   [(const_int 0)]
1586   "
1587 {
1588   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1589   high0 = gen_rtx_REG (SImode,
1590                        true_regnum (operands[0])
1591                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1592   high2 = gen_rtx_REG (SImode,
1593                        true_regnum (operands[2])
1594                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595   emit_insn (gen_clrt ());
1596   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1597   emit_insn (gen_subc1 (high0, high0, high2));
1598   DONE;
1599 }")
1600
1601 (define_insn "subc"
1602   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1603         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1604                             (match_operand:SI 2 "arith_reg_operand" "r"))
1605                   (reg:SI T_REG)))
1606    (set (reg:SI T_REG)
1607         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1608                           (reg:SI T_REG))
1609                 (match_dup 1)))]
1610   "TARGET_SH1"
1611   "subc %2,%0"
1612   [(set_attr "type" "arith")])
1613
1614 (define_insn "subc1"
1615   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1616         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1617                             (match_operand:SI 2 "arith_reg_operand" "r"))
1618                   (reg:SI T_REG)))
1619    (clobber (reg:SI T_REG))]
1620   "TARGET_SH1"
1621   "subc %2,%0"
1622   [(set_attr "type" "arith")])
1623
1624 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1625 ;; pattern for this case.  This helps multimedia applications that compute
1626 ;; the sum of absolute differences.
1627 (define_insn "mov_neg_si_t"
1628   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1629   "TARGET_SH1"
1630   "subc %0,%0"
1631   [(set_attr "type" "arith")])
1632
1633 (define_insn "*subsi3_internal"
1634   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1635         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1636                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1637   "TARGET_SH1"
1638   "sub  %2,%0"
1639   [(set_attr "type" "arith")])
1640
1641 (define_insn_and_split "*subsi3_media"
1642   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1643         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1644                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1645   "TARGET_SHMEDIA
1646    && (operands[1] != constm1_rtx
1647        || (GET_CODE (operands[2]) != TRUNCATE
1648            && GET_CODE (operands[2]) != SUBREG))"
1649   "sub.l        %N1, %2, %0"
1650   "operands[1] == constm1_rtx"
1651   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1652   ""
1653   [(set_attr "type" "arith_media")
1654    (set_attr "highpart" "ignore")])
1655
1656 (define_split
1657   [(set (match_operand:SI 0 "arith_reg_dest" "")
1658         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1659                                                        "general_extend_operand"
1660                                                        "") 0)) 0)))]
1661   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1662   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1663    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1664   "")
1665
1666 (define_split
1667   [(set (match_operand:SI 0 "arith_reg_dest" "")
1668         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669                                                        "general_extend_operand"
1670                                                        "") 0)) 3)))]
1671   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1672   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1674   "")
1675 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1676 ;; will sometimes save one instruction.  Otherwise we might get
1677 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1678 ;; are the same.
1679
1680 (define_expand "subsi3"
1681   [(set (match_operand:SI 0 "arith_reg_operand" "")
1682         (minus:SI (match_operand:SI 1 "arith_operand" "")
1683                   (match_operand:SI 2 "arith_reg_operand" "")))]
1684   ""
1685   "
1686 {
1687   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1688     {
1689       emit_insn (gen_negsi2 (operands[0], operands[2]));
1690       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1691       DONE;
1692     }
1693   if (TARGET_SHMEDIA)
1694     {
1695       if (!can_create_pseudo_p ()
1696           && ! 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_reg_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_reg_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_reg_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   "&& !can_create_pseudo_p ()"
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   "&& !can_create_pseudo_p ()"
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   "&& !can_create_pseudo_p ()"
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   if (satisfies_constraint_N (dividend))
2475     {
2476       emit_move_insn (result, dividend);
2477       DONE;
2478     }
2479
2480   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2481   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2482   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2483   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2484   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2485   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2486   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2487   DONE;
2488 }")
2489
2490 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2491 ;; inv1: tab_base, tab_ix, norm32
2492 ;; inv2: norm32, inv1, i92
2493 (define_insn_and_split "divsi_inv_m1_3"
2494   [(set (match_operand:SI 0 "register_operand" "=r")
2495         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2496                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2497                                 (match_operand:DI 3 "register_operand" "r")
2498                                 (match_operand:SI 4 "register_operand" "r")]
2499                      UNSPEC_DIV_INV_M1)
2500                     (unspec:SI [(match_dup 4)
2501                                 (unspec:SI [(match_dup 2)
2502                                             (match_dup 3)
2503                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2504                                 (match_operand:SI 5 "" "")]
2505                      UNSPEC_DIV_INV_M2)
2506                     (match_operand:DI 6 "register_operand" "r")
2507                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2508                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2509          UNSPEC_DIV_INV_M3))
2510    (clobber (match_operand:DI 9 "register_operand" "=r"))
2511    (clobber (match_operand:DI 10 "register_operand" "=r"))
2512    (clobber (match_operand:DI 11 "register_operand" "=r"))
2513    (clobber (match_operand:DI 12 "register_operand" "=r"))
2514    (clobber (match_operand:SI 13 "register_operand" "=r"))
2515    (clobber (match_operand:SI 14 "register_operand" "=r"))
2516    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2517   "TARGET_SHMEDIA
2518    && (TARGET_DIVIDE_INV_MINLAT
2519        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2520   "#"
2521   "&& !can_create_pseudo_p ()"
2522   [(pc)]
2523   "
2524 {
2525   rtx result = operands[0];
2526   rtx dividend = operands[1];
2527   rtx tab_base = operands[2];
2528   rtx tab_ix = operands[3];
2529   rtx norm32 = operands[4];
2530   /* rtx i92 = operands[5]; */
2531   rtx shift = operands[6];
2532   rtx i2p27 = operands[7];
2533   rtx i43 = operands[8];
2534   rtx scratch0 = operands[9];
2535   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2536   rtx scratch1 = operands[10];
2537   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2538   rtx scratch2 = operands[11];
2539   rtx scratch3 = operands[12];
2540   rtx scratch4 = operands[13];
2541   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2542   rtx scratch5 = operands[14];
2543   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2544   rtx scratch6 = operands[15];
2545
2546   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2547                                scratch0, scratch1));
2548   /* inv0 == scratch4 */
2549   if (! TARGET_DIVIDE_INV20U)
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2552       i2p27 = scratch0;
2553       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2554     }
2555   else
2556     {
2557       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2558       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2559     }
2560   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2561   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2562   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2563   /* inv1 == scratch4 */
2564
2565   if (TARGET_DIVIDE_INV_MINLAT)
2566     {
2567       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2568       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2569       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2570       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2571       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2572       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2573       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2574       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2575       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2576       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2577       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2578     }
2579   else
2580     {
2581       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2582       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2583       emit_insn (gen_nsbdi (scratch6,
2584                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2585       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2586       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2587       emit_insn (gen_divsi_inv20 (scratch2,
2588                                   norm32, scratch4, dividend,
2589                                   scratch6, scratch3, i43,
2590                                   /* scratch0 may be shared with i2p27.  */
2591                                   scratch0, scratch1, scratch5,
2592                                   label, label, i2p27));
2593     }
2594   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2595   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2596   DONE;
2597 }")
2598
2599 (define_insn "divsi_inv20"
2600   [(set (match_operand:DI 0 "register_operand" "=&r")
2601         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2602                     (match_operand:SI 2 "register_operand" "r")
2603                     (match_operand:SI 3 "register_operand" "r")
2604                     (match_operand:DI 4 "register_operand" "r")
2605                     (match_operand:DI 5 "register_operand" "r")
2606                     (match_operand:DI 6 "register_operand" "r")
2607                     (match_operand:DI 12 "register_operand" "r")
2608                     (match_operand 10 "target_operand" "b")
2609                     (match_operand 11 "immediate_operand" "i")]
2610          UNSPEC_DIV_INV20))
2611    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2612    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2613    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2614   "TARGET_SHMEDIA
2615    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2616   "*
2617 {
2618 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2619              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2620              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2621              %10 label (tr), %11 label (imm)
2622
2623  muls.l inv1, norm32, scratch0  // s2.60
2624   muls.l inv1, dividend, result // s32.30
2625   xor i2p27, result_sign, round_scratch
2626  bge/u dividend_nsb, i43, tr.. (label)
2627  shari scratch0, 16, scratch0   // s-16.44
2628  muls.l sratch0_si, inv1, scratch0 // s-16.74
2629   sub result, round_scratch, result
2630   shari dividend, 14, scratch1   // s19.-14
2631  shari scratch0, 30, scratch0   // s-16.44
2632  muls.l scratch0, scratch1, round_scratch // s15.30
2633 label:
2634  sub result, round_scratch, result */
2635
2636   int likely = TARGET_DIVIDE_INV20L;
2637
2638   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2639   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2640   output_asm_insn (likely
2641                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2642                    : \"bge/u\t%4, %6, %10\", operands);
2643   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2644   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2645   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2646   return (likely
2647           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2648           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2649 }")
2650
2651 (define_insn_and_split "divsi_inv_fp"
2652   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2653         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2654                 (match_operand:SI 2 "register_operand" "rf")))
2655    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2656    (clobber (match_operand:SI 4 "register_operand" "=r"))
2657    (clobber (match_operand:SI 5 "register_operand" "=r"))
2658    (clobber (match_operand:DF 6 "register_operand" "=r"))
2659    (clobber (match_operand:DF 7 "register_operand" "=r"))
2660    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2661   "TARGET_SHMEDIA_FPU"
2662   "#"
2663   "&& (high_life_started || reload_completed)"
2664   [(set (match_dup 0) (match_dup 3))]
2665   ""
2666   [(set_attr "highpart" "must_split")])
2667
2668 ;; If a matching group of divide-by-inverse instructions is in the same
2669 ;; basic block after gcse & loop optimizations, we want to transform them
2670 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2671 (define_insn_and_split "*divsi_inv_fp_combine"
2672   [(set (match_operand:SI 0 "register_operand" "=f")
2673         (div:SI (match_operand:SI 1 "register_operand" "f")
2674                 (match_operand:SI 2 "register_operand" "f")))
2675    (use (unspec:SI [(match_dup 1)
2676                     (match_operand:SI 3 "" "")
2677                     (unspec:SI [(match_operand:SI 4 "" "")
2678                                 (match_dup 3)
2679                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2680                     (match_operand:DI 6 "" "")
2681                     (const_int 0)
2682                     (const_int 0)] UNSPEC_DIV_INV_M3))
2683    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2684    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2685    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2686    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2687    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2688   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2689   "#"
2690   "&& 1"
2691   [(set (match_dup 9) (float:DF (match_dup 1)))
2692    (set (match_dup 10) (float:DF (match_dup 2)))
2693    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2694    (set (match_dup 8)
2695         (fix:SI (match_dup 11)))
2696    (set (match_dup 0) (match_dup 8))]
2697   "
2698 {
2699   if (! fp_arith_reg_operand (operands[1], SImode))
2700     {
2701       emit_move_insn (operands[7], operands[1]);
2702       operands[1] = operands[7];
2703     }
2704   if (! fp_arith_reg_operand (operands[2], SImode))
2705     {
2706       emit_move_insn (operands[8], operands[2]);
2707       operands[2] = operands[8];
2708     }
2709 }"
2710   [(set_attr "highpart" "must_split")])
2711 \f
2712 ;; -------------------------------------------------------------------------
2713 ;; Multiplication instructions
2714 ;; -------------------------------------------------------------------------
2715
2716 (define_insn "umulhisi3_i"
2717   [(set (reg:SI MACL_REG)
2718         (mult:SI (zero_extend:SI
2719                   (match_operand:HI 0 "arith_reg_operand" "r"))
2720                  (zero_extend:SI
2721                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2722   "TARGET_SH1"
2723   "mulu.w       %1,%0"
2724   [(set_attr "type" "smpy")])
2725
2726 (define_insn "mulhisi3_i"
2727   [(set (reg:SI MACL_REG)
2728         (mult:SI (sign_extend:SI
2729                   (match_operand:HI 0 "arith_reg_operand" "r"))
2730                  (sign_extend:SI
2731                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2732   "TARGET_SH1"
2733   "muls.w       %1,%0"
2734   [(set_attr "type" "smpy")])
2735
2736 (define_expand "mulhisi3"
2737   [(set (reg:SI MACL_REG)
2738         (mult:SI (sign_extend:SI
2739                   (match_operand:HI 1 "arith_reg_operand" ""))
2740                  (sign_extend:SI
2741                   (match_operand:HI 2 "arith_reg_operand" ""))))
2742    (set (match_operand:SI 0 "arith_reg_operand" "")
2743         (reg:SI MACL_REG))]
2744   "TARGET_SH1"
2745   "
2746 {
2747   rtx insn, macl;
2748
2749   macl = gen_rtx_REG (SImode, MACL_REG);
2750   start_sequence ();
2751   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2752   insn = get_insns ();  
2753   end_sequence ();
2754   /* expand_binop can't find a suitable code in umul_widen_optab to
2755      make a REG_EQUAL note from, so make one here.
2756      See also smulsi3_highpart.
2757      ??? Alternatively, we could put this at the calling site of expand_binop,
2758      i.e. expand_expr.  */
2759   /* Use emit_libcall_block for loop invariant code motion and to make
2760      a REG_EQUAL note.  */
2761   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2762
2763   DONE;
2764 }")
2765
2766 (define_expand "umulhisi3"
2767   [(set (reg:SI MACL_REG)
2768         (mult:SI (zero_extend:SI
2769                   (match_operand:HI 1 "arith_reg_operand" ""))
2770                  (zero_extend:SI
2771                   (match_operand:HI 2 "arith_reg_operand" ""))))
2772    (set (match_operand:SI 0 "arith_reg_operand" "")
2773         (reg:SI MACL_REG))]
2774   "TARGET_SH1"
2775   "
2776 {
2777   rtx insn, macl;
2778
2779   macl = gen_rtx_REG (SImode, MACL_REG);
2780   start_sequence ();
2781   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2782   insn = get_insns ();  
2783   end_sequence ();
2784   /* expand_binop can't find a suitable code in umul_widen_optab to
2785      make a REG_EQUAL note from, so make one here.
2786      See also smulsi3_highpart.
2787      ??? Alternatively, we could put this at the calling site of expand_binop,
2788      i.e. expand_expr.  */
2789   /* Use emit_libcall_block for loop invariant code motion and to make
2790      a REG_EQUAL note.  */
2791   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2792
2793   DONE;
2794 }")
2795
2796 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2797 ;; a call to a routine which clobbers known registers.
2798
2799 (define_insn ""
2800   [(set (match_operand:SI 1 "register_operand" "=z")
2801         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2802    (clobber (reg:SI MACL_REG))
2803    (clobber (reg:SI T_REG))
2804    (clobber (reg:SI PR_REG))
2805    (clobber (reg:SI R3_REG))
2806    (clobber (reg:SI R2_REG))
2807    (clobber (reg:SI R1_REG))
2808    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2809   "TARGET_SH1"
2810   "jsr  @%0%#"
2811   [(set_attr "type" "sfunc")
2812    (set_attr "needs_delay_slot" "yes")])
2813
2814 (define_expand "mulsi3_call"
2815   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2816    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2817    (parallel[(set (match_operand:SI 0 "register_operand" "")
2818                   (mult:SI (reg:SI R4_REG)
2819                            (reg:SI R5_REG)))
2820              (clobber (reg:SI MACL_REG))
2821              (clobber (reg:SI T_REG))
2822              (clobber (reg:SI PR_REG))
2823              (clobber (reg:SI R3_REG))
2824              (clobber (reg:SI R2_REG))
2825              (clobber (reg:SI R1_REG))
2826              (use (match_operand:SI 3 "register_operand" ""))])]
2827   "TARGET_SH1"
2828   "")
2829
2830 (define_insn "mul_r"
2831   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2832         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2833                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2834   "TARGET_SH2A"
2835   "mulr %2,%0"
2836   [(set_attr "type" "dmpy")])
2837
2838 (define_insn "mul_l"
2839   [(set (reg:SI MACL_REG)
2840         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2841                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2842   "TARGET_SH2"
2843   "mul.l        %1,%0"
2844   [(set_attr "type" "dmpy")])
2845
2846 (define_expand "mulsi3"
2847   [(set (reg:SI MACL_REG)
2848         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2849                   (match_operand:SI 2 "arith_reg_operand" "")))
2850    (set (match_operand:SI 0 "arith_reg_operand" "")
2851         (reg:SI MACL_REG))]
2852   "TARGET_SH1"
2853   "
2854 {
2855   if (!TARGET_SH2)
2856     {
2857       /* The address must be set outside the libcall,
2858          since it goes into a pseudo.  */
2859       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2860       rtx addr = force_reg (SImode, sym);
2861       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2862                                    operands[2], addr);
2863       emit_insn (insns);
2864     }
2865   else
2866     {
2867       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2868
2869       emit_insn (gen_mul_l (operands[1], operands[2]));
2870       /* consec_sets_giv can only recognize the first insn that sets a
2871          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2872          note.  */
2873       emit_insn (gen_movsi_i ((operands[0]), macl));
2874     }
2875   DONE;
2876 }")
2877
2878 (define_insn "mulsidi3_i"
2879   [(set (reg:SI MACH_REG)
2880         (truncate:SI
2881          (lshiftrt:DI
2882           (mult:DI
2883            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2884            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2885           (const_int 32))))
2886    (set (reg:SI MACL_REG)
2887         (mult:SI (match_dup 0)
2888                  (match_dup 1)))]
2889   "TARGET_SH2"
2890   "dmuls.l      %1,%0"
2891   [(set_attr "type" "dmpy")])
2892
2893 (define_expand "mulsidi3"
2894   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2895         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2896                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2897   "TARGET_SH2 || TARGET_SHMEDIA"
2898   "
2899 {
2900   if (TARGET_SH2)
2901     {
2902        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2903                                         operands[2]));
2904        DONE;
2905     }
2906 }")
2907
2908 (define_insn "mulsidi3_media"
2909   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2910         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2911                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2912   "TARGET_SHMEDIA"
2913   "muls.l       %1, %2, %0"
2914   [(set_attr "type" "dmpy_media")
2915    (set_attr "highpart" "ignore")])
2916
2917 (define_insn "mulsidi3_compact"
2918   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2919         (mult:DI
2920          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2921          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2922    (clobber (reg:SI MACH_REG))
2923    (clobber (reg:SI MACL_REG))]
2924   "TARGET_SH2"
2925   "#")
2926
2927 (define_split
2928   [(set (match_operand:DI 0 "arith_reg_dest" "")
2929         (mult:DI
2930          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2931          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2932    (clobber (reg:SI MACH_REG))
2933    (clobber (reg:SI MACL_REG))]
2934   "TARGET_SH2"
2935   [(const_int 0)]
2936   "
2937 {
2938   rtx low_dst = gen_lowpart (SImode, operands[0]);
2939   rtx high_dst = gen_highpart (SImode, operands[0]);
2940
2941   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2942
2943   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2944   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2945   /* We need something to tag the possible REG_EQUAL notes on to.  */
2946   emit_move_insn (operands[0], operands[0]);
2947   DONE;
2948 }")
2949
2950 (define_insn "umulsidi3_i"
2951   [(set (reg:SI MACH_REG)
2952         (truncate:SI
2953          (lshiftrt:DI
2954           (mult:DI
2955            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2956            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2957           (const_int 32))))
2958    (set (reg:SI MACL_REG)
2959         (mult:SI (match_dup 0)
2960                  (match_dup 1)))]
2961   "TARGET_SH2"
2962   "dmulu.l      %1,%0"
2963   [(set_attr "type" "dmpy")])
2964
2965 (define_expand "umulsidi3"
2966   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2967         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2968                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2969   "TARGET_SH2 || TARGET_SHMEDIA"
2970   "
2971 {
2972   if (TARGET_SH2)
2973     {
2974        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2975                                          operands[2]));
2976        DONE;
2977     }
2978 }")
2979
2980 (define_insn "umulsidi3_media"
2981   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2982         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2983                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2984   "TARGET_SHMEDIA"
2985   "mulu.l       %1, %2, %0"
2986   [(set_attr "type" "dmpy_media")
2987    (set_attr "highpart" "ignore")])
2988
2989 (define_insn "umulsidi3_compact"
2990   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2991         (mult:DI
2992          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2993          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2994    (clobber (reg:SI MACH_REG))
2995    (clobber (reg:SI MACL_REG))]
2996   "TARGET_SH2"
2997   "#")
2998
2999 (define_split
3000   [(set (match_operand:DI 0 "arith_reg_dest" "")
3001         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3002                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3003    (clobber (reg:SI MACH_REG))
3004    (clobber (reg:SI MACL_REG))]
3005   "TARGET_SH2"
3006   [(const_int 0)]
3007   "
3008 {
3009   rtx low_dst = gen_lowpart (SImode, operands[0]);
3010   rtx high_dst = gen_highpart (SImode, operands[0]);
3011
3012   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3013
3014   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3015   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3016   /* We need something to tag the possible REG_EQUAL notes on to.  */
3017   emit_move_insn (operands[0], operands[0]);
3018   DONE;
3019 }")
3020
3021 (define_insn "smulsi3_highpart_i"
3022   [(set (reg:SI MACH_REG)
3023         (truncate:SI
3024          (lshiftrt:DI
3025           (mult:DI
3026            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3027            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3028           (const_int 32))))
3029    (clobber (reg:SI MACL_REG))]
3030   "TARGET_SH2"
3031   "dmuls.l      %1,%0"
3032   [(set_attr "type" "dmpy")])
3033
3034 (define_expand "smulsi3_highpart"
3035   [(parallel
3036     [(set (reg:SI MACH_REG)
3037           (truncate:SI
3038            (lshiftrt:DI
3039             (mult:DI
3040              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3041              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3042             (const_int 32))))
3043     (clobber (reg:SI MACL_REG))])
3044    (set (match_operand:SI 0 "arith_reg_operand" "")
3045         (reg:SI MACH_REG))]
3046   "TARGET_SH2"
3047   "
3048 {
3049   rtx insn, mach;
3050
3051   mach = gen_rtx_REG (SImode, MACH_REG);
3052   start_sequence ();
3053   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3054   insn = get_insns ();  
3055   end_sequence ();
3056   /* expand_binop can't find a suitable code in mul_highpart_optab to
3057      make a REG_EQUAL note from, so make one here.
3058      See also {,u}mulhisi.
3059      ??? Alternatively, we could put this at the calling site of expand_binop,
3060      i.e. expand_mult_highpart.  */
3061   /* Use emit_libcall_block for loop invariant code motion and to make
3062      a REG_EQUAL note.  */
3063   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3064
3065   DONE;
3066 }")
3067
3068 (define_insn "umulsi3_highpart_i"
3069   [(set (reg:SI MACH_REG)
3070         (truncate:SI
3071          (lshiftrt:DI
3072           (mult:DI
3073            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3074            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3075           (const_int 32))))
3076    (clobber (reg:SI MACL_REG))]
3077   "TARGET_SH2"
3078   "dmulu.l      %1,%0"
3079   [(set_attr "type" "dmpy")])
3080
3081 (define_expand "umulsi3_highpart"
3082   [(parallel
3083     [(set (reg:SI MACH_REG)
3084           (truncate:SI
3085            (lshiftrt:DI
3086             (mult:DI
3087              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3088              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3089             (const_int 32))))
3090     (clobber (reg:SI MACL_REG))])
3091    (set (match_operand:SI 0 "arith_reg_operand" "")
3092         (reg:SI MACH_REG))]
3093   "TARGET_SH2"
3094   "
3095 {
3096   rtx insn, mach;
3097
3098   mach = gen_rtx_REG (SImode, MACH_REG);
3099   start_sequence ();
3100   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3101   insn = get_insns ();  
3102   end_sequence ();
3103   /* Use emit_libcall_block for loop invariant code motion and to make
3104      a REG_EQUAL note.  */
3105   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3106
3107   DONE;
3108 }")
3109
3110 (define_insn_and_split "muldi3"
3111   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3112         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3113                  (match_operand:DI 2 "arith_reg_operand" "r")))
3114    (clobber (match_scratch:DI 3 "=&r"))
3115    (clobber (match_scratch:DI 4 "=r"))]
3116   "TARGET_SHMEDIA"
3117   "#"
3118   "reload_completed"
3119   [(const_int 0)]
3120   "
3121 {
3122   rtx op3_v2si, op2_v2si;
3123
3124   op3_v2si = operands[3];
3125   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3126     {
3127       op3_v2si = XEXP (op3_v2si, 0);
3128       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3129     }
3130   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3131   op2_v2si = operands[2];
3132   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3133     {
3134       op2_v2si = XEXP (op2_v2si, 0);
3135       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3136     }
3137   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3138   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3139   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3140   emit_insn (gen_umulsidi3_media (operands[4],
3141                                  sh_gen_truncate (SImode, operands[1], 0),
3142                                  sh_gen_truncate (SImode, operands[2], 0)));
3143   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3144   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3145   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3146   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3147   DONE;
3148 }")
3149
3150 \f
3151 ;; -------------------------------------------------------------------------
3152 ;; Logical operations
3153 ;; -------------------------------------------------------------------------
3154
3155 (define_insn "*andsi3_compact"
3156   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3157         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3158                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3159   "TARGET_SH1"
3160   "and  %2,%0"
3161   [(set_attr "type" "arith")])
3162
3163 (define_insn "*andsi3_media"
3164   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3165         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3166                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3167   "TARGET_SHMEDIA"
3168   "@
3169         and     %1, %2, %0
3170         andi    %1, %2, %0"
3171   [(set_attr "type" "arith_media")])
3172
3173 (define_insn "*andsi3_bclr"
3174   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3175         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3176                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3177   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3178   "bclr\\t%W2,%0"
3179   [(set_attr "type" "arith")])
3180
3181 ;; If the constant is 255, then emit an extu.b instruction instead of an
3182 ;; and, since that will give better code.
3183
3184 (define_expand "andsi3"
3185   [(set (match_operand:SI 0 "arith_reg_operand" "")
3186         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3187                 (match_operand:SI 2 "logical_operand" "")))]
3188   ""
3189   "
3190 {
3191   if (TARGET_SH1
3192       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3193     {
3194       emit_insn (gen_zero_extendqisi2 (operands[0],
3195                                        gen_lowpart (QImode, operands[1])));
3196       DONE;
3197     }
3198 }")
3199
3200 (define_insn_and_split "anddi3"
3201   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3202         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3203                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3204   "TARGET_SHMEDIA"
3205   "@
3206         and     %1, %2, %0
3207         andi    %1, %2, %0
3208         #"
3209   "reload_completed
3210    && ! logical_operand (operands[2], DImode)"
3211   [(const_int 0)]
3212   "
3213 {
3214   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3215     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3216   else
3217     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3218   DONE;
3219 }"
3220   [(set_attr "type" "arith_media")])
3221
3222 (define_insn "andcsi3"
3223   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3224         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3225                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3226   "TARGET_SHMEDIA"
3227   "andc %1,%2,%0"
3228   [(set_attr "type" "arith_media")])
3229
3230 (define_insn "andcdi3"
3231   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3232         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3233                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3234   "TARGET_SHMEDIA"
3235   "andc %1,%2,%0"
3236   [(set_attr "type" "arith_media")])
3237
3238 (define_expand "iorsi3"
3239   [(set (match_operand:SI 0 "arith_reg_operand" "")
3240         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3241                 (match_operand:SI 2 "logical_operand" "")))]
3242   ""
3243   "")
3244
3245 (define_insn "*iorsi3_compact"
3246   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3247         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3248                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3249   "TARGET_SH1"
3250   "or   %2,%0"
3251   [(set_attr "type" "arith")])
3252
3253 (define_insn "*iorsi3_media"
3254   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3255         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3256                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3257   "TARGET_SHMEDIA"
3258   "@
3259         or      %1, %2, %0
3260         ori     %1, %2, %0"
3261   [(set_attr "type" "arith_media")])
3262
3263 (define_insn "*iorsi3_bset"
3264   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3265         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3266         (match_operand:SI 2 "const_int_operand" "Pso")))]
3267   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3268   "bset\\t%V2,%0"
3269   [(set_attr "type" "arith")])
3270
3271 (define_insn "iordi3"
3272   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3273         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3274                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3275   "TARGET_SHMEDIA"
3276   "@
3277         or      %1, %2, %0
3278         ori     %1, %2, %0"
3279   [(set_attr "type" "arith_media")])
3280
3281 (define_insn_and_split "*logical_sidi3"
3282   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3283         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3284                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3285                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3286   "TARGET_SHMEDIA"
3287   "#"
3288   "&& reload_completed"
3289   [(set (match_dup 0) (match_dup 3))]
3290   "
3291 {
3292   operands[3]
3293     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3294                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3295                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3296 }")
3297
3298 (define_insn_and_split "*logical_sidisi3"
3299   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3300         (truncate:SI (sign_extend:DI
3301                         (match_operator:SI 3 "logical_operator"
3302                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3303                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3304   "TARGET_SHMEDIA"
3305   "#"
3306   "&& 1"
3307   [(set (match_dup 0) (match_dup 3))])
3308
3309 (define_insn_and_split "*logical_sidi3_2"
3310   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3311         (sign_extend:DI (truncate:SI (sign_extend:DI
3312                         (match_operator:SI 3 "logical_operator"
3313                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3314                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3315   "TARGET_SHMEDIA"
3316   "#"
3317   "&& 1"
3318   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3319
3320 (define_expand "xorsi3"
3321   [(set (match_operand:SI 0 "arith_reg_operand" "")
3322         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3323                 (match_operand:SI 2 "xor_operand" "")))]
3324   ""
3325   "")
3326
3327 (define_insn "*xorsi3_compact"
3328   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3329         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3330                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3331   "TARGET_SH1"
3332   "xor  %2,%0"
3333   [(set_attr "type" "arith")])
3334
3335 (define_insn "*xorsi3_media"
3336   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3337         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3338                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3339   "TARGET_SHMEDIA"
3340   "@
3341         xor     %1, %2, %0
3342         xori    %1, %2, %0"
3343   [(set_attr "type" "arith_media")])
3344
3345 ;; Store the complements of the T bit in a register.
3346 (define_insn "xorsi3_movrt"
3347   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3348         (xor:SI (reg:SI T_REG)
3349                 (const_int 1)))]
3350   "TARGET_SH2A"
3351   "movrt\\t%0"
3352   [(set_attr "type" "arith")])
3353
3354 (define_insn "xordi3"
3355   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3356         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3357                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3358   "TARGET_SHMEDIA"
3359   "@
3360         xor     %1, %2, %0
3361         xori    %1, %2, %0"
3362   [(set_attr "type" "arith_media")])
3363
3364 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3365 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3366 (define_split
3367   [(set (match_operand:DI 0 "arith_reg_dest" "")
3368         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3369                           [(match_operand 1 "any_register_operand" "")
3370                            (match_operand 2 "any_register_operand" "")])))]
3371   "TARGET_SHMEDIA"
3372   [(set (match_dup 5) (match_dup 4))
3373    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3374 "
3375 {
3376   enum machine_mode inmode = GET_MODE (operands[1]);
3377   int offset = 0;
3378
3379   if (GET_CODE (operands[0]) == SUBREG)
3380     {
3381       offset = SUBREG_BYTE (operands[0]);
3382       operands[0] = SUBREG_REG (operands[0]);
3383     }
3384   gcc_assert (GET_CODE (operands[0]) == REG);
3385   if (! TARGET_LITTLE_ENDIAN)
3386     offset += 8 - GET_MODE_SIZE (inmode);
3387   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3388 }")
3389 \f
3390 ;; -------------------------------------------------------------------------
3391 ;; Shifts and rotates
3392 ;; -------------------------------------------------------------------------
3393
3394 (define_expand "rotldi3"
3395   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3396         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3397                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3398   "TARGET_SHMEDIA"
3399   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3400
3401 (define_insn "rotldi3_mextr"
3402   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3403         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3404                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3405   "TARGET_SHMEDIA"
3406   "*
3407 {
3408   static char templ[16];
3409
3410   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3411            8 - (int) (INTVAL (operands[2]) >> 3));
3412   return templ;
3413 }"
3414   [(set_attr "type" "arith_media")])
3415
3416 (define_expand "rotrdi3"
3417   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3418         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3419                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3420   "TARGET_SHMEDIA"
3421   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3422
3423 (define_insn "rotrdi3_mextr"
3424   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3425         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3426                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3427   "TARGET_SHMEDIA"
3428   "*
3429 {
3430   static char templ[16];
3431
3432   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3433   return templ;
3434 }"
3435   [(set_attr "type" "arith_media")])
3436
3437 (define_split
3438   [(set (match_operand:DI 0 "arith_reg_dest" "")
3439         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3440                                          "ua_address_operand" "")))
3441                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3442                            (const_int 8))))
3443    (clobber (match_operand:DI 3 "register_operand" ""))]
3444   "TARGET_SHMEDIA"
3445   [(match_dup 4) (match_dup 5)]
3446   "
3447 {
3448   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3449                  (operands[3], operands[1]));
3450   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3451                               GEN_INT (56), GEN_INT (8));
3452 }")
3453
3454 (define_insn "rotlsi3_1"
3455   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3456         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3457                    (const_int 1)))
3458    (set (reg:SI T_REG)
3459         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3460   "TARGET_SH1"
3461   "rotl %0"
3462   [(set_attr "type" "arith")])
3463
3464 (define_insn "rotlsi3_31"
3465   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3466         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3467                    (const_int 31)))
3468    (clobber (reg:SI T_REG))]
3469   "TARGET_SH1"
3470   "rotr %0"
3471   [(set_attr "type" "arith")])
3472
3473 (define_insn "rotlsi3_16"
3474   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3475         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3476                    (const_int 16)))]
3477   "TARGET_SH1"
3478   "swap.w       %1,%0"
3479   [(set_attr "type" "arith")])
3480
3481 (define_expand "rotlsi3"
3482   [(set (match_operand:SI 0 "arith_reg_dest" "")
3483         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3484                    (match_operand:SI 2 "immediate_operand" "")))]
3485   "TARGET_SH1"
3486   "
3487 {
3488   static const char rot_tab[] = {
3489     000, 000, 000, 000, 000, 000, 010, 001,
3490     001, 001, 011, 013, 003, 003, 003, 003,
3491     003, 003, 003, 003, 003, 013, 012, 002,
3492     002, 002, 010, 000, 000, 000, 000, 000,
3493   };
3494
3495   int count, choice;
3496
3497   if (GET_CODE (operands[2]) != CONST_INT)
3498     FAIL;
3499   count = INTVAL (operands[2]);
3500   choice = rot_tab[count];
3501   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3502     FAIL;
3503   choice &= 7;
3504   switch (choice)
3505     {
3506     case 0:
3507       emit_move_insn (operands[0], operands[1]);
3508       count -= (count & 16) * 2;
3509       break;
3510     case 3:
3511      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3512      count -= 16;
3513      break;
3514     case 1:
3515     case 2:
3516       {
3517         rtx parts[2];
3518         parts[0] = gen_reg_rtx (SImode);
3519         parts[1] = gen_reg_rtx (SImode);
3520         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3521         emit_move_insn (parts[choice-1], operands[1]);
3522         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3523         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3524         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3525         count = (count & ~16) - 8;
3526       }
3527     }
3528
3529   for (; count > 0; count--)
3530     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3531   for (; count < 0; count++)
3532     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3533
3534   DONE;
3535 }")
3536
3537 (define_insn "*rotlhi3_8"
3538   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3539         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3540                    (const_int 8)))]
3541   "TARGET_SH1"
3542   "swap.b       %1,%0"
3543   [(set_attr "type" "arith")])
3544
3545 (define_expand "rotlhi3"
3546   [(set (match_operand:HI 0 "arith_reg_operand" "")
3547         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3548                    (match_operand:HI 2 "immediate_operand" "")))]
3549   "TARGET_SH1"
3550   "
3551 {
3552   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3553     FAIL;
3554 }")
3555
3556 ;;
3557 ;; shift left
3558
3559 (define_insn "ashlsi3_sh2a"
3560   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3561         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3562                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3563   "TARGET_SH2A"
3564   "shad %2,%0"
3565   [(set_attr "type" "arith")
3566    (set_attr "length" "4")])
3567
3568 ;; This pattern is used by init_expmed for computing the costs of shift
3569 ;; insns.
3570
3571 (define_insn_and_split "ashlsi3_std"
3572   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3573         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3574                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3575    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3576   "TARGET_SH3
3577    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3578   "@
3579    shld %2,%0
3580    add  %0,%0
3581    shll%O2      %0
3582    #"
3583   "TARGET_SH3
3584    && reload_completed
3585    && GET_CODE (operands[2]) == CONST_INT
3586    && ! satisfies_constraint_P27 (operands[2])"
3587   [(set (match_dup 3) (match_dup 2))
3588    (parallel
3589     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3590      (clobber (match_dup 4))])]
3591   "operands[4] = gen_rtx_SCRATCH (SImode);"
3592   [(set_attr "length" "*,*,*,4")
3593    (set_attr "type" "dyn_shift,arith,arith,arith")])
3594
3595 (define_insn "ashlhi3_k"
3596   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3597         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3598                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3599   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3600   "@
3601         add     %0,%0
3602         shll%O2 %0"
3603   [(set_attr "type" "arith")])
3604
3605 (define_insn "ashlsi3_n"
3606   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3607         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3608                    (match_operand:SI 2 "const_int_operand" "n")))
3609    (clobber (reg:SI T_REG))]
3610   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3611   "#"
3612   [(set (attr "length")
3613         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3614                (const_string "2")
3615                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3616                (const_string "4")
3617                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3618                (const_string "6")]
3619               (const_string "8")))
3620    (set_attr "type" "arith")])
3621
3622 (define_split
3623   [(set (match_operand:SI 0 "arith_reg_dest" "")
3624         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3625                    (match_operand:SI 2 "const_int_operand" "")))
3626    (clobber (reg:SI T_REG))]
3627   "TARGET_SH1 && reload_completed"
3628   [(use (reg:SI R0_REG))]
3629   "
3630 {
3631   gen_shifty_op (ASHIFT, operands);
3632   DONE;
3633 }")
3634
3635 (define_insn "ashlsi3_media"
3636   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3637         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3638                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3639   "TARGET_SHMEDIA"
3640   "@
3641         shlld.l %1, %2, %0
3642         shlli.l %1, %2, %0"
3643   [(set_attr "type" "arith_media")
3644    (set_attr "highpart" "ignore")])
3645
3646 (define_expand "ashlsi3"
3647   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3648                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3649                               (match_operand:SI 2 "nonmemory_operand" "")))
3650               (clobber (reg:SI T_REG))])]
3651   ""
3652   "
3653 {
3654   if (TARGET_SHMEDIA)
3655     {
3656       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3657       DONE;
3658     }
3659   if (GET_CODE (operands[2]) == CONST_INT
3660       && sh_dynamicalize_shift_p (operands[2]))
3661     operands[2] = force_reg (SImode, operands[2]);
3662   if (TARGET_SH3)
3663     {
3664       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3665       DONE;
3666     }
3667   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3668     FAIL;
3669 }")
3670
3671 (define_insn "*ashlhi3_n"
3672   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3673         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3674                    (match_operand:HI 2 "const_int_operand" "n")))
3675    (clobber (reg:SI T_REG))]
3676   "TARGET_SH1"
3677   "#"
3678   [(set (attr "length")
3679         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3680                (const_string "2")
3681                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3682                (const_string "4")]
3683               (const_string "6")))
3684    (set_attr "type" "arith")])
3685
3686 (define_expand "ashlhi3"
3687   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3688                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3689                               (match_operand:SI 2 "nonmemory_operand" "")))
3690               (clobber (reg:SI T_REG))])]
3691   "TARGET_SH1"
3692   "
3693 {
3694   if (GET_CODE (operands[2]) != CONST_INT)
3695     FAIL;
3696   /* It may be possible to call gen_ashlhi3 directly with more generic
3697      operands.  Make sure operands[1] is a HImode register here.  */
3698   if (!arith_reg_operand (operands[1], HImode))
3699     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3700 }")
3701
3702 (define_split
3703   [(set (match_operand:HI 0 "arith_reg_dest" "")
3704         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3705                    (match_operand:HI 2 "const_int_operand" "")))
3706    (clobber (reg:SI T_REG))]
3707   "TARGET_SH1 && reload_completed"
3708   [(use (reg:SI R0_REG))]
3709   "
3710 {
3711   gen_shifty_hi_op (ASHIFT, operands);
3712   DONE;
3713 }")
3714
3715 ;
3716 ; arithmetic shift right
3717 ;
3718
3719 (define_insn "ashrsi3_sh2a"
3720   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3721         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3722                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3723   "TARGET_SH2A"
3724   "shad %2,%0"
3725   [(set_attr "type" "dyn_shift")
3726    (set_attr "length" "4")])
3727
3728 (define_insn "ashrsi3_k"
3729   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3730         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3731                      (match_operand:SI 2 "const_int_operand" "M")))
3732    (clobber (reg:SI T_REG))]
3733   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3734   "shar %0"
3735   [(set_attr "type" "arith")])
3736
3737 ;; We can't do HImode right shifts correctly unless we start out with an
3738 ;; explicit zero / sign extension; doing that would result in worse overall
3739 ;; code, so just let the machine independent code widen the mode.
3740 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3741
3742
3743 ;; ??? This should be a define expand.
3744
3745 (define_insn "ashrsi2_16"
3746   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3747         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3748                      (const_int 16)))]
3749   "TARGET_SH1"
3750   "#"
3751   [(set_attr "length" "4")])
3752
3753 (define_split
3754   [(set (match_operand:SI 0 "arith_reg_dest" "")
3755         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3756                      (const_int 16)))]
3757   "TARGET_SH1"
3758   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3759    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3760   "operands[2] = gen_lowpart (HImode, operands[0]);")
3761
3762 ;; ??? This should be a define expand.
3763
3764 (define_insn "ashrsi2_31"
3765   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767                      (const_int 31)))
3768    (clobber (reg:SI T_REG))]
3769   "TARGET_SH1"
3770   "#"
3771   [(set_attr "length" "4")])
3772
3773 (define_split
3774   [(set (match_operand:SI 0 "arith_reg_dest" "")
3775         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3776                      (const_int 31)))
3777    (clobber (reg:SI T_REG))]
3778   "TARGET_SH1"
3779   [(const_int 0)]
3780   "
3781 {
3782   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3783   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3784   DONE;
3785 }")
3786
3787 (define_peephole2
3788   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3789    (set (reg:SI T_REG)
3790         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3791   "TARGET_SH1
3792    && peep2_reg_dead_p (2, operands[0])
3793    && peep2_reg_dead_p (2, operands[1])"
3794   [(const_int 0)]
3795   "
3796 {
3797   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3798   DONE;
3799 }")
3800
3801 (define_insn "ashlsi_c"
3802   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3803         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3804    (set (reg:SI T_REG)
3805         (lt:SI (match_dup 1) (const_int 0)))]
3806   "TARGET_SH1"
3807   "shll %0"
3808   [(set_attr "type" "arith")])
3809
3810 (define_insn "*ashlsi_c_void"
3811   [(set (reg:SI T_REG)
3812         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3813    (clobber (match_scratch:SI 1 "=0"))]
3814   "TARGET_SH1 && cse_not_expected"
3815   "shll %0"
3816   [(set_attr "type" "arith")])
3817
3818 (define_insn "ashrsi3_d"
3819   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3820         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3821                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3822   "TARGET_SH3"
3823   "shad %2,%0"
3824   [(set_attr "type" "dyn_shift")])
3825
3826 (define_insn "ashrsi3_n"
3827   [(set (reg:SI R4_REG)
3828         (ashiftrt:SI (reg:SI R4_REG)
3829                      (match_operand:SI 0 "const_int_operand" "i")))
3830    (clobber (reg:SI T_REG))
3831    (clobber (reg:SI PR_REG))
3832    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3833   "TARGET_SH1"
3834   "jsr  @%1%#"
3835   [(set_attr "type" "sfunc")
3836    (set_attr "needs_delay_slot" "yes")])
3837
3838 (define_insn "ashrsi3_media"
3839   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3840         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3841                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3842   "TARGET_SHMEDIA"
3843   "@
3844         shard.l %1, %2, %0
3845         shari.l %1, %2, %0"
3846   [(set_attr "type" "arith_media")
3847    (set_attr "highpart" "ignore")])
3848
3849 (define_expand "ashrsi3"
3850   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3851                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3852                                 (match_operand:SI 2 "nonmemory_operand" "")))
3853               (clobber (reg:SI T_REG))])]
3854   ""
3855   "
3856 {
3857   if (TARGET_SHMEDIA)
3858     {
3859       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3860       DONE;
3861     }
3862   if (expand_ashiftrt (operands))
3863     DONE;
3864   else
3865     FAIL;
3866 }")
3867
3868 ;; logical shift right
3869
3870 (define_insn "lshrsi3_sh2a"
3871   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3872         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3873                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3874   "TARGET_SH2A"
3875   "shld %2,%0"
3876   [(set_attr "type" "dyn_shift")
3877    (set_attr "length" "4")])
3878
3879 (define_insn "lshrsi3_d"
3880   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3881         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3882                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3883   "TARGET_SH3"
3884   "shld %2,%0"
3885   [(set_attr "type" "dyn_shift")])
3886
3887 ;;  Only the single bit shift clobbers the T bit.
3888
3889 (define_insn "lshrsi3_m"
3890   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3891         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3892                      (match_operand:SI 2 "const_int_operand" "M")))
3893    (clobber (reg:SI T_REG))]
3894   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3895   "shlr %0"
3896   [(set_attr "type" "arith")])
3897
3898 (define_insn "lshrsi3_k"
3899   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3900         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3901                      (match_operand:SI 2 "const_int_operand" "P27")))]
3902   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3903    && ! satisfies_constraint_M (operands[2])"
3904   "shlr%O2      %0"
3905   [(set_attr "type" "arith")])
3906
3907 (define_insn "lshrsi3_n"
3908   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3909         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3910                      (match_operand:SI 2 "const_int_operand" "n")))
3911    (clobber (reg:SI T_REG))]
3912   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3913   "#"
3914   [(set (attr "length")
3915         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3916                (const_string "2")
3917                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3918                (const_string "4")
3919                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3920                (const_string "6")]
3921               (const_string "8")))
3922    (set_attr "type" "arith")])
3923
3924 (define_split
3925   [(set (match_operand:SI 0 "arith_reg_dest" "")
3926         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3927                      (match_operand:SI 2 "const_int_operand" "")))
3928    (clobber (reg:SI T_REG))]
3929   "TARGET_SH1 && reload_completed"
3930   [(use (reg:SI R0_REG))]
3931   "
3932 {
3933   gen_shifty_op (LSHIFTRT, operands);
3934   DONE;
3935 }")
3936
3937 (define_insn "lshrsi3_media"
3938   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3939         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3940                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3941   "TARGET_SHMEDIA"
3942   "@
3943         shlrd.l %1, %2, %0
3944         shlri.l %1, %2, %0"
3945   [(set_attr "type" "arith_media")
3946    (set_attr "highpart" "ignore")])
3947
3948 (define_expand "lshrsi3"
3949   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3950                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3951                                 (match_operand:SI 2 "nonmemory_operand" "")))
3952               (clobber (reg:SI T_REG))])]
3953   ""
3954   "
3955 {
3956   if (TARGET_SHMEDIA)
3957     {
3958       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3959       DONE;
3960     }
3961   if (GET_CODE (operands[2]) == CONST_INT
3962       && sh_dynamicalize_shift_p (operands[2]))
3963     operands[2] = force_reg (SImode, operands[2]);
3964   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3965     {
3966       rtx count = copy_to_mode_reg (SImode, operands[2]);
3967       emit_insn (gen_negsi2 (count, count));
3968       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3969       DONE;
3970     }
3971   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3972     FAIL;
3973 }")
3974
3975 ;; ??? This should be a define expand.
3976
3977 (define_insn "ashldi3_k"
3978   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3979         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3980                    (const_int 1)))
3981    (clobber (reg:SI T_REG))]
3982   "TARGET_SH1"
3983   "shll %R0\;rotcl      %S0"
3984   [(set_attr "length" "4")
3985    (set_attr "type" "arith")])
3986
3987 (define_insn "ashldi3_media"
3988   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3989         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3990                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3991   "TARGET_SHMEDIA"
3992   "@
3993         shlld   %1, %2, %0
3994         shlli   %1, %2, %0"
3995   [(set_attr "type" "arith_media")])
3996
3997 (define_insn "*ashldisi3_media"
3998   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3999         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4000                    (match_operand:DI 2 "const_int_operand" "n")))]
4001   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4002   "shlli.l      %1, %2, %0"
4003   [(set_attr "type" "arith_media")
4004    (set_attr "highpart" "ignore")])
4005
4006 (define_expand "ashldi3"
4007   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4008                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4009                               (match_operand:DI 2 "immediate_operand" "")))
4010               (clobber (reg:SI T_REG))])]
4011   ""
4012   "
4013 {
4014   if (TARGET_SHMEDIA)
4015     {
4016       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4017       DONE;
4018     }