OSDN Git Service

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