OSDN Git Service

PR target/32506
[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_reg_operand" "b"))]
1769   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1770   "blink        %1, r18"
1771   [(set_attr "type" "sfunc")
1772    (set_attr "needs_delay_slot" "yes")])
1773
1774 (define_expand "udivsi3_i4_media"
1775   [(set (match_dup 3)
1776         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1777    (set (match_dup 4)
1778         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779    (set (match_dup 5) (float:DF (match_dup 3)))
1780    (set (match_dup 6) (float:DF (match_dup 4)))
1781    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782    (set (match_dup 8) (fix:DI (match_dup 7)))
1783    (set (match_operand:SI 0 "register_operand" "")
1784         (truncate:SI (match_dup 8)))]
1785   "TARGET_SHMEDIA_FPU"
1786   "
1787 {
1788   operands[3] = gen_reg_rtx (DImode);
1789   operands[4] = gen_reg_rtx (DImode);
1790   operands[5] = gen_reg_rtx (DFmode);
1791   operands[6] = gen_reg_rtx (DFmode);
1792   operands[7] = gen_reg_rtx (DFmode);
1793   operands[8] = gen_reg_rtx (DImode);
1794 }")
1795
1796 (define_insn "udivsi3_i4"
1797   [(set (match_operand:SI 0 "register_operand" "=y")
1798         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799    (clobber (reg:SI T_REG))
1800    (clobber (reg:SI PR_REG))
1801    (clobber (reg:DF DR0_REG))
1802    (clobber (reg:DF DR2_REG))
1803    (clobber (reg:DF DR4_REG))
1804    (clobber (reg:SI R0_REG))
1805    (clobber (reg:SI R1_REG))
1806    (clobber (reg:SI R4_REG))
1807    (clobber (reg:SI R5_REG))
1808    (use (reg:PSI FPSCR_REG))
1809    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1811   "jsr  @%1%#"
1812   [(set_attr "type" "sfunc")
1813    (set_attr "fp_mode" "double")
1814    (set_attr "needs_delay_slot" "yes")])
1815
1816 (define_insn "udivsi3_i4_single"
1817   [(set (match_operand:SI 0 "register_operand" "=y")
1818         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819    (clobber (reg:SI T_REG))
1820    (clobber (reg:SI PR_REG))
1821    (clobber (reg:DF DR0_REG))
1822    (clobber (reg:DF DR2_REG))
1823    (clobber (reg:DF DR4_REG))
1824    (clobber (reg:SI R0_REG))
1825    (clobber (reg:SI R1_REG))
1826    (clobber (reg:SI R4_REG))
1827    (clobber (reg:SI R5_REG))
1828    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1830   "jsr  @%1%#"
1831   [(set_attr "type" "sfunc")
1832    (set_attr "needs_delay_slot" "yes")])
1833
1834 (define_insn "udivsi3_i4_int"
1835   [(set (match_operand:SI 0 "register_operand" "=z")
1836         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837    (clobber (reg:SI T_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI PR_REG))
1840    (clobber (reg:SI MACH_REG))
1841    (clobber (reg:SI MACL_REG))
1842    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843   "TARGET_SH1"
1844   "jsr  @%1%#"
1845   [(set_attr "type" "sfunc")
1846    (set_attr "needs_delay_slot" "yes")])
1847
1848
1849 (define_expand "udivsi3"
1850   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853    (parallel [(set (match_operand:SI 0 "register_operand" "")
1854                    (udiv:SI (reg:SI R4_REG)
1855                             (reg:SI R5_REG)))
1856               (clobber (reg:SI T_REG))
1857               (clobber (reg:SI PR_REG))
1858               (clobber (reg:SI R4_REG))
1859               (use (match_dup 3))])]
1860   ""
1861   "
1862 {
1863   rtx last;
1864
1865   operands[3] = gen_reg_rtx (Pmode);
1866   /* Emit the move of the address to a pseudo outside of the libcall.  */
1867   if (TARGET_DIVIDE_CALL_TABLE)
1868     {
1869       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870          that causes problems when the divide code is supposed to come from a
1871          separate library.  Division by zero is undefined, so dividing 1 can be
1872          implemented by comparing with the divisor.  */
1873       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1874         {
1875           emit_insn (gen_cmpsi (operands[1], operands[2]));
1876           emit_insn (gen_sgeu (operands[0]));
1877           DONE;
1878         }
1879       else if (operands[2] == const0_rtx)
1880         {
1881           emit_move_insn (operands[0], operands[2]);
1882           DONE;
1883         }
1884       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1886     }
1887   else if (TARGET_DIVIDE_CALL_FP)
1888     {
1889       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890       if (TARGET_FPU_SINGLE)
1891         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1892       else
1893         last = gen_udivsi3_i4 (operands[0], operands[3]);
1894     }
1895   else if (TARGET_SHMEDIA_FPU)
1896     {
1897       operands[1] = force_reg (SImode, operands[1]);
1898       operands[2] = force_reg (SImode, operands[2]);
1899       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1900       DONE;
1901     }
1902   else if (TARGET_SH2A)
1903     {
1904       operands[1] = force_reg (SImode, operands[1]);
1905       operands[2] = force_reg (SImode, operands[2]);
1906       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1907       DONE;
1908     }
1909   else if (TARGET_SH5)
1910     {
1911       function_symbol (operands[3],
1912                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1913                        SFUNC_STATIC);
1914
1915       if (TARGET_SHMEDIA)
1916         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917       else if (TARGET_FPU_ANY)
1918         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1919       else
1920         last = gen_udivsi3_i1 (operands[0], operands[3]);
1921     }
1922   else
1923     {
1924       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925       last = gen_udivsi3_i1 (operands[0], operands[3]);
1926     }
1927   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1929   emit_insn (last);
1930   DONE;
1931 }")
1932
1933 (define_insn "divsi3_sh2a"
1934   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1937   "TARGET_SH2A"
1938   "divs %2,%1"
1939   [(set_attr "type" "arith")
1940    (set_attr "in_delay_slot" "no")])
1941
1942 (define_insn "divsi3_i1"
1943   [(set (match_operand:SI 0 "register_operand" "=z")
1944         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945    (clobber (reg:SI T_REG))
1946    (clobber (reg:SI PR_REG))
1947    (clobber (reg:SI R1_REG))
1948    (clobber (reg:SI R2_REG))
1949    (clobber (reg:SI R3_REG))
1950    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951   "TARGET_SH1 && ! TARGET_SH4"
1952   "jsr  @%1%#"
1953   [(set_attr "type" "sfunc")
1954    (set_attr "needs_delay_slot" "yes")])
1955
1956 (define_insn "divsi3_i1_media"
1957   [(set (match_operand:SI 0 "register_operand" "=z")
1958         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959    (clobber (reg:SI T_MEDIA_REG))
1960    (clobber (reg:SI PR_MEDIA_REG))
1961    (clobber (reg:SI R1_REG))
1962    (clobber (reg:SI R20_REG))
1963    (clobber (reg:SI R21_REG))
1964    (clobber (reg:SI TR0_REG))
1965    (use (match_operand 1 "target_reg_operand" "b"))]
1966   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1967   "blink        %1, r18"
1968   [(set_attr "type" "sfunc")])
1969
1970 (define_insn "divsi3_media_2"
1971   [(set (match_operand:SI 0 "register_operand" "=z")
1972         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973    (clobber (reg:SI T_MEDIA_REG))
1974    (clobber (reg:SI PR_MEDIA_REG))
1975    (clobber (reg:SI R1_REG))
1976    (clobber (reg:SI R21_REG))
1977    (clobber (reg:SI TR0_REG))
1978    (use (reg:SI R20_REG))
1979    (use (match_operand 1 "target_reg_operand" "b"))]
1980   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1981   "blink        %1, r18"
1982   [(set_attr "type" "sfunc")])
1983
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988   [(set (match_operand:SI 0 "register_operand" "=r")
1989         (div:SI (match_operand:SI 1 "register_operand" "r")
1990                 (match_operand:SI 2 "register_operand" "r")))
1991    (clobber (reg:SI R4_REG))
1992    (clobber (reg:SI R5_REG))
1993    (clobber (reg:SI T_MEDIA_REG))
1994    (clobber (reg:SI PR_MEDIA_REG))
1995    (clobber (reg:SI R1_REG))
1996    (clobber (reg:SI R21_REG))
1997    (clobber (reg:SI TR0_REG))
1998    (clobber (reg:SI R20_REG))
1999    (use (match_operand:SI 3 "register_operand" "r"))]
2000   "TARGET_SHMEDIA"
2001   "#"
2002   "&& (high_life_started || reload_completed)"
2003   [(set (match_dup 0) (match_dup 3))]
2004   ""
2005   [(set_attr "highpart" "must_split")])
2006
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009   [(set (match_operand:SI 0 "register_operand" "=z")
2010         (div:SI (match_operand:SI 1 "register_operand" "r")
2011                 (match_operand:SI 2 "register_operand" "r")))
2012    (clobber (reg:SI R4_REG))
2013    (clobber (reg:SI R5_REG))
2014    (clobber (reg:SI T_MEDIA_REG))
2015    (clobber (reg:SI PR_MEDIA_REG))
2016    (clobber (reg:SI R1_REG))
2017    (clobber (reg:SI R21_REG))
2018    (clobber (reg:SI TR0_REG))
2019    (clobber (reg:SI R20_REG))
2020    (use (unspec:SI [(match_dup 1)
2021                     (match_operand:SI 3 "" "")
2022                     (unspec:SI [(match_operand:SI 4 "" "")
2023                                 (match_dup 3)
2024                                 (match_operand:DI 5 "" "")]
2025                      UNSPEC_DIV_INV_M2)
2026                     (match_operand:DI 6 "" "")
2027                     (const_int 0)
2028                     (const_int 0)]
2029          UNSPEC_DIV_INV_M3))]
2030   "TARGET_SHMEDIA"
2031   "#"
2032   "&& (high_life_started || reload_completed)"
2033   [(pc)]
2034   "
2035 {
2036   const char *name = sh_divsi3_libfunc;
2037   enum sh_function_kind kind = SFUNC_GOT;
2038   rtx sym;
2039
2040   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042   while (TARGET_DIVIDE_INV_CALL2)
2043     {
2044       rtx x = operands[3];
2045
2046       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2047         break;
2048       x = XVECEXP (x, 0, 0);
2049       name = \"__sdivsi3_2\";
2050       kind = SFUNC_STATIC;
2051       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2052       break;
2053     }
2054   sym = function_symbol (NULL, name, kind);
2055   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2056   DONE;
2057 }"
2058   [(set_attr "highpart" "must_split")])
2059
2060 (define_expand "divsi3_i4_media"
2061   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064    (set (match_operand:SI 0 "register_operand" "=r")
2065         (fix:SI (match_dup 5)))]
2066   "TARGET_SHMEDIA_FPU"
2067   "
2068 {
2069   operands[3] = gen_reg_rtx (DFmode);
2070   operands[4] = gen_reg_rtx (DFmode);
2071   operands[5] = gen_reg_rtx (DFmode);
2072 }")
2073
2074 (define_insn "divsi3_i4"
2075   [(set (match_operand:SI 0 "register_operand" "=y")
2076         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077    (clobber (reg:SI PR_REG))
2078    (clobber (reg:DF DR0_REG))
2079    (clobber (reg:DF DR2_REG))
2080    (use (reg:PSI FPSCR_REG))
2081    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2083   "jsr  @%1%#"
2084   [(set_attr "type" "sfunc")
2085    (set_attr "fp_mode" "double")
2086    (set_attr "needs_delay_slot" "yes")])
2087
2088 (define_insn "divsi3_i4_single"
2089   [(set (match_operand:SI 0 "register_operand" "=y")
2090         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091    (clobber (reg:SI PR_REG))
2092    (clobber (reg:DF DR0_REG))
2093    (clobber (reg:DF DR2_REG))
2094    (clobber (reg:SI R2_REG))
2095    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2097   "jsr  @%1%#"
2098   [(set_attr "type" "sfunc")
2099    (set_attr "needs_delay_slot" "yes")])
2100
2101 (define_insn "divsi3_i4_int"
2102   [(set (match_operand:SI 0 "register_operand" "=z")
2103         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104    (clobber (reg:SI T_REG))
2105    (clobber (reg:SI PR_REG))
2106    (clobber (reg:SI R1_REG))
2107    (clobber (reg:SI MACH_REG))
2108    (clobber (reg:SI MACL_REG))
2109    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110   "TARGET_SH1"
2111   "jsr  @%1%#"
2112   [(set_attr "type" "sfunc")
2113    (set_attr "needs_delay_slot" "yes")])
2114
2115 (define_expand "divsi3"
2116   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119    (parallel [(set (match_operand:SI 0 "register_operand" "")
2120                    (div:SI (reg:SI R4_REG)
2121                            (reg:SI R5_REG)))
2122               (clobber (reg:SI T_REG))
2123               (clobber (reg:SI PR_REG))
2124               (clobber (reg:SI R1_REG))
2125               (clobber (reg:SI R2_REG))
2126               (clobber (reg:SI R3_REG))
2127               (use (match_dup 3))])]
2128   ""
2129   "
2130 {
2131   rtx last;
2132
2133   operands[3] = gen_reg_rtx (Pmode);
2134   /* Emit the move of the address to a pseudo outside of the libcall.  */
2135   if (TARGET_DIVIDE_CALL_TABLE)
2136     {
2137       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138       last = gen_divsi3_i4_int (operands[0], operands[3]);
2139     }
2140   else if (TARGET_DIVIDE_CALL_FP)
2141     {
2142       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143       if (TARGET_FPU_SINGLE)
2144         last = gen_divsi3_i4_single (operands[0], operands[3]);
2145       else
2146         last = gen_divsi3_i4 (operands[0], operands[3]);
2147     }
2148   else if (TARGET_SH2A)
2149     {
2150       operands[1] = force_reg (SImode, operands[1]);
2151       operands[2] = force_reg (SImode, operands[2]);
2152       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2153       DONE;
2154     }
2155   else if (TARGET_DIVIDE_INV)
2156     {
2157       rtx dividend = operands[1];
2158       rtx divisor = operands[2];
2159       rtx tab_base;
2160       rtx nsb_res = gen_reg_rtx (DImode);
2161       rtx norm64 = gen_reg_rtx (DImode);
2162       rtx tab_ix = gen_reg_rtx (DImode);
2163       rtx norm32 = gen_reg_rtx (SImode);
2164       rtx i92 = force_reg (DImode, GEN_INT (92));
2165       rtx scratch0a = gen_reg_rtx (DImode);
2166       rtx scratch0b = gen_reg_rtx (DImode);
2167       rtx inv0 = gen_reg_rtx (SImode);
2168       rtx scratch1a = gen_reg_rtx (DImode);
2169       rtx scratch1b = gen_reg_rtx (DImode);
2170       rtx shift = gen_reg_rtx (DImode);
2171       rtx i2p27, i43;
2172       rtx inv1 = gen_reg_rtx (SImode);
2173       rtx scratch2a = gen_reg_rtx (DImode);
2174       rtx scratch2b = gen_reg_rtx (SImode);
2175       rtx inv2 = gen_reg_rtx (SImode);
2176       rtx scratch3a = gen_reg_rtx (DImode);
2177       rtx scratch3b = gen_reg_rtx (DImode);
2178       rtx scratch3c = gen_reg_rtx (DImode);
2179       rtx scratch3d = gen_reg_rtx (SImode);
2180       rtx scratch3e = gen_reg_rtx (DImode);
2181       rtx result = gen_reg_rtx (SImode);
2182
2183       if (! arith_reg_or_0_operand (dividend, SImode))
2184         dividend = force_reg (SImode, dividend);
2185       if (! arith_reg_operand (divisor, SImode))
2186         divisor = force_reg (SImode, divisor);
2187       if (flag_pic && Pmode != DImode)
2188         {
2189           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190           tab_base = gen_datalabel_ref (tab_base);
2191           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2192         }
2193       else
2194         {
2195           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196           tab_base = gen_datalabel_ref (tab_base);
2197           tab_base = force_reg (DImode, tab_base);
2198         }
2199       if (TARGET_DIVIDE_INV20U)
2200         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2201       else
2202         i2p27 = GEN_INT (0);
2203       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204         i43 = force_reg (DImode, GEN_INT (43));
2205       else
2206         i43 = GEN_INT (0);
2207       emit_insn (gen_nsbdi (nsb_res,
2208                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209       emit_insn (gen_ashldi3_media (norm64,
2210                                     gen_rtx_SUBREG (DImode, divisor, 0),
2211                                     nsb_res));
2212       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215                                    inv0, scratch0a, scratch0b,
2216                                    scratch1a, scratch1b));
2217       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2219                                    scratch2a));
2220       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2221                                    i2p27, i43,
2222                                    scratch3a, scratch3b, scratch3c,
2223                                    scratch2a, scratch2b, scratch3d, scratch3e));
2224       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226       else if (TARGET_DIVIDE_INV_FP)
2227         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230                                      gen_reg_rtx (DFmode)));
2231       else
2232         emit_move_insn (operands[0], result);
2233       DONE;
2234     }
2235   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2236     {
2237       operands[1] = force_reg (SImode, operands[1]);
2238       operands[2] = force_reg (SImode, operands[2]);
2239       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2240       DONE;
2241     }
2242   else if (TARGET_SH5)
2243     {
2244       if (TARGET_DIVIDE_CALL2)
2245         {
2246           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247           tab_base = gen_datalabel_ref (tab_base);
2248           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2249         }
2250       if (TARGET_FPU_ANY && TARGET_SH1)
2251         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252       else if (TARGET_DIVIDE_CALL2)
2253         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2254       else
2255         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2256
2257       if (TARGET_SHMEDIA)
2258         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259                 (operands[0], operands[3]));
2260       else if (TARGET_FPU_ANY)
2261         last = gen_divsi3_i4_single (operands[0], operands[3]);
2262       else
2263         last = gen_divsi3_i1 (operands[0], operands[3]);
2264     }
2265   else
2266     {
2267       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268       last = gen_divsi3_i1 (operands[0], operands[3]);
2269     }
2270   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2272   emit_insn (last);
2273   DONE;
2274 }")
2275
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload.  See PR27117.
2280
2281 (define_insn "divsi_inv_qitable"
2282   [(set (match_operand:DI 0 "register_operand" "=r")
2283         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284                                     (match_operand:DI 2 "register_operand" "r")]
2285                          UNSPEC_DIV_INV_TABLE)))]
2286   "TARGET_SHMEDIA"
2287   "@
2288         ldx.ub  %1, %2, %0"
2289   [(set_attr "type" "load_media")
2290    (set_attr "highpart" "user")])
2291
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294   [(set (match_operand:DI 0 "register_operand" "=r")
2295         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296                                     (match_operand:DI 2 "register_operand" "r")]
2297                          UNSPEC_DIV_INV_TABLE)))]
2298   "TARGET_SHMEDIA"
2299   "@
2300         ldx.w   %1, %2, %0"
2301   [(set_attr "type" "load_media")
2302    (set_attr "highpart" "user")])
2303
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307   [(set (match_operand:SI 0 "register_operand" "=r")
2308         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309                     (match_operand:DI 2 "register_operand" "r")
2310                     (match_operand:SI 3 "register_operand" "r")]
2311          UNSPEC_DIV_INV_M0))
2312    (clobber (match_operand:DI 4 "register_operand" "=r"))
2313    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2314   "TARGET_SHMEDIA"
2315   "
2316 {
2317 /*
2318 tab_base: r20
2319 tab_ix: r21
2320 norm32: r25
2321  ldx.ub r20, r21, r19 // u0.8
2322  shlli r21, 1, r21
2323  muls.l r25, r19, r19 // s2.38
2324  ldx.w r20, r21, r21  // s2.14
2325  shari r19, 24, r19   // truncate to s2.14
2326  sub r21, r19, r19    // some 11 bit inverse in s1.14
2327 */
2328
2329   rtx inv0 = operands[0];
2330   rtx tab_base = operands[1];
2331   rtx tab_ix = operands[2];
2332   rtx norm32 = operands[3];
2333   rtx scratch0 = operands[4];
2334   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335   rtx scratch1 = operands[5];
2336
2337   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2343   DONE;
2344 }")
2345
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348   [(set (match_operand:SI 0 "register_operand" "=r")
2349         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350                     (match_operand:DI 2 "register_operand" "r")
2351                     (match_operand:SI 3 "register_operand" "r")]
2352          UNSPEC_DIV_INV_M1))
2353    (clobber (match_operand:SI 4 "register_operand" "=r"))
2354    (clobber (match_operand:DI 5 "register_operand" "=r"))
2355    (clobber (match_operand:DI 6 "register_operand" "=r"))
2356    (clobber (match_operand:DI 7 "register_operand" "=r"))
2357    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2358   "TARGET_SHMEDIA"
2359   "#"
2360   "&& no_new_pseudos"
2361   [(pc)]
2362   "
2363 {
2364 /* inv0: r19
2365  muls.l r19, r19, r18 // u0.28
2366  muls.l r25, r18, r18 // s2.58
2367  shlli r19, 45, r0    // multiply by two and convert to s2.58
2368  sub r0, r18, r18
2369  shari r18, 28, r18   // some 18 bit inverse in s1.30
2370 */
2371
2372   rtx inv1 = operands[0];
2373   rtx tab_base = operands[1];
2374   rtx tab_ix = operands[2];
2375   rtx norm32 = operands[3];
2376   rtx inv0 = operands[4];
2377   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378   rtx scratch0a = operands[5];
2379   rtx scratch0b = operands[6];
2380   rtx scratch0 = operands[7];
2381   rtx scratch1 = operands[8];
2382   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2383
2384   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385                                scratch0a, scratch0b));
2386   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2391   DONE;
2392 }")
2393
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396   [(set (match_operand:SI 0 "register_operand" "=r")
2397         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398                     (match_operand:SI 2 "register_operand" "r")
2399                     (match_operand:DI 3 "register_operand" "r")]
2400          UNSPEC_DIV_INV_M2))
2401    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2402   "TARGET_SHMEDIA"
2403   "#"
2404   "&& no_new_pseudos"
2405   [(pc)]
2406   "
2407 {
2408 /*
2409  muls.l r18, r25, r0  // s2.60
2410  shari r0, 16, r0     // s-16.44
2411   sub
2412  muls.l r0, r18, r19  // s-16.74
2413  shari r19, 30, r19   // s-16.44
2414 */
2415   rtx inv2 = operands[0];
2416   rtx norm32 = operands[1];
2417   rtx inv1 = operands[2];
2418   rtx i92 = operands[3];
2419   rtx scratch0 = operands[4];
2420   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2421
2422   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2427   DONE;
2428 }")
2429
2430 (define_insn_and_split "divsi_inv_m3"
2431   [(set (match_operand:SI 0 "register_operand" "=r")
2432         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2438          UNSPEC_DIV_INV_M3))
2439    (clobber (match_operand:DI 7 "register_operand" "=r"))
2440    (clobber (match_operand:DI 8 "register_operand" "=r"))
2441    (clobber (match_operand:DI 9 "register_operand" "=r"))
2442    (clobber (match_operand:DI 10 "register_operand" "=r"))
2443    (clobber (match_operand:SI 11 "register_operand" "=r"))
2444    (clobber (match_operand:SI 12 "register_operand" "=r"))
2445    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2446   "TARGET_SHMEDIA"
2447   "#"
2448   "&& no_new_pseudos"
2449   [(pc)]
2450   "
2451 {
2452 /*
2453   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2454   r0: scratch0  r19: scratch1 r21: scratch2
2455
2456   muls.l r18, r4, r25 // s32.30
2457  muls.l r19, r4, r19  // s15.30
2458  shari r25, 63, r21
2459   shari r19, 14, r19  // s18.-14
2460  sub r25, r19, r0
2461  shard r0, r1, r0
2462  sub r0, r21, r0
2463 */
2464
2465   rtx result = operands[0];
2466   rtx dividend = operands[1];
2467   rtx inv1 = operands[2];
2468   rtx inv2 = operands[3];
2469   rtx shift = operands[4];
2470   rtx scratch0 = operands[7];
2471   rtx scratch1 = operands[8];
2472   rtx scratch2 = operands[9];
2473
2474   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2481   DONE;
2482 }")
2483
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488   [(set (match_operand:SI 0 "register_operand" "=r")
2489         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491                                 (match_operand:DI 3 "register_operand" "r")
2492                                 (match_operand:SI 4 "register_operand" "r")]
2493                      UNSPEC_DIV_INV_M1)
2494                     (unspec:SI [(match_dup 4)
2495                                 (unspec:SI [(match_dup 2)
2496                                             (match_dup 3)
2497                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2498                                 (match_operand:SI 5 "" "")]
2499                      UNSPEC_DIV_INV_M2)
2500                     (match_operand:DI 6 "register_operand" "r")
2501                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2503          UNSPEC_DIV_INV_M3))
2504    (clobber (match_operand:DI 9 "register_operand" "=r"))
2505    (clobber (match_operand:DI 10 "register_operand" "=r"))
2506    (clobber (match_operand:DI 11 "register_operand" "=r"))
2507    (clobber (match_operand:DI 12 "register_operand" "=r"))
2508    (clobber (match_operand:SI 13 "register_operand" "=r"))
2509    (clobber (match_operand:SI 14 "register_operand" "=r"))
2510    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2511   "TARGET_SHMEDIA
2512    && (TARGET_DIVIDE_INV_MINLAT
2513        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2514   "#"
2515   "&& no_new_pseudos"
2516   [(pc)]
2517   "
2518 {
2519   rtx result = operands[0];
2520   rtx dividend = operands[1];
2521   rtx tab_base = operands[2];
2522   rtx tab_ix = operands[3];
2523   rtx norm32 = operands[4];
2524   /* rtx i92 = operands[5]; */
2525   rtx shift = operands[6];
2526   rtx i2p27 = operands[7];
2527   rtx i43 = operands[8];
2528   rtx scratch0 = operands[9];
2529   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530   rtx scratch1 = operands[10];
2531   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532   rtx scratch2 = operands[11];
2533   rtx scratch3 = operands[12];
2534   rtx scratch4 = operands[13];
2535   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536   rtx scratch5 = operands[14];
2537   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538   rtx scratch6 = operands[15];
2539
2540   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541                                scratch0, scratch1));
2542   /* inv0 == scratch4 */
2543   if (! TARGET_DIVIDE_INV20U)
2544     {
2545       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2546       i2p27 = scratch0;
2547       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2548     }
2549   else
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2553     }
2554   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557   /* inv1 == scratch4 */
2558
2559   if (TARGET_DIVIDE_INV_MINLAT)
2560     {
2561       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2572     }
2573   else
2574     {
2575       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2577       emit_insn (gen_nsbdi (scratch6,
2578                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581       emit_insn (gen_divsi_inv20 (scratch2,
2582                                   norm32, scratch4, dividend,
2583                                   scratch6, scratch3, i43,
2584                                   /* scratch0 may be shared with i2p27.  */
2585                                   scratch0, scratch1, scratch5,
2586                                   label, label, i2p27));
2587     }
2588   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2590   DONE;
2591 }")
2592
2593 (define_insn "divsi_inv20"
2594   [(set (match_operand:DI 0 "register_operand" "=&r")
2595         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596                     (match_operand:SI 2 "register_operand" "r")
2597                     (match_operand:SI 3 "register_operand" "r")
2598                     (match_operand:DI 4 "register_operand" "r")
2599                     (match_operand:DI 5 "register_operand" "r")
2600                     (match_operand:DI 6 "register_operand" "r")
2601                     (match_operand:DI 12 "register_operand" "r")
2602                     (match_operand 10 "target_operand" "b")
2603                     (match_operand 11 "immediate_operand" "i")]
2604          UNSPEC_DIV_INV20))
2605    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2608   "TARGET_SHMEDIA
2609    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2610   "*
2611 {
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615              %10 label (tr), %11 label (imm)
2616
2617  muls.l inv1, norm32, scratch0  // s2.60
2618   muls.l inv1, dividend, result // s32.30
2619   xor i2p27, result_sign, round_scratch
2620  bge/u dividend_nsb, i43, tr.. (label)
2621  shari scratch0, 16, scratch0   // s-16.44
2622  muls.l sratch0_si, inv1, scratch0 // s-16.74
2623   sub result, round_scratch, result
2624   shari dividend, 14, scratch1   // s19.-14
2625  shari scratch0, 30, scratch0   // s-16.44
2626  muls.l scratch0, scratch1, round_scratch // s15.30
2627 label:
2628  sub result, round_scratch, result */
2629
2630   int likely = TARGET_DIVIDE_INV20L;
2631
2632   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634   output_asm_insn (likely
2635                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636                    : \"bge/u\t%4, %6, %10\", operands);
2637   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2640   return (likely
2641           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2643 }")
2644
2645 (define_insn_and_split "divsi_inv_fp"
2646   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648                 (match_operand:SI 2 "register_operand" "rf")))
2649    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650    (clobber (match_operand:SI 4 "register_operand" "=r"))
2651    (clobber (match_operand:SI 5 "register_operand" "=r"))
2652    (clobber (match_operand:DF 6 "register_operand" "=r"))
2653    (clobber (match_operand:DF 7 "register_operand" "=r"))
2654    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655   "TARGET_SHMEDIA_FPU"
2656   "#"
2657   "&& (high_life_started || reload_completed)"
2658   [(set (match_dup 0) (match_dup 3))]
2659   ""
2660   [(set_attr "highpart" "must_split")])
2661
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666   [(set (match_operand:SI 0 "register_operand" "=f")
2667         (div:SI (match_operand:SI 1 "register_operand" "f")
2668                 (match_operand:SI 2 "register_operand" "f")))
2669    (use (unspec:SI [(match_dup 1)
2670                     (match_operand:SI 3 "" "")
2671                     (unspec:SI [(match_operand:SI 4 "" "")
2672                                 (match_dup 3)
2673                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674                     (match_operand:DI 6 "" "")
2675                     (const_int 0)
2676                     (const_int 0)] UNSPEC_DIV_INV_M3))
2677    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2683   "#"
2684   "&& 1"
2685   [(set (match_dup 9) (float:DF (match_dup 1)))
2686    (set (match_dup 10) (float:DF (match_dup 2)))
2687    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2688    (set (match_dup 8)
2689         (fix:SI (match_dup 11)))
2690    (set (match_dup 0) (match_dup 8))]
2691   "
2692 {
2693   if (! fp_arith_reg_operand (operands[1], SImode))
2694     {
2695       emit_move_insn (operands[7], operands[1]);
2696       operands[1] = operands[7];
2697     }
2698   if (! fp_arith_reg_operand (operands[2], SImode))
2699     {
2700       emit_move_insn (operands[8], operands[2]);
2701       operands[2] = operands[8];
2702     }
2703 }"
2704   [(set_attr "highpart" "must_split")])
2705 \f
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2709
2710 (define_insn "umulhisi3_i"
2711   [(set (reg:SI MACL_REG)
2712         (mult:SI (zero_extend:SI
2713                   (match_operand:HI 0 "arith_reg_operand" "r"))
2714                  (zero_extend:SI
2715                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716   "TARGET_SH1"
2717   "mulu.w       %1,%0"
2718   [(set_attr "type" "smpy")])
2719
2720 (define_insn "mulhisi3_i"
2721   [(set (reg:SI MACL_REG)
2722         (mult:SI (sign_extend:SI
2723                   (match_operand:HI 0 "arith_reg_operand" "r"))
2724                  (sign_extend:SI
2725                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2726   "TARGET_SH1"
2727   "muls.w       %1,%0"
2728   [(set_attr "type" "smpy")])
2729
2730 (define_expand "mulhisi3"
2731   [(set (reg:SI MACL_REG)
2732         (mult:SI (sign_extend:SI
2733                   (match_operand:HI 1 "arith_reg_operand" ""))
2734                  (sign_extend:SI
2735                   (match_operand:HI 2 "arith_reg_operand" ""))))
2736    (set (match_operand:SI 0 "arith_reg_operand" "")
2737         (reg:SI MACL_REG))]
2738   "TARGET_SH1"
2739   "
2740 {
2741   rtx insn, macl;
2742
2743   macl = gen_rtx_REG (SImode, MACL_REG);
2744   start_sequence ();
2745   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746   insn = get_insns ();  
2747   end_sequence ();
2748   /* expand_binop can't find a suitable code in umul_widen_optab to
2749      make a REG_EQUAL note from, so make one here.
2750      See also smulsi3_highpart.
2751      ??? Alternatively, we could put this at the calling site of expand_binop,
2752      i.e. expand_expr.  */
2753   /* Use emit_libcall_block for loop invariant code motion and to make
2754      a REG_EQUAL note.  */
2755   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2756
2757   DONE;
2758 }")
2759
2760 (define_expand "umulhisi3"
2761   [(set (reg:SI MACL_REG)
2762         (mult:SI (zero_extend:SI
2763                   (match_operand:HI 1 "arith_reg_operand" ""))
2764                  (zero_extend:SI
2765                   (match_operand:HI 2 "arith_reg_operand" ""))))
2766    (set (match_operand:SI 0 "arith_reg_operand" "")
2767         (reg:SI MACL_REG))]
2768   "TARGET_SH1"
2769   "
2770 {
2771   rtx insn, macl;
2772
2773   macl = gen_rtx_REG (SImode, MACL_REG);
2774   start_sequence ();
2775   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776   insn = get_insns ();  
2777   end_sequence ();
2778   /* expand_binop can't find a suitable code in umul_widen_optab to
2779      make a REG_EQUAL note from, so make one here.
2780      See also smulsi3_highpart.
2781      ??? Alternatively, we could put this at the calling site of expand_binop,
2782      i.e. expand_expr.  */
2783   /* Use emit_libcall_block for loop invariant code motion and to make
2784      a REG_EQUAL note.  */
2785   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2786
2787   DONE;
2788 }")
2789
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2792
2793 (define_insn ""
2794   [(set (match_operand:SI 1 "register_operand" "=z")
2795         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796    (clobber (reg:SI MACL_REG))
2797    (clobber (reg:SI T_REG))
2798    (clobber (reg:SI PR_REG))
2799    (clobber (reg:SI R3_REG))
2800    (clobber (reg:SI R2_REG))
2801    (clobber (reg:SI R1_REG))
2802    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2803   "TARGET_SH1"
2804   "jsr  @%0%#"
2805   [(set_attr "type" "sfunc")
2806    (set_attr "needs_delay_slot" "yes")])
2807
2808 (define_expand "mulsi3_call"
2809   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811    (parallel[(set (match_operand:SI 0 "register_operand" "")
2812                   (mult:SI (reg:SI R4_REG)
2813                            (reg:SI R5_REG)))
2814              (clobber (reg:SI MACL_REG))
2815              (clobber (reg:SI T_REG))
2816              (clobber (reg:SI PR_REG))
2817              (clobber (reg:SI R3_REG))
2818              (clobber (reg:SI R2_REG))
2819              (clobber (reg:SI R1_REG))
2820              (use (match_operand:SI 3 "register_operand" ""))])]
2821   "TARGET_SH1"
2822   "")
2823
2824 (define_insn "mul_r"
2825   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2828   "TARGET_SH2A"
2829   "mulr %2,%0"
2830   [(set_attr "type" "dmpy")])
2831
2832 (define_insn "mul_l"
2833   [(set (reg:SI MACL_REG)
2834         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2836   "TARGET_SH2"
2837   "mul.l        %1,%0"
2838   [(set_attr "type" "dmpy")])
2839
2840 (define_expand "mulsi3"
2841   [(set (reg:SI MACL_REG)
2842         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2843                   (match_operand:SI 2 "arith_reg_operand" "")))
2844    (set (match_operand:SI 0 "arith_reg_operand" "")
2845         (reg:SI MACL_REG))]
2846   "TARGET_SH1"
2847   "
2848 {
2849   if (!TARGET_SH2)
2850     {
2851       /* The address must be set outside the libcall,
2852          since it goes into a pseudo.  */
2853       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854       rtx addr = force_reg (SImode, sym);
2855       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2856                                    operands[2], addr);
2857       emit_insn (insns);
2858     }
2859   else
2860     {
2861       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2862
2863       emit_insn (gen_mul_l (operands[1], operands[2]));
2864       /* consec_sets_giv can only recognize the first insn that sets a
2865          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2866          note.  */
2867       emit_insn (gen_movsi_i ((operands[0]), macl));
2868     }
2869   DONE;
2870 }")
2871
2872 (define_insn "mulsidi3_i"
2873   [(set (reg:SI MACH_REG)
2874         (truncate:SI
2875          (lshiftrt:DI
2876           (mult:DI
2877            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2879           (const_int 32))))
2880    (set (reg:SI MACL_REG)
2881         (mult:SI (match_dup 0)
2882                  (match_dup 1)))]
2883   "TARGET_SH2"
2884   "dmuls.l      %1,%0"
2885   [(set_attr "type" "dmpy")])
2886
2887 (define_expand "mulsidi3"
2888   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891   "TARGET_SH2 || TARGET_SHMEDIA"
2892   "
2893 {
2894   if (TARGET_SH2)
2895     {
2896        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2897                                         operands[2]));
2898        DONE;
2899     }
2900 }")
2901
2902 (define_insn "mulsidi3_media"
2903   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2906   "TARGET_SHMEDIA"
2907   "muls.l       %1, %2, %0"
2908   [(set_attr "type" "dmpy_media")
2909    (set_attr "highpart" "ignore")])
2910
2911 (define_insn "mulsidi3_compact"
2912   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913         (mult:DI
2914          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916    (clobber (reg:SI MACH_REG))
2917    (clobber (reg:SI MACL_REG))]
2918   "TARGET_SH2"
2919   "#")
2920
2921 (define_split
2922   [(set (match_operand:DI 0 "arith_reg_dest" "")
2923         (mult:DI
2924          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926    (clobber (reg:SI MACH_REG))
2927    (clobber (reg:SI MACL_REG))]
2928   "TARGET_SH2"
2929   [(const_int 0)]
2930   "
2931 {
2932   rtx low_dst = gen_lowpart (SImode, operands[0]);
2933   rtx high_dst = gen_highpart (SImode, operands[0]);
2934
2935   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2936
2937   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939   /* We need something to tag the possible REG_EQUAL notes on to.  */
2940   emit_move_insn (operands[0], operands[0]);
2941   DONE;
2942 }")
2943
2944 (define_insn "umulsidi3_i"
2945   [(set (reg:SI MACH_REG)
2946         (truncate:SI
2947          (lshiftrt:DI
2948           (mult:DI
2949            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2951           (const_int 32))))
2952    (set (reg:SI MACL_REG)
2953         (mult:SI (match_dup 0)
2954                  (match_dup 1)))]
2955   "TARGET_SH2"
2956   "dmulu.l      %1,%0"
2957   [(set_attr "type" "dmpy")])
2958
2959 (define_expand "umulsidi3"
2960   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963   "TARGET_SH2 || TARGET_SHMEDIA"
2964   "
2965 {
2966   if (TARGET_SH2)
2967     {
2968        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2969                                          operands[2]));
2970        DONE;
2971     }
2972 }")
2973
2974 (define_insn "umulsidi3_media"
2975   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2978   "TARGET_SHMEDIA"
2979   "mulu.l       %1, %2, %0"
2980   [(set_attr "type" "dmpy_media")
2981    (set_attr "highpart" "ignore")])
2982
2983 (define_insn "umulsidi3_compact"
2984   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985         (mult:DI
2986          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988    (clobber (reg:SI MACH_REG))
2989    (clobber (reg:SI MACL_REG))]
2990   "TARGET_SH2"
2991   "#")
2992
2993 (define_split
2994   [(set (match_operand:DI 0 "arith_reg_dest" "")
2995         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997    (clobber (reg:SI MACH_REG))
2998    (clobber (reg:SI MACL_REG))]
2999   "TARGET_SH2"
3000   [(const_int 0)]
3001   "
3002 {
3003   rtx low_dst = gen_lowpart (SImode, operands[0]);
3004   rtx high_dst = gen_highpart (SImode, operands[0]);
3005
3006   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3007
3008   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010   /* We need something to tag the possible REG_EQUAL notes on to.  */
3011   emit_move_insn (operands[0], operands[0]);
3012   DONE;
3013 }")
3014
3015 (define_insn "smulsi3_highpart_i"
3016   [(set (reg:SI MACH_REG)
3017         (truncate:SI
3018          (lshiftrt:DI
3019           (mult:DI
3020            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3022           (const_int 32))))
3023    (clobber (reg:SI MACL_REG))]
3024   "TARGET_SH2"
3025   "dmuls.l      %1,%0"
3026   [(set_attr "type" "dmpy")])
3027
3028 (define_expand "smulsi3_highpart"
3029   [(parallel
3030     [(set (reg:SI MACH_REG)
3031           (truncate:SI
3032            (lshiftrt:DI
3033             (mult:DI
3034              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3036             (const_int 32))))
3037     (clobber (reg:SI MACL_REG))])
3038    (set (match_operand:SI 0 "arith_reg_operand" "")
3039         (reg:SI MACH_REG))]
3040   "TARGET_SH2"
3041   "
3042 {
3043   rtx insn, mach;
3044
3045   mach = gen_rtx_REG (SImode, MACH_REG);
3046   start_sequence ();
3047   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048   insn = get_insns ();  
3049   end_sequence ();
3050   /* expand_binop can't find a suitable code in mul_highpart_optab to
3051      make a REG_EQUAL note from, so make one here.
3052      See also {,u}mulhisi.
3053      ??? Alternatively, we could put this at the calling site of expand_binop,
3054      i.e. expand_mult_highpart.  */
3055   /* Use emit_libcall_block for loop invariant code motion and to make
3056      a REG_EQUAL note.  */
3057   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3058
3059   DONE;
3060 }")
3061
3062 (define_insn "umulsi3_highpart_i"
3063   [(set (reg:SI MACH_REG)
3064         (truncate:SI
3065          (lshiftrt:DI
3066           (mult:DI
3067            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3069           (const_int 32))))
3070    (clobber (reg:SI MACL_REG))]
3071   "TARGET_SH2"
3072   "dmulu.l      %1,%0"
3073   [(set_attr "type" "dmpy")])
3074
3075 (define_expand "umulsi3_highpart"
3076   [(parallel
3077     [(set (reg:SI MACH_REG)
3078           (truncate:SI
3079            (lshiftrt:DI
3080             (mult:DI
3081              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3083             (const_int 32))))
3084     (clobber (reg:SI MACL_REG))])
3085    (set (match_operand:SI 0 "arith_reg_operand" "")
3086         (reg:SI MACH_REG))]
3087   "TARGET_SH2"
3088   "
3089 {
3090   rtx insn, mach;
3091
3092   mach = gen_rtx_REG (SImode, MACH_REG);
3093   start_sequence ();
3094   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095   insn = get_insns ();  
3096   end_sequence ();
3097   /* Use emit_libcall_block for loop invariant code motion and to make
3098      a REG_EQUAL note.  */
3099   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3100
3101   DONE;
3102 }")
3103
3104 (define_insn_and_split "muldi3"
3105   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107                  (match_operand:DI 2 "arith_reg_operand" "r")))
3108    (clobber (match_scratch:DI 3 "=&r"))
3109    (clobber (match_scratch:DI 4 "=r"))]
3110   "TARGET_SHMEDIA"
3111   "#"
3112   "reload_completed"
3113   [(const_int 0)]
3114   "
3115 {
3116   rtx op3_v2si, op2_v2si;
3117
3118   op3_v2si = operands[3];
3119   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3120     {
3121       op3_v2si = XEXP (op3_v2si, 0);
3122       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3123     }
3124   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125   op2_v2si = operands[2];
3126   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3127     {
3128       op2_v2si = XEXP (op2_v2si, 0);
3129       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3130     }
3131   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134   emit_insn (gen_umulsidi3_media (operands[4],
3135                                  sh_gen_truncate (SImode, operands[1], 0),
3136                                  sh_gen_truncate (SImode, operands[2], 0)));
3137   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3141   DONE;
3142 }")
3143
3144 \f
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3148
3149 (define_insn "*andsi3_compact"
3150   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3153   "TARGET_SH1"
3154   "and  %2,%0"
3155   [(set_attr "type" "arith")])
3156
3157 (define_insn "*andsi3_media"
3158   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3161   "TARGET_SHMEDIA"
3162   "@
3163         and     %1, %2, %0
3164         andi    %1, %2, %0"
3165   [(set_attr "type" "arith_media")])
3166
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3169
3170 (define_expand "andsi3"
3171   [(set (match_operand:SI 0 "arith_reg_operand" "")
3172         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173                 (match_operand:SI 2 "logical_operand" "")))]
3174   ""
3175   "
3176 {
3177   if (TARGET_SH1
3178       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3179     {
3180       emit_insn (gen_zero_extendqisi2 (operands[0],
3181                                        gen_lowpart (QImode, operands[1])));
3182       DONE;
3183     }
3184 }")
3185
3186 (define_insn_and_split "anddi3"
3187   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3190   "TARGET_SHMEDIA"
3191   "@
3192         and     %1, %2, %0
3193         andi    %1, %2, %0
3194         #"
3195   "reload_completed
3196    && ! logical_operand (operands[2], DImode)"
3197   [(const_int 0)]
3198   "
3199 {
3200   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3202   else
3203     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3204   DONE;
3205 }"
3206   [(set_attr "type" "arith_media")])
3207
3208 (define_insn "andcsi3"
3209   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3212   "TARGET_SHMEDIA"
3213   "andc %1,%2,%0"
3214   [(set_attr "type" "arith_media")])
3215
3216 (define_insn "andcdi3"
3217   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3220   "TARGET_SHMEDIA"
3221   "andc %1,%2,%0"
3222   [(set_attr "type" "arith_media")])
3223
3224 (define_expand "iorsi3"
3225   [(set (match_operand:SI 0 "arith_reg_operand" "")
3226         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227                 (match_operand:SI 2 "logical_operand" "")))]
3228   ""
3229   "")
3230
3231 (define_insn "*iorsi3_compact"
3232   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3235   "TARGET_SH1"
3236   "or   %2,%0"
3237   [(set_attr "type" "arith")])
3238
3239 (define_insn "*iorsi3_media"
3240   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3243   "TARGET_SHMEDIA"
3244   "@
3245         or      %1, %2, %0
3246         ori     %1, %2, %0"
3247   [(set_attr "type" "arith_media")])
3248
3249 (define_insn "iordi3"
3250   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3253   "TARGET_SHMEDIA"
3254   "@
3255         or      %1, %2, %0
3256         ori     %1, %2, %0"
3257   [(set_attr "type" "arith_media")])
3258
3259 (define_insn_and_split "*logical_sidi3"
3260   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3264   "TARGET_SHMEDIA"
3265   "#"
3266   "&& reload_completed"
3267   [(set (match_dup 0) (match_dup 3))]
3268   "
3269 {
3270   operands[3]
3271     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3274 }")
3275
3276 (define_insn_and_split "*logical_sidisi3"
3277   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278         (truncate:SI (sign_extend:DI
3279                         (match_operator:SI 3 "logical_operator"
3280                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3282   "TARGET_SHMEDIA"
3283   "#"
3284   "&& 1"
3285   [(set (match_dup 0) (match_dup 3))])
3286
3287 (define_insn_and_split "*logical_sidi3_2"
3288   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289         (sign_extend:DI (truncate:SI (sign_extend:DI
3290                         (match_operator:SI 3 "logical_operator"
3291                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3293   "TARGET_SHMEDIA"
3294   "#"
3295   "&& 1"
3296   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3297
3298 (define_expand "xorsi3"
3299   [(set (match_operand:SI 0 "arith_reg_operand" "")
3300         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301                 (match_operand:SI 2 "xor_operand" "")))]
3302   ""
3303   "")
3304
3305 (define_insn "*xorsi3_compact"
3306   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3309   "TARGET_SH1"
3310   "xor  %2,%0"
3311   [(set_attr "type" "arith")])
3312
3313 (define_insn "*xorsi3_media"
3314   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3317   "TARGET_SHMEDIA"
3318   "@
3319         xor     %1, %2, %0
3320         xori    %1, %2, %0"
3321   [(set_attr "type" "arith_media")])
3322
3323 (define_insn "xordi3"
3324   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3327   "TARGET_SHMEDIA"
3328   "@
3329         xor     %1, %2, %0
3330         xori    %1, %2, %0"
3331   [(set_attr "type" "arith_media")])
3332
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3335 (define_split
3336   [(set (match_operand:DI 0 "arith_reg_dest" "")
3337         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338                           [(match_operand 1 "any_register_operand" "")
3339                            (match_operand 2 "any_register_operand" "")])))]
3340   "TARGET_SHMEDIA"
3341   [(set (match_dup 5) (match_dup 4))
3342    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3343 "
3344 {
3345   enum machine_mode inmode = GET_MODE (operands[1]);
3346   int offset = 0;
3347
3348   if (GET_CODE (operands[0]) == SUBREG)
3349     {
3350       offset = SUBREG_BYTE (operands[0]);
3351       operands[0] = SUBREG_REG (operands[0]);
3352     }
3353   gcc_assert (GET_CODE (operands[0]) == REG);
3354   if (! TARGET_LITTLE_ENDIAN)
3355     offset += 8 - GET_MODE_SIZE (inmode);
3356   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3357 }")
3358 \f
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3362
3363 (define_expand "rotldi3"
3364   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3367   "TARGET_SHMEDIA"
3368   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3369
3370 (define_insn "rotldi3_mextr"
3371   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3374   "TARGET_SHMEDIA"
3375   "*
3376 {
3377   static char templ[16];
3378
3379   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380            8 - (int) (INTVAL (operands[2]) >> 3));
3381   return templ;
3382 }"
3383   [(set_attr "type" "arith_media")])
3384
3385 (define_expand "rotrdi3"
3386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3389   "TARGET_SHMEDIA"
3390   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3391
3392 (define_insn "rotrdi3_mextr"
3393   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3396   "TARGET_SHMEDIA"
3397   "*
3398 {
3399   static char templ[16];
3400
3401   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3402   return templ;
3403 }"
3404   [(set_attr "type" "arith_media")])
3405
3406 (define_split
3407   [(set (match_operand:DI 0 "arith_reg_dest" "")
3408         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409                                          "ua_address_operand" "")))
3410                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3411                            (const_int 8))))
3412    (clobber (match_operand:DI 3 "register_operand" ""))]
3413   "TARGET_SHMEDIA"
3414   [(match_dup 4) (match_dup 5)]
3415   "
3416 {
3417   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418                  (operands[3], operands[1]));