OSDN Git Service

90353b2df7ba8deb79056106f01943858515b5ca
[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[0] == 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   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2481   DONE;
2482 }")
2483
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488   [(set (match_operand:SI 0 "register_operand" "=r")
2489         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491                                 (match_operand:DI 3 "register_operand" "r")
2492                                 (match_operand:SI 4 "register_operand" "r")]
2493                      UNSPEC_DIV_INV_M1)
2494                     (unspec:SI [(match_dup 4)
2495                                 (unspec:SI [(match_dup 2)
2496                                             (match_dup 3)
2497                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2498                                 (match_operand:SI 5 "" "")]
2499                      UNSPEC_DIV_INV_M2)
2500                     (match_operand:DI 6 "register_operand" "r")
2501                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2503          UNSPEC_DIV_INV_M3))
2504    (clobber (match_operand:DI 9 "register_operand" "=r"))
2505    (clobber (match_operand:DI 10 "register_operand" "=r"))
2506    (clobber (match_operand:DI 11 "register_operand" "=r"))
2507    (clobber (match_operand:DI 12 "register_operand" "=r"))
2508    (clobber (match_operand:SI 13 "register_operand" "=r"))
2509    (clobber (match_operand:SI 14 "register_operand" "=r"))
2510    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2511   "TARGET_SHMEDIA
2512    && (TARGET_DIVIDE_INV_MINLAT
2513        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2514   "#"
2515   "&& !can_create_pseudo_p ()"
2516   [(pc)]
2517   "
2518 {
2519   rtx result = operands[0];
2520   rtx dividend = operands[1];
2521   rtx tab_base = operands[2];
2522   rtx tab_ix = operands[3];
2523   rtx norm32 = operands[4];
2524   /* rtx i92 = operands[5]; */
2525   rtx shift = operands[6];
2526   rtx i2p27 = operands[7];
2527   rtx i43 = operands[8];
2528   rtx scratch0 = operands[9];
2529   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530   rtx scratch1 = operands[10];
2531   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532   rtx scratch2 = operands[11];
2533   rtx scratch3 = operands[12];
2534   rtx scratch4 = operands[13];
2535   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536   rtx scratch5 = operands[14];
2537   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538   rtx scratch6 = operands[15];
2539
2540   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541                                scratch0, scratch1));
2542   /* inv0 == scratch4 */
2543   if (! TARGET_DIVIDE_INV20U)
2544     {
2545       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2546       i2p27 = scratch0;
2547       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2548     }
2549   else
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2553     }
2554   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557   /* inv1 == scratch4 */
2558
2559   if (TARGET_DIVIDE_INV_MINLAT)
2560     {
2561       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2572     }
2573   else
2574     {
2575       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2577       emit_insn (gen_nsbdi (scratch6,
2578                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581       emit_insn (gen_divsi_inv20 (scratch2,
2582                                   norm32, scratch4, dividend,
2583                                   scratch6, scratch3, i43,
2584                                   /* scratch0 may be shared with i2p27.  */
2585                                   scratch0, scratch1, scratch5,
2586                                   label, label, i2p27));
2587     }
2588   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2590   DONE;
2591 }")
2592
2593 (define_insn "divsi_inv20"
2594   [(set (match_operand:DI 0 "register_operand" "=&r")
2595         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596                     (match_operand:SI 2 "register_operand" "r")
2597                     (match_operand:SI 3 "register_operand" "r")
2598                     (match_operand:DI 4 "register_operand" "r")
2599                     (match_operand:DI 5 "register_operand" "r")
2600                     (match_operand:DI 6 "register_operand" "r")
2601                     (match_operand:DI 12 "register_operand" "r")
2602                     (match_operand 10 "target_operand" "b")
2603                     (match_operand 11 "immediate_operand" "i")]
2604          UNSPEC_DIV_INV20))
2605    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2608   "TARGET_SHMEDIA
2609    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2610   "*
2611 {
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615              %10 label (tr), %11 label (imm)
2616
2617  muls.l inv1, norm32, scratch0  // s2.60
2618   muls.l inv1, dividend, result // s32.30
2619   xor i2p27, result_sign, round_scratch
2620  bge/u dividend_nsb, i43, tr.. (label)
2621  shari scratch0, 16, scratch0   // s-16.44
2622  muls.l sratch0_si, inv1, scratch0 // s-16.74
2623   sub result, round_scratch, result
2624   shari dividend, 14, scratch1   // s19.-14
2625  shari scratch0, 30, scratch0   // s-16.44
2626  muls.l scratch0, scratch1, round_scratch // s15.30
2627 label:
2628  sub result, round_scratch, result */
2629
2630   int likely = TARGET_DIVIDE_INV20L;
2631
2632   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634   output_asm_insn (likely
2635                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636                    : \"bge/u\t%4, %6, %10\", operands);
2637   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2640   return (likely
2641           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2643 }")
2644
2645 (define_insn_and_split "divsi_inv_fp"
2646   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648                 (match_operand:SI 2 "register_operand" "rf")))
2649    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650    (clobber (match_operand:SI 4 "register_operand" "=r"))
2651    (clobber (match_operand:SI 5 "register_operand" "=r"))
2652    (clobber (match_operand:DF 6 "register_operand" "=r"))
2653    (clobber (match_operand:DF 7 "register_operand" "=r"))
2654    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655   "TARGET_SHMEDIA_FPU"
2656   "#"
2657   "&& (high_life_started || reload_completed)"
2658   [(set (match_dup 0) (match_dup 3))]
2659   ""
2660   [(set_attr "highpart" "must_split")])
2661
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666   [(set (match_operand:SI 0 "register_operand" "=f")
2667         (div:SI (match_operand:SI 1 "register_operand" "f")
2668                 (match_operand:SI 2 "register_operand" "f")))
2669    (use (unspec:SI [(match_dup 1)
2670                     (match_operand:SI 3 "" "")
2671                     (unspec:SI [(match_operand:SI 4 "" "")
2672                                 (match_dup 3)
2673                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674                     (match_operand:DI 6 "" "")
2675                     (const_int 0)
2676                     (const_int 0)] UNSPEC_DIV_INV_M3))
2677    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2683   "#"
2684   "&& 1"
2685   [(set (match_dup 9) (float:DF (match_dup 1)))
2686    (set (match_dup 10) (float:DF (match_dup 2)))
2687    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2688    (set (match_dup 8)
2689         (fix:SI (match_dup 11)))
2690    (set (match_dup 0) (match_dup 8))]
2691   "
2692 {
2693   if (! fp_arith_reg_operand (operands[1], SImode))
2694     {
2695       emit_move_insn (operands[7], operands[1]);
2696       operands[1] = operands[7];
2697     }
2698   if (! fp_arith_reg_operand (operands[2], SImode))
2699     {
2700       emit_move_insn (operands[8], operands[2]);
2701       operands[2] = operands[8];
2702     }
2703 }"
2704   [(set_attr "highpart" "must_split")])
2705 \f
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2709
2710 (define_insn "umulhisi3_i"
2711   [(set (reg:SI MACL_REG)
2712         (mult:SI (zero_extend:SI
2713                   (match_operand:HI 0 "arith_reg_operand" "r"))
2714                  (zero_extend:SI
2715                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716   "TARGET_SH1"
2717   "mulu.w       %1,%0"
2718   [(set_attr "type" "smpy")])
2719
2720 (define_insn "mulhisi3_i"
2721   [(set (reg:SI MACL_REG)
2722         (mult:SI (sign_extend:SI
2723                   (match_operand:HI 0 "arith_reg_operand" "r"))
2724                  (sign_extend:SI
2725                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2726   "TARGET_SH1"
2727   "muls.w       %1,%0"
2728   [(set_attr "type" "smpy")])
2729
2730 (define_expand "mulhisi3"
2731   [(set (reg:SI MACL_REG)
2732         (mult:SI (sign_extend:SI
2733                   (match_operand:HI 1 "arith_reg_operand" ""))
2734                  (sign_extend:SI
2735                   (match_operand:HI 2 "arith_reg_operand" ""))))
2736    (set (match_operand:SI 0 "arith_reg_operand" "")
2737         (reg:SI MACL_REG))]
2738   "TARGET_SH1"
2739   "
2740 {
2741   rtx insn, macl;
2742
2743   macl = gen_rtx_REG (SImode, MACL_REG);
2744   start_sequence ();
2745   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746   insn = get_insns ();  
2747   end_sequence ();
2748   /* expand_binop can't find a suitable code in umul_widen_optab to
2749      make a REG_EQUAL note from, so make one here.
2750      See also smulsi3_highpart.
2751      ??? Alternatively, we could put this at the calling site of expand_binop,
2752      i.e. expand_expr.  */
2753   /* Use emit_libcall_block for loop invariant code motion and to make
2754      a REG_EQUAL note.  */
2755   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2756
2757   DONE;
2758 }")
2759
2760 (define_expand "umulhisi3"
2761   [(set (reg:SI MACL_REG)
2762         (mult:SI (zero_extend:SI
2763                   (match_operand:HI 1 "arith_reg_operand" ""))
2764                  (zero_extend:SI
2765                   (match_operand:HI 2 "arith_reg_operand" ""))))
2766    (set (match_operand:SI 0 "arith_reg_operand" "")
2767         (reg:SI MACL_REG))]
2768   "TARGET_SH1"
2769   "
2770 {
2771   rtx insn, macl;
2772
2773   macl = gen_rtx_REG (SImode, MACL_REG);
2774   start_sequence ();
2775   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776   insn = get_insns ();  
2777   end_sequence ();
2778   /* expand_binop can't find a suitable code in umul_widen_optab to
2779      make a REG_EQUAL note from, so make one here.
2780      See also smulsi3_highpart.
2781      ??? Alternatively, we could put this at the calling site of expand_binop,
2782      i.e. expand_expr.  */
2783   /* Use emit_libcall_block for loop invariant code motion and to make
2784      a REG_EQUAL note.  */
2785   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2786
2787   DONE;
2788 }")
2789
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2792
2793 (define_insn ""
2794   [(set (match_operand:SI 1 "register_operand" "=z")
2795         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796    (clobber (reg:SI MACL_REG))
2797    (clobber (reg:SI T_REG))
2798    (clobber (reg:SI PR_REG))
2799    (clobber (reg:SI R3_REG))
2800    (clobber (reg:SI R2_REG))
2801    (clobber (reg:SI R1_REG))
2802    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2803   "TARGET_SH1"
2804   "jsr  @%0%#"
2805   [(set_attr "type" "sfunc")
2806    (set_attr "needs_delay_slot" "yes")])
2807
2808 (define_expand "mulsi3_call"
2809   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811    (parallel[(set (match_operand:SI 0 "register_operand" "")
2812                   (mult:SI (reg:SI R4_REG)
2813                            (reg:SI R5_REG)))
2814              (clobber (reg:SI MACL_REG))
2815              (clobber (reg:SI T_REG))
2816              (clobber (reg:SI PR_REG))
2817              (clobber (reg:SI R3_REG))
2818              (clobber (reg:SI R2_REG))
2819              (clobber (reg:SI R1_REG))
2820              (use (match_operand:SI 3 "register_operand" ""))])]
2821   "TARGET_SH1"
2822   "")
2823
2824 (define_insn "mul_r"
2825   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2828   "TARGET_SH2A"
2829   "mulr %2,%0"
2830   [(set_attr "type" "dmpy")])
2831
2832 (define_insn "mul_l"
2833   [(set (reg:SI MACL_REG)
2834         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2836   "TARGET_SH2"
2837   "mul.l        %1,%0"
2838   [(set_attr "type" "dmpy")])
2839
2840 (define_expand "mulsi3"
2841   [(set (reg:SI MACL_REG)
2842         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2843                   (match_operand:SI 2 "arith_reg_operand" "")))
2844    (set (match_operand:SI 0 "arith_reg_operand" "")
2845         (reg:SI MACL_REG))]
2846   "TARGET_SH1"
2847   "
2848 {
2849   if (!TARGET_SH2)
2850     {
2851       /* The address must be set outside the libcall,
2852          since it goes into a pseudo.  */
2853       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854       rtx addr = force_reg (SImode, sym);
2855       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2856                                    operands[2], addr);
2857       emit_insn (insns);
2858     }
2859   else
2860     {
2861       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2862
2863       emit_insn (gen_mul_l (operands[1], operands[2]));
2864       /* consec_sets_giv can only recognize the first insn that sets a
2865          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2866          note.  */
2867       emit_insn (gen_movsi_i ((operands[0]), macl));
2868     }
2869   DONE;
2870 }")
2871
2872 (define_insn "mulsidi3_i"
2873   [(set (reg:SI MACH_REG)
2874         (truncate:SI
2875          (lshiftrt:DI
2876           (mult:DI
2877            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2879           (const_int 32))))
2880    (set (reg:SI MACL_REG)
2881         (mult:SI (match_dup 0)
2882                  (match_dup 1)))]
2883   "TARGET_SH2"
2884   "dmuls.l      %1,%0"
2885   [(set_attr "type" "dmpy")])
2886
2887 (define_expand "mulsidi3"
2888   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891   "TARGET_SH2 || TARGET_SHMEDIA"
2892   "
2893 {
2894   if (TARGET_SH2)
2895     {
2896        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2897                                         operands[2]));
2898        DONE;
2899     }
2900 }")
2901
2902 (define_insn "mulsidi3_media"
2903   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2906   "TARGET_SHMEDIA"
2907   "muls.l       %1, %2, %0"
2908   [(set_attr "type" "dmpy_media")
2909    (set_attr "highpart" "ignore")])
2910
2911 (define_insn "mulsidi3_compact"
2912   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913         (mult:DI
2914          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916    (clobber (reg:SI MACH_REG))
2917    (clobber (reg:SI MACL_REG))]
2918   "TARGET_SH2"
2919   "#")
2920
2921 (define_split
2922   [(set (match_operand:DI 0 "arith_reg_dest" "")
2923         (mult:DI
2924          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926    (clobber (reg:SI MACH_REG))
2927    (clobber (reg:SI MACL_REG))]
2928   "TARGET_SH2"
2929   [(const_int 0)]
2930   "
2931 {
2932   rtx low_dst = gen_lowpart (SImode, operands[0]);
2933   rtx high_dst = gen_highpart (SImode, operands[0]);
2934
2935   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2936
2937   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939   /* We need something to tag the possible REG_EQUAL notes on to.  */
2940   emit_move_insn (operands[0], operands[0]);
2941   DONE;
2942 }")
2943
2944 (define_insn "umulsidi3_i"
2945   [(set (reg:SI MACH_REG)
2946         (truncate:SI
2947          (lshiftrt:DI
2948           (mult:DI
2949            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2951           (const_int 32))))
2952    (set (reg:SI MACL_REG)
2953         (mult:SI (match_dup 0)
2954                  (match_dup 1)))]
2955   "TARGET_SH2"
2956   "dmulu.l      %1,%0"
2957   [(set_attr "type" "dmpy")])
2958
2959 (define_expand "umulsidi3"
2960   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963   "TARGET_SH2 || TARGET_SHMEDIA"
2964   "
2965 {
2966   if (TARGET_SH2)
2967     {
2968        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2969                                          operands[2]));
2970        DONE;
2971     }
2972 }")
2973
2974 (define_insn "umulsidi3_media"
2975   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2978   "TARGET_SHMEDIA"
2979   "mulu.l       %1, %2, %0"
2980   [(set_attr "type" "dmpy_media")
2981    (set_attr "highpart" "ignore")])
2982
2983 (define_insn "umulsidi3_compact"
2984   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985         (mult:DI
2986          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988    (clobber (reg:SI MACH_REG))
2989    (clobber (reg:SI MACL_REG))]
2990   "TARGET_SH2"
2991   "#")
2992
2993 (define_split
2994   [(set (match_operand:DI 0 "arith_reg_dest" "")
2995         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997    (clobber (reg:SI MACH_REG))
2998    (clobber (reg:SI MACL_REG))]
2999   "TARGET_SH2"
3000   [(const_int 0)]
3001   "
3002 {
3003   rtx low_dst = gen_lowpart (SImode, operands[0]);
3004   rtx high_dst = gen_highpart (SImode, operands[0]);
3005
3006   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3007
3008   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010   /* We need something to tag the possible REG_EQUAL notes on to.  */
3011   emit_move_insn (operands[0], operands[0]);
3012   DONE;
3013 }")
3014
3015 (define_insn "smulsi3_highpart_i"
3016   [(set (reg:SI MACH_REG)
3017         (truncate:SI
3018          (lshiftrt:DI
3019           (mult:DI
3020            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3022           (const_int 32))))
3023    (clobber (reg:SI MACL_REG))]
3024   "TARGET_SH2"
3025   "dmuls.l      %1,%0"
3026   [(set_attr "type" "dmpy")])
3027
3028 (define_expand "smulsi3_highpart"
3029   [(parallel
3030     [(set (reg:SI MACH_REG)
3031           (truncate:SI
3032            (lshiftrt:DI
3033             (mult:DI
3034              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3036             (const_int 32))))
3037     (clobber (reg:SI MACL_REG))])
3038    (set (match_operand:SI 0 "arith_reg_operand" "")
3039         (reg:SI MACH_REG))]
3040   "TARGET_SH2"
3041   "
3042 {
3043   rtx insn, mach;
3044
3045   mach = gen_rtx_REG (SImode, MACH_REG);
3046   start_sequence ();
3047   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048   insn = get_insns ();  
3049   end_sequence ();
3050   /* expand_binop can't find a suitable code in mul_highpart_optab to
3051      make a REG_EQUAL note from, so make one here.
3052      See also {,u}mulhisi.
3053      ??? Alternatively, we could put this at the calling site of expand_binop,
3054      i.e. expand_mult_highpart.  */
3055   /* Use emit_libcall_block for loop invariant code motion and to make
3056      a REG_EQUAL note.  */
3057   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3058
3059   DONE;
3060 }")
3061
3062 (define_insn "umulsi3_highpart_i"
3063   [(set (reg:SI MACH_REG)
3064         (truncate:SI
3065          (lshiftrt:DI
3066           (mult:DI
3067            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3069           (const_int 32))))
3070    (clobber (reg:SI MACL_REG))]
3071   "TARGET_SH2"
3072   "dmulu.l      %1,%0"
3073   [(set_attr "type" "dmpy")])
3074
3075 (define_expand "umulsi3_highpart"
3076   [(parallel
3077     [(set (reg:SI MACH_REG)
3078           (truncate:SI
3079            (lshiftrt:DI
3080             (mult:DI
3081              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3083             (const_int 32))))
3084     (clobber (reg:SI MACL_REG))])
3085    (set (match_operand:SI 0 "arith_reg_operand" "")
3086         (reg:SI MACH_REG))]
3087   "TARGET_SH2"
3088   "
3089 {
3090   rtx insn, mach;
3091
3092   mach = gen_rtx_REG (SImode, MACH_REG);
3093   start_sequence ();
3094   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095   insn = get_insns ();  
3096   end_sequence ();
3097   /* Use emit_libcall_block for loop invariant code motion and to make
3098      a REG_EQUAL note.  */
3099   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3100
3101   DONE;
3102 }")
3103
3104 (define_insn_and_split "muldi3"
3105   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107                  (match_operand:DI 2 "arith_reg_operand" "r")))
3108    (clobber (match_scratch:DI 3 "=&r"))
3109    (clobber (match_scratch:DI 4 "=r"))]
3110   "TARGET_SHMEDIA"
3111   "#"
3112   "reload_completed"
3113   [(const_int 0)]
3114   "
3115 {
3116   rtx op3_v2si, op2_v2si;
3117
3118   op3_v2si = operands[3];
3119   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3120     {
3121       op3_v2si = XEXP (op3_v2si, 0);
3122       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3123     }
3124   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125   op2_v2si = operands[2];
3126   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3127     {
3128       op2_v2si = XEXP (op2_v2si, 0);
3129       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3130     }
3131   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134   emit_insn (gen_umulsidi3_media (operands[4],
3135                                  sh_gen_truncate (SImode, operands[1], 0),
3136                                  sh_gen_truncate (SImode, operands[2], 0)));
3137   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3141   DONE;
3142 }")
3143
3144 \f
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3148
3149 (define_insn "*andsi3_compact"
3150   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3153   "TARGET_SH1"
3154   "and  %2,%0"
3155   [(set_attr "type" "arith")])
3156
3157 (define_insn "*andsi3_media"
3158   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3161   "TARGET_SHMEDIA"
3162   "@
3163         and     %1, %2, %0
3164         andi    %1, %2, %0"
3165   [(set_attr "type" "arith_media")])
3166
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3169
3170 (define_expand "andsi3"
3171   [(set (match_operand:SI 0 "arith_reg_operand" "")
3172         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173                 (match_operand:SI 2 "logical_operand" "")))]
3174   ""
3175   "
3176 {
3177   if (TARGET_SH1
3178       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3179     {
3180       emit_insn (gen_zero_extendqisi2 (operands[0],
3181                                        gen_lowpart (QImode, operands[1])));
3182       DONE;
3183     }
3184 }")
3185
3186 (define_insn_and_split "anddi3"
3187   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3190   "TARGET_SHMEDIA"
3191   "@
3192         and     %1, %2, %0
3193         andi    %1, %2, %0
3194         #"
3195   "reload_completed
3196    && ! logical_operand (operands[2], DImode)"
3197   [(const_int 0)]
3198   "
3199 {
3200   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3202   else
3203     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3204   DONE;
3205 }"
3206   [(set_attr "type" "arith_media")])
3207
3208 (define_insn "andcsi3"
3209   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3212   "TARGET_SHMEDIA"
3213   "andc %1,%2,%0"
3214   [(set_attr "type" "arith_media")])
3215
3216 (define_insn "andcdi3"
3217   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3220   "TARGET_SHMEDIA"
3221   "andc %1,%2,%0"
3222   [(set_attr "type" "arith_media")])
3223
3224 (define_expand "iorsi3"
3225   [(set (match_operand:SI 0 "arith_reg_operand" "")
3226         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227                 (match_operand:SI 2 "logical_operand" "")))]
3228   ""
3229   "")
3230
3231 (define_insn "*iorsi3_compact"
3232   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3235   "TARGET_SH1"
3236   "or   %2,%0"
3237   [(set_attr "type" "arith")])
3238
3239 (define_insn "*iorsi3_media"
3240   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3243   "TARGET_SHMEDIA"
3244   "@
3245         or      %1, %2, %0
3246         ori     %1, %2, %0"
3247   [(set_attr "type" "arith_media")])
3248
3249 (define_insn "iordi3"
3250   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3253   "TARGET_SHMEDIA"
3254   "@
3255         or      %1, %2, %0
3256         ori     %1, %2, %0"
3257   [(set_attr "type" "arith_media")])
3258
3259 (define_insn_and_split "*logical_sidi3"
3260   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3264   "TARGET_SHMEDIA"
3265   "#"
3266   "&& reload_completed"
3267   [(set (match_dup 0) (match_dup 3))]
3268   "
3269 {
3270   operands[3]
3271     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3274 }")
3275
3276 (define_insn_and_split "*logical_sidisi3"
3277   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278         (truncate:SI (sign_extend:DI
3279                         (match_operator:SI 3 "logical_operator"
3280                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3282   "TARGET_SHMEDIA"
3283   "#"
3284   "&& 1"
3285   [(set (match_dup 0) (match_dup 3))])
3286
3287 (define_insn_and_split "*logical_sidi3_2"
3288   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289         (sign_extend:DI (truncate:SI (sign_extend:DI
3290                         (match_operator:SI 3 "logical_operator"
3291                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3293   "TARGET_SHMEDIA"
3294   "#"
3295   "&& 1"
3296   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3297
3298 (define_expand "xorsi3"
3299   [(set (match_operand:SI 0 "arith_reg_operand" "")
3300         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301                 (match_operand:SI 2 "xor_operand" "")))]
3302   ""
3303   "")
3304
3305 (define_insn "*xorsi3_compact"
3306   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3309   "TARGET_SH1"
3310   "xor  %2,%0"
3311   [(set_attr "type" "arith")])
3312
3313 (define_insn "*xorsi3_media"
3314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3317   "TARGET_SHMEDIA"
3318   "@
3319         xor     %1, %2, %0
3320         xori    %1, %2, %0"
3321   [(set_attr "type" "arith_media")])
3322
3323 (define_insn "xordi3"
3324   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3327   "TARGET_SHMEDIA"
3328   "@
3329         xor     %1, %2, %0
3330         xori    %1, %2, %0"
3331   [(set_attr "type" "arith_media")])
3332
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3335 (define_split
3336   [(set (match_operand:DI 0 "arith_reg_dest" "")
3337         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338                           [(match_operand 1 "any_register_operand" "")
3339                            (match_operand 2 "any_register_operand" "")])))]
3340   "TARGET_SHMEDIA"
3341   [(set (match_dup 5) (match_dup 4))
3342    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3343 "
3344 {
3345   enum machine_mode inmode = GET_MODE (operands[1]);
3346   int offset = 0;
3347
3348   if (GET_CODE (operands[0]) == SUBREG)
3349     {
3350       offset = SUBREG_BYTE (operands[0]);
3351       operands[0] = SUBREG_REG (operands[0]);
3352     }
3353   gcc_assert (GET_CODE (operands[0]) == REG);
3354   if (! TARGET_LITTLE_ENDIAN)
3355     offset += 8 - GET_MODE_SIZE (inmode);
3356   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3357 }")
3358 \f
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3362
3363 (define_expand "rotldi3"
3364   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3367   "TARGET_SHMEDIA"
3368   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3369
3370 (define_insn "rotldi3_mextr"
3371   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3374   "TARGET_SHMEDIA"
3375   "*
3376 {
3377   static char templ[16];
3378
3379   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380            8 - (int) (INTVAL (operands[2]) >> 3));
3381   return templ;
3382 }"
3383   [(set_attr "type" "arith_media")])
3384
3385 (define_expand "rotrdi3"
3386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3389   "TARGET_SHMEDIA"
3390   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3391
3392 (define_insn "rotrdi3_mextr"
3393   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3396   "TARGET_SHMEDIA"
3397   "*
3398 {
3399   static char templ[16];
3400
3401   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3402   return templ;
3403 }"
3404   [(set_attr "type" "arith_media")])
3405
3406 (define_split
3407   [(set (match_operand:DI 0 "arith_reg_dest" "")
3408         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409                                          "ua_address_operand" "")))
3410                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3411                            (const_int 8))))
3412    (clobber (match_operand:DI 3 "register_operand" ""))]
3413   "TARGET_SHMEDIA"
3414   [(match_dup 4) (match_dup 5)]
3415   "
3416 {
3417   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418                  (operands[3], operands[1]));
3419   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3420                               GEN_INT (56), GEN_INT (8));
3421 }")
3422
3423 (define_insn "rotlsi3_1"
3424   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3425         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3426                    (const_int 1)))
3427    (set (reg:SI T_REG)
3428         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3429   "TARGET_SH1"
3430   "rotl %0"
3431   [(set_attr "type" "arith")])
3432
3433 (define_insn "rotlsi3_31"
3434   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3436                    (const_int 31)))
3437    (clobber (reg:SI T_REG))]
3438   "TARGET_SH1"
3439   "rotr %0"
3440   [(set_attr "type" "arith")])
3441
3442 (define_insn "rotlsi3_16"
3443   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3444         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3445                    (const_int 16)))]
3446   "TARGET_SH1"
3447   "swap.w       %1,%0"
3448   [(set_attr "type" "arith")])
3449
3450 (define_expand "rotlsi3"
3451   [(set (match_operand:SI 0 "arith_reg_dest" "")
3452         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3453                    (match_operand:SI 2 "immediate_operand" "")))]
3454   "TARGET_SH1"
3455   "
3456 {
3457   static const char rot_tab[] = {
3458     000, 000, 000, 000, 000, 000, 010, 001,
3459     001, 001, 011, 013, 003, 003, 003, 003,
3460     003, 003, 003, 003, 003, 013, 012, 002,
3461     002, 002, 010, 000, 000, 000, 000, 000,
3462   };
3463
3464   int count, choice;
3465
3466   if (GET_CODE (operands[2]) != CONST_INT)
3467     FAIL;
3468   count = INTVAL (operands[2]);
3469   choice = rot_tab[count];
3470   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3471     FAIL;
3472   choice &= 7;
3473   switch (choice)
3474     {
3475     case 0:
3476       emit_move_insn (operands[0], operands[1]);
3477       count -= (count & 16) * 2;
3478       break;
3479     case 3:
3480      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3481      count -= 16;
3482      break;
3483     case 1:
3484     case 2:
3485       {
3486         rtx parts[2];
3487         parts[0] = gen_reg_rtx (SImode);
3488         parts[1] = gen_reg_rtx (SImode);
3489         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3490         emit_move_insn (parts[choice-1], operands[1]);
3491         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3492         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3493         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3494         count = (count & ~16) - 8;
3495       }
3496     }
3497
3498   for (; count > 0; count--)
3499     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3500   for (; count < 0; count++)
3501     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3502
3503   DONE;
3504 }")
3505
3506 (define_insn "*rotlhi3_8"
3507   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3508         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3509                    (const_int 8)))]
3510   "TARGET_SH1"
3511   "swap.b       %1,%0"
3512   [(set_attr "type" "arith")])
3513
3514 (define_expand "rotlhi3"
3515   [(set (match_operand:HI 0 "arith_reg_operand" "")
3516         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3517                    (match_operand:HI 2 "immediate_operand" "")))]
3518   "TARGET_SH1"
3519   "
3520 {
3521   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3522     FAIL;
3523 }")
3524
3525 ;;
3526 ;; shift left
3527
3528 (define_insn "ashlsi3_sh2a"
3529   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3532   "TARGET_SH2A"
3533   "shad %2,%0"
3534   [(set_attr "type" "arith")
3535    (set_attr "length" "4")])
3536
3537 ;; This pattern is used by init_expmed for computing the costs of shift
3538 ;; insns.
3539
3540 (define_insn_and_split "ashlsi3_std"
3541   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3542         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3543                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3544    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3545   "TARGET_SH3
3546    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3547   "@
3548    shld %2,%0
3549    add  %0,%0
3550    shll%O2      %0
3551    #"
3552   "TARGET_SH3
3553    && reload_completed
3554    && GET_CODE (operands[2]) == CONST_INT
3555    && ! satisfies_constraint_P27 (operands[2])"
3556   [(set (match_dup 3) (match_dup 2))
3557    (parallel
3558     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3559      (clobber (match_dup 4))])]
3560   "operands[4] = gen_rtx_SCRATCH (SImode);"
3561   [(set_attr "length" "*,*,*,4")
3562    (set_attr "type" "dyn_shift,arith,arith,arith")])
3563
3564 (define_insn "ashlhi3_k"
3565   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3566         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3567                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3568   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3569   "@
3570         add     %0,%0
3571         shll%O2 %0"
3572   [(set_attr "type" "arith")])
3573
3574 (define_insn "ashlsi3_n"
3575   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577                    (match_operand:SI 2 "const_int_operand" "n")))
3578    (clobber (reg:SI T_REG))]
3579   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3580   "#"
3581   [(set (attr "length")
3582         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3583                (const_string "2")
3584                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3585                (const_string "4")
3586                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3587                (const_string "6")]
3588               (const_string "8")))
3589    (set_attr "type" "arith")])
3590
3591 (define_split
3592   [(set (match_operand:SI 0 "arith_reg_dest" "")
3593         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3594                    (match_operand:SI 2 "const_int_operand" "")))
3595    (clobber (reg:SI T_REG))]
3596   "TARGET_SH1 && reload_completed"
3597   [(use (reg:SI R0_REG))]
3598   "
3599 {
3600   gen_shifty_op (ASHIFT, operands);
3601   DONE;
3602 }")
3603
3604 (define_insn "ashlsi3_media"
3605   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3606         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3607                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3608   "TARGET_SHMEDIA"
3609   "@
3610         shlld.l %1, %2, %0
3611         shlli.l %1, %2, %0"
3612   [(set_attr "type" "arith_media")
3613    (set_attr "highpart" "ignore")])
3614
3615 (define_expand "ashlsi3"
3616   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3617                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3618                               (match_operand:SI 2 "nonmemory_operand" "")))
3619               (clobber (reg:SI T_REG))])]
3620   ""
3621   "
3622 {
3623   if (TARGET_SHMEDIA)
3624     {
3625       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3626       DONE;
3627     }
3628   if (GET_CODE (operands[2]) == CONST_INT
3629       && sh_dynamicalize_shift_p (operands[2]))
3630     operands[2] = force_reg (SImode, operands[2]);
3631   if (TARGET_SH3)
3632     {
3633       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3634       DONE;
3635     }
3636   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3637     FAIL;
3638 }")
3639
3640 (define_insn "*ashlhi3_n"
3641   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3642         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3643                    (match_operand:HI 2 "const_int_operand" "n")))
3644    (clobber (reg:SI T_REG))]
3645   "TARGET_SH1"
3646   "#"
3647   [(set (attr "length")
3648         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3649                (const_string "2")
3650                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3651                (const_string "4")]
3652               (const_string "6")))
3653    (set_attr "type" "arith")])
3654
3655 (define_expand "ashlhi3"
3656   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3657                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3658                               (match_operand:SI 2 "nonmemory_operand" "")))
3659               (clobber (reg:SI T_REG))])]
3660   "TARGET_SH1"
3661   "
3662 {
3663   if (GET_CODE (operands[2]) != CONST_INT)
3664     FAIL;
3665   /* It may be possible to call gen_ashlhi3 directly with more generic
3666      operands.  Make sure operands[1] is a HImode register here.  */
3667   if (!arith_reg_operand (operands[1], HImode))
3668     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3669 }")
3670
3671 (define_split
3672   [(set (match_operand:HI 0 "arith_reg_dest" "")
3673         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3674                    (match_operand:HI 2 "const_int_operand" "")))
3675    (clobber (reg:SI T_REG))]
3676   "TARGET_SH1 && reload_completed"
3677   [(use (reg:SI R0_REG))]
3678   "
3679 {
3680   gen_shifty_hi_op (ASHIFT, operands);
3681   DONE;
3682 }")
3683
3684 ;
3685 ; arithmetic shift right
3686 ;
3687
3688 (define_insn "ashrsi3_sh2a"
3689   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692   "TARGET_SH2A"
3693   "shad %2,%0"
3694   [(set_attr "type" "dyn_shift")
3695    (set_attr "length" "4")])
3696
3697 (define_insn "ashrsi3_k"
3698   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3700                      (match_operand:SI 2 "const_int_operand" "M")))
3701    (clobber (reg:SI T_REG))]
3702   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3703   "shar %0"
3704   [(set_attr "type" "arith")])
3705
3706 ;; We can't do HImode right shifts correctly unless we start out with an
3707 ;; explicit zero / sign extension; doing that would result in worse overall
3708 ;; code, so just let the machine independent code widen the mode.
3709 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3710
3711
3712 ;; ??? This should be a define expand.
3713
3714 (define_insn "ashrsi2_16"
3715   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3716         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3717                      (const_int 16)))]
3718   "TARGET_SH1"
3719   "#"
3720   [(set_attr "length" "4")])
3721
3722 (define_split
3723   [(set (match_operand:SI 0 "arith_reg_dest" "")
3724         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3725                      (const_int 16)))]
3726   "TARGET_SH1"
3727   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3728    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3729   "operands[2] = gen_lowpart (HImode, operands[0]);")
3730
3731 ;; ??? This should be a define expand.
3732
3733 (define_insn "ashrsi2_31"
3734   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3736                      (const_int 31)))
3737    (clobber (reg:SI T_REG))]
3738   "TARGET_SH1"
3739   "#"
3740   [(set_attr "length" "4")])
3741
3742 (define_split
3743   [(set (match_operand:SI 0 "arith_reg_dest" "")
3744         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3745                      (const_int 31)))
3746    (clobber (reg:SI T_REG))]
3747   "TARGET_SH1"
3748   [(const_int 0)]
3749   "
3750 {
3751   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3752   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3753   DONE;
3754 }")
3755
3756 (define_peephole2
3757   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3758    (set (reg:SI T_REG)
3759         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3760   "TARGET_SH1
3761    && peep2_reg_dead_p (2, operands[0])
3762    && peep2_reg_dead_p (2, operands[1])"
3763   [(const_int 0)]
3764   "
3765 {
3766   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3767   DONE;
3768 }")
3769
3770 (define_insn "ashlsi_c"
3771   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3773    (set (reg:SI T_REG)
3774         (lt:SI (match_dup 1) (const_int 0)))]
3775   "TARGET_SH1"
3776   "shll %0"
3777   [(set_attr "type" "arith")])
3778
3779 (define_insn "*ashlsi_c_void"
3780   [(set (reg:SI T_REG)
3781         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3782    (clobber (match_scratch:SI 1 "=0"))]
3783   "TARGET_SH1 && cse_not_expected"
3784   "shll %0"
3785   [(set_attr "type" "arith")])
3786
3787 (define_insn "ashrsi3_d"
3788   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3789         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3790                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3791   "TARGET_SH3"
3792   "shad %2,%0"
3793   [(set_attr "type" "dyn_shift")])
3794
3795 (define_insn "ashrsi3_n"
3796   [(set (reg:SI R4_REG)
3797         (ashiftrt:SI (reg:SI R4_REG)
3798                      (match_operand:SI 0 "const_int_operand" "i")))
3799    (clobber (reg:SI T_REG))
3800    (clobber (reg:SI PR_REG))
3801    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3802   "TARGET_SH1"
3803   "jsr  @%1%#"
3804   [(set_attr "type" "sfunc")
3805    (set_attr "needs_delay_slot" "yes")])
3806
3807 (define_insn "ashrsi3_media"
3808   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3809         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3810                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3811   "TARGET_SHMEDIA"
3812   "@
3813         shard.l %1, %2, %0
3814         shari.l %1, %2, %0"
3815   [(set_attr "type" "arith_media")
3816    (set_attr "highpart" "ignore")])
3817
3818 (define_expand "ashrsi3"
3819   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3820                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3821                                 (match_operand:SI 2 "nonmemory_operand" "")))
3822               (clobber (reg:SI T_REG))])]
3823   ""
3824   "
3825 {
3826   if (TARGET_SHMEDIA)
3827     {
3828       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3829       DONE;
3830     }
3831   if (expand_ashiftrt (operands))
3832     DONE;
3833   else
3834     FAIL;
3835 }")
3836
3837 ;; logical shift right
3838
3839 (define_insn "lshrsi3_sh2a"
3840   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3841         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3842                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3843   "TARGET_SH2A"
3844   "shld %2,%0"
3845   [(set_attr "type" "dyn_shift")
3846    (set_attr "length" "4")])
3847
3848 (define_insn "lshrsi3_d"
3849   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3850         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3851                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3852   "TARGET_SH3"
3853   "shld %2,%0"
3854   [(set_attr "type" "dyn_shift")])
3855
3856 ;;  Only the single bit shift clobbers the T bit.
3857
3858 (define_insn "lshrsi3_m"
3859   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3860         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3861                      (match_operand:SI 2 "const_int_operand" "M")))
3862    (clobber (reg:SI T_REG))]
3863   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3864   "shlr %0"
3865   [(set_attr "type" "arith")])
3866
3867 (define_insn "lshrsi3_k"
3868   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3869         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3870                      (match_operand:SI 2 "const_int_operand" "P27")))]
3871   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3872    && ! satisfies_constraint_M (operands[2])"
3873   "shlr%O2      %0"
3874   [(set_attr "type" "arith")])
3875
3876 (define_insn "lshrsi3_n"
3877   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879                      (match_operand:SI 2 "const_int_operand" "n")))
3880    (clobber (reg:SI T_REG))]
3881   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3882   "#"
3883   [(set (attr "length")
3884         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3885                (const_string "2")
3886                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3887                (const_string "4")
3888                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3889                (const_string "6")]
3890               (const_string "8")))
3891    (set_attr "type" "arith")])
3892
3893 (define_split
3894   [(set (match_operand:SI 0 "arith_reg_dest" "")
3895         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3896                      (match_operand:SI 2 "const_int_operand" "")))
3897    (clobber (reg:SI T_REG))]
3898   "TARGET_SH1 && reload_completed"
3899   [(use (reg:SI R0_REG))]
3900   "
3901 {
3902   gen_shifty_op (LSHIFTRT, operands);
3903   DONE;
3904 }")
3905
3906 (define_insn "lshrsi3_media"
3907   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3909                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3910   "TARGET_SHMEDIA"
3911   "@
3912         shlrd.l %1, %2, %0
3913         shlri.l %1, %2, %0"
3914   [(set_attr "type" "arith_media")
3915    (set_attr "highpart" "ignore")])
3916
3917 (define_expand "lshrsi3"
3918   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3919                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3920                                 (match_operand:SI 2 "nonmemory_operand" "")))
3921               (clobber (reg:SI T_REG))])]
3922   ""
3923   "
3924 {
3925   if (TARGET_SHMEDIA)
3926     {
3927       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3928       DONE;
3929     }
3930   if (GET_CODE (operands[2]) == CONST_INT
3931       && sh_dynamicalize_shift_p (operands[2]))
3932     operands[2] = force_reg (SImode, operands[2]);
3933   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3934     {
3935       rtx count = copy_to_mode_reg (SImode, operands[2]);
3936       emit_insn (gen_negsi2 (count, count));
3937       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3938       DONE;
3939     }
3940   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3941     FAIL;
3942 }")
3943
3944 ;; ??? This should be a define expand.
3945
3946 (define_insn "ashldi3_k"
3947   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3949                    (const_int 1)))
3950    (clobber (reg:SI T_REG))]
3951   "TARGET_SH1"
3952   "shll %R0\;rotcl      %S0"
3953   [(set_attr "length" "4")
3954    (set_attr "type" "arith")])
3955
3956 (define_insn "ashldi3_media"
3957   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3958         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3960   "TARGET_SHMEDIA"
3961   "@
3962         shlld   %1, %2, %0
3963         shlli   %1, %2, %0"
3964   [(set_attr "type" "arith_media")])
3965
3966 (define_insn "*ashldisi3_media"
3967   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3968         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3969                    (match_operand:DI 2 "const_int_operand" "n")))]
3970   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3971   "shlli.l      %1, %2, %0"
3972   [(set_attr "type" "arith_media")
3973    (set_attr "highpart" "ignore")])
3974
3975 (define_expand "ashldi3"
3976   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3977                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3978                               (match_operand:DI 2 "immediate_operand" "")))
3979               (clobber (reg:SI T_REG))])]
3980   ""
3981   "
3982 {
3983   if (TARGET_SHMEDIA)
3984     {
3985       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3986       DONE;
3987     }
3988   if (GET_CODE (operands[2]) != CONST_INT
3989       || INTVAL (operands[2]) != 1)
3990     FAIL;
3991 }")
3992
3993 ;; ??? This should be a define expand.
3994
3995 (define_insn "lshrdi3_k"
3996   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3997         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3998                      (const_int 1)))
3999    (clobber (reg:SI T_REG))]
4000   "TARGET_SH1"
4001   "shlr %S0\;rotcr      %R0"
4002   [(set_attr "length" "4")
4003    (set_attr "type" "arith")])
4004
4005 (define_insn "lshrdi3_media"
4006   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4007         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4008                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4009   "TARGET_SHMEDIA
4010    && (arith_reg_dest (operands[0], DImode)
4011        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4012   "@
4013         shlrd   %1, %2, %0
4014         shlri   %1, %2, %0"
4015   [(set_attr "type" "arith_media")])
4016
4017 (define_insn "*lshrdisi3_media"