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[1] == 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 if (satisfies_constraint_N (dividend))
2476 emit_move_insn (result, dividend);
2480 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2481 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2482 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2483 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2484 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2485 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2486 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2490 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2491 ;; inv1: tab_base, tab_ix, norm32
2492 ;; inv2: norm32, inv1, i92
2493 (define_insn_and_split "divsi_inv_m1_3"
2494 [(set (match_operand:SI 0 "register_operand" "=r")
2495 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2496 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2497 (match_operand:DI 3 "register_operand" "r")
2498 (match_operand:SI 4 "register_operand" "r")]
2500 (unspec:SI [(match_dup 4)
2501 (unspec:SI [(match_dup 2)
2503 (match_dup 4)] UNSPEC_DIV_INV_M1)
2504 (match_operand:SI 5 "" "")]
2506 (match_operand:DI 6 "register_operand" "r")
2507 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2508 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2510 (clobber (match_operand:DI 9 "register_operand" "=r"))
2511 (clobber (match_operand:DI 10 "register_operand" "=r"))
2512 (clobber (match_operand:DI 11 "register_operand" "=r"))
2513 (clobber (match_operand:DI 12 "register_operand" "=r"))
2514 (clobber (match_operand:SI 13 "register_operand" "=r"))
2515 (clobber (match_operand:SI 14 "register_operand" "=r"))
2516 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2518 && (TARGET_DIVIDE_INV_MINLAT
2519 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2521 "&& !can_create_pseudo_p ()"
2525 rtx result = operands[0];
2526 rtx dividend = operands[1];
2527 rtx tab_base = operands[2];
2528 rtx tab_ix = operands[3];
2529 rtx norm32 = operands[4];
2530 /* rtx i92 = operands[5]; */
2531 rtx shift = operands[6];
2532 rtx i2p27 = operands[7];
2533 rtx i43 = operands[8];
2534 rtx scratch0 = operands[9];
2535 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2536 rtx scratch1 = operands[10];
2537 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2538 rtx scratch2 = operands[11];
2539 rtx scratch3 = operands[12];
2540 rtx scratch4 = operands[13];
2541 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2542 rtx scratch5 = operands[14];
2543 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2544 rtx scratch6 = operands[15];
2546 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2547 scratch0, scratch1));
2548 /* inv0 == scratch4 */
2549 if (! TARGET_DIVIDE_INV20U)
2551 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2553 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2557 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2558 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2560 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2561 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2562 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2563 /* inv1 == scratch4 */
2565 if (TARGET_DIVIDE_INV_MINLAT)
2567 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2568 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2569 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2570 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2571 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2572 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2573 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2574 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2575 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2576 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2577 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2581 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2582 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2583 emit_insn (gen_nsbdi (scratch6,
2584 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2585 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2586 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2587 emit_insn (gen_divsi_inv20 (scratch2,
2588 norm32, scratch4, dividend,
2589 scratch6, scratch3, i43,
2590 /* scratch0 may be shared with i2p27. */
2591 scratch0, scratch1, scratch5,
2592 label, label, i2p27));
2594 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2595 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2599 (define_insn "divsi_inv20"
2600 [(set (match_operand:DI 0 "register_operand" "=&r")
2601 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2602 (match_operand:SI 2 "register_operand" "r")
2603 (match_operand:SI 3 "register_operand" "r")
2604 (match_operand:DI 4 "register_operand" "r")
2605 (match_operand:DI 5 "register_operand" "r")
2606 (match_operand:DI 6 "register_operand" "r")
2607 (match_operand:DI 12 "register_operand" "r")
2608 (match_operand 10 "target_operand" "b")
2609 (match_operand 11 "immediate_operand" "i")]
2611 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2612 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2613 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2615 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2618 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2619 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2620 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2621 %10 label (tr), %11 label (imm)
2623 muls.l inv1, norm32, scratch0 // s2.60
2624 muls.l inv1, dividend, result // s32.30
2625 xor i2p27, result_sign, round_scratch
2626 bge/u dividend_nsb, i43, tr.. (label)
2627 shari scratch0, 16, scratch0 // s-16.44
2628 muls.l sratch0_si, inv1, scratch0 // s-16.74
2629 sub result, round_scratch, result
2630 shari dividend, 14, scratch1 // s19.-14
2631 shari scratch0, 30, scratch0 // s-16.44
2632 muls.l scratch0, scratch1, round_scratch // s15.30
2634 sub result, round_scratch, result */
2636 int likely = TARGET_DIVIDE_INV20L;
2638 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2639 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2640 output_asm_insn (likely
2641 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2642 : \"bge/u\t%4, %6, %10\", operands);
2643 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2644 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2645 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2647 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2648 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2651 (define_insn_and_split "divsi_inv_fp"
2652 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2653 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2654 (match_operand:SI 2 "register_operand" "rf")))
2655 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2656 (clobber (match_operand:SI 4 "register_operand" "=r"))
2657 (clobber (match_operand:SI 5 "register_operand" "=r"))
2658 (clobber (match_operand:DF 6 "register_operand" "=r"))
2659 (clobber (match_operand:DF 7 "register_operand" "=r"))
2660 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2661 "TARGET_SHMEDIA_FPU"
2663 "&& (high_life_started || reload_completed)"
2664 [(set (match_dup 0) (match_dup 3))]
2666 [(set_attr "highpart" "must_split")])
2668 ;; If a matching group of divide-by-inverse instructions is in the same
2669 ;; basic block after gcse & loop optimizations, we want to transform them
2670 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2671 (define_insn_and_split "*divsi_inv_fp_combine"
2672 [(set (match_operand:SI 0 "register_operand" "=f")
2673 (div:SI (match_operand:SI 1 "register_operand" "f")
2674 (match_operand:SI 2 "register_operand" "f")))
2675 (use (unspec:SI [(match_dup 1)
2676 (match_operand:SI 3 "" "")
2677 (unspec:SI [(match_operand:SI 4 "" "")
2679 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2680 (match_operand:DI 6 "" "")
2682 (const_int 0)] UNSPEC_DIV_INV_M3))
2683 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2684 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2685 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2686 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2687 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2688 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2691 [(set (match_dup 9) (float:DF (match_dup 1)))
2692 (set (match_dup 10) (float:DF (match_dup 2)))
2693 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2695 (fix:SI (match_dup 11)))
2696 (set (match_dup 0) (match_dup 8))]
2699 if (! fp_arith_reg_operand (operands[1], SImode))
2701 emit_move_insn (operands[7], operands[1]);
2702 operands[1] = operands[7];
2704 if (! fp_arith_reg_operand (operands[2], SImode))
2706 emit_move_insn (operands[8], operands[2]);
2707 operands[2] = operands[8];
2710 [(set_attr "highpart" "must_split")])
2712 ;; -------------------------------------------------------------------------
2713 ;; Multiplication instructions
2714 ;; -------------------------------------------------------------------------
2716 (define_insn "umulhisi3_i"
2717 [(set (reg:SI MACL_REG)
2718 (mult:SI (zero_extend:SI
2719 (match_operand:HI 0 "arith_reg_operand" "r"))
2721 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2724 [(set_attr "type" "smpy")])
2726 (define_insn "mulhisi3_i"
2727 [(set (reg:SI MACL_REG)
2728 (mult:SI (sign_extend:SI
2729 (match_operand:HI 0 "arith_reg_operand" "r"))
2731 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2734 [(set_attr "type" "smpy")])
2736 (define_expand "mulhisi3"
2737 [(set (reg:SI MACL_REG)
2738 (mult:SI (sign_extend:SI
2739 (match_operand:HI 1 "arith_reg_operand" ""))
2741 (match_operand:HI 2 "arith_reg_operand" ""))))
2742 (set (match_operand:SI 0 "arith_reg_operand" "")
2749 macl = gen_rtx_REG (SImode, MACL_REG);
2751 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2752 insn = get_insns ();
2754 /* expand_binop can't find a suitable code in umul_widen_optab to
2755 make a REG_EQUAL note from, so make one here.
2756 See also smulsi3_highpart.
2757 ??? Alternatively, we could put this at the calling site of expand_binop,
2758 i.e. expand_expr. */
2759 /* Use emit_libcall_block for loop invariant code motion and to make
2760 a REG_EQUAL note. */
2761 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2766 (define_expand "umulhisi3"
2767 [(set (reg:SI MACL_REG)
2768 (mult:SI (zero_extend:SI
2769 (match_operand:HI 1 "arith_reg_operand" ""))
2771 (match_operand:HI 2 "arith_reg_operand" ""))))
2772 (set (match_operand:SI 0 "arith_reg_operand" "")
2779 macl = gen_rtx_REG (SImode, MACL_REG);
2781 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2782 insn = get_insns ();
2784 /* expand_binop can't find a suitable code in umul_widen_optab to
2785 make a REG_EQUAL note from, so make one here.
2786 See also smulsi3_highpart.
2787 ??? Alternatively, we could put this at the calling site of expand_binop,
2788 i.e. expand_expr. */
2789 /* Use emit_libcall_block for loop invariant code motion and to make
2790 a REG_EQUAL note. */
2791 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2796 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2797 ;; a call to a routine which clobbers known registers.
2800 [(set (match_operand:SI 1 "register_operand" "=z")
2801 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2802 (clobber (reg:SI MACL_REG))
2803 (clobber (reg:SI T_REG))
2804 (clobber (reg:SI PR_REG))
2805 (clobber (reg:SI R3_REG))
2806 (clobber (reg:SI R2_REG))
2807 (clobber (reg:SI R1_REG))
2808 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2811 [(set_attr "type" "sfunc")
2812 (set_attr "needs_delay_slot" "yes")])
2814 (define_expand "mulsi3_call"
2815 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2816 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2817 (parallel[(set (match_operand:SI 0 "register_operand" "")
2818 (mult:SI (reg:SI R4_REG)
2820 (clobber (reg:SI MACL_REG))
2821 (clobber (reg:SI T_REG))
2822 (clobber (reg:SI PR_REG))
2823 (clobber (reg:SI R3_REG))
2824 (clobber (reg:SI R2_REG))
2825 (clobber (reg:SI R1_REG))
2826 (use (match_operand:SI 3 "register_operand" ""))])]
2830 (define_insn "mul_r"
2831 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2832 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2833 (match_operand:SI 2 "arith_reg_operand" "z")))]
2836 [(set_attr "type" "dmpy")])
2838 (define_insn "mul_l"
2839 [(set (reg:SI MACL_REG)
2840 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2841 (match_operand:SI 1 "arith_reg_operand" "r")))]
2844 [(set_attr "type" "dmpy")])
2846 (define_expand "mulsi3"
2847 [(set (reg:SI MACL_REG)
2848 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2849 (match_operand:SI 2 "arith_reg_operand" "")))
2850 (set (match_operand:SI 0 "arith_reg_operand" "")
2857 /* The address must be set outside the libcall,
2858 since it goes into a pseudo. */
2859 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2860 rtx addr = force_reg (SImode, sym);
2861 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2867 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2869 emit_insn (gen_mul_l (operands[1], operands[2]));
2870 /* consec_sets_giv can only recognize the first insn that sets a
2871 giv as the giv insn. So we must tag this also with a REG_EQUAL
2873 emit_insn (gen_movsi_i ((operands[0]), macl));
2878 (define_insn "mulsidi3_i"
2879 [(set (reg:SI MACH_REG)
2883 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2884 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2886 (set (reg:SI MACL_REG)
2887 (mult:SI (match_dup 0)
2891 [(set_attr "type" "dmpy")])
2893 (define_expand "mulsidi3"
2894 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2895 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2896 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2897 "TARGET_SH2 || TARGET_SHMEDIA"
2902 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2908 (define_insn "mulsidi3_media"
2909 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2910 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2911 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2914 [(set_attr "type" "dmpy_media")
2915 (set_attr "highpart" "ignore")])
2917 (define_insn "mulsidi3_compact"
2918 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2920 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2921 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2922 (clobber (reg:SI MACH_REG))
2923 (clobber (reg:SI MACL_REG))]
2928 [(set (match_operand:DI 0 "arith_reg_dest" "")
2930 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2931 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2932 (clobber (reg:SI MACH_REG))
2933 (clobber (reg:SI MACL_REG))]
2938 rtx low_dst = gen_lowpart (SImode, operands[0]);
2939 rtx high_dst = gen_highpart (SImode, operands[0]);
2941 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2943 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2944 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2945 /* We need something to tag the possible REG_EQUAL notes on to. */
2946 emit_move_insn (operands[0], operands[0]);
2950 (define_insn "umulsidi3_i"
2951 [(set (reg:SI MACH_REG)
2955 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2956 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2958 (set (reg:SI MACL_REG)
2959 (mult:SI (match_dup 0)
2963 [(set_attr "type" "dmpy")])
2965 (define_expand "umulsidi3"
2966 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2967 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2968 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2969 "TARGET_SH2 || TARGET_SHMEDIA"
2974 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2980 (define_insn "umulsidi3_media"
2981 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2982 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2983 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2986 [(set_attr "type" "dmpy_media")
2987 (set_attr "highpart" "ignore")])
2989 (define_insn "umulsidi3_compact"
2990 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2992 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2993 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2994 (clobber (reg:SI MACH_REG))
2995 (clobber (reg:SI MACL_REG))]
3000 [(set (match_operand:DI 0 "arith_reg_dest" "")
3001 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3002 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3003 (clobber (reg:SI MACH_REG))
3004 (clobber (reg:SI MACL_REG))]
3009 rtx low_dst = gen_lowpart (SImode, operands[0]);
3010 rtx high_dst = gen_highpart (SImode, operands[0]);
3012 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3014 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3015 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3016 /* We need something to tag the possible REG_EQUAL notes on to. */
3017 emit_move_insn (operands[0], operands[0]);
3021 (define_insn "smulsi3_highpart_i"
3022 [(set (reg:SI MACH_REG)
3026 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3027 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3029 (clobber (reg:SI MACL_REG))]
3032 [(set_attr "type" "dmpy")])
3034 (define_expand "smulsi3_highpart"
3036 [(set (reg:SI MACH_REG)
3040 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3041 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3043 (clobber (reg:SI MACL_REG))])
3044 (set (match_operand:SI 0 "arith_reg_operand" "")
3051 mach = gen_rtx_REG (SImode, MACH_REG);
3053 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3054 insn = get_insns ();
3056 /* expand_binop can't find a suitable code in mul_highpart_optab to
3057 make a REG_EQUAL note from, so make one here.
3058 See also {,u}mulhisi.
3059 ??? Alternatively, we could put this at the calling site of expand_binop,
3060 i.e. expand_mult_highpart. */
3061 /* Use emit_libcall_block for loop invariant code motion and to make
3062 a REG_EQUAL note. */
3063 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3068 (define_insn "umulsi3_highpart_i"
3069 [(set (reg:SI MACH_REG)
3073 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3074 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3076 (clobber (reg:SI MACL_REG))]
3079 [(set_attr "type" "dmpy")])
3081 (define_expand "umulsi3_highpart"
3083 [(set (reg:SI MACH_REG)
3087 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3088 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3090 (clobber (reg:SI MACL_REG))])
3091 (set (match_operand:SI 0 "arith_reg_operand" "")
3098 mach = gen_rtx_REG (SImode, MACH_REG);
3100 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3101 insn = get_insns ();
3103 /* Use emit_libcall_block for loop invariant code motion and to make
3104 a REG_EQUAL note. */
3105 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3110 (define_insn_and_split "muldi3"
3111 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3112 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3113 (match_operand:DI 2 "arith_reg_operand" "r")))
3114 (clobber (match_scratch:DI 3 "=&r"))
3115 (clobber (match_scratch:DI 4 "=r"))]
3122 rtx op3_v2si, op2_v2si;
3124 op3_v2si = operands[3];
3125 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3127 op3_v2si = XEXP (op3_v2si, 0);
3128 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3130 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3131 op2_v2si = operands[2];
3132 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3134 op2_v2si = XEXP (op2_v2si, 0);
3135 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3137 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3138 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3139 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3140 emit_insn (gen_umulsidi3_media (operands[4],
3141 sh_gen_truncate (SImode, operands[1], 0),
3142 sh_gen_truncate (SImode, operands[2], 0)));
3143 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3144 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3145 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3146 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3151 ;; -------------------------------------------------------------------------
3152 ;; Logical operations
3153 ;; -------------------------------------------------------------------------
3155 (define_insn "*andsi3_compact"
3156 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3157 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3158 (match_operand:SI 2 "logical_operand" "r,K08")))]
3161 [(set_attr "type" "arith")])
3163 (define_insn "*andsi3_media"
3164 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3165 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3166 (match_operand:SI 2 "logical_operand" "r,I10")))]
3171 [(set_attr "type" "arith_media")])
3173 (define_insn "*andsi3_bclr"
3174 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3175 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3176 (match_operand:SI 2 "const_int_operand" "Psz")))]
3177 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3179 [(set_attr "type" "arith")])
3181 ;; If the constant is 255, then emit an extu.b instruction instead of an
3182 ;; and, since that will give better code.
3184 (define_expand "andsi3"
3185 [(set (match_operand:SI 0 "arith_reg_operand" "")
3186 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3187 (match_operand:SI 2 "logical_operand" "")))]
3192 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3194 emit_insn (gen_zero_extendqisi2 (operands[0],
3195 gen_lowpart (QImode, operands[1])));
3200 (define_insn_and_split "anddi3"
3201 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3202 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3203 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3210 && ! logical_operand (operands[2], DImode)"
3214 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3215 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3217 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3220 [(set_attr "type" "arith_media")])
3222 (define_insn "andcsi3"
3223 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3224 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3225 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3228 [(set_attr "type" "arith_media")])
3230 (define_insn "andcdi3"
3231 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3232 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3233 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3236 [(set_attr "type" "arith_media")])
3238 (define_expand "iorsi3"
3239 [(set (match_operand:SI 0 "arith_reg_operand" "")
3240 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3241 (match_operand:SI 2 "logical_operand" "")))]
3245 (define_insn "*iorsi3_compact"
3246 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3247 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3248 (match_operand:SI 2 "logical_operand" "r,K08")))]
3250 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3252 [(set_attr "type" "arith")])
3254 (define_insn "*iorsi3_media"
3255 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3256 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3257 (match_operand:SI 2 "logical_operand" "r,I10")))]
3262 [(set_attr "type" "arith_media")])
3264 (define_insn "*iorsi3_bset"
3265 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3266 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3267 (match_operand:SI 2 "const_int_operand" "Pso")))]
3268 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3270 [(set_attr "type" "arith")])
3272 (define_insn "iordi3"
3273 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3274 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3275 (match_operand:DI 2 "logical_operand" "r,I10")))]
3280 [(set_attr "type" "arith_media")])
3282 (define_insn_and_split "*logical_sidi3"
3283 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3284 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3285 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3286 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3289 "&& reload_completed"
3290 [(set (match_dup 0) (match_dup 3))]
3294 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3295 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3296 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3299 (define_insn_and_split "*logical_sidisi3"
3300 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3301 (truncate:SI (sign_extend:DI
3302 (match_operator:SI 3 "logical_operator"
3303 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3304 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3308 [(set (match_dup 0) (match_dup 3))])
3310 (define_insn_and_split "*logical_sidi3_2"
3311 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3312 (sign_extend:DI (truncate:SI (sign_extend:DI
3313 (match_operator:SI 3 "logical_operator"
3314 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3315 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3319 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3321 (define_expand "xorsi3"
3322 [(set (match_operand:SI 0 "arith_reg_operand" "")
3323 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3324 (match_operand:SI 2 "xor_operand" "")))]
3328 (define_insn "*xorsi3_compact"
3329 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3330 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3331 (match_operand:SI 2 "logical_operand" "K08,r")))]
3334 [(set_attr "type" "arith")])
3336 (define_insn "*xorsi3_media"
3337 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3338 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3339 (match_operand:SI 2 "xor_operand" "r,I06")))]
3344 [(set_attr "type" "arith_media")])
3346 ;; Store the complements of the T bit in a register.
3347 (define_insn "xorsi3_movrt"
3348 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3349 (xor:SI (reg:SI T_REG)
3353 [(set_attr "type" "arith")])
3355 (define_insn "xordi3"
3356 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3357 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3358 (match_operand:DI 2 "xor_operand" "r,I06")))]
3363 [(set_attr "type" "arith_media")])
3365 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3366 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3368 [(set (match_operand:DI 0 "arith_reg_dest" "")
3369 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3370 [(match_operand 1 "any_register_operand" "")
3371 (match_operand 2 "any_register_operand" "")])))]
3373 [(set (match_dup 5) (match_dup 4))
3374 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3377 enum machine_mode inmode = GET_MODE (operands[1]);
3380 if (GET_CODE (operands[0]) == SUBREG)
3382 offset = SUBREG_BYTE (operands[0]);
3383 operands[0] = SUBREG_REG (operands[0]);
3385 gcc_assert (GET_CODE (operands[0]) == REG);
3386 if (! TARGET_LITTLE_ENDIAN)
3387 offset += 8 - GET_MODE_SIZE (inmode);
3388 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3391 ;; -------------------------------------------------------------------------
3392 ;; Shifts and rotates
3393 ;; -------------------------------------------------------------------------
3395 (define_expand "rotldi3"
3396 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3397 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3398 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3400 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3402 (define_insn "rotldi3_mextr"
3403 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3404 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3405 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3409 static char templ[16];
3411 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3412 8 - (int) (INTVAL (operands[2]) >> 3));
3415 [(set_attr "type" "arith_media")])
3417 (define_expand "rotrdi3"
3418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3419 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")