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