OSDN Git Service

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