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 3, 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 COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences. Especially the sequences for arithmetic right shifts.
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
32 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
33 ;; way to generate them.
35 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
36 ;; for a str* inline function.
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42 ;; Special constraints for SH machine description:
49 ;; Special formats used for outputting SH instructions:
51 ;; %. -- print a .s if insn needs delay slot
52 ;; %@ -- print rte/rts if is/isn't an interrupt function
53 ;; %# -- output a nop if there is nothing to put in the delay slot
54 ;; %O -- print a constant without the #
55 ;; %R -- print the lsw reg of a double
56 ;; %S -- print the msw reg of a double
57 ;; %T -- print next word of a double REG or MEM
59 ;; Special predicates:
61 ;; arith_operand -- operand is valid source for arithmetic op
62 ;; arith_reg_operand -- operand is valid register for arithmetic op
63 ;; general_movdst_operand -- operand is valid move destination
64 ;; general_movsrc_operand -- operand is valid move source
65 ;; logical_operand -- operand is valid source for logical op
67 ;; -------------------------------------------------------------------------
69 ;; -------------------------------------------------------------------------
117 ;; These are used with unspec.
118 (UNSPEC_COMPACT_ARGS 0)
131 (UNSPEC_INIT_TRAMP 13)
144 (UNSPEC_DIV_INV_M0 30)
145 (UNSPEC_DIV_INV_M1 31)
146 (UNSPEC_DIV_INV_M2 32)
147 (UNSPEC_DIV_INV_M3 33)
148 (UNSPEC_DIV_INV20 34)
149 (UNSPEC_DIV_INV_TABLE 37)
156 ;; These are used with unspec_volatile.
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
164 (UNSPECV_EH_RETURN 12)
167 ;; -------------------------------------------------------------------------
169 ;; -------------------------------------------------------------------------
174 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175 (const (symbol_ref "sh_cpu_attr")))
177 (define_attr "endian" "big,little"
178 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179 (const_string "little") (const_string "big"))))
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184 (const_string "yes") (const_string "no"))))
186 (define_attr "fmovd" "yes,no"
187 (const (if_then_else (symbol_ref "TARGET_FMOVD")
188 (const_string "yes") (const_string "no"))))
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
192 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194 (const_string "sh1"))))
196 ;; cbranch conditional branch instructions
197 ;; jump unconditional jumps
198 ;; arith ordinary arithmetic
199 ;; arith3 a compound insn that behaves similarly to a sequence of
200 ;; three insns of type arith
201 ;; arith3b like above, but might end with a redirected branch
203 ;; load_si Likewise, SImode variant for general register.
204 ;; fload Likewise, but load to fp register.
206 ;; fstore floating point register to memory
207 ;; move general purpose register to register
208 ;; movi8 8-bit immediate to general purpose register
209 ;; mt_group other sh4 mt instructions
210 ;; fmove register to register, floating point
211 ;; smpy word precision integer multiply
212 ;; dmpy longword or doublelongword precision integer multiply
214 ;; pload load of pr reg, which can't be put into delay slot of rts
215 ;; prset copy register to pr reg, ditto
216 ;; pstore store of pr reg, which can't be put into delay slot of jsr
217 ;; prget copy pr to register, ditto
218 ;; pcload pc relative load of constant value
219 ;; pcfload Likewise, but load to fp register.
220 ;; pcload_si Likewise, SImode variant for general register.
221 ;; rte return from exception
222 ;; sfunc special function call with known used registers
223 ;; call function call
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv floating point divide (or square root)
227 ;; gp_fpul move from general purpose register to fpul
228 ;; fpul_gp move from fpul to general purpose register
229 ;; mac_gp move from mac[lh] to general purpose register
230 ;; gp_mac move from general purpose register to mac[lh]
231 ;; mac_mem move from mac[lh] to memory
232 ;; mem_mac move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s fix_truncsfsi2_i4
235 ;; dfdiv double precision floating point divide (or square root)
236 ;; cwb ic_invalidate_line_i
237 ;; movua SH4a unaligned load
238 ;; fsrra square root reciprocal approximate
239 ;; fsca sine and cosine approximate
240 ;; tls_load load TLS related address
241 ;; arith_media SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media SHmedia compare instructions
244 ;; dfdiv_media SHmedia double precision divide and square root
245 ;; dfmul_media SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media SHmedia longword multiply
249 ;; fcmp_media SHmedia floating point compare instructions
250 ;; fdiv_media SHmedia single precision divide and square root
251 ;; fload_media SHmedia floating point register load instructions
252 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media SHmedia unconditional branch instructions
259 ;; load_media SHmedia general register load instructions
260 ;; pt_media SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media SHmedia ptabs instruction
262 ;; store_media SHmedia general register store instructions
263 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media SHmedia mac-style fixed point operations
265 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil no-op move, will be deleted.
271 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
272 (const_string "other"))
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
277 ;; mt_group SH4 "mt" group instructions.
279 ;; ex_group SH4 "ex" group instructions.
281 ;; ls_group SH4 "ls" group instructions.
284 (define_attr "insn_class"
285 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289 (eq_attr "type" "cbranch,jump") (const_string "br_group")
290 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291 (const_string "fe_group")
292 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
293 (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long. Something in the
312 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
317 ;; The maximum range used for SImode constant pool entries is 1018. A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table. That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
335 (define_attr "short_cbranch_p" "no,yes"
336 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
338 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
340 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
342 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
344 ] (const_string "no")))
346 (define_attr "med_branch_p" "no,yes"
347 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
350 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
355 ] (const_string "no")))
357 (define_attr "med_cbranch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
361 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
366 ] (const_string "no")))
368 (define_attr "braf_branch_p" "no,yes"
369 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
371 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
374 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
379 ] (const_string "no")))
381 (define_attr "braf_cbranch_p" "no,yes"
382 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
387 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
392 ] (const_string "no")))
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
401 ; All other instructions are two bytes long by default.
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406 (cond [(eq_attr "type" "cbranch")
407 (cond [(eq_attr "short_cbranch_p" "yes")
409 (eq_attr "med_cbranch_p" "yes")
411 (eq_attr "braf_cbranch_p" "yes")
413 ;; ??? using pc is not computed transitively.
414 (ne (match_dup 0) (match_dup 0))
416 (ne (symbol_ref ("flag_pic")) (const_int 0))
419 (eq_attr "type" "jump")
420 (cond [(eq_attr "med_branch_p" "yes")
422 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
424 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
426 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427 (symbol_ref "code_for_indirect_jump_scratch"))))
428 (cond [(eq_attr "braf_branch_p" "yes")
430 (eq (symbol_ref "flag_pic") (const_int 0))
432 (ne (symbol_ref "TARGET_SH2") (const_int 0))
433 (const_int 10)] (const_int 18))
434 (eq_attr "braf_branch_p" "yes")
436 ;; ??? using pc is not computed transitively.
437 (ne (match_dup 0) (match_dup 0))
439 (ne (symbol_ref ("flag_pic")) (const_int 0))
442 (eq_attr "type" "pt_media")
443 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444 (const_int 20) (const_int 12))
445 (and (eq_attr "type" "jump_media")
446 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
448 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
452 ;; DFA descriptions for the pipelines
455 (include "shmedia.md")
458 (include "predicates.md")
459 (include "constraints.md")
461 ;; Definitions for filling delay slots
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465 (define_attr "banked" "yes,no"
466 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
468 (const_string "yes")]
469 (const_string "no")))
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
476 (const_string "yes")))
478 (define_attr "interrupt_function" "no,yes"
479 (const (symbol_ref "current_function_interrupt")))
481 (define_attr "in_delay_slot" "yes,no"
482 (cond [(eq_attr "type" "cbranch") (const_string "no")
483 (eq_attr "type" "pcload,pcload_si") (const_string "no")
484 (eq_attr "needs_delay_slot" "yes") (const_string "no")
485 (eq_attr "length" "2") (const_string "yes")
486 ] (const_string "no")))
488 (define_attr "cond_delay_slot" "yes,no"
489 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490 ] (const_string "no")))
492 (define_attr "is_sfunc" ""
493 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
495 (define_attr "is_mac_media" ""
496 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
498 (define_attr "branch_zero" "yes,no"
499 (cond [(eq_attr "type" "!cbranch") (const_string "no")
500 (ne (symbol_ref "(next_active_insn (insn)\
501 == (prev_active_insn\
502 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503 && get_attr_length (next_active_insn (insn)) == 2")
505 (const_string "yes")]
506 (const_string "no")))
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512 (const_string "no")))
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519 (const_string "yes")]
520 (const_string "no")))
522 (define_attr "any_int_load" "yes,no"
523 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524 (const_string "yes")]
525 (const_string "no")))
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528 (const_string "user"))
531 (eq_attr "needs_delay_slot" "yes")
532 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
543 (eq_attr "type" "return")
544 [(and (eq_attr "in_delay_slot" "yes")
545 (ior (and (eq_attr "interrupt_function" "no")
546 (eq_attr "type" "!pload,prset"))
547 (and (eq_attr "interrupt_function" "yes")
549 (eq (symbol_ref "TARGET_SH3") (const_int 0))
550 (eq_attr "hit_stack" "no")
551 (eq_attr "banked" "no"))))) (nil) (nil)])
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
557 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558 [(and (eq_attr "in_delay_slot" "yes")
559 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
569 (and (eq_attr "type" "cbranch")
570 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571 ;; SH2e has a hardware bug that pretty much prohibits the use of
572 ;; annuled delay slots.
573 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574 (not (eq_attr "cpu" "sh2e"))) (nil)])
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
582 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583 (match_operand:SI 1 "arith_operand" "K08,r"))
587 [(set_attr "type" "mt_group")])
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
595 (define_insn "cmpeqsi_t"
597 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
604 [(set_attr "type" "mt_group")])
606 (define_insn "cmpgtsi_t"
608 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
614 [(set_attr "type" "mt_group")])
616 (define_insn "cmpgesi_t"
618 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
624 [(set_attr "type" "mt_group")])
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
630 (define_expand "cbranchsi4"
632 (if_then_else (match_operator 0 "comparison_operator"
633 [(match_operand:SI 1 "arith_operand" "")
634 (match_operand:SI 2 "arith_operand" "")])
635 (label_ref (match_operand 3 "" ""))
637 (clobber (reg:SI T_REG))]
639 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
645 (define_insn_and_split "cmpgeusi_t"
647 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
651 "&& operands[0] == CONST0_RTX (SImode)"
655 emit_insn (gen_sett ());
658 [(set_attr "type" "mt_group")])
660 (define_insn "cmpgtusi_t"
662 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663 (match_operand:SI 1 "arith_reg_operand" "r")))]
666 [(set_attr "type" "mt_group")])
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
671 (define_expand "cmpsi"
673 (compare (match_operand:SI 0 "cmpsi_operand" "")
674 (match_operand:SI 1 "arith_operand" "")))]
675 "TARGET_SH1 || TARGET_SHMEDIA"
678 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679 && GET_CODE (operands[1]) != CONST_INT)
680 operands[0] = copy_to_mode_reg (SImode, operands[0]);
681 sh_compare_op0 = operands[0];
682 sh_compare_op1 = operands[1];
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
696 (define_expand "cbranchdi4"
698 (if_then_else (match_operator 0 "comparison_operator"
699 [(match_operand:DI 1 "arith_operand" "")
700 (match_operand:DI 2 "arith_operand" "")])
701 (label_ref (match_operand 3 "" ""))
703 (clobber (match_dup 4))
704 (clobber (reg:SI T_REG))]
708 enum rtx_code comparison;
710 if (TARGET_EXPAND_CBRANCHDI4)
712 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
715 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716 if (comparison != GET_CODE (operands[0]))
718 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719 operands[4] = gen_rtx_SCRATCH (SImode);
722 (define_insn_and_split "cbranchdi4_i"
724 (if_then_else (match_operator 0 "comparison_operator"
725 [(match_operand:DI 1 "arith_operand" "r,r")
726 (match_operand:DI 2 "arith_operand" "rN,i")])
727 (label_ref (match_operand 3 "" ""))
729 (clobber (match_scratch:SI 4 "=X,&r"))
730 (clobber (reg:SI T_REG))]
733 "&& reload_completed"
737 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
748 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749 (match_operand:DI 1 "arith_operand" "r"))
752 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
754 [(set_attr "length" "6")
755 (set_attr "type" "arith3b")])
757 (define_insn "cmpeqdi_t"
759 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
763 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
764 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765 [(set_attr "length" "6")
766 (set_attr "type" "arith3b")])
770 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
775 "TARGET_SH1 && reload_completed && optimize"
776 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778 (label_ref (match_dup 6))
780 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
785 = gen_rtx_REG (SImode,
786 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
788 = (operands[1] == const0_rtx
790 : gen_rtx_REG (SImode,
791 true_regnum (operands[1])
792 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793 operands[4] = gen_lowpart (SImode, operands[0]);
794 operands[5] = gen_lowpart (SImode, operands[1]);
795 operands[6] = gen_label_rtx ();
798 (define_insn "cmpgtdi_t"
800 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
804 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806 [(set_attr "length" "8")
807 (set_attr "type" "arith3")])
809 (define_insn "cmpgedi_t"
811 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
815 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
817 [(set_attr "length" "8,2")
818 (set_attr "type" "arith3,mt_group")])
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
824 (define_insn "cmpgeudi_t"
826 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827 (match_operand:DI 1 "arith_reg_operand" "r")))]
829 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830 [(set_attr "length" "8")
831 (set_attr "type" "arith3")])
833 (define_insn "cmpgtudi_t"
835 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836 (match_operand:DI 1 "arith_reg_operand" "r")))]
838 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839 [(set_attr "length" "8")
840 (set_attr "type" "arith3")])
842 (define_insn "cmpeqsi_media"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845 (match_operand:SI 2 "cmp_operand" "Nr")))]
848 [(set_attr "type" "cmp_media")])
850 (define_insn "cmpeqdi_media"
851 [(set (match_operand:SI 0 "register_operand" "=r")
852 (eq:SI (match_operand:DI 1 "register_operand" "%r")
853 (match_operand:DI 2 "cmp_operand" "Nr")))]
856 [(set_attr "type" "cmp_media")])
858 (define_insn "cmpgtsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861 (match_operand:SI 2 "cmp_operand" "rN")))]
864 [(set_attr "type" "cmp_media")])
866 (define_insn "cmpgtdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
872 [(set_attr "type" "cmp_media")])
874 (define_insn "cmpgtusi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
879 "cmpgtu %N1, %N2, %0"
880 [(set_attr "type" "cmp_media")])
882 (define_insn "cmpgtudi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
887 "cmpgtu %N1, %N2, %0"
888 [(set_attr "type" "cmp_media")])
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
896 [(set_attr "type" "cmp_media")])
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
901 (define_expand "cmpdi"
903 (compare (match_operand:DI 0 "arith_operand" "")
904 (match_operand:DI 1 "arith_operand" "")))]
905 "TARGET_SH2 || TARGET_SHMEDIA"
908 sh_compare_op0 = operands[0];
909 sh_compare_op1 = operands[1];
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
919 (define_insn "movdicc_false"
920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
923 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924 (match_operand:DI 3 "arith_reg_operand" "0")))]
927 [(set_attr "type" "arith_media")])
929 (define_insn "movdicc_true"
930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
933 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934 (match_operand:DI 3 "arith_reg_operand" "0")))]
937 [(set_attr "type" "arith_media")])
940 [(set (match_operand:DI 0 "arith_reg_dest" "")
941 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942 [(match_operand:DI 1 "arith_reg_operand" "")
944 (match_operand:DI 2 "arith_reg_dest" "")
946 (set (match_dup 2) (match_dup 0))]
947 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
949 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953 VOIDmode, operands[1], CONST0_RTX (DImode));
957 [(set (match_operand:DI 0 "general_movdst_operand" "")
958 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959 (set (match_operand:DI 2 "arith_reg_dest" "")
960 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961 [(match_operand:DI 3 "arith_reg_operand" "")
965 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
967 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970 (define_expand "movdicc"
971 [(set (match_operand:DI 0 "register_operand" "")
972 (if_then_else:DI (match_operand 1 "comparison_operator" "")
973 (match_operand:DI 2 "register_operand" "")
974 (match_operand:DI 3 "register_operand" "")))]
978 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979 && GET_MODE (sh_compare_op0) == DImode
980 && sh_compare_op1 == const0_rtx)
981 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982 sh_compare_op0, sh_compare_op1);
987 if (!can_create_pseudo_p ())
990 tmp = gen_reg_rtx (DImode);
992 switch (GET_CODE (operands[1]))
995 emit_insn (gen_seq (tmp));
996 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1000 emit_insn (gen_seq (tmp));
1001 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1005 emit_insn (gen_sgt (tmp));
1006 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1010 emit_insn (gen_slt (tmp));
1011 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1015 emit_insn (gen_slt (tmp));
1016 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1020 emit_insn (gen_sgt (tmp));
1021 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1025 emit_insn (gen_sgtu (tmp));
1026 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1030 emit_insn (gen_sltu (tmp));
1031 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1035 emit_insn (gen_sltu (tmp));
1036 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1040 emit_insn (gen_sgtu (tmp));
1041 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1045 emit_insn (gen_sunordered (tmp));
1046 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1050 emit_insn (gen_sunordered (tmp));
1051 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1074 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075 (match_operand:SI 3 "arith_reg_operand" "0")))]
1078 [(set_attr "type" "arith_media")])
1080 (define_insn "movsicc_true"
1081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1084 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085 (match_operand:SI 3 "arith_reg_operand" "0")))]
1088 [(set_attr "type" "arith_media")])
1091 [(set (match_operand:SI 0 "arith_reg_dest" "")
1092 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093 [(match_operand:SI 1 "arith_reg_operand" "")
1095 (match_operand:SI 2 "arith_reg_dest" "")
1097 (set (match_dup 2) (match_dup 0))]
1098 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1100 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1103 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104 VOIDmode, operands[1], CONST0_RTX (SImode));
1108 [(set (match_operand:SI 0 "general_movdst_operand" "")
1109 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110 (set (match_operand:SI 2 "arith_reg_dest" "")
1111 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112 [(match_operand:SI 3 "arith_reg_operand" "")
1116 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1119 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1122 replace_rtx (operands[4], operands[0], operands[1]);
1126 [(set (match_operand 0 "any_register_operand" "")
1127 (match_operand 1 "any_register_operand" ""))
1128 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138 && (REGNO_REG_CLASS (REGNO (operands[0]))
1139 == REGNO_REG_CLASS (REGNO (operands[2])))
1140 && (REGNO_REG_CLASS (REGNO (operands[1]))
1141 == REGNO_REG_CLASS (REGNO (operands[0])))"
1142 [(set (match_dup 0) (match_dup 3))
1143 (set (match_dup 4) (match_dup 5))]
1147 rtx replacements[4];
1149 /* We want to replace occurrences of operands[0] with operands[1] and
1150 operands[2] with operands[0] in operands[4]/operands[5].
1151 Doing just two replace_rtx calls naively would result in the second
1152 replacement undoing all that the first did if operands[1] and operands[2]
1153 are identical, so we must do this simultaneously. */
1154 replacements[0] = operands[0];
1155 replacements[1] = operands[1];
1156 replacements[2] = operands[2];
1157 replacements[3] = operands[0];
1158 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1163 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166 /* The operands array is aliased to recog_data.operand, which gets
1167 clobbered by extract_insn, so finish with it now. */
1168 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171 always uses emit_insn. */
1172 /* Check that we don't violate matching constraints or earlyclobbers. */
1173 extract_insn (emit_insn (set1));
1174 if (! constrain_operands (1))
1176 extract_insn (emit (set2));
1177 if (! constrain_operands (1))
1181 tmp = replacements[0];
1182 replacements[0] = replacements[1];
1183 replacements[1] = tmp;
1184 tmp = replacements[2];
1185 replacements[2] = replacements[3];
1186 replacements[3] = tmp;
1187 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1188 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1189 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1195 ;; The register allocator is rather clumsy in handling multi-way conditional
1196 ;; moves, so allow the combiner to make them, and we split them up after
1198 (define_insn_and_split "*movsicc_umin"
1199 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1200 (umin:SI (if_then_else:SI
1201 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1203 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1204 (match_operand:SI 3 "register_operand" "0"))
1205 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1206 (clobber (match_scratch:SI 5 "=&r"))]
1207 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1209 "TARGET_SHMEDIA && reload_completed"
1213 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1215 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1216 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1221 (define_insn "*movsicc_t_false"
1222 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1223 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1224 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1225 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1226 "TARGET_PRETEND_CMOVE
1227 && (arith_reg_operand (operands[1], SImode)
1228 || (immediate_operand (operands[1], SImode)
1229 && satisfies_constraint_I08 (operands[1])))"
1230 "bt 0f\;mov %1,%0\\n0:"
1231 [(set_attr "type" "mt_group,arith") ;; poor approximation
1232 (set_attr "length" "4")])
1234 (define_insn "*movsicc_t_true"
1235 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1237 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1238 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1239 "TARGET_PRETEND_CMOVE
1240 && (arith_reg_operand (operands[1], SImode)
1241 || (immediate_operand (operands[1], SImode)
1242 && satisfies_constraint_I08 (operands[1])))"
1243 "bf 0f\;mov %1,%0\\n0:"
1244 [(set_attr "type" "mt_group,arith") ;; poor approximation
1245 (set_attr "length" "4")])
1247 (define_expand "movsicc"
1248 [(set (match_operand:SI 0 "arith_reg_dest" "")
1249 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1250 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1251 (match_operand:SI 3 "arith_reg_operand" "")))]
1252 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1255 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1256 && GET_MODE (sh_compare_op0) == SImode
1258 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1259 && sh_compare_op1 == const0_rtx)
1260 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1261 sh_compare_op0, sh_compare_op1);
1262 else if (TARGET_PRETEND_CMOVE)
1264 enum rtx_code code = GET_CODE (operands[1]);
1265 enum rtx_code new_code = code;
1268 if (! currently_expanding_to_rtl)
1272 case LT: case LE: case LEU: case LTU:
1273 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1276 new_code = reverse_condition (code);
1278 case EQ: case GT: case GE: case GEU: case GTU:
1283 tmp = prepare_scc_operands (new_code);
1284 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1291 if (!can_create_pseudo_p ())
1294 tmp = gen_reg_rtx (SImode);
1296 switch (GET_CODE (operands[1]))
1299 emit_insn (gen_seq (tmp));
1300 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1304 emit_insn (gen_seq (tmp));
1305 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1309 emit_insn (gen_sgt (tmp));
1310 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1314 emit_insn (gen_slt (tmp));
1315 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1319 emit_insn (gen_slt (tmp));
1320 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1324 emit_insn (gen_sgt (tmp));
1325 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1329 emit_insn (gen_sgtu (tmp));
1330 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1334 emit_insn (gen_sltu (tmp));
1335 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1339 emit_insn (gen_sltu (tmp));
1340 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1344 emit_insn (gen_sgtu (tmp));
1345 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1349 emit_insn (gen_sunordered (tmp));
1350 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1354 emit_insn (gen_sunordered (tmp));
1355 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1372 (define_expand "movqicc"
1373 [(set (match_operand:QI 0 "register_operand" "")
1374 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375 (match_operand:QI 2 "register_operand" "")
1376 (match_operand:QI 3 "register_operand" "")))]
1380 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1381 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1382 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1383 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1387 ;; -------------------------------------------------------------------------
1388 ;; Addition instructions
1389 ;; -------------------------------------------------------------------------
1391 (define_expand "adddi3"
1392 [(set (match_operand:DI 0 "arith_reg_operand" "")
1393 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1394 (match_operand:DI 2 "arith_operand" "")))]
1400 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1402 operands[2] = force_reg (DImode, operands[2]);
1403 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1408 (define_insn "*adddi3_media"
1409 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1410 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1411 (match_operand:DI 2 "arith_operand" "r,I10")))]
1416 [(set_attr "type" "arith_media")])
1418 (define_insn "*adddisi3_media"
1419 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1420 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421 (match_operand:DI 2 "arith_operand" "r,I10")))]
1426 [(set_attr "type" "arith_media")
1427 (set_attr "highpart" "ignore")])
1429 (define_insn "adddi3z_media"
1430 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1432 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1433 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1435 "addz.l %1, %N2, %0"
1436 [(set_attr "type" "arith_media")
1437 (set_attr "highpart" "ignore")])
1439 (define_insn "adddi3_compact"
1440 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1441 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1442 (match_operand:DI 2 "arith_reg_operand" "r")))
1443 (clobber (reg:SI T_REG))]
1446 [(set_attr "length" "6")])
1449 [(set (match_operand:DI 0 "arith_reg_dest" "")
1450 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1451 (match_operand:DI 2 "arith_reg_operand" "")))
1452 (clobber (reg:SI T_REG))]
1453 "TARGET_SH1 && reload_completed"
1457 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1458 high0 = gen_rtx_REG (SImode,
1459 true_regnum (operands[0])
1460 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461 high2 = gen_rtx_REG (SImode,
1462 true_regnum (operands[2])
1463 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464 emit_insn (gen_clrt ());
1465 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1466 emit_insn (gen_addc1 (high0, high0, high2));
1471 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1472 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1473 (match_operand:SI 2 "arith_reg_operand" "r"))
1476 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1479 [(set_attr "type" "arith")])
1481 (define_insn "addc1"
1482 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1483 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1484 (match_operand:SI 2 "arith_reg_operand" "r"))
1486 (clobber (reg:SI T_REG))]
1489 [(set_attr "type" "arith")])
1491 (define_expand "addsi3"
1492 [(set (match_operand:SI 0 "arith_reg_operand" "")
1493 (plus:SI (match_operand:SI 1 "arith_operand" "")
1494 (match_operand:SI 2 "arith_operand" "")))]
1499 operands[1] = force_reg (SImode, operands[1]);
1502 (define_insn "addsi3_media"
1503 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1504 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1505 (match_operand:SI 2 "arith_operand" "r,I10")))]
1510 [(set_attr "type" "arith_media")
1511 (set_attr "highpart" "ignore")])
1513 (define_insn "addsidi3_media"
1514 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1515 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1517 (match_operand:SI 2 "arith_operand"
1523 [(set_attr "type" "arith_media")
1524 (set_attr "highpart" "ignore")])
1526 (define_insn "*addsi3_compact"
1527 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1528 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1529 (match_operand:SI 2 "arith_operand" "rI08")))]
1532 [(set_attr "type" "arith")])
1534 ;; -------------------------------------------------------------------------
1535 ;; Subtraction instructions
1536 ;; -------------------------------------------------------------------------
1538 (define_expand "subdi3"
1539 [(set (match_operand:DI 0 "arith_reg_operand" "")
1540 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1541 (match_operand:DI 2 "arith_reg_operand" "")))]
1547 operands[1] = force_reg (DImode, operands[1]);
1548 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1553 (define_insn "*subdi3_media"
1554 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1555 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1556 (match_operand:DI 2 "arith_reg_operand" "r")))]
1559 [(set_attr "type" "arith_media")])
1561 (define_insn "subdisi3_media"
1562 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1563 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1564 (match_operand:DI 2 "arith_reg_operand" "r")))]
1567 [(set_attr "type" "arith_media")
1568 (set_attr "highpart" "ignore")])
1570 (define_insn "subdi3_compact"
1571 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1572 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1573 (match_operand:DI 2 "arith_reg_operand" "r")))
1574 (clobber (reg:SI T_REG))]
1577 [(set_attr "length" "6")])
1580 [(set (match_operand:DI 0 "arith_reg_dest" "")
1581 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1582 (match_operand:DI 2 "arith_reg_operand" "")))
1583 (clobber (reg:SI T_REG))]
1584 "TARGET_SH1 && reload_completed"
1588 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1589 high0 = gen_rtx_REG (SImode,
1590 true_regnum (operands[0])
1591 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1592 high2 = gen_rtx_REG (SImode,
1593 true_regnum (operands[2])
1594 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595 emit_insn (gen_clrt ());
1596 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1597 emit_insn (gen_subc1 (high0, high0, high2));
1602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1603 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1604 (match_operand:SI 2 "arith_reg_operand" "r"))
1607 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1612 [(set_attr "type" "arith")])
1614 (define_insn "subc1"
1615 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1616 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1617 (match_operand:SI 2 "arith_reg_operand" "r"))
1619 (clobber (reg:SI T_REG))]
1622 [(set_attr "type" "arith")])
1624 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1625 ;; pattern for this case. This helps multimedia applications that compute
1626 ;; the sum of absolute differences.
1627 (define_insn "mov_neg_si_t"
1628 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1631 [(set_attr "type" "arith")])
1633 (define_insn "*subsi3_internal"
1634 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1635 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1636 (match_operand:SI 2 "arith_reg_operand" "r")))]
1639 [(set_attr "type" "arith")])
1641 (define_insn_and_split "*subsi3_media"
1642 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1643 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1644 (match_operand:SI 2 "extend_reg_operand" "r")))]
1646 && (operands[1] != constm1_rtx
1647 || (GET_CODE (operands[2]) != TRUNCATE
1648 && GET_CODE (operands[2]) != SUBREG))"
1650 "operands[1] == constm1_rtx"
1651 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1653 [(set_attr "type" "arith_media")
1654 (set_attr "highpart" "ignore")])
1657 [(set (match_operand:SI 0 "arith_reg_dest" "")
1658 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1659 "general_extend_operand"
1661 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1662 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1663 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1667 [(set (match_operand:SI 0 "arith_reg_dest" "")
1668 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669 "general_extend_operand"
1671 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1672 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1675 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1676 ;; will sometimes save one instruction. Otherwise we might get
1677 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1680 (define_expand "subsi3"
1681 [(set (match_operand:SI 0 "arith_reg_operand" "")
1682 (minus:SI (match_operand:SI 1 "arith_operand" "")
1683 (match_operand:SI 2 "arith_reg_operand" "")))]
1687 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1689 emit_insn (gen_negsi2 (operands[0], operands[2]));
1690 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1695 if (!can_create_pseudo_p ()
1696 && ! 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_reg_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_reg_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_reg_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"))]
2360 "&& !can_create_pseudo_p ()"
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"))]
2404 "&& !can_create_pseudo_p ()"
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"))]
2448 "&& !can_create_pseudo_p ()"
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)"
2515 "&& !can_create_pseudo_p ()"
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 && !can_create_pseudo_p ()"
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"