OSDN Git Service

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