1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
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.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
157 ;; These are used with unspec_volatile.
163 (UNSPECV_WINDOW_END 10)
164 (UNSPECV_CONST_END 11)
165 (UNSPECV_EH_RETURN 12)
168 ;; -------------------------------------------------------------------------
170 ;; -------------------------------------------------------------------------
175 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
176 (const (symbol_ref "sh_cpu_attr")))
178 (define_attr "endian" "big,little"
179 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
180 (const_string "little") (const_string "big"))))
182 ;; Indicate if the default fpu mode is single precision.
183 (define_attr "fpu_single" "yes,no"
184 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
185 (const_string "yes") (const_string "no"))))
187 (define_attr "fmovd" "yes,no"
188 (const (if_then_else (symbol_ref "TARGET_FMOVD")
189 (const_string "yes") (const_string "no"))))
191 (define_attr "pipe_model" "sh1,sh4,sh5media"
193 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
194 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
195 (const_string "sh1"))))
197 ;; cbranch conditional branch instructions
198 ;; jump unconditional jumps
199 ;; arith ordinary arithmetic
200 ;; arith3 a compound insn that behaves similarly to a sequence of
201 ;; three insns of type arith
202 ;; arith3b like above, but might end with a redirected branch
204 ;; load_si Likewise, SImode variant for general register.
205 ;; fload Likewise, but load to fp register.
207 ;; fstore floating point register to memory
208 ;; move general purpose register to register
209 ;; movi8 8-bit immediate to general purpose register
210 ;; mt_group other sh4 mt instructions
211 ;; fmove register to register, floating point
212 ;; smpy word precision integer multiply
213 ;; dmpy longword or doublelongword precision integer multiply
215 ;; pload load of pr reg, which can't be put into delay slot of rts
216 ;; prset copy register to pr reg, ditto
217 ;; pstore store of pr reg, which can't be put into delay slot of jsr
218 ;; prget copy pr to register, ditto
219 ;; pcload pc relative load of constant value
220 ;; pcfload Likewise, but load to fp register.
221 ;; pcload_si Likewise, SImode variant for general register.
222 ;; rte return from exception
223 ;; sfunc special function call with known used registers
224 ;; call function call
226 ;; fpscr_toggle toggle a bit in the fpscr
227 ;; fdiv floating point divide (or square root)
228 ;; gp_fpul move from general purpose register to fpul
229 ;; fpul_gp move from fpul to general purpose register
230 ;; mac_gp move from mac[lh] to general purpose register
231 ;; gp_mac move from general purpose register to mac[lh]
232 ;; mac_mem move from mac[lh] to memory
233 ;; mem_mac move from memory to mac[lh]
234 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
235 ;; ftrc_s fix_truncsfsi2_i4
236 ;; dfdiv double precision floating point divide (or square root)
237 ;; cwb ic_invalidate_line_i
238 ;; movua SH4a unaligned load
239 ;; fsrra square root reciprocal approximate
240 ;; fsca sine and cosine approximate
241 ;; tls_load load TLS related address
242 ;; arith_media SHmedia arithmetic, logical, and shift instructions
243 ;; cbranch_media SHmedia conditional branch instructions
244 ;; cmp_media SHmedia compare instructions
245 ;; dfdiv_media SHmedia double precision divide and square root
246 ;; dfmul_media SHmedia double precision multiply instruction
247 ;; dfparith_media SHmedia double precision floating point arithmetic
248 ;; dfpconv_media SHmedia double precision floating point conversions
249 ;; dmpy_media SHmedia longword multiply
250 ;; fcmp_media SHmedia floating point compare instructions
251 ;; fdiv_media SHmedia single precision divide and square root
252 ;; fload_media SHmedia floating point register load instructions
253 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
254 ;; fparith_media SHmedia single precision floating point arithmetic
255 ;; fpconv_media SHmedia single precision floating point conversions
256 ;; fstore_media SHmedia floating point register store instructions
257 ;; gettr_media SHmedia gettr instruction
258 ;; invalidate_line_media SHmedia invalidate_line sequence
259 ;; jump_media SHmedia unconditional branch instructions
260 ;; load_media SHmedia general register load instructions
261 ;; pt_media SHmedia pt instruction (expanded by assembler)
262 ;; ptabs_media SHmedia ptabs instruction
263 ;; store_media SHmedia general register store instructions
264 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
265 ;; mac_media SHmedia mac-style fixed point operations
266 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
267 ;; atrans_media SHmedia approximate transcendental functions
268 ;; ustore_media SHmedia unaligned stores
269 ;; nil no-op move, will be deleted.
272 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
273 (const_string "other"))
275 ;; We define a new attribute namely "insn_class".We use
276 ;; this for the DFA based pipeline description.
278 ;; mt_group SH4 "mt" group instructions.
280 ;; ex_group SH4 "ex" group instructions.
282 ;; ls_group SH4 "ls" group instructions.
285 (define_attr "insn_class"
286 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
287 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
288 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
289 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
290 (eq_attr "type" "cbranch,jump") (const_string "br_group")
291 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
292 (const_string "fe_group")
293 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
294 (const_string "none")))
295 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
296 ;; so these do not belong in an insn group, although they are modeled
297 ;; with their own define_insn_reservations.
299 ;; Indicate what precision must be selected in fpscr for this insn, if any.
301 (define_attr "fp_mode" "single,double,none" (const_string "none"))
303 ;; Indicate if the fpu mode is set by this instruction
304 ;; "unknown" must have the value as "none" in fp_mode, and means
305 ;; that the instruction/abi has left the processor in an unknown
307 ;; "none" means that nothing has changed and no mode is set.
308 ;; This attribute is only used for the Renesas ABI.
309 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
311 ; If a conditional branch destination is within -252..258 bytes away
312 ; from the instruction it can be 2 bytes long. Something in the
313 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
314 ; branches are initially assumed to be 16 bytes long.
315 ; In machine_dependent_reorg, we split all branches that are longer than
318 ;; The maximum range used for SImode constant pool entries is 1018. A final
319 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
320 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
321 ;; instruction around the pool table, 2 bytes of alignment before the table,
322 ;; and 30 bytes of alignment after the table. That gives a maximum total
323 ;; pool size of 1058 bytes.
324 ;; Worst case code/pool content size ratio is 1:2 (using asms).
325 ;; Thus, in the worst case, there is one instruction in front of a maximum
326 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
327 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
328 ;; If we have a forward branch, the initial table will be put after the
329 ;; unconditional branch.
331 ;; ??? We could do much better by keeping track of the actual pcloads within
332 ;; the branch range and in the pcload range in front of the branch range.
334 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
336 (define_attr "short_cbranch_p" "no,yes"
337 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
339 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
341 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
343 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
345 ] (const_string "no")))
347 (define_attr "med_branch_p" "no,yes"
348 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
351 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
356 ] (const_string "no")))
358 (define_attr "med_cbranch_p" "no,yes"
359 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
362 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
367 ] (const_string "no")))
369 (define_attr "braf_branch_p" "no,yes"
370 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
372 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
375 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
380 ] (const_string "no")))
382 (define_attr "braf_cbranch_p" "no,yes"
383 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
385 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
388 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
393 ] (const_string "no")))
395 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
396 ; For wider ranges, we need a combination of a code and a data part.
397 ; If we can get a scratch register for a long range jump, the code
398 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
399 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
400 ; long; otherwise, it must be 6 bytes long.
402 ; All other instructions are two bytes long by default.
404 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
405 ;; but getattrtab doesn't understand this.
406 (define_attr "length" ""
407 (cond [(eq_attr "type" "cbranch")
408 (cond [(eq_attr "short_cbranch_p" "yes")
410 (eq_attr "med_cbranch_p" "yes")
412 (eq_attr "braf_cbranch_p" "yes")
414 ;; ??? using pc is not computed transitively.
415 (ne (match_dup 0) (match_dup 0))
417 (ne (symbol_ref ("flag_pic")) (const_int 0))
420 (eq_attr "type" "jump")
421 (cond [(eq_attr "med_branch_p" "yes")
423 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
425 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
427 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
428 (symbol_ref "code_for_indirect_jump_scratch"))))
429 (cond [(eq_attr "braf_branch_p" "yes")
431 (eq (symbol_ref "flag_pic") (const_int 0))
433 (ne (symbol_ref "TARGET_SH2") (const_int 0))
434 (const_int 10)] (const_int 18))
435 (eq_attr "braf_branch_p" "yes")
437 ;; ??? using pc is not computed transitively.
438 (ne (match_dup 0) (match_dup 0))
440 (ne (symbol_ref ("flag_pic")) (const_int 0))
443 (eq_attr "type" "pt_media")
444 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
445 (const_int 20) (const_int 12))
446 (and (eq_attr "type" "jump_media")
447 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
449 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
453 ;; DFA descriptions for the pipelines
456 (include "shmedia.md")
459 (include "predicates.md")
460 (include "constraints.md")
462 ;; Definitions for filling delay slots
464 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
466 (define_attr "banked" "yes,no"
467 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
469 (const_string "yes")]
470 (const_string "no")))
472 ;; ??? This should be (nil) instead of (const_int 0)
473 (define_attr "hit_stack" "yes,no"
474 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
477 (const_string "yes")))
479 (define_attr "interrupt_function" "no,yes"
480 (const (symbol_ref "current_function_interrupt")))
482 (define_attr "in_delay_slot" "yes,no"
483 (cond [(eq_attr "type" "cbranch") (const_string "no")
484 (eq_attr "type" "pcload,pcload_si") (const_string "no")
485 (eq_attr "needs_delay_slot" "yes") (const_string "no")
486 (eq_attr "length" "2") (const_string "yes")
487 ] (const_string "no")))
489 (define_attr "cond_delay_slot" "yes,no"
490 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
491 ] (const_string "no")))
493 (define_attr "is_sfunc" ""
494 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
496 (define_attr "is_mac_media" ""
497 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
499 (define_attr "branch_zero" "yes,no"
500 (cond [(eq_attr "type" "!cbranch") (const_string "no")
501 (ne (symbol_ref "(next_active_insn (insn)\
502 == (prev_active_insn\
503 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
504 && get_attr_length (next_active_insn (insn)) == 2")
506 (const_string "yes")]
507 (const_string "no")))
509 ;; SH4 Double-precision computation with double-precision result -
510 ;; the two halves are ready at different times.
511 (define_attr "dfp_comp" "yes,no"
512 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
513 (const_string "no")))
515 ;; Insns for which the latency of a preceding fp insn is decreased by one.
516 (define_attr "late_fp_use" "yes,no" (const_string "no"))
517 ;; And feeding insns for which this relevant.
518 (define_attr "any_fp_comp" "yes,no"
519 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
520 (const_string "yes")]
521 (const_string "no")))
523 (define_attr "any_int_load" "yes,no"
524 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
525 (const_string "yes")]
526 (const_string "no")))
528 (define_attr "highpart" "user, ignore, extend, depend, must_split"
529 (const_string "user"))
532 (eq_attr "needs_delay_slot" "yes")
533 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
535 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
536 ;; and thus we can't put a pop instruction in its delay slot.
537 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
538 ;; instruction can go in the delay slot.
540 ;; Since a normal return (rts) implicitly uses the PR register,
541 ;; we can't allow PR register loads in an rts delay slot.
544 (eq_attr "type" "return")
545 [(and (eq_attr "in_delay_slot" "yes")
546 (ior (and (eq_attr "interrupt_function" "no")
547 (eq_attr "type" "!pload,prset"))
548 (and (eq_attr "interrupt_function" "yes")
550 (eq (symbol_ref "TARGET_SH3") (const_int 0))
551 (eq_attr "hit_stack" "no")
552 (eq_attr "banked" "no"))))) (nil) (nil)])
554 ;; Since a call implicitly uses the PR register, we can't allow
555 ;; a PR register store in a jsr delay slot.
558 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
559 [(and (eq_attr "in_delay_slot" "yes")
560 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
562 ;; Say that we have annulled true branches, since this gives smaller and
563 ;; faster code when branches are predicted as not taken.
565 ;; ??? The non-annulled condition should really be "in_delay_slot",
566 ;; but insns that can be filled in non-annulled get priority over insns
567 ;; that can only be filled in anulled.
570 (and (eq_attr "type" "cbranch")
571 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
572 ;; SH2e has a hardware bug that pretty much prohibits the use of
573 ;; annuled delay slots.
574 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
575 (not (eq_attr "cpu" "sh2e"))) (nil)])
577 ;; -------------------------------------------------------------------------
578 ;; SImode signed integer comparisons
579 ;; -------------------------------------------------------------------------
583 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
584 (match_operand:SI 1 "arith_operand" "K08,r"))
588 [(set_attr "type" "mt_group")])
590 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
591 ;; That would still allow reload to create cmpi instructions, but would
592 ;; perhaps allow forcing the constant into a register when that is better.
593 ;; Probably should use r0 for mem/imm compares, but force constant into a
594 ;; register for pseudo/imm compares.
596 (define_insn "cmpeqsi_t"
598 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
599 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
605 [(set_attr "type" "mt_group")])
607 (define_insn "cmpgtsi_t"
609 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
610 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
615 [(set_attr "type" "mt_group")])
617 (define_insn "cmpgesi_t"
619 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
625 [(set_attr "type" "mt_group")])
627 ;; -------------------------------------------------------------------------
628 ;; SImode compare and branch
629 ;; -------------------------------------------------------------------------
631 (define_expand "cbranchsi4"
633 (if_then_else (match_operator 0 "comparison_operator"
634 [(match_operand:SI 1 "arith_operand" "")
635 (match_operand:SI 2 "arith_operand" "")])
636 (label_ref (match_operand 3 "" ""))
638 (clobber (reg:SI T_REG))]
640 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
642 ;; -------------------------------------------------------------------------
643 ;; SImode unsigned integer comparisons
644 ;; -------------------------------------------------------------------------
646 (define_insn_and_split "cmpgeusi_t"
648 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
649 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
652 "&& operands[0] == CONST0_RTX (SImode)"
656 emit_insn (gen_sett ());
659 [(set_attr "type" "mt_group")])
661 (define_insn "cmpgtusi_t"
663 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
664 (match_operand:SI 1 "arith_reg_operand" "r")))]
667 [(set_attr "type" "mt_group")])
669 ;; We save the compare operands in the cmpxx patterns and use them when
670 ;; we generate the branch.
672 (define_expand "cmpsi"
674 (compare (match_operand:SI 0 "cmpsi_operand" "")
675 (match_operand:SI 1 "arith_operand" "")))]
676 "TARGET_SH1 || TARGET_SHMEDIA"
679 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
680 && GET_CODE (operands[1]) != CONST_INT)
681 operands[0] = copy_to_mode_reg (SImode, operands[0]);
682 sh_compare_op0 = operands[0];
683 sh_compare_op1 = operands[1];
687 ;; -------------------------------------------------------------------------
688 ;; DImode compare and branch
689 ;; -------------------------------------------------------------------------
692 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693 ;; Therefore, we aim to have a set of three branches that go straight to the
694 ;; destination, i.e. only one of them is taken at any one time.
695 ;; This mechanism should also be slightly better for the sh4-200.
697 (define_expand "cbranchdi4"
699 (if_then_else (match_operator 0 "comparison_operator"
700 [(match_operand:DI 1 "arith_operand" "")
701 (match_operand:DI 2 "arith_operand" "")])
702 (label_ref (match_operand 3 "" ""))
704 (clobber (match_dup 4))
705 (clobber (reg:SI T_REG))]
709 enum rtx_code comparison;
711 if (TARGET_EXPAND_CBRANCHDI4)
713 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
716 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
717 if (comparison != GET_CODE (operands[0]))
719 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
720 operands[4] = gen_rtx_SCRATCH (SImode);
723 (define_insn_and_split "cbranchdi4_i"
725 (if_then_else (match_operator 0 "comparison_operator"
726 [(match_operand:DI 1 "arith_operand" "r,r")
727 (match_operand:DI 2 "arith_operand" "rN,i")])
728 (label_ref (match_operand 3 "" ""))
730 (clobber (match_scratch:SI 4 "=X,&r"))
731 (clobber (reg:SI T_REG))]
734 "&& reload_completed"
738 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
743 ;; -------------------------------------------------------------------------
744 ;; DImode signed integer comparisons
745 ;; -------------------------------------------------------------------------
749 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
750 (match_operand:DI 1 "arith_operand" "r"))
753 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
755 [(set_attr "length" "6")
756 (set_attr "type" "arith3b")])
758 (define_insn "cmpeqdi_t"
760 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
761 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
764 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
765 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
766 [(set_attr "length" "6")
767 (set_attr "type" "arith3b")])
771 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
772 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
773 ;; If we applied this split when not optimizing, it would only be
774 ;; applied during the machine-dependent reorg, when no new basic blocks
776 "TARGET_SH1 && reload_completed && optimize"
777 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
778 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
779 (label_ref (match_dup 6))
781 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
786 = gen_rtx_REG (SImode,
787 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
789 = (operands[1] == const0_rtx
791 : gen_rtx_REG (SImode,
792 true_regnum (operands[1])
793 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
794 operands[4] = gen_lowpart (SImode, operands[0]);
795 operands[5] = gen_lowpart (SImode, operands[1]);
796 operands[6] = gen_label_rtx ();
799 (define_insn "cmpgtdi_t"
801 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
802 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
805 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
806 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
807 [(set_attr "length" "8")
808 (set_attr "type" "arith3")])
810 (define_insn "cmpgedi_t"
812 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
813 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
816 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
818 [(set_attr "length" "8,2")
819 (set_attr "type" "arith3,mt_group")])
821 ;; -------------------------------------------------------------------------
822 ;; DImode unsigned integer comparisons
823 ;; -------------------------------------------------------------------------
825 (define_insn "cmpgeudi_t"
827 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
828 (match_operand:DI 1 "arith_reg_operand" "r")))]
830 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
831 [(set_attr "length" "8")
832 (set_attr "type" "arith3")])
834 (define_insn "cmpgtudi_t"
836 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
837 (match_operand:DI 1 "arith_reg_operand" "r")))]
839 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
840 [(set_attr "length" "8")
841 (set_attr "type" "arith3")])
843 (define_insn "cmpeqsi_media"
844 [(set (match_operand:SI 0 "register_operand" "=r")
845 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
846 (match_operand:SI 2 "cmp_operand" "Nr")))]
849 [(set_attr "type" "cmp_media")])
851 (define_insn "cmpeqdi_media"
852 [(set (match_operand:SI 0 "register_operand" "=r")
853 (eq:SI (match_operand:DI 1 "register_operand" "%r")
854 (match_operand:DI 2 "cmp_operand" "Nr")))]
857 [(set_attr "type" "cmp_media")])
859 (define_insn "cmpgtsi_media"
860 [(set (match_operand:SI 0 "register_operand" "=r")
861 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
862 (match_operand:SI 2 "cmp_operand" "rN")))]
865 [(set_attr "type" "cmp_media")])
867 (define_insn "cmpgtdi_media"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
870 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
873 [(set_attr "type" "cmp_media")])
875 (define_insn "cmpgtusi_media"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
878 (match_operand:SI 2 "cmp_operand" "rN")))]
880 "cmpgtu %N1, %N2, %0"
881 [(set_attr "type" "cmp_media")])
883 (define_insn "cmpgtudi_media"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
886 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
888 "cmpgtu %N1, %N2, %0"
889 [(set_attr "type" "cmp_media")])
891 ; These two patterns are for combine.
892 (define_insn "*cmpne0sisi_media"
893 [(set (match_operand:SI 0 "register_operand" "=r")
894 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
897 [(set_attr "type" "cmp_media")])
899 ;; We save the compare operands in the cmpxx patterns and use them when
900 ;; we generate the branch.
902 (define_expand "cmpdi"
904 (compare (match_operand:DI 0 "arith_operand" "")
905 (match_operand:DI 1 "arith_operand" "")))]
906 "TARGET_SH2 || TARGET_SHMEDIA"
909 sh_compare_op0 = operands[0];
910 sh_compare_op1 = operands[1];
913 ;; -------------------------------------------------------------------------
914 ;; Conditional move instructions
915 ;; -------------------------------------------------------------------------
917 ;; The insn names may seem reversed, but note that cmveq performs the move
918 ;; if op1 == 0, and cmvne does it if op1 != 0.
920 (define_insn "movdicc_false"
921 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
922 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
924 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
925 (match_operand:DI 3 "arith_reg_operand" "0")))]
928 [(set_attr "type" "arith_media")])
930 (define_insn "movdicc_true"
931 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
932 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
934 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
935 (match_operand:DI 3 "arith_reg_operand" "0")))]
938 [(set_attr "type" "arith_media")])
941 [(set (match_operand:DI 0 "arith_reg_dest" "")
942 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
943 [(match_operand:DI 1 "arith_reg_operand" "")
945 (match_operand:DI 2 "arith_reg_dest" "")
947 (set (match_dup 2) (match_dup 0))]
948 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
950 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
953 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
954 VOIDmode, operands[1], CONST0_RTX (DImode));
958 [(set (match_operand:DI 0 "general_movdst_operand" "")
959 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
960 (set (match_operand:DI 2 "arith_reg_dest" "")
961 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
962 [(match_operand:DI 3 "arith_reg_operand" "")
966 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
968 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
971 (define_expand "movdicc"
972 [(set (match_operand:DI 0 "register_operand" "")
973 (if_then_else:DI (match_operand 1 "comparison_operator" "")
974 (match_operand:DI 2 "register_operand" "")
975 (match_operand:DI 3 "register_operand" "")))]
979 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
980 && GET_MODE (sh_compare_op0) == DImode
981 && sh_compare_op1 == const0_rtx)
982 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
983 sh_compare_op0, sh_compare_op1);
991 tmp = gen_reg_rtx (DImode);
993 switch (GET_CODE (operands[1]))
996 emit_insn (gen_seq (tmp));
997 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1001 emit_insn (gen_seq (tmp));
1002 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006 emit_insn (gen_sgt (tmp));
1007 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011 emit_insn (gen_slt (tmp));
1012 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1016 emit_insn (gen_slt (tmp));
1017 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1021 emit_insn (gen_sgt (tmp));
1022 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1026 emit_insn (gen_sgtu (tmp));
1027 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1031 emit_insn (gen_sltu (tmp));
1032 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1036 emit_insn (gen_sltu (tmp));
1037 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1041 emit_insn (gen_sgtu (tmp));
1042 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1046 emit_insn (gen_sunordered (tmp));
1047 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1051 emit_insn (gen_sunordered (tmp));
1052 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1069 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1070 ;; SImode to DImode.
1071 (define_insn "movsicc_false"
1072 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1073 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1075 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1076 (match_operand:SI 3 "arith_reg_operand" "0")))]
1079 [(set_attr "type" "arith_media")])
1081 (define_insn "movsicc_true"
1082 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1083 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1085 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1086 (match_operand:SI 3 "arith_reg_operand" "0")))]
1089 [(set_attr "type" "arith_media")])
1092 [(set (match_operand:SI 0 "arith_reg_dest" "")
1093 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1094 [(match_operand:SI 1 "arith_reg_operand" "")
1096 (match_operand:SI 2 "arith_reg_dest" "")
1098 (set (match_dup 2) (match_dup 0))]
1099 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1101 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1104 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1105 VOIDmode, operands[1], CONST0_RTX (SImode));
1109 [(set (match_operand:SI 0 "general_movdst_operand" "")
1110 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1111 (set (match_operand:SI 2 "arith_reg_dest" "")
1112 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1113 [(match_operand:SI 3 "arith_reg_operand" "")
1117 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1118 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1120 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1123 replace_rtx (operands[4], operands[0], operands[1]);
1127 [(set (match_operand 0 "any_register_operand" "")
1128 (match_operand 1 "any_register_operand" ""))
1129 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1130 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1131 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1132 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1133 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1134 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1135 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1136 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1137 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1138 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1139 && (REGNO_REG_CLASS (REGNO (operands[0]))
1140 == REGNO_REG_CLASS (REGNO (operands[2])))
1141 && (REGNO_REG_CLASS (REGNO (operands[1]))
1142 == REGNO_REG_CLASS (REGNO (operands[0])))"
1143 [(set (match_dup 0) (match_dup 3))
1144 (set (match_dup 4) (match_dup 5))]
1148 rtx replacements[4];
1150 /* We want to replace occurrences of operands[0] with operands[1] and
1151 operands[2] with operands[0] in operands[4]/operands[5].
1152 Doing just two replace_rtx calls naively would result in the second
1153 replacement undoing all that the first did if operands[1] and operands[2]
1154 are identical, so we must do this simultaneously. */
1155 replacements[0] = operands[0];
1156 replacements[1] = operands[1];
1157 replacements[2] = operands[2];
1158 replacements[3] = operands[0];
1159 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1160 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1161 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1164 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1165 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1166 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1167 /* The operands array is aliased to recog_data.operand, which gets
1168 clobbered by extract_insn, so finish with it now. */
1169 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1170 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1171 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1172 always uses emit_insn. */
1173 /* Check that we don't violate matching constraints or earlyclobbers. */
1174 extract_insn (emit_insn (set1));
1175 if (! constrain_operands (1))
1177 extract_insn (emit (set2));
1178 if (! constrain_operands (1))
1182 tmp = replacements[0];
1183 replacements[0] = replacements[1];
1184 replacements[1] = tmp;
1185 tmp = replacements[2];
1186 replacements[2] = replacements[3];
1187 replacements[3] = tmp;
1188 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1189 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1190 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1196 ;; The register allocator is rather clumsy in handling multi-way conditional
1197 ;; moves, so allow the combiner to make them, and we split them up after
1199 (define_insn_and_split "*movsicc_umin"
1200 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1201 (umin:SI (if_then_else:SI
1202 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1204 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1205 (match_operand:SI 3 "register_operand" "0"))
1206 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1207 (clobber (match_scratch:SI 5 "=&r"))]
1208 "TARGET_SHMEDIA && no_new_pseudos"
1210 "TARGET_SHMEDIA && reload_completed"
1214 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1216 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1217 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1222 (define_insn "*movsicc_t_false"
1223 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1224 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1225 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1226 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1227 "TARGET_PRETEND_CMOVE
1228 && (arith_reg_operand (operands[1], SImode)
1229 || (immediate_operand (operands[1], SImode)
1230 && satisfies_constraint_I08 (operands[1])))"
1231 "bt 0f\;mov %1,%0\\n0:"
1232 [(set_attr "type" "mt_group,arith") ;; poor approximation
1233 (set_attr "length" "4")])
1235 (define_insn "*movsicc_t_true"
1236 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1237 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1238 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1239 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1240 "TARGET_PRETEND_CMOVE
1241 && (arith_reg_operand (operands[1], SImode)
1242 || (immediate_operand (operands[1], SImode)
1243 && satisfies_constraint_I08 (operands[1])))"
1244 "bf 0f\;mov %1,%0\\n0:"
1245 [(set_attr "type" "mt_group,arith") ;; poor approximation
1246 (set_attr "length" "4")])
1248 (define_expand "movsicc"
1249 [(set (match_operand:SI 0 "arith_reg_dest" "")
1250 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1251 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1252 (match_operand:SI 3 "arith_reg_operand" "")))]
1253 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1256 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1257 && GET_MODE (sh_compare_op0) == SImode
1259 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1260 && sh_compare_op1 == const0_rtx)
1261 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1262 sh_compare_op0, sh_compare_op1);
1263 else if (TARGET_PRETEND_CMOVE)
1265 enum rtx_code code = GET_CODE (operands[1]);
1266 enum rtx_code new_code = code;
1269 if (! currently_expanding_to_rtl)
1273 case LT: case LE: case LEU: case LTU:
1274 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1277 new_code = reverse_condition (code);
1279 case EQ: case GT: case GE: case GEU: case GTU:
1284 tmp = prepare_scc_operands (new_code);
1285 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1295 tmp = gen_reg_rtx (SImode);
1297 switch (GET_CODE (operands[1]))
1300 emit_insn (gen_seq (tmp));
1301 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1305 emit_insn (gen_seq (tmp));
1306 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1310 emit_insn (gen_sgt (tmp));
1311 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1315 emit_insn (gen_slt (tmp));
1316 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1320 emit_insn (gen_slt (tmp));
1321 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1325 emit_insn (gen_sgt (tmp));
1326 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1330 emit_insn (gen_sgtu (tmp));
1331 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1335 emit_insn (gen_sltu (tmp));
1336 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1340 emit_insn (gen_sltu (tmp));
1341 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1345 emit_insn (gen_sgtu (tmp));
1346 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1350 emit_insn (gen_sunordered (tmp));
1351 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1355 emit_insn (gen_sunordered (tmp));
1356 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1373 (define_expand "movqicc"
1374 [(set (match_operand:QI 0 "register_operand" "")
1375 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1376 (match_operand:QI 2 "register_operand" "")
1377 (match_operand:QI 3 "register_operand" "")))]
1381 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1382 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1383 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1384 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1388 ;; -------------------------------------------------------------------------
1389 ;; Addition instructions
1390 ;; -------------------------------------------------------------------------
1392 (define_expand "adddi3"
1393 [(set (match_operand:DI 0 "arith_reg_operand" "")
1394 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1395 (match_operand:DI 2 "arith_operand" "")))]
1401 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1403 operands[2] = force_reg (DImode, operands[2]);
1404 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1409 (define_insn "*adddi3_media"
1410 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1411 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1412 (match_operand:DI 2 "arith_operand" "r,I10")))]
1417 [(set_attr "type" "arith_media")])
1419 (define_insn "*adddisi3_media"
1420 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1421 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1422 (match_operand:DI 2 "arith_operand" "r,I10")))]
1427 [(set_attr "type" "arith_media")
1428 (set_attr "highpart" "ignore")])
1430 (define_insn "adddi3z_media"
1431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1433 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1434 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1436 "addz.l %1, %N2, %0"
1437 [(set_attr "type" "arith_media")
1438 (set_attr "highpart" "ignore")])
1440 (define_insn "adddi3_compact"
1441 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1442 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1443 (match_operand:DI 2 "arith_reg_operand" "r")))
1444 (clobber (reg:SI T_REG))]
1447 [(set_attr "length" "6")])
1450 [(set (match_operand:DI 0 "arith_reg_dest" "")
1451 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1452 (match_operand:DI 2 "arith_reg_operand" "")))
1453 (clobber (reg:SI T_REG))]
1454 "TARGET_SH1 && reload_completed"
1458 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1459 high0 = gen_rtx_REG (SImode,
1460 true_regnum (operands[0])
1461 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1462 high2 = gen_rtx_REG (SImode,
1463 true_regnum (operands[2])
1464 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1465 emit_insn (gen_clrt ());
1466 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1467 emit_insn (gen_addc1 (high0, high0, high2));
1472 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1473 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1474 (match_operand:SI 2 "arith_reg_operand" "r"))
1477 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1480 [(set_attr "type" "arith")])
1482 (define_insn "addc1"
1483 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1484 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1485 (match_operand:SI 2 "arith_reg_operand" "r"))
1487 (clobber (reg:SI T_REG))]
1490 [(set_attr "type" "arith")])
1492 (define_expand "addsi3"
1493 [(set (match_operand:SI 0 "arith_reg_operand" "")
1494 (plus:SI (match_operand:SI 1 "arith_operand" "")
1495 (match_operand:SI 2 "arith_operand" "")))]
1500 operands[1] = force_reg (SImode, operands[1]);
1503 (define_insn "addsi3_media"
1504 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1505 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1506 (match_operand:SI 2 "arith_operand" "r,I10")))]
1511 [(set_attr "type" "arith_media")
1512 (set_attr "highpart" "ignore")])
1514 (define_insn "addsidi3_media"
1515 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1516 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1518 (match_operand:SI 2 "arith_operand"
1524 [(set_attr "type" "arith_media")
1525 (set_attr "highpart" "ignore")])
1527 (define_insn "*addsi3_compact"
1528 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1529 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1530 (match_operand:SI 2 "arith_operand" "rI08")))]
1533 [(set_attr "type" "arith")])
1535 ;; -------------------------------------------------------------------------
1536 ;; Subtraction instructions
1537 ;; -------------------------------------------------------------------------
1539 (define_expand "subdi3"
1540 [(set (match_operand:DI 0 "arith_reg_operand" "")
1541 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1542 (match_operand:DI 2 "arith_reg_operand" "")))]
1548 operands[1] = force_reg (DImode, operands[1]);
1549 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1554 (define_insn "*subdi3_media"
1555 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1556 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1557 (match_operand:DI 2 "arith_reg_operand" "r")))]
1560 [(set_attr "type" "arith_media")])
1562 (define_insn "subdisi3_media"
1563 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1564 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1565 (match_operand:DI 2 "arith_reg_operand" "r")))]
1568 [(set_attr "type" "arith_media")
1569 (set_attr "highpart" "ignore")])
1571 (define_insn "subdi3_compact"
1572 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1573 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1574 (match_operand:DI 2 "arith_reg_operand" "r")))
1575 (clobber (reg:SI T_REG))]
1578 [(set_attr "length" "6")])
1581 [(set (match_operand:DI 0 "arith_reg_dest" "")
1582 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1583 (match_operand:DI 2 "arith_reg_operand" "")))
1584 (clobber (reg:SI T_REG))]
1585 "TARGET_SH1 && reload_completed"
1589 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1590 high0 = gen_rtx_REG (SImode,
1591 true_regnum (operands[0])
1592 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1593 high2 = gen_rtx_REG (SImode,
1594 true_regnum (operands[2])
1595 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1596 emit_insn (gen_clrt ());
1597 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1598 emit_insn (gen_subc1 (high0, high0, high2));
1603 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1604 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1605 (match_operand:SI 2 "arith_reg_operand" "r"))
1608 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1613 [(set_attr "type" "arith")])
1615 (define_insn "subc1"
1616 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1617 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1618 (match_operand:SI 2 "arith_reg_operand" "r"))
1620 (clobber (reg:SI T_REG))]
1623 [(set_attr "type" "arith")])
1625 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1626 ;; pattern for this case. This helps multimedia applications that compute
1627 ;; the sum of absolute differences.
1628 (define_insn "mov_neg_si_t"
1629 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1632 [(set_attr "type" "arith")])
1634 (define_insn "*subsi3_internal"
1635 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1636 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1637 (match_operand:SI 2 "arith_reg_operand" "r")))]
1640 [(set_attr "type" "arith")])
1642 (define_insn_and_split "*subsi3_media"
1643 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1644 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1645 (match_operand:SI 2 "extend_reg_operand" "r")))]
1647 && (operands[1] != constm1_rtx
1648 || (GET_CODE (operands[2]) != TRUNCATE
1649 && GET_CODE (operands[2]) != SUBREG))"
1651 "operands[1] == constm1_rtx"
1652 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1654 [(set_attr "type" "arith_media")
1655 (set_attr "highpart" "ignore")])
1658 [(set (match_operand:SI 0 "arith_reg_dest" "")
1659 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1660 "general_extend_operand"
1662 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1663 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1664 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1668 [(set (match_operand:SI 0 "arith_reg_dest" "")
1669 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1670 "general_extend_operand"
1672 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1673 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1674 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1676 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1677 ;; will sometimes save one instruction. Otherwise we might get
1678 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1681 (define_expand "subsi3"
1682 [(set (match_operand:SI 0 "arith_reg_operand" "")
1683 (minus:SI (match_operand:SI 1 "arith_operand" "")
1684 (match_operand:SI 2 "arith_reg_operand" "")))]
1688 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1690 emit_insn (gen_negsi2 (operands[0], operands[2]));
1691 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1696 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1698 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1699 operands[1] = force_reg (SImode, operands[1]);
1703 ;; -------------------------------------------------------------------------
1704 ;; Division instructions
1705 ;; -------------------------------------------------------------------------
1707 ;; We take advantage of the library routines which don't clobber as many
1708 ;; registers as a normal function call would.
1710 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1711 ;; also has an effect on the register that holds the address of the sfunc.
1712 ;; To make this work, we have an extra dummy insn that shows the use
1713 ;; of this register for reorg.
1715 (define_insn "use_sfunc_addr"
1716 [(set (reg:SI PR_REG)
1717 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1718 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1720 [(set_attr "length" "0")])
1722 (define_insn "udivsi3_sh2a"
1723 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1724 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1725 (match_operand:SI 2 "arith_reg_operand" "z")))]
1728 [(set_attr "type" "arith")
1729 (set_attr "in_delay_slot" "no")])
1731 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1732 ;; hard register 0. If we used hard register 0, then the next instruction
1733 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1734 ;; gets allocated to a stack slot that needs its address reloaded, then
1735 ;; there is nothing to prevent reload from using r0 to reload the address.
1736 ;; This reload would clobber the value in r0 we are trying to store.
1737 ;; If we let reload allocate r0, then this problem can never happen.
1739 (define_insn "udivsi3_i1"
1740 [(set (match_operand:SI 0 "register_operand" "=z")
1741 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1742 (clobber (reg:SI T_REG))
1743 (clobber (reg:SI PR_REG))
1744 (clobber (reg:SI R4_REG))
1745 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1746 "TARGET_SH1 && ! TARGET_SH4"
1748 [(set_attr "type" "sfunc")
1749 (set_attr "needs_delay_slot" "yes")])
1751 ; Since shmedia-nofpu code could be linked against shcompact code, and
1752 ; the udivsi3 libcall has the same name, we must consider all registers
1753 ; clobbered that are in the union of the registers clobbered by the
1754 ; shmedia and the shcompact implementation. Note, if the shcompact
1755 ; implementation actually used shcompact code, we'd need to clobber
1756 ; also r23 and fr23.
1757 (define_insn "udivsi3_i1_media"
1758 [(set (match_operand:SI 0 "register_operand" "=z")
1759 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760 (clobber (reg:SI T_MEDIA_REG))
1761 (clobber (reg:SI PR_MEDIA_REG))
1762 (clobber (reg:SI R20_REG))
1763 (clobber (reg:SI R21_REG))
1764 (clobber (reg:SI R22_REG))
1765 (clobber (reg:DI TR0_REG))
1766 (clobber (reg:DI TR1_REG))
1767 (clobber (reg:DI TR2_REG))
1768 (use (match_operand 1 "target_operand" "b"))]
1769 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1771 [(set_attr "type" "sfunc")
1772 (set_attr "needs_delay_slot" "yes")])
1774 (define_expand "udivsi3_i4_media"
1776 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1778 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779 (set (match_dup 5) (float:DF (match_dup 3)))
1780 (set (match_dup 6) (float:DF (match_dup 4)))
1781 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782 (set (match_dup 8) (fix:DI (match_dup 7)))
1783 (set (match_operand:SI 0 "register_operand" "")
1784 (truncate:SI (match_dup 8)))]
1785 "TARGET_SHMEDIA_FPU"
1788 operands[3] = gen_reg_rtx (DImode);
1789 operands[4] = gen_reg_rtx (DImode);
1790 operands[5] = gen_reg_rtx (DFmode);
1791 operands[6] = gen_reg_rtx (DFmode);
1792 operands[7] = gen_reg_rtx (DFmode);
1793 operands[8] = gen_reg_rtx (DImode);
1796 (define_insn "udivsi3_i4"
1797 [(set (match_operand:SI 0 "register_operand" "=y")
1798 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799 (clobber (reg:SI T_REG))
1800 (clobber (reg:SI PR_REG))
1801 (clobber (reg:DF DR0_REG))
1802 (clobber (reg:DF DR2_REG))
1803 (clobber (reg:DF DR4_REG))
1804 (clobber (reg:SI R0_REG))
1805 (clobber (reg:SI R1_REG))
1806 (clobber (reg:SI R4_REG))
1807 (clobber (reg:SI R5_REG))
1808 (use (reg:PSI FPSCR_REG))
1809 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1812 [(set_attr "type" "sfunc")
1813 (set_attr "fp_mode" "double")
1814 (set_attr "needs_delay_slot" "yes")])
1816 (define_insn "udivsi3_i4_single"
1817 [(set (match_operand:SI 0 "register_operand" "=y")
1818 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819 (clobber (reg:SI T_REG))
1820 (clobber (reg:SI PR_REG))
1821 (clobber (reg:DF DR0_REG))
1822 (clobber (reg:DF DR2_REG))
1823 (clobber (reg:DF DR4_REG))
1824 (clobber (reg:SI R0_REG))
1825 (clobber (reg:SI R1_REG))
1826 (clobber (reg:SI R4_REG))
1827 (clobber (reg:SI R5_REG))
1828 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1831 [(set_attr "type" "sfunc")
1832 (set_attr "needs_delay_slot" "yes")])
1834 (define_insn "udivsi3_i4_int"
1835 [(set (match_operand:SI 0 "register_operand" "=z")
1836 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837 (clobber (reg:SI T_REG))
1838 (clobber (reg:SI R1_REG))
1839 (clobber (reg:SI PR_REG))
1840 (clobber (reg:SI MACH_REG))
1841 (clobber (reg:SI MACL_REG))
1842 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1845 [(set_attr "type" "sfunc")
1846 (set_attr "needs_delay_slot" "yes")])
1849 (define_expand "udivsi3"
1850 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853 (parallel [(set (match_operand:SI 0 "register_operand" "")
1854 (udiv:SI (reg:SI R4_REG)
1856 (clobber (reg:SI T_REG))
1857 (clobber (reg:SI PR_REG))
1858 (clobber (reg:SI R4_REG))
1859 (use (match_dup 3))])]
1865 operands[3] = gen_reg_rtx (Pmode);
1866 /* Emit the move of the address to a pseudo outside of the libcall. */
1867 if (TARGET_DIVIDE_CALL_TABLE)
1869 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870 that causes problems when the divide code is supposed to come from a
1871 separate library. Division by zero is undefined, so dividing 1 can be
1872 implemented by comparing with the divisor. */
1873 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1875 emit_insn (gen_cmpsi (operands[1], operands[2]));
1876 emit_insn (gen_sgeu (operands[0]));
1879 else if (operands[2] == const0_rtx)
1881 emit_move_insn (operands[0], operands[2]);
1884 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1887 else if (TARGET_DIVIDE_CALL_FP)
1889 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890 if (TARGET_FPU_SINGLE)
1891 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1893 last = gen_udivsi3_i4 (operands[0], operands[3]);
1895 else if (TARGET_SHMEDIA_FPU)
1897 operands[1] = force_reg (SImode, operands[1]);
1898 operands[2] = force_reg (SImode, operands[2]);
1899 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1902 else if (TARGET_SH2A)
1904 operands[1] = force_reg (SImode, operands[1]);
1905 operands[2] = force_reg (SImode, operands[2]);
1906 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1909 else if (TARGET_SH5)
1911 function_symbol (operands[3],
1912 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1916 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917 else if (TARGET_FPU_ANY)
1918 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1920 last = gen_udivsi3_i1 (operands[0], operands[3]);
1924 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925 last = gen_udivsi3_i1 (operands[0], operands[3]);
1927 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1933 (define_insn "divsi3_sh2a"
1934 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936 (match_operand:SI 2 "arith_reg_operand" "z")))]
1939 [(set_attr "type" "arith")
1940 (set_attr "in_delay_slot" "no")])
1942 (define_insn "divsi3_i1"
1943 [(set (match_operand:SI 0 "register_operand" "=z")
1944 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945 (clobber (reg:SI T_REG))
1946 (clobber (reg:SI PR_REG))
1947 (clobber (reg:SI R1_REG))
1948 (clobber (reg:SI R2_REG))
1949 (clobber (reg:SI R3_REG))
1950 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951 "TARGET_SH1 && ! TARGET_SH4"
1953 [(set_attr "type" "sfunc")
1954 (set_attr "needs_delay_slot" "yes")])
1956 (define_insn "divsi3_i1_media"
1957 [(set (match_operand:SI 0 "register_operand" "=z")
1958 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959 (clobber (reg:SI T_MEDIA_REG))
1960 (clobber (reg:SI PR_MEDIA_REG))
1961 (clobber (reg:SI R1_REG))
1962 (clobber (reg:SI R20_REG))
1963 (clobber (reg:SI R21_REG))
1964 (clobber (reg:SI TR0_REG))
1965 (use (match_operand 1 "target_operand" "b"))]
1966 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1968 [(set_attr "type" "sfunc")])
1970 (define_insn "divsi3_media_2"
1971 [(set (match_operand:SI 0 "register_operand" "=z")
1972 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973 (clobber (reg:SI T_MEDIA_REG))
1974 (clobber (reg:SI PR_MEDIA_REG))
1975 (clobber (reg:SI R1_REG))
1976 (clobber (reg:SI R21_REG))
1977 (clobber (reg:SI TR0_REG))
1978 (use (reg:SI R20_REG))
1979 (use (match_operand 1 "target_operand" "b"))]
1980 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1982 [(set_attr "type" "sfunc")])
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988 [(set (match_operand:SI 0 "register_operand" "=r")
1989 (div:SI (match_operand:SI 1 "register_operand" "r")
1990 (match_operand:SI 2 "register_operand" "r")))
1991 (clobber (reg:SI R4_REG))
1992 (clobber (reg:SI R5_REG))
1993 (clobber (reg:SI T_MEDIA_REG))
1994 (clobber (reg:SI PR_MEDIA_REG))
1995 (clobber (reg:SI R1_REG))
1996 (clobber (reg:SI R21_REG))
1997 (clobber (reg:SI TR0_REG))
1998 (clobber (reg:SI R20_REG))
1999 (use (match_operand:SI 3 "register_operand" "r"))]
2002 "&& (high_life_started || reload_completed)"
2003 [(set (match_dup 0) (match_dup 3))]
2005 [(set_attr "highpart" "must_split")])
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009 [(set (match_operand:SI 0 "register_operand" "=z")
2010 (div:SI (match_operand:SI 1 "register_operand" "r")
2011 (match_operand:SI 2 "register_operand" "r")))
2012 (clobber (reg:SI R4_REG))
2013 (clobber (reg:SI R5_REG))
2014 (clobber (reg:SI T_MEDIA_REG))
2015 (clobber (reg:SI PR_MEDIA_REG))
2016 (clobber (reg:SI R1_REG))
2017 (clobber (reg:SI R21_REG))
2018 (clobber (reg:SI TR0_REG))
2019 (clobber (reg:SI R20_REG))
2020 (use (unspec:SI [(match_dup 1)
2021 (match_operand:SI 3 "" "")
2022 (unspec:SI [(match_operand:SI 4 "" "")
2024 (match_operand:DI 5 "" "")]
2026 (match_operand:DI 6 "" "")
2029 UNSPEC_DIV_INV_M3))]
2032 "&& (high_life_started || reload_completed)"
2036 const char *name = sh_divsi3_libfunc;
2037 enum sh_function_kind kind = SFUNC_GOT;
2040 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042 while (TARGET_DIVIDE_INV_CALL2)
2044 rtx x = operands[3];
2046 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2048 x = XVECEXP (x, 0, 0);
2049 name = \"__sdivsi3_2\";
2050 kind = SFUNC_STATIC;
2051 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2054 sym = function_symbol (NULL, name, kind);
2055 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2058 [(set_attr "highpart" "must_split")])
2060 (define_expand "divsi3_i4_media"
2061 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064 (set (match_operand:SI 0 "register_operand" "=r")
2065 (fix:SI (match_dup 5)))]
2066 "TARGET_SHMEDIA_FPU"
2069 operands[3] = gen_reg_rtx (DFmode);
2070 operands[4] = gen_reg_rtx (DFmode);
2071 operands[5] = gen_reg_rtx (DFmode);
2074 (define_insn "divsi3_i4"
2075 [(set (match_operand:SI 0 "register_operand" "=y")
2076 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077 (clobber (reg:SI PR_REG))
2078 (clobber (reg:DF DR0_REG))
2079 (clobber (reg:DF DR2_REG))
2080 (use (reg:PSI FPSCR_REG))
2081 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2084 [(set_attr "type" "sfunc")
2085 (set_attr "fp_mode" "double")
2086 (set_attr "needs_delay_slot" "yes")])
2088 (define_insn "divsi3_i4_single"
2089 [(set (match_operand:SI 0 "register_operand" "=y")
2090 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091 (clobber (reg:SI PR_REG))
2092 (clobber (reg:DF DR0_REG))
2093 (clobber (reg:DF DR2_REG))
2094 (clobber (reg:SI R2_REG))
2095 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2098 [(set_attr "type" "sfunc")
2099 (set_attr "needs_delay_slot" "yes")])
2101 (define_insn "divsi3_i4_int"
2102 [(set (match_operand:SI 0 "register_operand" "=z")
2103 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104 (clobber (reg:SI T_REG))
2105 (clobber (reg:SI PR_REG))
2106 (clobber (reg:SI R1_REG))
2107 (clobber (reg:SI MACH_REG))
2108 (clobber (reg:SI MACL_REG))
2109 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2112 [(set_attr "type" "sfunc")
2113 (set_attr "needs_delay_slot" "yes")])
2115 (define_expand "divsi3"
2116 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119 (parallel [(set (match_operand:SI 0 "register_operand" "")
2120 (div:SI (reg:SI R4_REG)
2122 (clobber (reg:SI T_REG))
2123 (clobber (reg:SI PR_REG))
2124 (clobber (reg:SI R1_REG))
2125 (clobber (reg:SI R2_REG))
2126 (clobber (reg:SI R3_REG))
2127 (use (match_dup 3))])]
2133 operands[3] = gen_reg_rtx (Pmode);
2134 /* Emit the move of the address to a pseudo outside of the libcall. */
2135 if (TARGET_DIVIDE_CALL_TABLE)
2137 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138 last = gen_divsi3_i4_int (operands[0], operands[3]);
2140 else if (TARGET_DIVIDE_CALL_FP)
2142 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143 if (TARGET_FPU_SINGLE)
2144 last = gen_divsi3_i4_single (operands[0], operands[3]);
2146 last = gen_divsi3_i4 (operands[0], operands[3]);
2148 else if (TARGET_SH2A)
2150 operands[1] = force_reg (SImode, operands[1]);
2151 operands[2] = force_reg (SImode, operands[2]);
2152 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2155 else if (TARGET_DIVIDE_INV)
2157 rtx dividend = operands[1];
2158 rtx divisor = operands[2];
2160 rtx nsb_res = gen_reg_rtx (DImode);
2161 rtx norm64 = gen_reg_rtx (DImode);
2162 rtx tab_ix = gen_reg_rtx (DImode);
2163 rtx norm32 = gen_reg_rtx (SImode);
2164 rtx i92 = force_reg (DImode, GEN_INT (92));
2165 rtx scratch0a = gen_reg_rtx (DImode);
2166 rtx scratch0b = gen_reg_rtx (DImode);
2167 rtx inv0 = gen_reg_rtx (SImode);
2168 rtx scratch1a = gen_reg_rtx (DImode);
2169 rtx scratch1b = gen_reg_rtx (DImode);
2170 rtx shift = gen_reg_rtx (DImode);
2172 rtx inv1 = gen_reg_rtx (SImode);
2173 rtx scratch2a = gen_reg_rtx (DImode);
2174 rtx scratch2b = gen_reg_rtx (SImode);
2175 rtx inv2 = gen_reg_rtx (SImode);
2176 rtx scratch3a = gen_reg_rtx (DImode);
2177 rtx scratch3b = gen_reg_rtx (DImode);
2178 rtx scratch3c = gen_reg_rtx (DImode);
2179 rtx scratch3d = gen_reg_rtx (SImode);
2180 rtx scratch3e = gen_reg_rtx (DImode);
2181 rtx result = gen_reg_rtx (SImode);
2183 if (! arith_reg_or_0_operand (dividend, SImode))
2184 dividend = force_reg (SImode, dividend);
2185 if (! arith_reg_operand (divisor, SImode))
2186 divisor = force_reg (SImode, divisor);
2187 if (flag_pic && Pmode != DImode)
2189 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190 tab_base = gen_datalabel_ref (tab_base);
2191 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2195 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196 tab_base = gen_datalabel_ref (tab_base);
2197 tab_base = force_reg (DImode, tab_base);
2199 if (TARGET_DIVIDE_INV20U)
2200 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2202 i2p27 = GEN_INT (0);
2203 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204 i43 = force_reg (DImode, GEN_INT (43));
2207 emit_insn (gen_nsbdi (nsb_res,
2208 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209 emit_insn (gen_ashldi3_media (norm64,
2210 gen_rtx_SUBREG (DImode, divisor, 0),
2212 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215 inv0, scratch0a, scratch0b,
2216 scratch1a, scratch1b));
2217 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2220 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2222 scratch3a, scratch3b, scratch3c,
2223 scratch2a, scratch2b, scratch3d, scratch3e));
2224 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226 else if (TARGET_DIVIDE_INV_FP)
2227 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230 gen_reg_rtx (DFmode)));
2232 emit_move_insn (operands[0], result);
2235 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2237 operands[1] = force_reg (SImode, operands[1]);
2238 operands[2] = force_reg (SImode, operands[2]);
2239 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2242 else if (TARGET_SH5)
2244 if (TARGET_DIVIDE_CALL2)
2246 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247 tab_base = gen_datalabel_ref (tab_base);
2248 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2250 if (TARGET_FPU_ANY && TARGET_SH1)
2251 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252 else if (TARGET_DIVIDE_CALL2)
2253 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2255 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2258 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259 (operands[0], operands[3]));
2260 else if (TARGET_FPU_ANY)
2261 last = gen_divsi3_i4_single (operands[0], operands[3]);
2263 last = gen_divsi3_i1 (operands[0], operands[3]);
2267 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268 last = gen_divsi3_i1 (operands[0], operands[3]);
2270 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload. See PR27117.
2281 (define_insn "divsi_inv_qitable"
2282 [(set (match_operand:DI 0 "register_operand" "=r")
2283 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284 (match_operand:DI 2 "register_operand" "r")]
2285 UNSPEC_DIV_INV_TABLE)))]
2289 [(set_attr "type" "load_media")
2290 (set_attr "highpart" "user")])
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296 (match_operand:DI 2 "register_operand" "r")]
2297 UNSPEC_DIV_INV_TABLE)))]
2301 [(set_attr "type" "load_media")
2302 (set_attr "highpart" "user")])
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307 [(set (match_operand:SI 0 "register_operand" "=r")
2308 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309 (match_operand:DI 2 "register_operand" "r")
2310 (match_operand:SI 3 "register_operand" "r")]
2312 (clobber (match_operand:DI 4 "register_operand" "=r"))
2313 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2321 ldx.ub r20, r21, r19 // u0.8
2323 muls.l r25, r19, r19 // s2.38
2324 ldx.w r20, r21, r21 // s2.14
2325 shari r19, 24, r19 // truncate to s2.14
2326 sub r21, r19, r19 // some 11 bit inverse in s1.14
2329 rtx inv0 = operands[0];
2330 rtx tab_base = operands[1];
2331 rtx tab_ix = operands[2];
2332 rtx norm32 = operands[3];
2333 rtx scratch0 = operands[4];
2334 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335 rtx scratch1 = operands[5];
2337 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350 (match_operand:DI 2 "register_operand" "r")
2351 (match_operand:SI 3 "register_operand" "r")]
2353 (clobber (match_operand:SI 4 "register_operand" "=r"))
2354 (clobber (match_operand:DI 5 "register_operand" "=r"))
2355 (clobber (match_operand:DI 6 "register_operand" "=r"))
2356 (clobber (match_operand:DI 7 "register_operand" "=r"))
2357 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2365 muls.l r19, r19, r18 // u0.28
2366 muls.l r25, r18, r18 // s2.58
2367 shlli r19, 45, r0 // multiply by two and convert to s2.58
2369 shari r18, 28, r18 // some 18 bit inverse in s1.30
2372 rtx inv1 = operands[0];
2373 rtx tab_base = operands[1];
2374 rtx tab_ix = operands[2];
2375 rtx norm32 = operands[3];
2376 rtx inv0 = operands[4];
2377 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378 rtx scratch0a = operands[5];
2379 rtx scratch0b = operands[6];
2380 rtx scratch0 = operands[7];
2381 rtx scratch1 = operands[8];
2382 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2384 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385 scratch0a, scratch0b));
2386 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398 (match_operand:SI 2 "register_operand" "r")
2399 (match_operand:DI 3 "register_operand" "r")]
2401 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2409 muls.l r18, r25, r0 // s2.60
2410 shari r0, 16, r0 // s-16.44
2412 muls.l r0, r18, r19 // s-16.74
2413 shari r19, 30, r19 // s-16.44
2415 rtx inv2 = operands[0];
2416 rtx norm32 = operands[1];
2417 rtx inv1 = operands[2];
2418 rtx i92 = operands[3];
2419 rtx scratch0 = operands[4];
2420 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2422 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2430 (define_insn_and_split "divsi_inv_m3"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433 (match_operand:SI 2 "register_operand" "r")
2434 (match_operand:SI 3 "register_operand" "r")
2435 (match_operand:DI 4 "register_operand" "r")
2436 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2439 (clobber (match_operand:DI 7 "register_operand" "=r"))
2440 (clobber (match_operand:DI 8 "register_operand" "=r"))
2441 (clobber (match_operand:DI 9 "register_operand" "=r"))
2442 (clobber (match_operand:DI 10 "register_operand" "=r"))
2443 (clobber (match_operand:SI 11 "register_operand" "=r"))
2444 (clobber (match_operand:SI 12 "register_operand" "=r"))
2445 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2453 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2454 r0: scratch0 r19: scratch1 r21: scratch2
2456 muls.l r18, r4, r25 // s32.30
2457 muls.l r19, r4, r19 // s15.30
2459 shari r19, 14, r19 // s18.-14
2465 rtx result = operands[0];
2466 rtx dividend = operands[1];
2467 rtx inv1 = operands[2];
2468 rtx inv2 = operands[3];
2469 rtx shift = operands[4];
2470 rtx scratch0 = operands[7];
2471 rtx scratch1 = operands[8];
2472 rtx scratch2 = operands[9];
2474 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488 [(set (match_operand:SI 0 "register_operand" "=r")
2489 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491 (match_operand:DI 3 "register_operand" "r")
2492 (match_operand:SI 4 "register_operand" "r")]
2494 (unspec:SI [(match_dup 4)
2495 (unspec:SI [(match_dup 2)
2497 (match_dup 4)] UNSPEC_DIV_INV_M1)
2498 (match_operand:SI 5 "" "")]
2500 (match_operand:DI 6 "register_operand" "r")
2501 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2504 (clobber (match_operand:DI 9 "register_operand" "=r"))
2505 (clobber (match_operand:DI 10 "register_operand" "=r"))
2506 (clobber (match_operand:DI 11 "register_operand" "=r"))
2507 (clobber (match_operand:DI 12 "register_operand" "=r"))
2508 (clobber (match_operand:SI 13 "register_operand" "=r"))
2509 (clobber (match_operand:SI 14 "register_operand" "=r"))
2510 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2512 && (TARGET_DIVIDE_INV_MINLAT
2513 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2519 rtx result = operands[0];
2520 rtx dividend = operands[1];
2521 rtx tab_base = operands[2];
2522 rtx tab_ix = operands[3];
2523 rtx norm32 = operands[4];
2524 /* rtx i92 = operands[5]; */
2525 rtx shift = operands[6];
2526 rtx i2p27 = operands[7];
2527 rtx i43 = operands[8];
2528 rtx scratch0 = operands[9];
2529 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530 rtx scratch1 = operands[10];
2531 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532 rtx scratch2 = operands[11];
2533 rtx scratch3 = operands[12];
2534 rtx scratch4 = operands[13];
2535 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536 rtx scratch5 = operands[14];
2537 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538 rtx scratch6 = operands[15];
2540 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541 scratch0, scratch1));
2542 /* inv0 == scratch4 */
2543 if (! TARGET_DIVIDE_INV20U)
2545 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2547 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2551 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2554 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557 /* inv1 == scratch4 */
2559 if (TARGET_DIVIDE_INV_MINLAT)
2561 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2575 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2577 emit_insn (gen_nsbdi (scratch6,
2578 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581 emit_insn (gen_divsi_inv20 (scratch2,
2582 norm32, scratch4, dividend,
2583 scratch6, scratch3, i43,
2584 /* scratch0 may be shared with i2p27. */
2585 scratch0, scratch1, scratch5,
2586 label, label, i2p27));
2588 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2593 (define_insn "divsi_inv20"
2594 [(set (match_operand:DI 0 "register_operand" "=&r")
2595 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596 (match_operand:SI 2 "register_operand" "r")
2597 (match_operand:SI 3 "register_operand" "r")
2598 (match_operand:DI 4 "register_operand" "r")
2599 (match_operand:DI 5 "register_operand" "r")
2600 (match_operand:DI 6 "register_operand" "r")
2601 (match_operand:DI 12 "register_operand" "r")
2602 (match_operand 10 "target_operand" "b")
2603 (match_operand 11 "immediate_operand" "i")]
2605 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2609 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615 %10 label (tr), %11 label (imm)
2617 muls.l inv1, norm32, scratch0 // s2.60
2618 muls.l inv1, dividend, result // s32.30
2619 xor i2p27, result_sign, round_scratch
2620 bge/u dividend_nsb, i43, tr.. (label)
2621 shari scratch0, 16, scratch0 // s-16.44
2622 muls.l sratch0_si, inv1, scratch0 // s-16.74
2623 sub result, round_scratch, result
2624 shari dividend, 14, scratch1 // s19.-14
2625 shari scratch0, 30, scratch0 // s-16.44
2626 muls.l scratch0, scratch1, round_scratch // s15.30
2628 sub result, round_scratch, result */
2630 int likely = TARGET_DIVIDE_INV20L;
2632 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634 output_asm_insn (likely
2635 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636 : \"bge/u\t%4, %6, %10\", operands);
2637 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2641 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2645 (define_insn_and_split "divsi_inv_fp"
2646 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648 (match_operand:SI 2 "register_operand" "rf")))
2649 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650 (clobber (match_operand:SI 4 "register_operand" "=r"))
2651 (clobber (match_operand:SI 5 "register_operand" "=r"))
2652 (clobber (match_operand:DF 6 "register_operand" "=r"))
2653 (clobber (match_operand:DF 7 "register_operand" "=r"))
2654 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655 "TARGET_SHMEDIA_FPU"
2657 "&& (high_life_started || reload_completed)"
2658 [(set (match_dup 0) (match_dup 3))]
2660 [(set_attr "highpart" "must_split")])
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666 [(set (match_operand:SI 0 "register_operand" "=f")
2667 (div:SI (match_operand:SI 1 "register_operand" "f")
2668 (match_operand:SI 2 "register_operand" "f")))
2669 (use (unspec:SI [(match_dup 1)
2670 (match_operand:SI 3 "" "")
2671 (unspec:SI [(match_operand:SI 4 "" "")
2673 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674 (match_operand:DI 6 "" "")
2676 (const_int 0)] UNSPEC_DIV_INV_M3))
2677 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2685 [(set (match_dup 9) (float:DF (match_dup 1)))
2686 (set (match_dup 10) (float:DF (match_dup 2)))
2687 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2689 (fix:SI (match_dup 11)))
2690 (set (match_dup 0) (match_dup 8))]
2693 if (! fp_arith_reg_operand (operands[1], SImode))
2695 emit_move_insn (operands[7], operands[1]);
2696 operands[1] = operands[7];
2698 if (! fp_arith_reg_operand (operands[2], SImode))
2700 emit_move_insn (operands[8], operands[2]);
2701 operands[2] = operands[8];
2704 [(set_attr "highpart" "must_split")])
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2710 (define_insn "umulhisi3_i"
2711 [(set (reg:SI MACL_REG)
2712 (mult:SI (zero_extend:SI
2713 (match_operand:HI 0 "arith_reg_operand" "r"))
2715 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2718 [(set_attr "type" "smpy")])
2720 (define_insn "mulhisi3_i"
2721 [(set (reg:SI MACL_REG)
2722 (mult:SI (sign_extend:SI
2723 (match_operand:HI 0 "arith_reg_operand" "r"))
2725 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2728 [(set_attr "type" "smpy")])
2730 (define_expand "mulhisi3"
2731 [(set (reg:SI MACL_REG)
2732 (mult:SI (sign_extend:SI
2733 (match_operand:HI 1 "arith_reg_operand" ""))
2735 (match_operand:HI 2 "arith_reg_operand" ""))))
2736 (set (match_operand:SI 0 "arith_reg_operand" "")
2743 macl = gen_rtx_REG (SImode, MACL_REG);
2745 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746 insn = get_insns ();
2748 /* expand_binop can't find a suitable code in umul_widen_optab to
2749 make a REG_EQUAL note from, so make one here.
2750 See also smulsi3_highpart.
2751 ??? Alternatively, we could put this at the calling site of expand_binop,
2752 i.e. expand_expr. */
2753 /* Use emit_libcall_block for loop invariant code motion and to make
2754 a REG_EQUAL note. */
2755 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2760 (define_expand "umulhisi3"
2761 [(set (reg:SI MACL_REG)
2762 (mult:SI (zero_extend:SI
2763 (match_operand:HI 1 "arith_reg_operand" ""))
2765 (match_operand:HI 2 "arith_reg_operand" ""))))
2766 (set (match_operand:SI 0 "arith_reg_operand" "")
2773 macl = gen_rtx_REG (SImode, MACL_REG);
2775 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776 insn = get_insns ();
2778 /* expand_binop can't find a suitable code in umul_widen_optab to
2779 make a REG_EQUAL note from, so make one here.
2780 See also smulsi3_highpart.
2781 ??? Alternatively, we could put this at the calling site of expand_binop,
2782 i.e. expand_expr. */
2783 /* Use emit_libcall_block for loop invariant code motion and to make
2784 a REG_EQUAL note. */
2785 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2794 [(set (match_operand:SI 1 "register_operand" "=z")
2795 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796 (clobber (reg:SI MACL_REG))
2797 (clobber (reg:SI T_REG))
2798 (clobber (reg:SI PR_REG))
2799 (clobber (reg:SI R3_REG))
2800 (clobber (reg:SI R2_REG))
2801 (clobber (reg:SI R1_REG))
2802 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2805 [(set_attr "type" "sfunc")
2806 (set_attr "needs_delay_slot" "yes")])
2808 (define_expand "mulsi3_call"
2809 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811 (parallel[(set (match_operand:SI 0 "register_operand" "")
2812 (mult:SI (reg:SI R4_REG)
2814 (clobber (reg:SI MACL_REG))
2815 (clobber (reg:SI T_REG))
2816 (clobber (reg:SI PR_REG))
2817 (clobber (reg:SI R3_REG))
2818 (clobber (reg:SI R2_REG))
2819 (clobber (reg:SI R1_REG))
2820 (use (match_operand:SI 3 "register_operand" ""))])]
2824 (define_insn "mul_r"
2825 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827 (match_operand:SI 2 "arith_reg_operand" "z")))]
2830 [(set_attr "type" "dmpy")])
2832 (define_insn "mul_l"
2833 [(set (reg:SI MACL_REG)
2834 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835 (match_operand:SI 1 "arith_reg_operand" "r")))]
2838 [(set_attr "type" "dmpy")])
2840 (define_expand "mulsi3"
2841 [(set (reg:SI MACL_REG)
2842 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2843 (match_operand:SI 2 "arith_reg_operand" "")))
2844 (set (match_operand:SI 0 "arith_reg_operand" "")
2851 /* The address must be set outside the libcall,
2852 since it goes into a pseudo. */
2853 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854 rtx addr = force_reg (SImode, sym);
2855 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2861 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2863 emit_insn (gen_mul_l (operands[1], operands[2]));
2864 /* consec_sets_giv can only recognize the first insn that sets a
2865 giv as the giv insn. So we must tag this also with a REG_EQUAL
2867 emit_insn (gen_movsi_i ((operands[0]), macl));
2872 (define_insn "mulsidi3_i"
2873 [(set (reg:SI MACH_REG)
2877 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2880 (set (reg:SI MACL_REG)
2881 (mult:SI (match_dup 0)
2885 [(set_attr "type" "dmpy")])
2887 (define_expand "mulsidi3"
2888 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891 "TARGET_SH2 || TARGET_SHMEDIA"
2896 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2902 (define_insn "mulsidi3_media"
2903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2908 [(set_attr "type" "dmpy_media")
2909 (set_attr "highpart" "ignore")])
2911 (define_insn "mulsidi3_compact"
2912 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2914 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916 (clobber (reg:SI MACH_REG))
2917 (clobber (reg:SI MACL_REG))]
2922 [(set (match_operand:DI 0 "arith_reg_dest" "")
2924 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926 (clobber (reg:SI MACH_REG))
2927 (clobber (reg:SI MACL_REG))]
2932 rtx low_dst = gen_lowpart (SImode, operands[0]);
2933 rtx high_dst = gen_highpart (SImode, operands[0]);
2935 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2937 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939 /* We need something to tag the possible REG_EQUAL notes on to. */
2940 emit_move_insn (operands[0], operands[0]);
2944 (define_insn "umulsidi3_i"
2945 [(set (reg:SI MACH_REG)
2949 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2952 (set (reg:SI MACL_REG)
2953 (mult:SI (match_dup 0)
2957 [(set_attr "type" "dmpy")])
2959 (define_expand "umulsidi3"
2960 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963 "TARGET_SH2 || TARGET_SHMEDIA"
2968 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2974 (define_insn "umulsidi3_media"
2975 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2980 [(set_attr "type" "dmpy_media")
2981 (set_attr "highpart" "ignore")])
2983 (define_insn "umulsidi3_compact"
2984 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2986 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988 (clobber (reg:SI MACH_REG))
2989 (clobber (reg:SI MACL_REG))]
2994 [(set (match_operand:DI 0 "arith_reg_dest" "")
2995 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997 (clobber (reg:SI MACH_REG))
2998 (clobber (reg:SI MACL_REG))]
3003 rtx low_dst = gen_lowpart (SImode, operands[0]);
3004 rtx high_dst = gen_highpart (SImode, operands[0]);
3006 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3008 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010 /* We need something to tag the possible REG_EQUAL notes on to. */
3011 emit_move_insn (operands[0], operands[0]);
3015 (define_insn "smulsi3_highpart_i"
3016 [(set (reg:SI MACH_REG)
3020 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3023 (clobber (reg:SI MACL_REG))]
3026 [(set_attr "type" "dmpy")])
3028 (define_expand "smulsi3_highpart"
3030 [(set (reg:SI MACH_REG)
3034 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3037 (clobber (reg:SI MACL_REG))])
3038 (set (match_operand:SI 0 "arith_reg_operand" "")
3045 mach = gen_rtx_REG (SImode, MACH_REG);
3047 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048 insn = get_insns ();
3050 /* expand_binop can't find a suitable code in mul_highpart_optab to
3051 make a REG_EQUAL note from, so make one here.
3052 See also {,u}mulhisi.
3053 ??? Alternatively, we could put this at the calling site of expand_binop,
3054 i.e. expand_mult_highpart. */
3055 /* Use emit_libcall_block for loop invariant code motion and to make
3056 a REG_EQUAL note. */
3057 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3062 (define_insn "umulsi3_highpart_i"
3063 [(set (reg:SI MACH_REG)
3067 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3070 (clobber (reg:SI MACL_REG))]
3073 [(set_attr "type" "dmpy")])
3075 (define_expand "umulsi3_highpart"
3077 [(set (reg:SI MACH_REG)
3081 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3084 (clobber (reg:SI MACL_REG))])
3085 (set (match_operand:SI 0 "arith_reg_operand" "")
3092 mach = gen_rtx_REG (SImode, MACH_REG);
3094 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095 insn = get_insns ();
3097 /* Use emit_libcall_block for loop invariant code motion and to make
3098 a REG_EQUAL note. */
3099 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3104 (define_insn_and_split "muldi3"
3105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107 (match_operand:DI 2 "arith_reg_operand" "r")))
3108 (clobber (match_scratch:DI 3 "=&r"))
3109 (clobber (match_scratch:DI 4 "=r"))]
3116 rtx op3_v2si, op2_v2si;
3118 op3_v2si = operands[3];
3119 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3121 op3_v2si = XEXP (op3_v2si, 0);
3122 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3124 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125 op2_v2si = operands[2];
3126 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3128 op2_v2si = XEXP (op2_v2si, 0);
3129 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3131 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134 emit_insn (gen_umulsidi3_media (operands[4],
3135 sh_gen_truncate (SImode, operands[1], 0),
3136 sh_gen_truncate (SImode, operands[2], 0)));
3137 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3149 (define_insn "*andsi3_compact"
3150 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152 (match_operand:SI 2 "logical_operand" "r,K08")))]
3155 [(set_attr "type" "arith")])
3157 (define_insn "*andsi3_media"
3158 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160 (match_operand:SI 2 "logical_operand" "r,I10")))]
3165 [(set_attr "type" "arith_media")])
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3170 (define_expand "andsi3"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "")
3172 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173 (match_operand:SI 2 "logical_operand" "")))]
3178 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3180 emit_insn (gen_zero_extendqisi2 (operands[0],
3181 gen_lowpart (QImode, operands[1])));
3186 (define_insn_and_split "anddi3"
3187 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3196 && ! logical_operand (operands[2], DImode)"
3200 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3203 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3206 [(set_attr "type" "arith_media")])
3208 (define_insn "andcsi3"
3209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3214 [(set_attr "type" "arith_media")])
3216 (define_insn "andcdi3"
3217 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3222 [(set_attr "type" "arith_media")])
3224 (define_expand "iorsi3"
3225 [(set (match_operand:SI 0 "arith_reg_operand" "")
3226 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227 (match_operand:SI 2 "logical_operand" "")))]
3231 (define_insn "*iorsi3_compact"
3232 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234 (match_operand:SI 2 "logical_operand" "r,K08")))]
3237 [(set_attr "type" "arith")])
3239 (define_insn "*iorsi3_media"
3240 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242 (match_operand:SI 2 "logical_operand" "r,I10")))]
3247 [(set_attr "type" "arith_media")])
3249 (define_insn "iordi3"
3250 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252 (match_operand:DI 2 "logical_operand" "r,I10")))]
3257 [(set_attr "type" "arith_media")])
3259 (define_insn_and_split "*logical_sidi3"
3260 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3266 "&& reload_completed"
3267 [(set (match_dup 0) (match_dup 3))]
3271 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3276 (define_insn_and_split "*logical_sidisi3"
3277 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278 (truncate:SI (sign_extend:DI
3279 (match_operator:SI 3 "logical_operator"
3280 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3285 [(set (match_dup 0) (match_dup 3))])
3287 (define_insn_and_split "*logical_sidi3_2"
3288 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289 (sign_extend:DI (truncate:SI (sign_extend:DI
3290 (match_operator:SI 3 "logical_operator"
3291 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3296 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3298 (define_expand "xorsi3"
3299 [(set (match_operand:SI 0 "arith_reg_operand" "")
3300 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301 (match_operand:SI 2 "xor_operand" "")))]
3305 (define_insn "*xorsi3_compact"
3306 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308 (match_operand:SI 2 "logical_operand" "K08,r")))]
3311 [(set_attr "type" "arith")])
3313 (define_insn "*xorsi3_media"
3314 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316 (match_operand:SI 2 "xor_operand" "r,I06")))]
3321 [(set_attr "type" "arith_media")])
3323 (define_insn "xordi3"
3324 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326 (match_operand:DI 2 "xor_operand" "r,I06")))]
3331 [(set_attr "type" "arith_media")])
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3336 [(set (match_operand:DI 0 "arith_reg_dest" "")
3337 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338 [(match_operand 1 "any_register_operand" "")
3339 (match_operand 2 "any_register_operand" "")])))]
3341 [(set (match_dup 5) (match_dup 4))
3342 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3345 enum machine_mode inmode = GET_MODE (operands[1]);
3348 if (GET_CODE (operands[0]) == SUBREG)
3350 offset = SUBREG_BYTE (operands[0]);
3351 operands[0] = SUBREG_REG (operands[0]);
3353 gcc_assert (GET_CODE (operands[0]) == REG);
3354 if (! TARGET_LITTLE_ENDIAN)
3355 offset += 8 - GET_MODE_SIZE (inmode);
3356 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3363 (define_expand "rotldi3"
3364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3368 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3370 (define_insn "rotldi3_mextr"
3371 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3377 static char templ[16];
3379 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380 8 - (int) (INTVAL (operands[2]) >> 3));
3383 [(set_attr "type" "arith_media")])
3385 (define_expand "rotrdi3"
3386 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3390 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3392 (define_insn "rotrdi3_mextr"
3393 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3399 static char templ[16];
3401 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3404 [(set_attr "type" "arith_media")])
3407 [(set (match_operand:DI 0 "arith_reg_dest" "")
3408 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409 "ua_address_operand" "")))
3410 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3412 (clobber (match_operand:DI 3 "register_operand" ""))]
3414 [(match_dup 4) (match_dup 5)]
3417 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418 (operands[3], operands[1]));
3419 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3420 GEN_INT (56), GEN_INT (8));
3423 (define_insn "rotlsi3_1"
3424 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3425 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3431 [(set_attr "type" "arith")])
3433 (define_insn "rotlsi3_31"
3434 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3437 (clobber (reg:SI T_REG))]
3440 [(set_attr "type" "arith")])
3442 (define_insn "rotlsi3_16"
3443 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3444 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3448 [(set_attr "type" "arith")])
3450 (define_expand "rotlsi3"
3451 [(set (match_operand:SI 0 "arith_reg_dest" "")
3452 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3453 (match_operand:SI 2 "immediate_operand" "")))]
3457 static const char rot_tab[] = {
3458 000, 000, 000, 000, 000, 000, 010, 001,
3459 001, 001, 011, 013, 003, 003, 003, 003,
3460 003, 003, 003, 003, 003, 013, 012, 002,
3461 002, 002, 010, 000, 000, 000, 000, 000,
3466 if (GET_CODE (operands[2]) != CONST_INT)
3468 count = INTVAL (operands[2]);
3469 choice = rot_tab[count];
3470 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3476 emit_move_insn (operands[0], operands[1]);
3477 count -= (count & 16) * 2;
3480 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3487 parts[0] = gen_reg_rtx (SImode);
3488 parts[1] = gen_reg_rtx (SImode);
3489 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3490 emit_move_insn (parts[choice-1], operands[1]);
3491 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3492 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3493 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3494 count = (count & ~16) - 8;
3498 for (; count > 0; count--)
3499 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3500 for (; count < 0; count++)
3501 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3506 (define_insn "*rotlhi3_8"
3507 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3508 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3512 [(set_attr "type" "arith")])
3514 (define_expand "rotlhi3"
3515 [(set (match_operand:HI 0 "arith_reg_operand" "")
3516 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3517 (match_operand:HI 2 "immediate_operand" "")))]
3521 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3528 (define_insn "ashlsi3_sh2a"
3529 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531 (match_operand:SI 2 "arith_reg_operand" "r")))]
3534 [(set_attr "type" "arith")
3535 (set_attr "length" "4")])
3537 ;; This pattern is used by init_expmed for computing the costs of shift
3540 (define_insn_and_split "ashlsi3_std"
3541 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3542 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3543 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3544 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3546 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3554 && GET_CODE (operands[2]) == CONST_INT
3555 && ! satisfies_constraint_P27 (operands[2])"
3556 [(set (match_dup 3) (match_dup 2))
3558 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3559 (clobber (match_dup 4))])]
3560 "operands[4] = gen_rtx_SCRATCH (SImode);"
3561 [(set_attr "length" "*,*,*,4")
3562 (set_attr "type" "dyn_shift,arith,arith,arith")])
3564 (define_insn "ashlhi3_k"
3565 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3566 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3567 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3568 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3572 [(set_attr "type" "arith")])
3574 (define_insn "ashlsi3_n"
3575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577 (match_operand:SI 2 "const_int_operand" "n")))
3578 (clobber (reg:SI T_REG))]
3579 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3581 [(set (attr "length")
3582 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3584 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3586 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3588 (const_string "8")))
3589 (set_attr "type" "arith")])
3592 [(set (match_operand:SI 0 "arith_reg_dest" "")
3593 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3594 (match_operand:SI 2 "const_int_operand" "")))
3595 (clobber (reg:SI T_REG))]
3596 "TARGET_SH1 && reload_completed"
3597 [(use (reg:SI R0_REG))]
3600 gen_shifty_op (ASHIFT, operands);
3604 (define_insn "ashlsi3_media"
3605 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3606 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3607 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3612 [(set_attr "type" "arith_media")
3613 (set_attr "highpart" "ignore")])
3615 (define_expand "ashlsi3"
3616 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3617 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3618 (match_operand:SI 2 "nonmemory_operand" "")))
3619 (clobber (reg:SI T_REG))])]
3625 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3628 if (GET_CODE (operands[2]) == CONST_INT
3629 && sh_dynamicalize_shift_p (operands[2]))
3630 operands[2] = force_reg (SImode, operands[2]);
3633 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3636 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3640 (define_insn "*ashlhi3_n"
3641 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3642 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3643 (match_operand:HI 2 "const_int_operand" "n")))
3644 (clobber (reg:SI T_REG))]
3647 [(set (attr "length")
3648 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3650 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3652 (const_string "6")))
3653 (set_attr "type" "arith")])
3655 (define_expand "ashlhi3"
3656 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3657 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3658 (match_operand:SI 2 "nonmemory_operand" "")))
3659 (clobber (reg:SI T_REG))])]
3663 if (GET_CODE (operands[2]) != CONST_INT)
3665 /* It may be possible to call gen_ashlhi3 directly with more generic
3666 operands. Make sure operands[1] is a HImode register here. */
3667 if (!arith_reg_operand (operands[1], HImode))
3668 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3672 [(set (match_operand:HI 0 "arith_reg_dest" "")
3673 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3674 (match_operand:HI 2 "const_int_operand" "")))
3675 (clobber (reg:SI T_REG))]
3676 "TARGET_SH1 && reload_completed"
3677 [(use (reg:SI R0_REG))]
3680 gen_shifty_hi_op (ASHIFT, operands);
3685 ; arithmetic shift right
3688 (define_insn "ashrsi3_sh2a"
3689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694 [(set_attr "type" "dyn_shift")
3695 (set_attr "length" "4")])
3697 (define_insn "ashrsi3_k"
3698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3700 (match_operand:SI 2 "const_int_operand" "M")))
3701 (clobber (reg:SI T_REG))]
3702 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3704 [(set_attr "type" "arith")])
3706 ;; We can't do HImode right shifts correctly unless we start out with an
3707 ;; explicit zero / sign extension; doing that would result in worse overall
3708 ;; code, so just let the machine independent code widen the mode.
3709 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3712 ;; ??? This should be a define expand.
3714 (define_insn "ashrsi2_16"
3715 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3716 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3720 [(set_attr "length" "4")])
3723 [(set (match_operand:SI 0 "arith_reg_dest" "")
3724 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3727 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3728 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3729 "operands[2] = gen_lowpart (HImode, operands[0]);")
3731 ;; ??? This should be a define expand.
3733 (define_insn "ashrsi2_31"
3734 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3737 (clobber (reg:SI T_REG))]
3740 [(set_attr "length" "4")])
3743 [(set (match_operand:SI 0 "arith_reg_dest" "")
3744 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3746 (clobber (reg:SI T_REG))]
3751 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3752 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3757 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3759 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3761 && peep2_reg_dead_p (2, operands[0])
3762 && peep2_reg_dead_p (2, operands[1])"
3766 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3770 (define_insn "ashlsi_c"
3771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3774 (lt:SI (match_dup 1) (const_int 0)))]
3777 [(set_attr "type" "arith")])
3779 (define_insn "*ashlsi_c_void"
3780 [(set (reg:SI T_REG)
3781 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3782 (clobber (match_scratch:SI 1 "=0"))]
3783 "TARGET_SH1 && cse_not_expected"
3785 [(set_attr "type" "arith")])
3787 (define_insn "ashrsi3_d"
3788 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3789 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3790 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3793 [(set_attr "type" "dyn_shift")])
3795 (define_insn "ashrsi3_n"
3796 [(set (reg:SI R4_REG)
3797 (ashiftrt:SI (reg:SI R4_REG)
3798 (match_operand:SI 0 "const_int_operand" "i")))
3799 (clobber (reg:SI T_REG))
3800 (clobber (reg:SI PR_REG))
3801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3804 [(set_attr "type" "sfunc")
3805 (set_attr "needs_delay_slot" "yes")])
3807 (define_insn "ashrsi3_media"
3808 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3809 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3810 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3815 [(set_attr "type" "arith_media")
3816 (set_attr "highpart" "ignore")])
3818 (define_expand "ashrsi3"
3819 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3820 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3821 (match_operand:SI 2 "nonmemory_operand" "")))
3822 (clobber (reg:SI T_REG))])]
3828 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3831 if (expand_ashiftrt (operands))
3837 ;; logical shift right
3839 (define_insn "lshrsi3_sh2a"
3840 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3841 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3842 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3845 [(set_attr "type" "dyn_shift")
3846 (set_attr "length" "4")])
3848 (define_insn "lshrsi3_d"
3849 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3850 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3851 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3854 [(set_attr "type" "dyn_shift")])
3856 ;; Only the single bit shift clobbers the T bit.
3858 (define_insn "lshrsi3_m"
3859 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3860 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3861 (match_operand:SI 2 "const_int_operand" "M")))
3862 (clobber (reg:SI T_REG))]
3863 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3865 [(set_attr "type" "arith")])
3867 (define_insn "lshrsi3_k"
3868 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3869 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3870 (match_operand:SI 2 "const_int_operand" "P27")))]
3871 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3872 && ! satisfies_constraint_M (operands[2])"
3874 [(set_attr "type" "arith")])
3876 (define_insn "lshrsi3_n"
3877 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879 (match_operand:SI 2 "const_int_operand" "n")))
3880 (clobber (reg:SI T_REG))]
3881 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3883 [(set (attr "length")
3884 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3886 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3888 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3890 (const_string "8")))
3891 (set_attr "type" "arith")])
3894 [(set (match_operand:SI 0 "arith_reg_dest" "")
3895 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3896 (match_operand:SI 2 "const_int_operand" "")))
3897 (clobber (reg:SI T_REG))]
3898 "TARGET_SH1 && reload_completed"
3899 [(use (reg:SI R0_REG))]
3902 gen_shifty_op (LSHIFTRT, operands);
3906 (define_insn "lshrsi3_media"
3907 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3909 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3914 [(set_attr "type" "arith_media")
3915 (set_attr "highpart" "ignore")])
3917 (define_expand "lshrsi3"
3918 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3919 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3920 (match_operand:SI 2 "nonmemory_operand" "")))
3921 (clobber (reg:SI T_REG))])]
3927 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3930 if (GET_CODE (operands[2]) == CONST_INT
3931 && sh_dynamicalize_shift_p (operands[2]))
3932 operands[2] = force_reg (SImode, operands[2]);
3933 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3935 rtx count = copy_to_mode_reg (SImode, operands[2]);
3936 emit_insn (gen_negsi2 (count, count));
3937 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3940 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3944 ;; ??? This should be a define expand.
3946 (define_insn "ashldi3_k"
3947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3950 (clobber (reg:SI T_REG))]
3952 "shll %R0\;rotcl %S0"
3953 [(set_attr "length" "4")
3954 (set_attr "type" "arith")])
3956 (define_insn "ashldi3_media"
3957 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3958 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3964 [(set_attr "type" "arith_media")])
3966 (define_insn "*ashldisi3_media"
3967 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3968 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3969 (match_operand:DI 2 "const_int_operand" "n")))]
3970 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3971 "shlli.l %1, %2, %0"
3972 [(set_attr "type" "arith_media")
3973 (set_attr "highpart" "ignore")])
3975 (define_expand "ashldi3"
3976 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3977 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3978 (match_operand:DI 2 "immediate_operand" "")))
3979 (clobber (reg:SI T_REG))])]
3985 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3988 if (GET_CODE (operands[2]) != CONST_INT
3989 || INTVAL (operands[2]) != 1)
3993 ;; ??? This should be a define expand.
3995 (define_insn "lshrdi3_k"
3996 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3997 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3999 (clobber (reg:SI T_REG))]
4001 "shlr %S0\;rotcr %R0"
4002 [(set_attr "length" "4")
4003 (set_attr "type" "arith")])
4005 (define_insn "lshrdi3_media"
4006 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4007 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4008 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4010 && (arith_reg_dest (operands[0], DImode)
4011 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4015 [(set_attr "type" "arith_media")])
4017 (define_insn "*lshrdisi3_media"
4018 [(set (subreg:DI (match_operand:SI 0