1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences. Especially the sequences for arithmetic right shifts.
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
32 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
33 ;; way to generate them.
35 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
36 ;; for a str* inline function.
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42 ;; Special constraints for SH machine description:
49 ;; Special formats used for outputting SH instructions:
51 ;; %. -- print a .s if insn needs delay slot
52 ;; %@ -- print rte/rts if is/isn't an interrupt function
53 ;; %# -- output a nop if there is nothing to put in the delay slot
54 ;; %O -- print a constant without the #
55 ;; %R -- print the lsw reg of a double
56 ;; %S -- print the msw reg of a double
57 ;; %T -- print next word of a double REG or MEM
59 ;; Special predicates:
61 ;; arith_operand -- operand is valid source for arithmetic op
62 ;; arith_reg_operand -- operand is valid register for arithmetic op
63 ;; general_movdst_operand -- operand is valid move destination
64 ;; general_movsrc_operand -- operand is valid move source
65 ;; logical_operand -- operand is valid source for logical op
67 ;; -------------------------------------------------------------------------
69 ;; -------------------------------------------------------------------------
117 ;; These are used with unspec.
118 (UNSPEC_COMPACT_ARGS 0)
131 (UNSPEC_INIT_TRAMP 13)
144 (UNSPEC_DIV_INV_M0 30)
145 (UNSPEC_DIV_INV_M1 31)
146 (UNSPEC_DIV_INV_M2 32)
147 (UNSPEC_DIV_INV_M3 33)
148 (UNSPEC_DIV_INV20 34)
149 (UNSPEC_DIV_INV_TABLE 37)
156 ;; These are used with unspec_volatile.
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
164 (UNSPECV_EH_RETURN 12)
167 ;; -------------------------------------------------------------------------
169 ;; -------------------------------------------------------------------------
174 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175 (const (symbol_ref "sh_cpu_attr")))
177 (define_attr "endian" "big,little"
178 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179 (const_string "little") (const_string "big"))))
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184 (const_string "yes") (const_string "no"))))
186 (define_attr "fmovd" "yes,no"
187 (const (if_then_else (symbol_ref "TARGET_FMOVD")
188 (const_string "yes") (const_string "no"))))
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
192 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194 (const_string "sh1"))))
196 ;; cbranch conditional branch instructions
197 ;; jump unconditional jumps
198 ;; arith ordinary arithmetic
199 ;; arith3 a compound insn that behaves similarly to a sequence of
200 ;; three insns of type arith
201 ;; arith3b like above, but might end with a redirected branch
203 ;; load_si Likewise, SImode variant for general register.
204 ;; fload Likewise, but load to fp register.
206 ;; fstore floating point register to memory
207 ;; move general purpose register to register
208 ;; movi8 8-bit immediate to general purpose register
209 ;; mt_group other sh4 mt instructions
210 ;; fmove register to register, floating point
211 ;; smpy word precision integer multiply
212 ;; dmpy longword or doublelongword precision integer multiply
214 ;; pload load of pr reg, which can't be put into delay slot of rts
215 ;; prset copy register to pr reg, ditto
216 ;; pstore store of pr reg, which can't be put into delay slot of jsr
217 ;; prget copy pr to register, ditto
218 ;; pcload pc relative load of constant value
219 ;; pcfload Likewise, but load to fp register.
220 ;; pcload_si Likewise, SImode variant for general register.
221 ;; rte return from exception
222 ;; sfunc special function call with known used registers
223 ;; call function call
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv floating point divide (or square root)
227 ;; gp_fpul move from general purpose register to fpul
228 ;; fpul_gp move from fpul to general purpose register
229 ;; mac_gp move from mac[lh] to general purpose register
230 ;; gp_mac move from general purpose register to mac[lh]
231 ;; mac_mem move from mac[lh] to memory
232 ;; mem_mac move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s fix_truncsfsi2_i4
235 ;; dfdiv double precision floating point divide (or square root)
236 ;; cwb ic_invalidate_line_i
237 ;; movua SH4a unaligned load
238 ;; fsrra square root reciprocal approximate
239 ;; fsca sine and cosine approximate
240 ;; tls_load load TLS related address
241 ;; arith_media SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media SHmedia compare instructions
244 ;; dfdiv_media SHmedia double precision divide and square root
245 ;; dfmul_media SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media SHmedia longword multiply
249 ;; fcmp_media SHmedia floating point compare instructions
250 ;; fdiv_media SHmedia single precision divide and square root
251 ;; fload_media SHmedia floating point register load instructions
252 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media SHmedia unconditional branch instructions
259 ;; load_media SHmedia general register load instructions
260 ;; pt_media SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media SHmedia ptabs instruction
262 ;; store_media SHmedia general register store instructions
263 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media SHmedia mac-style fixed point operations
265 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil no-op move, will be deleted.
271 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
272 (const_string "other"))
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
277 ;; mt_group SH4 "mt" group instructions.
279 ;; ex_group SH4 "ex" group instructions.
281 ;; ls_group SH4 "ls" group instructions.
284 (define_attr "insn_class"
285 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289 (eq_attr "type" "cbranch,jump") (const_string "br_group")
290 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291 (const_string "fe_group")
292 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
293 (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long. Something in the
312 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
317 ;; The maximum range used for SImode constant pool entries is 1018. A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table. That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
335 (define_attr "short_cbranch_p" "no,yes"
336 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
338 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
340 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
342 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
344 ] (const_string "no")))
346 (define_attr "med_branch_p" "no,yes"
347 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
350 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
355 ] (const_string "no")))
357 (define_attr "med_cbranch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
361 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
366 ] (const_string "no")))
368 (define_attr "braf_branch_p" "no,yes"
369 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
371 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
374 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
379 ] (const_string "no")))
381 (define_attr "braf_cbranch_p" "no,yes"
382 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
387 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
392 ] (const_string "no")))
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
401 ; All other instructions are two bytes long by default.
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406 (cond [(eq_attr "type" "cbranch")
407 (cond [(eq_attr "short_cbranch_p" "yes")
409 (eq_attr "med_cbranch_p" "yes")
411 (eq_attr "braf_cbranch_p" "yes")
413 ;; ??? using pc is not computed transitively.
414 (ne (match_dup 0) (match_dup 0))
416 (ne (symbol_ref ("flag_pic")) (const_int 0))
419 (eq_attr "type" "jump")
420 (cond [(eq_attr "med_branch_p" "yes")
422 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
424 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
426 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427 (symbol_ref "code_for_indirect_jump_scratch"))))
428 (cond [(eq_attr "braf_branch_p" "yes")
430 (eq (symbol_ref "flag_pic") (const_int 0))
432 (ne (symbol_ref "TARGET_SH2") (const_int 0))
433 (const_int 10)] (const_int 18))
434 (eq_attr "braf_branch_p" "yes")
436 ;; ??? using pc is not computed transitively.
437 (ne (match_dup 0) (match_dup 0))
439 (ne (symbol_ref ("flag_pic")) (const_int 0))
442 (eq_attr "type" "pt_media")
443 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444 (const_int 20) (const_int 12))
445 (and (eq_attr "type" "jump_media")
446 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
448 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
452 ;; DFA descriptions for the pipelines
455 (include "shmedia.md")
458 (include "predicates.md")
459 (include "constraints.md")
461 ;; Definitions for filling delay slots
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465 (define_attr "banked" "yes,no"
466 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
468 (const_string "yes")]
469 (const_string "no")))
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
476 (const_string "yes")))
478 (define_attr "interrupt_function" "no,yes"
479 (const (symbol_ref "current_function_interrupt")))
481 (define_attr "in_delay_slot" "yes,no"
482 (cond [(eq_attr "type" "cbranch") (const_string "no")
483 (eq_attr "type" "pcload,pcload_si") (const_string "no")
484 (eq_attr "needs_delay_slot" "yes") (const_string "no")
485 (eq_attr "length" "2") (const_string "yes")
486 ] (const_string "no")))
488 (define_attr "cond_delay_slot" "yes,no"
489 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490 ] (const_string "no")))
492 (define_attr "is_sfunc" ""
493 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
495 (define_attr "is_mac_media" ""
496 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
498 (define_attr "branch_zero" "yes,no"
499 (cond [(eq_attr "type" "!cbranch") (const_string "no")
500 (ne (symbol_ref "(next_active_insn (insn)\
501 == (prev_active_insn\
502 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503 && get_attr_length (next_active_insn (insn)) == 2")
505 (const_string "yes")]
506 (const_string "no")))
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512 (const_string "no")))
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519 (const_string "yes")]
520 (const_string "no")))
522 (define_attr "any_int_load" "yes,no"
523 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524 (const_string "yes")]
525 (const_string "no")))
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528 (const_string "user"))
531 (eq_attr "needs_delay_slot" "yes")
532 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
543 (eq_attr "type" "return")
544 [(and (eq_attr "in_delay_slot" "yes")
545 (ior (and (eq_attr "interrupt_function" "no")
546 (eq_attr "type" "!pload,prset"))
547 (and (eq_attr "interrupt_function" "yes")
549 (eq (symbol_ref "TARGET_SH3") (const_int 0))
550 (eq_attr "hit_stack" "no")
551 (eq_attr "banked" "no"))))) (nil) (nil)])
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
557 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558 [(and (eq_attr "in_delay_slot" "yes")
559 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
569 (and (eq_attr "type" "cbranch")
570 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571 ;; SH2e has a hardware bug that pretty much prohibits the use of
572 ;; annuled delay slots.
573 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574 (not (eq_attr "cpu" "sh2e"))) (nil)])
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
582 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583 (match_operand:SI 1 "arith_operand" "K08,r"))
587 [(set_attr "type" "mt_group")])
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
595 (define_insn "cmpeqsi_t"
597 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
604 [(set_attr "type" "mt_group")])
606 (define_insn "cmpgtsi_t"
608 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
614 [(set_attr "type" "mt_group")])
616 (define_insn "cmpgesi_t"
618 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
624 [(set_attr "type" "mt_group")])
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
630 (define_expand "cbranchsi4"
632 (if_then_else (match_operator 0 "comparison_operator"
633 [(match_operand:SI 1 "arith_operand" "")
634 (match_operand:SI 2 "arith_operand" "")])
635 (label_ref (match_operand 3 "" ""))
637 (clobber (reg:SI T_REG))]
639 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
645 (define_insn_and_split "cmpgeusi_t"
647 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
651 "&& operands[0] == CONST0_RTX (SImode)"
655 emit_insn (gen_sett ());
658 [(set_attr "type" "mt_group")])
660 (define_insn "cmpgtusi_t"
662 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663 (match_operand:SI 1 "arith_reg_operand" "r")))]
666 [(set_attr "type" "mt_group")])
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
671 (define_expand "cmpsi"
673 (compare (match_operand:SI 0 "cmpsi_operand" "")
674 (match_operand:SI 1 "arith_operand" "")))]
675 "TARGET_SH1 || TARGET_SHMEDIA"
678 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679 && GET_CODE (operands[1]) != CONST_INT)
680 operands[0] = copy_to_mode_reg (SImode, operands[0]);
681 sh_compare_op0 = operands[0];
682 sh_compare_op1 = operands[1];
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
696 (define_expand "cbranchdi4"
698 (if_then_else (match_operator 0 "comparison_operator"
699 [(match_operand:DI 1 "arith_operand" "")
700 (match_operand:DI 2 "arith_operand" "")])
701 (label_ref (match_operand 3 "" ""))
703 (clobber (match_dup 4))
704 (clobber (reg:SI T_REG))]
708 enum rtx_code comparison;
710 if (TARGET_EXPAND_CBRANCHDI4)
712 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
715 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716 if (comparison != GET_CODE (operands[0]))
718 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719 operands[4] = gen_rtx_SCRATCH (SImode);
722 (define_insn_and_split "cbranchdi4_i"
724 (if_then_else (match_operator 0 "comparison_operator"
725 [(match_operand:DI 1 "arith_operand" "r,r")
726 (match_operand:DI 2 "arith_operand" "rN,i")])
727 (label_ref (match_operand 3 "" ""))
729 (clobber (match_scratch:SI 4 "=X,&r"))
730 (clobber (reg:SI T_REG))]
733 "&& reload_completed"
737 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
748 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749 (match_operand:DI 1 "arith_operand" "r"))
752 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
754 [(set_attr "length" "6")
755 (set_attr "type" "arith3b")])
757 (define_insn "cmpeqdi_t"
759 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
763 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
764 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765 [(set_attr "length" "6")
766 (set_attr "type" "arith3b")])
770 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
775 "TARGET_SH1 && reload_completed && optimize"
776 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778 (label_ref (match_dup 6))
780 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
785 = gen_rtx_REG (SImode,
786 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
788 = (operands[1] == const0_rtx
790 : gen_rtx_REG (SImode,
791 true_regnum (operands[1])
792 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793 operands[4] = gen_lowpart (SImode, operands[0]);
794 operands[5] = gen_lowpart (SImode, operands[1]);
795 operands[6] = gen_label_rtx ();
798 (define_insn "cmpgtdi_t"
800 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
804 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806 [(set_attr "length" "8")
807 (set_attr "type" "arith3")])
809 (define_insn "cmpgedi_t"
811 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
815 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
817 [(set_attr "length" "8,2")
818 (set_attr "type" "arith3,mt_group")])
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
824 (define_insn "cmpgeudi_t"
826 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827 (match_operand:DI 1 "arith_reg_operand" "r")))]
829 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830 [(set_attr "length" "8")
831 (set_attr "type" "arith3")])
833 (define_insn "cmpgtudi_t"
835 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836 (match_operand:DI 1 "arith_reg_operand" "r")))]
838 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839 [(set_attr "length" "8")
840 (set_attr "type" "arith3")])
842 (define_insn "cmpeqsi_media"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845 (match_operand:SI 2 "cmp_operand" "Nr")))]
848 [(set_attr "type" "cmp_media")])
850 (define_insn "cmpeqdi_media"
851 [(set (match_operand:SI 0 "register_operand" "=r")
852 (eq:SI (match_operand:DI 1 "register_operand" "%r")
853 (match_operand:DI 2 "cmp_operand" "Nr")))]
856 [(set_attr "type" "cmp_media")])
858 (define_insn "cmpgtsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861 (match_operand:SI 2 "cmp_operand" "rN")))]
864 [(set_attr "type" "cmp_media")])
866 (define_insn "cmpgtdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
872 [(set_attr "type" "cmp_media")])
874 (define_insn "cmpgtusi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
879 "cmpgtu %N1, %N2, %0"
880 [(set_attr "type" "cmp_media")])
882 (define_insn "cmpgtudi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
887 "cmpgtu %N1, %N2, %0"
888 [(set_attr "type" "cmp_media")])
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
896 [(set_attr "type" "cmp_media")])
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
901 (define_expand "cmpdi"
903 (compare (match_operand:DI 0 "arith_operand" "")
904 (match_operand:DI 1 "arith_operand" "")))]
905 "TARGET_SH2 || TARGET_SHMEDIA"
908 sh_compare_op0 = operands[0];
909 sh_compare_op1 = operands[1];
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
919 (define_insn "movdicc_false"
920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
923 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924 (match_operand:DI 3 "arith_reg_operand" "0")))]
927 [(set_attr "type" "arith_media")])
929 (define_insn "movdicc_true"
930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
933 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934 (match_operand:DI 3 "arith_reg_operand" "0")))]
937 [(set_attr "type" "arith_media")])
940 [(set (match_operand:DI 0 "arith_reg_dest" "")
941 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942 [(match_operand:DI 1 "arith_reg_operand" "")
944 (match_operand:DI 2 "arith_reg_dest" "")
946 (set (match_dup 2) (match_dup 0))]
947 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
949 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953 VOIDmode, operands[1], CONST0_RTX (DImode));
957 [(set (match_operand:DI 0 "general_movdst_operand" "")
958 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959 (set (match_operand:DI 2 "arith_reg_dest" "")
960 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961 [(match_operand:DI 3 "arith_reg_operand" "")
965 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
967 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970 (define_expand "movdicc"
971 [(set (match_operand:DI 0 "register_operand" "")
972 (if_then_else:DI (match_operand 1 "comparison_operator" "")
973 (match_operand:DI 2 "register_operand" "")
974 (match_operand:DI 3 "register_operand" "")))]
978 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979 && GET_MODE (sh_compare_op0) == DImode
980 && sh_compare_op1 == const0_rtx)
981 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982 sh_compare_op0, sh_compare_op1);
987 if (!can_create_pseudo_p ())
990 tmp = gen_reg_rtx (DImode);
992 switch (GET_CODE (operands[1]))
995 emit_insn (gen_seq (tmp));
996 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1000 emit_insn (gen_seq (tmp));
1001 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1005 emit_insn (gen_sgt (tmp));
1006 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1010 emit_insn (gen_slt (tmp));
1011 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1015 emit_insn (gen_slt (tmp));
1016 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1020 emit_insn (gen_sgt (tmp));
1021 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1025 emit_insn (gen_sgtu (tmp));
1026 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1030 emit_insn (gen_sltu (tmp));
1031 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1035 emit_insn (gen_sltu (tmp));
1036 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1040 emit_insn (gen_sgtu (tmp));
1041 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1045 emit_insn (gen_sunordered (tmp));
1046 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1050 emit_insn (gen_sunordered (tmp));
1051 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1074 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075 (match_operand:SI 3 "arith_reg_operand" "0")))]
1078 [(set_attr "type" "arith_media")])
1080 (define_insn "movsicc_true"
1081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1084 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085 (match_operand:SI 3 "arith_reg_operand" "0")))]
1088 [(set_attr "type" "arith_media")])
1091 [(set (match_operand:SI 0 "arith_reg_dest" "")
1092 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093 [(match_operand:SI 1 "arith_reg_operand" "")
1095 (match_operand:SI 2 "arith_reg_dest" "")
1097 (set (match_dup 2) (match_dup 0))]
1098 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1100 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1103 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104 VOIDmode, operands[1], CONST0_RTX (SImode));
1108 [(set (match_operand:SI 0 "general_movdst_operand" "")
1109 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110 (set (match_operand:SI 2 "arith_reg_dest" "")
1111 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112 [(match_operand:SI 3 "arith_reg_operand" "")
1116 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1119 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1122 replace_rtx (operands[4], operands[0], operands[1]);
1126 [(set (match_operand 0 "any_register_operand" "")
1127 (match_operand 1 "any_register_operand" ""))
1128 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138 && (REGNO_REG_CLASS (REGNO (operands[0]))
1139 == REGNO_REG_CLASS (REGNO (operands[2])))
1140 && (REGNO_REG_CLASS (REGNO (operands[1]))
1141 == REGNO_REG_CLASS (REGNO (operands[0])))"
1142 [(set (match_dup 0) (match_dup 3))
1143 (set (match_dup 4) (match_dup 5))]
1147 rtx replacements[4];
1149 /* We want to replace occurrences of operands[0] with operands[1] and
1150 operands[2] with operands[0] in operands[4]/operands[5].
1151 Doing just two replace_rtx calls naively would result in the second
1152 replacement undoing all that the first did if operands[1] and operands[2]
1153 are identical, so we must do this simultaneously. */
1154 replacements[0] = operands[0];
1155 replacements[1] = operands[1];
1156 replacements[2] = operands[2];
1157 replacements[3] = operands[0];
1158 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1163 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166 /* The operands array is aliased to recog_data.operand, which gets
1167 clobbered by extract_insn, so finish with it now. */
1168 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171 always uses emit_insn. */
1172 /* Check that we don't violate matching constraints or earlyclobbers. */
1173 extract_insn (emit_insn (set1));
1174 if (! constrain_operands (1))
1176 extract_insn (emit (set2));
1177 if (! constrain_operands (1))
1181 tmp = replacements[0];
1182 replacements[0] = replacements[1];
1183 replacements[1] = tmp;
1184 tmp = replacements[2];
1185 replacements[2] = replacements[3];
1186 replacements[3] = tmp;
1187 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1188 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1189 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1195 ;; The register allocator is rather clumsy in handling multi-way conditional
1196 ;; moves, so allow the combiner to make them, and we split them up after
1198 (define_insn_and_split "*movsicc_umin"
1199 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1200 (umin:SI (if_then_else:SI
1201 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1203 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1204 (match_operand:SI 3 "register_operand" "0"))
1205 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1206 (clobber (match_scratch:SI 5 "=&r"))]
1207 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1209 "TARGET_SHMEDIA && reload_completed"
1213 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1215 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1216 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1221 (define_insn "*movsicc_t_false"
1222 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1223 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1224 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1225 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1226 "TARGET_PRETEND_CMOVE
1227 && (arith_reg_operand (operands[1], SImode)
1228 || (immediate_operand (operands[1], SImode)
1229 && satisfies_constraint_I08 (operands[1])))"
1230 "bt 0f\;mov %1,%0\\n0:"
1231 [(set_attr "type" "mt_group,arith") ;; poor approximation
1232 (set_attr "length" "4")])
1234 (define_insn "*movsicc_t_true"
1235 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1237 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1238 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1239 "TARGET_PRETEND_CMOVE
1240 && (arith_reg_operand (operands[1], SImode)
1241 || (immediate_operand (operands[1], SImode)
1242 && satisfies_constraint_I08 (operands[1])))"
1243 "bf 0f\;mov %1,%0\\n0:"
1244 [(set_attr "type" "mt_group,arith") ;; poor approximation
1245 (set_attr "length" "4")])
1247 (define_expand "movsicc"
1248 [(set (match_operand:SI 0 "arith_reg_dest" "")
1249 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1250 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1251 (match_operand:SI 3 "arith_reg_operand" "")))]
1252 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1255 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1256 && GET_MODE (sh_compare_op0) == SImode
1258 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1259 && sh_compare_op1 == const0_rtx)
1260 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1261 sh_compare_op0, sh_compare_op1);
1262 else if (TARGET_PRETEND_CMOVE)
1264 enum rtx_code code = GET_CODE (operands[1]);
1265 enum rtx_code new_code = code;
1268 if (! currently_expanding_to_rtl)
1272 case LT: case LE: case LEU: case LTU:
1273 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1276 new_code = reverse_condition (code);
1278 case EQ: case GT: case GE: case GEU: case GTU:
1283 tmp = prepare_scc_operands (new_code);
1284 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1291 if (!can_create_pseudo_p ())
1294 tmp = gen_reg_rtx (SImode);
1296 switch (GET_CODE (operands[1]))
1299 emit_insn (gen_seq (tmp));
1300 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1304 emit_insn (gen_seq (tmp));
1305 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1309 emit_insn (gen_sgt (tmp));
1310 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1314 emit_insn (gen_slt (tmp));
1315 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1319 emit_insn (gen_slt (tmp));
1320 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1324 emit_insn (gen_sgt (tmp));
1325 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1329 emit_insn (gen_sgtu (tmp));
1330 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1334 emit_insn (gen_sltu (tmp));
1335 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1339 emit_insn (gen_sltu (tmp));
1340 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1344 emit_insn (gen_sgtu (tmp));
1345 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1349 emit_insn (gen_sunordered (tmp));
1350 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1354 emit_insn (gen_sunordered (tmp));
1355 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1372 (define_expand "movqicc"
1373 [(set (match_operand:QI 0 "register_operand" "")
1374 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375 (match_operand:QI 2 "register_operand" "")
1376 (match_operand:QI 3 "register_operand" "")))]
1380 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1381 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1382 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1383 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1387 ;; -------------------------------------------------------------------------
1388 ;; Addition instructions
1389 ;; -------------------------------------------------------------------------
1391 (define_expand "adddi3"
1392 [(set (match_operand:DI 0 "arith_reg_operand" "")
1393 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1394 (match_operand:DI 2 "arith_operand" "")))]
1400 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1402 operands[2] = force_reg (DImode, operands[2]);
1403 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1408 (define_insn "*adddi3_media"
1409 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1410 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1411 (match_operand:DI 2 "arith_operand" "r,I10")))]
1416 [(set_attr "type" "arith_media")])
1418 (define_insn "*adddisi3_media"
1419 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1420 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421 (match_operand:DI 2 "arith_operand" "r,I10")))]
1426 [(set_attr "type" "arith_media")
1427 (set_attr "highpart" "ignore")])
1429 (define_insn "adddi3z_media"
1430 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1432 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1433 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1435 "addz.l %1, %N2, %0"
1436 [(set_attr "type" "arith_media")
1437 (set_attr "highpart" "ignore")])
1439 (define_insn "adddi3_compact"
1440 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1441 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1442 (match_operand:DI 2 "arith_reg_operand" "r")))
1443 (clobber (reg:SI T_REG))]
1446 [(set_attr "length" "6")])
1449 [(set (match_operand:DI 0 "arith_reg_dest" "")
1450 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1451 (match_operand:DI 2 "arith_reg_operand" "")))
1452 (clobber (reg:SI T_REG))]
1453 "TARGET_SH1 && reload_completed"
1457 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1458 high0 = gen_rtx_REG (SImode,
1459 true_regnum (operands[0])
1460 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461 high2 = gen_rtx_REG (SImode,
1462 true_regnum (operands[2])
1463 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464 emit_insn (gen_clrt ());
1465 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1466 emit_insn (gen_addc1 (high0, high0, high2));
1471 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1472 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1473 (match_operand:SI 2 "arith_reg_operand" "r"))
1476 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1479 [(set_attr "type" "arith")])
1481 (define_insn "addc1"
1482 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1483 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1484 (match_operand:SI 2 "arith_reg_operand" "r"))
1486 (clobber (reg:SI T_REG))]
1489 [(set_attr "type" "arith")])
1491 (define_expand "addsi3"
1492 [(set (match_operand:SI 0 "arith_reg_operand" "")
1493 (plus:SI (match_operand:SI 1 "arith_operand" "")
1494 (match_operand:SI 2 "arith_operand" "")))]
1499 operands[1] = force_reg (SImode, operands[1]);
1502 (define_insn "addsi3_media"
1503 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1504 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1505 (match_operand:SI 2 "arith_operand" "r,I10")))]
1510 [(set_attr "type" "arith_media")
1511 (set_attr "highpart" "ignore")])
1513 (define_insn "addsidi3_media"
1514 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1515 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1517 (match_operand:SI 2 "arith_operand"
1523 [(set_attr "type" "arith_media")
1524 (set_attr "highpart" "ignore")])
1526 (define_insn "*addsi3_compact"
1527 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1528 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1529 (match_operand:SI 2 "arith_operand" "rI08")))]
1532 [(set_attr "type" "arith")])
1534 ;; -------------------------------------------------------------------------
1535 ;; Subtraction instructions
1536 ;; -------------------------------------------------------------------------
1538 (define_expand "subdi3"
1539 [(set (match_operand:DI 0 "arith_reg_operand" "")
1540 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1541 (match_operand:DI 2 "arith_reg_operand" "")))]
1547 operands[1] = force_reg (DImode, operands[1]);
1548 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1553 (define_insn "*subdi3_media"
1554 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1555 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1556 (match_operand:DI 2 "arith_reg_operand" "r")))]
1559 [(set_attr "type" "arith_media")])
1561 (define_insn "subdisi3_media"
1562 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1563 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1564 (match_operand:DI 2 "arith_reg_operand" "r")))]
1567 [(set_attr "type" "arith_media")
1568 (set_attr "highpart" "ignore")])
1570 (define_insn "subdi3_compact"
1571 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1572 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1573 (match_operand:DI 2 "arith_reg_operand" "r")))
1574 (clobber (reg:SI T_REG))]
1577 [(set_attr "length" "6")])
1580 [(set (match_operand:DI 0 "arith_reg_dest" "")
1581 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1582 (match_operand:DI 2 "arith_reg_operand" "")))
1583 (clobber (reg:SI T_REG))]
1584 "TARGET_SH1 && reload_completed"
1588 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1589 high0 = gen_rtx_REG (SImode,
1590 true_regnum (operands[0])
1591 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1592 high2 = gen_rtx_REG (SImode,
1593 true_regnum (operands[2])
1594 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595 emit_insn (gen_clrt ());
1596 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1597 emit_insn (gen_subc1 (high0, high0, high2));
1602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1603 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1604 (match_operand:SI 2 "arith_reg_operand" "r"))
1607 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1612 [(set_attr "type" "arith")])
1614 (define_insn "subc1"
1615 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1616 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1617 (match_operand:SI 2 "arith_reg_operand" "r"))
1619 (clobber (reg:SI T_REG))]
1622 [(set_attr "type" "arith")])
1624 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1625 ;; pattern for this case. This helps multimedia applications that compute
1626 ;; the sum of absolute differences.
1627 (define_insn "mov_neg_si_t"
1628 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1631 [(set_attr "type" "arith")])
1633 (define_insn "*subsi3_internal"
1634 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1635 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1636 (match_operand:SI 2 "arith_reg_operand" "r")))]
1639 [(set_attr "type" "arith")])
1641 (define_insn_and_split "*subsi3_media"
1642 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1643 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1644 (match_operand:SI 2 "extend_reg_operand" "r")))]
1646 && (operands[1] != constm1_rtx
1647 || (GET_CODE (operands[2]) != TRUNCATE
1648 && GET_CODE (operands[2]) != SUBREG))"
1650 "operands[1] == constm1_rtx"
1651 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1653 [(set_attr "type" "arith_media")
1654 (set_attr "highpart" "ignore")])
1657 [(set (match_operand:SI 0 "arith_reg_dest" "")
1658 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1659 "general_extend_operand"
1661 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1662 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1663 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1667 [(set (match_operand:SI 0 "arith_reg_dest" "")
1668 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669 "general_extend_operand"
1671 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1672 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1675 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1676 ;; will sometimes save one instruction. Otherwise we might get
1677 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1680 (define_expand "subsi3"
1681 [(set (match_operand:SI 0 "arith_reg_operand" "")
1682 (minus:SI (match_operand:SI 1 "arith_operand" "")
1683 (match_operand:SI 2 "arith_reg_operand" "")))]
1687 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1689 emit_insn (gen_negsi2 (operands[0], operands[2]));
1690 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1695 if (!can_create_pseudo_p ()
1696 && ! arith_reg_or_0_operand (operands[1], SImode))
1698 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1699 operands[1] = force_reg (SImode, operands[1]);
1703 ;; -------------------------------------------------------------------------
1704 ;; Division instructions
1705 ;; -------------------------------------------------------------------------
1707 ;; We take advantage of the library routines which don't clobber as many
1708 ;; registers as a normal function call would.
1710 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1711 ;; also has an effect on the register that holds the address of the sfunc.
1712 ;; To make this work, we have an extra dummy insn that shows the use
1713 ;; of this register for reorg.
1715 (define_insn "use_sfunc_addr"
1716 [(set (reg:SI PR_REG)
1717 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1718 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1720 [(set_attr "length" "0")])
1722 (define_insn "udivsi3_sh2a"
1723 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1724 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1725 (match_operand:SI 2 "arith_reg_operand" "z")))]
1728 [(set_attr "type" "arith")
1729 (set_attr "in_delay_slot" "no")])
1731 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1732 ;; hard register 0. If we used hard register 0, then the next instruction
1733 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1734 ;; gets allocated to a stack slot that needs its address reloaded, then
1735 ;; there is nothing to prevent reload from using r0 to reload the address.
1736 ;; This reload would clobber the value in r0 we are trying to store.
1737 ;; If we let reload allocate r0, then this problem can never happen.
1739 (define_insn "udivsi3_i1"
1740 [(set (match_operand:SI 0 "register_operand" "=z")
1741 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1742 (clobber (reg:SI T_REG))
1743 (clobber (reg:SI PR_REG))
1744 (clobber (reg:SI R4_REG))
1745 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1746 "TARGET_SH1 && ! TARGET_SH4"
1748 [(set_attr "type" "sfunc")
1749 (set_attr "needs_delay_slot" "yes")])
1751 ; Since shmedia-nofpu code could be linked against shcompact code, and
1752 ; the udivsi3 libcall has the same name, we must consider all registers
1753 ; clobbered that are in the union of the registers clobbered by the
1754 ; shmedia and the shcompact implementation. Note, if the shcompact
1755 ; implementation actually used shcompact code, we'd need to clobber
1756 ; also r23 and fr23.
1757 (define_insn "udivsi3_i1_media"
1758 [(set (match_operand:SI 0 "register_operand" "=z")
1759 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760 (clobber (reg:SI T_MEDIA_REG))
1761 (clobber (reg:SI PR_MEDIA_REG))
1762 (clobber (reg:SI R20_REG))
1763 (clobber (reg:SI R21_REG))
1764 (clobber (reg:SI R22_REG))
1765 (clobber (reg:DI TR0_REG))
1766 (clobber (reg:DI TR1_REG))
1767 (clobber (reg:DI TR2_REG))
1768 (use (match_operand 1 "target_reg_operand" "b"))]
1769 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1771 [(set_attr "type" "sfunc")
1772 (set_attr "needs_delay_slot" "yes")])
1774 (define_expand "udivsi3_i4_media"
1776 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1778 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779 (set (match_dup 5) (float:DF (match_dup 3)))
1780 (set (match_dup 6) (float:DF (match_dup 4)))
1781 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782 (set (match_dup 8) (fix:DI (match_dup 7)))
1783 (set (match_operand:SI 0 "register_operand" "")
1784 (truncate:SI (match_dup 8)))]
1785 "TARGET_SHMEDIA_FPU"
1788 operands[3] = gen_reg_rtx (DImode);
1789 operands[4] = gen_reg_rtx (DImode);
1790 operands[5] = gen_reg_rtx (DFmode);
1791 operands[6] = gen_reg_rtx (DFmode);
1792 operands[7] = gen_reg_rtx (DFmode);
1793 operands[8] = gen_reg_rtx (DImode);
1796 (define_insn "udivsi3_i4"
1797 [(set (match_operand:SI 0 "register_operand" "=y")
1798 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799 (clobber (reg:SI T_REG))
1800 (clobber (reg:SI PR_REG))
1801 (clobber (reg:DF DR0_REG))
1802 (clobber (reg:DF DR2_REG))
1803 (clobber (reg:DF DR4_REG))
1804 (clobber (reg:SI R0_REG))
1805 (clobber (reg:SI R1_REG))
1806 (clobber (reg:SI R4_REG))
1807 (clobber (reg:SI R5_REG))
1808 (use (reg:PSI FPSCR_REG))
1809 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1812 [(set_attr "type" "sfunc")
1813 (set_attr "fp_mode" "double")
1814 (set_attr "needs_delay_slot" "yes")])
1816 (define_insn "udivsi3_i4_single"
1817 [(set (match_operand:SI 0 "register_operand" "=y")
1818 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819 (clobber (reg:SI T_REG))
1820 (clobber (reg:SI PR_REG))
1821 (clobber (reg:DF DR0_REG))
1822 (clobber (reg:DF DR2_REG))
1823 (clobber (reg:DF DR4_REG))
1824 (clobber (reg:SI R0_REG))
1825 (clobber (reg:SI R1_REG))
1826 (clobber (reg:SI R4_REG))
1827 (clobber (reg:SI R5_REG))
1828 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1831 [(set_attr "type" "sfunc")
1832 (set_attr "needs_delay_slot" "yes")])
1834 (define_insn "udivsi3_i4_int"
1835 [(set (match_operand:SI 0 "register_operand" "=z")
1836 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837 (clobber (reg:SI T_REG))
1838 (clobber (reg:SI R1_REG))
1839 (clobber (reg:SI PR_REG))
1840 (clobber (reg:SI MACH_REG))
1841 (clobber (reg:SI MACL_REG))
1842 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1845 [(set_attr "type" "sfunc")
1846 (set_attr "needs_delay_slot" "yes")])
1849 (define_expand "udivsi3"
1850 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853 (parallel [(set (match_operand:SI 0 "register_operand" "")
1854 (udiv:SI (reg:SI R4_REG)
1856 (clobber (reg:SI T_REG))
1857 (clobber (reg:SI PR_REG))
1858 (clobber (reg:SI R4_REG))
1859 (use (match_dup 3))])]
1865 operands[3] = gen_reg_rtx (Pmode);
1866 /* Emit the move of the address to a pseudo outside of the libcall. */
1867 if (TARGET_DIVIDE_CALL_TABLE)
1869 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870 that causes problems when the divide code is supposed to come from a
1871 separate library. Division by zero is undefined, so dividing 1 can be
1872 implemented by comparing with the divisor. */
1873 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1875 emit_insn (gen_cmpsi (operands[1], operands[2]));
1876 emit_insn (gen_sgeu (operands[0]));
1879 else if (operands[2] == const0_rtx)
1881 emit_move_insn (operands[0], operands[2]);
1884 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1887 else if (TARGET_DIVIDE_CALL_FP)
1889 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890 if (TARGET_FPU_SINGLE)
1891 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1893 last = gen_udivsi3_i4 (operands[0], operands[3]);
1895 else if (TARGET_SHMEDIA_FPU)
1897 operands[1] = force_reg (SImode, operands[1]);
1898 operands[2] = force_reg (SImode, operands[2]);
1899 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1902 else if (TARGET_SH2A)
1904 operands[1] = force_reg (SImode, operands[1]);
1905 operands[2] = force_reg (SImode, operands[2]);
1906 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1909 else if (TARGET_SH5)
1911 function_symbol (operands[3],
1912 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1916 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917 else if (TARGET_FPU_ANY)
1918 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1920 last = gen_udivsi3_i1 (operands[0], operands[3]);
1924 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925 last = gen_udivsi3_i1 (operands[0], operands[3]);
1927 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1933 (define_insn "divsi3_sh2a"
1934 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936 (match_operand:SI 2 "arith_reg_operand" "z")))]
1939 [(set_attr "type" "arith")
1940 (set_attr "in_delay_slot" "no")])
1942 (define_insn "divsi3_i1"
1943 [(set (match_operand:SI 0 "register_operand" "=z")
1944 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945 (clobber (reg:SI T_REG))
1946 (clobber (reg:SI PR_REG))
1947 (clobber (reg:SI R1_REG))
1948 (clobber (reg:SI R2_REG))
1949 (clobber (reg:SI R3_REG))
1950 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951 "TARGET_SH1 && ! TARGET_SH4"
1953 [(set_attr "type" "sfunc")
1954 (set_attr "needs_delay_slot" "yes")])
1956 (define_insn "divsi3_i1_media"
1957 [(set (match_operand:SI 0 "register_operand" "=z")
1958 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959 (clobber (reg:SI T_MEDIA_REG))
1960 (clobber (reg:SI PR_MEDIA_REG))
1961 (clobber (reg:SI R1_REG))
1962 (clobber (reg:SI R20_REG))
1963 (clobber (reg:SI R21_REG))
1964 (clobber (reg:SI TR0_REG))
1965 (use (match_operand 1 "target_reg_operand" "b"))]
1966 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1968 [(set_attr "type" "sfunc")])
1970 (define_insn "divsi3_media_2"
1971 [(set (match_operand:SI 0 "register_operand" "=z")
1972 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973 (clobber (reg:SI T_MEDIA_REG))
1974 (clobber (reg:SI PR_MEDIA_REG))
1975 (clobber (reg:SI R1_REG))
1976 (clobber (reg:SI R21_REG))
1977 (clobber (reg:SI TR0_REG))
1978 (use (reg:SI R20_REG))
1979 (use (match_operand 1 "target_reg_operand" "b"))]
1980 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1982 [(set_attr "type" "sfunc")])
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988 [(set (match_operand:SI 0 "register_operand" "=r")
1989 (div:SI (match_operand:SI 1 "register_operand" "r")
1990 (match_operand:SI 2 "register_operand" "r")))
1991 (clobber (reg:SI R4_REG))
1992 (clobber (reg:SI R5_REG))
1993 (clobber (reg:SI T_MEDIA_REG))
1994 (clobber (reg:SI PR_MEDIA_REG))
1995 (clobber (reg:SI R1_REG))
1996 (clobber (reg:SI R21_REG))
1997 (clobber (reg:SI TR0_REG))
1998 (clobber (reg:SI R20_REG))
1999 (use (match_operand:SI 3 "register_operand" "r"))]
2002 "&& (high_life_started || reload_completed)"
2003 [(set (match_dup 0) (match_dup 3))]
2005 [(set_attr "highpart" "must_split")])
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009 [(set (match_operand:SI 0 "register_operand" "=z")
2010 (div:SI (match_operand:SI 1 "register_operand" "r")
2011 (match_operand:SI 2 "register_operand" "r")))
2012 (clobber (reg:SI R4_REG))
2013 (clobber (reg:SI R5_REG))
2014 (clobber (reg:SI T_MEDIA_REG))
2015 (clobber (reg:SI PR_MEDIA_REG))
2016 (clobber (reg:SI R1_REG))
2017 (clobber (reg:SI R21_REG))
2018 (clobber (reg:SI TR0_REG))
2019 (clobber (reg:SI R20_REG))
2020 (use (unspec:SI [(match_dup 1)
2021 (match_operand:SI 3 "" "")
2022 (unspec:SI [(match_operand:SI 4 "" "")
2024 (match_operand:DI 5 "" "")]
2026 (match_operand:DI 6 "" "")
2029 UNSPEC_DIV_INV_M3))]
2032 "&& (high_life_started || reload_completed)"
2036 const char *name = sh_divsi3_libfunc;
2037 enum sh_function_kind kind = SFUNC_GOT;
2040 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042 while (TARGET_DIVIDE_INV_CALL2)
2044 rtx x = operands[3];
2046 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2048 x = XVECEXP (x, 0, 0);
2049 name = \"__sdivsi3_2\";
2050 kind = SFUNC_STATIC;
2051 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2054 sym = function_symbol (NULL, name, kind);
2055 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2058 [(set_attr "highpart" "must_split")])
2060 (define_expand "divsi3_i4_media"
2061 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064 (set (match_operand:SI 0 "register_operand" "=r")
2065 (fix:SI (match_dup 5)))]
2066 "TARGET_SHMEDIA_FPU"
2069 operands[3] = gen_reg_rtx (DFmode);
2070 operands[4] = gen_reg_rtx (DFmode);
2071 operands[5] = gen_reg_rtx (DFmode);
2074 (define_insn "divsi3_i4"
2075 [(set (match_operand:SI 0 "register_operand" "=y")
2076 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077 (clobber (reg:SI PR_REG))
2078 (clobber (reg:DF DR0_REG))
2079 (clobber (reg:DF DR2_REG))
2080 (use (reg:PSI FPSCR_REG))
2081 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2084 [(set_attr "type" "sfunc")
2085 (set_attr "fp_mode" "double")
2086 (set_attr "needs_delay_slot" "yes")])
2088 (define_insn "divsi3_i4_single"
2089 [(set (match_operand:SI 0 "register_operand" "=y")
2090 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091 (clobber (reg:SI PR_REG))
2092 (clobber (reg:DF DR0_REG))
2093 (clobber (reg:DF DR2_REG))
2094 (clobber (reg:SI R2_REG))
2095 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2098 [(set_attr "type" "sfunc")
2099 (set_attr "needs_delay_slot" "yes")])
2101 (define_insn "divsi3_i4_int"
2102 [(set (match_operand:SI 0 "register_operand" "=z")
2103 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104 (clobber (reg:SI T_REG))
2105 (clobber (reg:SI PR_REG))
2106 (clobber (reg:SI R1_REG))
2107 (clobber (reg:SI MACH_REG))
2108 (clobber (reg:SI MACL_REG))
2109 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2112 [(set_attr "type" "sfunc")
2113 (set_attr "needs_delay_slot" "yes")])
2115 (define_expand "divsi3"
2116 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119 (parallel [(set (match_operand:SI 0 "register_operand" "")
2120 (div:SI (reg:SI R4_REG)
2122 (clobber (reg:SI T_REG))
2123 (clobber (reg:SI PR_REG))
2124 (clobber (reg:SI R1_REG))
2125 (clobber (reg:SI R2_REG))
2126 (clobber (reg:SI R3_REG))
2127 (use (match_dup 3))])]
2133 operands[3] = gen_reg_rtx (Pmode);
2134 /* Emit the move of the address to a pseudo outside of the libcall. */
2135 if (TARGET_DIVIDE_CALL_TABLE)
2137 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138 last = gen_divsi3_i4_int (operands[0], operands[3]);
2140 else if (TARGET_DIVIDE_CALL_FP)
2142 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143 if (TARGET_FPU_SINGLE)
2144 last = gen_divsi3_i4_single (operands[0], operands[3]);
2146 last = gen_divsi3_i4 (operands[0], operands[3]);
2148 else if (TARGET_SH2A)
2150 operands[1] = force_reg (SImode, operands[1]);
2151 operands[2] = force_reg (SImode, operands[2]);
2152 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2155 else if (TARGET_DIVIDE_INV)
2157 rtx dividend = operands[1];
2158 rtx divisor = operands[2];
2160 rtx nsb_res = gen_reg_rtx (DImode);
2161 rtx norm64 = gen_reg_rtx (DImode);
2162 rtx tab_ix = gen_reg_rtx (DImode);
2163 rtx norm32 = gen_reg_rtx (SImode);
2164 rtx i92 = force_reg (DImode, GEN_INT (92));
2165 rtx scratch0a = gen_reg_rtx (DImode);
2166 rtx scratch0b = gen_reg_rtx (DImode);
2167 rtx inv0 = gen_reg_rtx (SImode);
2168 rtx scratch1a = gen_reg_rtx (DImode);
2169 rtx scratch1b = gen_reg_rtx (DImode);
2170 rtx shift = gen_reg_rtx (DImode);
2172 rtx inv1 = gen_reg_rtx (SImode);
2173 rtx scratch2a = gen_reg_rtx (DImode);
2174 rtx scratch2b = gen_reg_rtx (SImode);
2175 rtx inv2 = gen_reg_rtx (SImode);
2176 rtx scratch3a = gen_reg_rtx (DImode);
2177 rtx scratch3b = gen_reg_rtx (DImode);
2178 rtx scratch3c = gen_reg_rtx (DImode);
2179 rtx scratch3d = gen_reg_rtx (SImode);
2180 rtx scratch3e = gen_reg_rtx (DImode);
2181 rtx result = gen_reg_rtx (SImode);
2183 if (! arith_reg_or_0_operand (dividend, SImode))
2184 dividend = force_reg (SImode, dividend);
2185 if (! arith_reg_operand (divisor, SImode))
2186 divisor = force_reg (SImode, divisor);
2187 if (flag_pic && Pmode != DImode)
2189 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190 tab_base = gen_datalabel_ref (tab_base);
2191 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2195 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196 tab_base = gen_datalabel_ref (tab_base);
2197 tab_base = force_reg (DImode, tab_base);
2199 if (TARGET_DIVIDE_INV20U)
2200 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2202 i2p27 = GEN_INT (0);
2203 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204 i43 = force_reg (DImode, GEN_INT (43));
2207 emit_insn (gen_nsbdi (nsb_res,
2208 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209 emit_insn (gen_ashldi3_media (norm64,
2210 gen_rtx_SUBREG (DImode, divisor, 0),
2212 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215 inv0, scratch0a, scratch0b,
2216 scratch1a, scratch1b));
2217 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2220 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2222 scratch3a, scratch3b, scratch3c,
2223 scratch2a, scratch2b, scratch3d, scratch3e));
2224 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226 else if (TARGET_DIVIDE_INV_FP)
2227 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230 gen_reg_rtx (DFmode)));
2232 emit_move_insn (operands[0], result);
2235 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2237 operands[1] = force_reg (SImode, operands[1]);
2238 operands[2] = force_reg (SImode, operands[2]);
2239 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2242 else if (TARGET_SH5)
2244 if (TARGET_DIVIDE_CALL2)
2246 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247 tab_base = gen_datalabel_ref (tab_base);
2248 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2250 if (TARGET_FPU_ANY && TARGET_SH1)
2251 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252 else if (TARGET_DIVIDE_CALL2)
2253 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2255 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2258 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259 (operands[0], operands[3]));
2260 else if (TARGET_FPU_ANY)
2261 last = gen_divsi3_i4_single (operands[0], operands[3]);
2263 last = gen_divsi3_i1 (operands[0], operands[3]);
2267 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268 last = gen_divsi3_i1 (operands[0], operands[3]);
2270 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload. See PR27117.
2281 (define_insn "divsi_inv_qitable"
2282 [(set (match_operand:DI 0 "register_operand" "=r")
2283 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284 (match_operand:DI 2 "register_operand" "r")]
2285 UNSPEC_DIV_INV_TABLE)))]
2289 [(set_attr "type" "load_media")
2290 (set_attr "highpart" "user")])
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296 (match_operand:DI 2 "register_operand" "r")]
2297 UNSPEC_DIV_INV_TABLE)))]
2301 [(set_attr "type" "load_media")
2302 (set_attr "highpart" "user")])
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307 [(set (match_operand:SI 0 "register_operand" "=r")
2308 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309 (match_operand:DI 2 "register_operand" "r")
2310 (match_operand:SI 3 "register_operand" "r")]
2312 (clobber (match_operand:DI 4 "register_operand" "=r"))
2313 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2321 ldx.ub r20, r21, r19 // u0.8
2323 muls.l r25, r19, r19 // s2.38
2324 ldx.w r20, r21, r21 // s2.14
2325 shari r19, 24, r19 // truncate to s2.14
2326 sub r21, r19, r19 // some 11 bit inverse in s1.14
2329 rtx inv0 = operands[0];
2330 rtx tab_base = operands[1];
2331 rtx tab_ix = operands[2];
2332 rtx norm32 = operands[3];
2333 rtx scratch0 = operands[4];
2334 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335 rtx scratch1 = operands[5];
2337 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350 (match_operand:DI 2 "register_operand" "r")
2351 (match_operand:SI 3 "register_operand" "r")]
2353 (clobber (match_operand:SI 4 "register_operand" "=r"))
2354 (clobber (match_operand:DI 5 "register_operand" "=r"))
2355 (clobber (match_operand:DI 6 "register_operand" "=r"))
2356 (clobber (match_operand:DI 7 "register_operand" "=r"))
2357 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2360 "&& !can_create_pseudo_p ()"
2365 muls.l r19, r19, r18 // u0.28
2366 muls.l r25, r18, r18 // s2.58
2367 shlli r19, 45, r0 // multiply by two and convert to s2.58
2369 shari r18, 28, r18 // some 18 bit inverse in s1.30
2372 rtx inv1 = operands[0];
2373 rtx tab_base = operands[1];
2374 rtx tab_ix = operands[2];
2375 rtx norm32 = operands[3];
2376 rtx inv0 = operands[4];
2377 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378 rtx scratch0a = operands[5];
2379 rtx scratch0b = operands[6];
2380 rtx scratch0 = operands[7];
2381 rtx scratch1 = operands[8];
2382 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2384 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385 scratch0a, scratch0b));
2386 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398 (match_operand:SI 2 "register_operand" "r")
2399 (match_operand:DI 3 "register_operand" "r")]
2401 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2404 "&& !can_create_pseudo_p ()"
2409 muls.l r18, r25, r0 // s2.60
2410 shari r0, 16, r0 // s-16.44
2412 muls.l r0, r18, r19 // s-16.74
2413 shari r19, 30, r19 // s-16.44
2415 rtx inv2 = operands[0];
2416 rtx norm32 = operands[1];
2417 rtx inv1 = operands[2];
2418 rtx i92 = operands[3];
2419 rtx scratch0 = operands[4];
2420 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2422 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2430 (define_insn_and_split "divsi_inv_m3"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433 (match_operand:SI 2 "register_operand" "r")
2434 (match_operand:SI 3 "register_operand" "r")
2435 (match_operand:DI 4 "register_operand" "r")
2436 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2439 (clobber (match_operand:DI 7 "register_operand" "=r"))
2440 (clobber (match_operand:DI 8 "register_operand" "=r"))
2441 (clobber (match_operand:DI 9 "register_operand" "=r"))
2442 (clobber (match_operand:DI 10 "register_operand" "=r"))
2443 (clobber (match_operand:SI 11 "register_operand" "=r"))
2444 (clobber (match_operand:SI 12 "register_operand" "=r"))
2445 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2448 "&& !can_create_pseudo_p ()"
2453 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2454 r0: scratch0 r19: scratch1 r21: scratch2
2456 muls.l r18, r4, r25 // s32.30
2457 muls.l r19, r4, r19 // s15.30
2459 shari r19, 14, r19 // s18.-14
2465 rtx result = operands[0];
2466 rtx dividend = operands[1];
2467 rtx inv1 = operands[2];
2468 rtx inv2 = operands[3];
2469 rtx shift = operands[4];
2470 rtx scratch0 = operands[7];
2471 rtx scratch1 = operands[8];
2472 rtx scratch2 = operands[9];
2474 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488 [(set (match_operand:SI 0 "register_operand" "=r")
2489 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491 (match_operand:DI 3 "register_operand" "r")
2492 (match_operand:SI 4 "register_operand" "r")]
2494 (unspec:SI [(match_dup 4)
2495 (unspec:SI [(match_dup 2)
2497 (match_dup 4)] UNSPEC_DIV_INV_M1)
2498 (match_operand:SI 5 "" "")]
2500 (match_operand:DI 6 "register_operand" "r")
2501 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2504 (clobber (match_operand:DI 9 "register_operand" "=r"))
2505 (clobber (match_operand:DI 10 "register_operand" "=r"))
2506 (clobber (match_operand:DI 11 "register_operand" "=r"))
2507 (clobber (match_operand:DI 12 "register_operand" "=r"))
2508 (clobber (match_operand:SI 13 "register_operand" "=r"))
2509 (clobber (match_operand:SI 14 "register_operand" "=r"))
2510 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2512 && (TARGET_DIVIDE_INV_MINLAT
2513 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2515 "&& !can_create_pseudo_p ()"
2519 rtx result = operands[0];
2520 rtx dividend = operands[1];
2521 rtx tab_base = operands[2];
2522 rtx tab_ix = operands[3];
2523 rtx norm32 = operands[4];
2524 /* rtx i92 = operands[5]; */
2525 rtx shift = operands[6];
2526 rtx i2p27 = operands[7];
2527 rtx i43 = operands[8];
2528 rtx scratch0 = operands[9];
2529 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530 rtx scratch1 = operands[10];
2531 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532 rtx scratch2 = operands[11];
2533 rtx scratch3 = operands[12];
2534 rtx scratch4 = operands[13];
2535 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536 rtx scratch5 = operands[14];
2537 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538 rtx scratch6 = operands[15];
2540 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541 scratch0, scratch1));
2542 /* inv0 == scratch4 */
2543 if (! TARGET_DIVIDE_INV20U)
2545 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2547 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2551 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2554 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557 /* inv1 == scratch4 */
2559 if (TARGET_DIVIDE_INV_MINLAT)
2561 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2575 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2577 emit_insn (gen_nsbdi (scratch6,
2578 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581 emit_insn (gen_divsi_inv20 (scratch2,
2582 norm32, scratch4, dividend,
2583 scratch6, scratch3, i43,
2584 /* scratch0 may be shared with i2p27. */
2585 scratch0, scratch1, scratch5,
2586 label, label, i2p27));
2588 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2593 (define_insn "divsi_inv20"
2594 [(set (match_operand:DI 0 "register_operand" "=&r")
2595 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596 (match_operand:SI 2 "register_operand" "r")
2597 (match_operand:SI 3 "register_operand" "r")
2598 (match_operand:DI 4 "register_operand" "r")
2599 (match_operand:DI 5 "register_operand" "r")
2600 (match_operand:DI 6 "register_operand" "r")
2601 (match_operand:DI 12 "register_operand" "r")
2602 (match_operand 10 "target_operand" "b")
2603 (match_operand 11 "immediate_operand" "i")]
2605 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2609 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615 %10 label (tr), %11 label (imm)
2617 muls.l inv1, norm32, scratch0 // s2.60
2618 muls.l inv1, dividend, result // s32.30
2619 xor i2p27, result_sign, round_scratch
2620 bge/u dividend_nsb, i43, tr.. (label)
2621 shari scratch0, 16, scratch0 // s-16.44
2622 muls.l sratch0_si, inv1, scratch0 // s-16.74
2623 sub result, round_scratch, result
2624 shari dividend, 14, scratch1 // s19.-14
2625 shari scratch0, 30, scratch0 // s-16.44
2626 muls.l scratch0, scratch1, round_scratch // s15.30
2628 sub result, round_scratch, result */
2630 int likely = TARGET_DIVIDE_INV20L;
2632 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634 output_asm_insn (likely
2635 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636 : \"bge/u\t%4, %6, %10\", operands);
2637 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2641 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2645 (define_insn_and_split "divsi_inv_fp"
2646 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648 (match_operand:SI 2 "register_operand" "rf")))
2649 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650 (clobber (match_operand:SI 4 "register_operand" "=r"))
2651 (clobber (match_operand:SI 5 "register_operand" "=r"))
2652 (clobber (match_operand:DF 6 "register_operand" "=r"))
2653 (clobber (match_operand:DF 7 "register_operand" "=r"))
2654 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655 "TARGET_SHMEDIA_FPU"
2657 "&& (high_life_started || reload_completed)"
2658 [(set (match_dup 0) (match_dup 3))]
2660 [(set_attr "highpart" "must_split")])
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666 [(set (match_operand:SI 0 "register_operand" "=f")
2667 (div:SI (match_operand:SI 1 "register_operand" "f")
2668 (match_operand:SI 2 "register_operand" "f")))
2669 (use (unspec:SI [(match_dup 1)
2670 (match_operand:SI 3 "" "")
2671 (unspec:SI [(match_operand:SI 4 "" "")
2673 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674 (match_operand:DI 6 "" "")
2676 (const_int 0)] UNSPEC_DIV_INV_M3))
2677 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2685 [(set (match_dup 9) (float:DF (match_dup 1)))
2686 (set (match_dup 10) (float:DF (match_dup 2)))
2687 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2689 (fix:SI (match_dup 11)))
2690 (set (match_dup 0) (match_dup 8))]
2693 if (! fp_arith_reg_operand (operands[1], SImode))
2695 emit_move_insn (operands[7], operands[1]);
2696 operands[1] = operands[7];
2698 if (! fp_arith_reg_operand (operands[2], SImode))
2700 emit_move_insn (operands[8], operands[2]);
2701 operands[2] = operands[8];
2704 [(set_attr "highpart" "must_split")])
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2710 (define_insn "umulhisi3_i"
2711 [(set (reg:SI MACL_REG)
2712 (mult:SI (zero_extend:SI
2713 (match_operand:HI 0 "arith_reg_operand" "r"))
2715 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2718 [(set_attr "type" "smpy")])
2720 (define_insn "mulhisi3_i"
2721 [(set (reg:SI MACL_REG)
2722 (mult:SI (sign_extend:SI
2723 (match_operand:HI 0 "arith_reg_operand" "r"))
2725 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2728 [(set_attr "type" "smpy")])
2730 (define_expand "mulhisi3"
2731 [(set (reg:SI MACL_REG)
2732 (mult:SI (sign_extend:SI
2733 (match_operand:HI 1 "arith_reg_operand" ""))
2735 (match_operand:HI 2 "arith_reg_operand" ""))))
2736 (set (match_operand:SI 0 "arith_reg_operand" "")
2743 macl = gen_rtx_REG (SImode, MACL_REG);
2745 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746 insn = get_insns ();
2748 /* expand_binop can't find a suitable code in umul_widen_optab to
2749 make a REG_EQUAL note from, so make one here.
2750 See also smulsi3_highpart.
2751 ??? Alternatively, we could put this at the calling site of expand_binop,
2752 i.e. expand_expr. */
2753 /* Use emit_libcall_block for loop invariant code motion and to make
2754 a REG_EQUAL note. */
2755 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2760 (define_expand "umulhisi3"
2761 [(set (reg:SI MACL_REG)
2762 (mult:SI (zero_extend:SI
2763 (match_operand:HI 1 "arith_reg_operand" ""))
2765 (match_operand:HI 2 "arith_reg_operand" ""))))
2766 (set (match_operand:SI 0 "arith_reg_operand" "")
2773 macl = gen_rtx_REG (SImode, MACL_REG);
2775 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776 insn = get_insns ();
2778 /* expand_binop can't find a suitable code in umul_widen_optab to
2779 make a REG_EQUAL note from, so make one here.
2780 See also smulsi3_highpart.
2781 ??? Alternatively, we could put this at the calling site of expand_binop,
2782 i.e. expand_expr. */
2783 /* Use emit_libcall_block for loop invariant code motion and to make
2784 a REG_EQUAL note. */
2785 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2794 [(set (match_operand:SI 1 "register_operand" "=z")
2795 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796 (clobber (reg:SI MACL_REG))
2797 (clobber (reg:SI T_REG))
2798 (clobber (reg:SI PR_REG))
2799 (clobber (reg:SI R3_REG))
2800 (clobber (reg:SI R2_REG))
2801 (clobber (reg:SI R1_REG))
2802 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2805 [(set_attr "type" "sfunc")
2806 (set_attr "needs_delay_slot" "yes")])
2808 (define_expand "mulsi3_call"
2809 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811 (parallel[(set (match_operand:SI 0 "register_operand" "")
2812 (mult:SI (reg:SI R4_REG)
2814 (clobber (reg:SI MACL_REG))
2815 (clobber (reg:SI T_REG))
2816 (clobber (reg:SI PR_REG))
2817 (clobber (reg:SI R3_REG))
2818 (clobber (reg:SI R2_REG))
2819 (clobber (reg:SI R1_REG))
2820 (use (match_operand:SI 3 "register_operand" ""))])]
2824 (define_insn "mul_r"
2825 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827 (match_operand:SI 2 "arith_reg_operand" "z")))]
2830 [(set_attr "type" "dmpy")])
2832 (define_insn "mul_l"
2833 [(set (reg:SI MACL_REG)
2834 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835 (match_operand:SI 1 "arith_reg_operand" "r")))]
2838 [(set_attr "type" "dmpy")])
2840 (define_expand "mulsi3"
2841 [(set (reg:SI MACL_REG)
2842 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2843 (match_operand:SI 2 "arith_reg_operand" "")))
2844 (set (match_operand:SI 0 "arith_reg_operand" "")
2851 /* The address must be set outside the libcall,
2852 since it goes into a pseudo. */
2853 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854 rtx addr = force_reg (SImode, sym);
2855 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2861 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2863 emit_insn (gen_mul_l (operands[1], operands[2]));
2864 /* consec_sets_giv can only recognize the first insn that sets a
2865 giv as the giv insn. So we must tag this also with a REG_EQUAL
2867 emit_insn (gen_movsi_i ((operands[0]), macl));
2872 (define_insn "mulsidi3_i"
2873 [(set (reg:SI MACH_REG)
2877 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2880 (set (reg:SI MACL_REG)
2881 (mult:SI (match_dup 0)
2885 [(set_attr "type" "dmpy")])
2887 (define_expand "mulsidi3"
2888 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891 "TARGET_SH2 || TARGET_SHMEDIA"
2896 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2902 (define_insn "mulsidi3_media"
2903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2908 [(set_attr "type" "dmpy_media")
2909 (set_attr "highpart" "ignore")])
2911 (define_insn "mulsidi3_compact"
2912 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2914 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916 (clobber (reg:SI MACH_REG))
2917 (clobber (reg:SI MACL_REG))]
2922 [(set (match_operand:DI 0 "arith_reg_dest" "")
2924 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926 (clobber (reg:SI MACH_REG))
2927 (clobber (reg:SI MACL_REG))]
2932 rtx low_dst = gen_lowpart (SImode, operands[0]);
2933 rtx high_dst = gen_highpart (SImode, operands[0]);
2935 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2937 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939 /* We need something to tag the possible REG_EQUAL notes on to. */
2940 emit_move_insn (operands[0], operands[0]);
2944 (define_insn "umulsidi3_i"
2945 [(set (reg:SI MACH_REG)
2949 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2952 (set (reg:SI MACL_REG)
2953 (mult:SI (match_dup 0)
2957 [(set_attr "type" "dmpy")])
2959 (define_expand "umulsidi3"
2960 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963 "TARGET_SH2 || TARGET_SHMEDIA"
2968 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2974 (define_insn "umulsidi3_media"
2975 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2980 [(set_attr "type" "dmpy_media")
2981 (set_attr "highpart" "ignore")])
2983 (define_insn "umulsidi3_compact"
2984 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2986 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988 (clobber (reg:SI MACH_REG))
2989 (clobber (reg:SI MACL_REG))]
2994 [(set (match_operand:DI 0 "arith_reg_dest" "")
2995 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997 (clobber (reg:SI MACH_REG))
2998 (clobber (reg:SI MACL_REG))]
3003 rtx low_dst = gen_lowpart (SImode, operands[0]);
3004 rtx high_dst = gen_highpart (SImode, operands[0]);
3006 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3008 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010 /* We need something to tag the possible REG_EQUAL notes on to. */
3011 emit_move_insn (operands[0], operands[0]);
3015 (define_insn "smulsi3_highpart_i"
3016 [(set (reg:SI MACH_REG)
3020 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3023 (clobber (reg:SI MACL_REG))]
3026 [(set_attr "type" "dmpy")])
3028 (define_expand "smulsi3_highpart"
3030 [(set (reg:SI MACH_REG)
3034 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3037 (clobber (reg:SI MACL_REG))])
3038 (set (match_operand:SI 0 "arith_reg_operand" "")
3045 mach = gen_rtx_REG (SImode, MACH_REG);
3047 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048 insn = get_insns ();
3050 /* expand_binop can't find a suitable code in mul_highpart_optab to
3051 make a REG_EQUAL note from, so make one here.
3052 See also {,u}mulhisi.
3053 ??? Alternatively, we could put this at the calling site of expand_binop,
3054 i.e. expand_mult_highpart. */
3055 /* Use emit_libcall_block for loop invariant code motion and to make
3056 a REG_EQUAL note. */
3057 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3062 (define_insn "umulsi3_highpart_i"
3063 [(set (reg:SI MACH_REG)
3067 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3070 (clobber (reg:SI MACL_REG))]
3073 [(set_attr "type" "dmpy")])
3075 (define_expand "umulsi3_highpart"
3077 [(set (reg:SI MACH_REG)
3081 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3084 (clobber (reg:SI MACL_REG))])
3085 (set (match_operand:SI 0 "arith_reg_operand" "")
3092 mach = gen_rtx_REG (SImode, MACH_REG);
3094 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095 insn = get_insns ();
3097 /* Use emit_libcall_block for loop invariant code motion and to make
3098 a REG_EQUAL note. */
3099 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3104 (define_insn_and_split "muldi3"
3105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107 (match_operand:DI 2 "arith_reg_operand" "r")))
3108 (clobber (match_scratch:DI 3 "=&r"))
3109 (clobber (match_scratch:DI 4 "=r"))]
3116 rtx op3_v2si, op2_v2si;
3118 op3_v2si = operands[3];
3119 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3121 op3_v2si = XEXP (op3_v2si, 0);
3122 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3124 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125 op2_v2si = operands[2];
3126 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3128 op2_v2si = XEXP (op2_v2si, 0);
3129 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3131 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134 emit_insn (gen_umulsidi3_media (operands[4],
3135 sh_gen_truncate (SImode, operands[1], 0),
3136 sh_gen_truncate (SImode, operands[2], 0)));
3137 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3149 (define_insn "*andsi3_compact"
3150 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152 (match_operand:SI 2 "logical_operand" "r,K08")))]
3155 [(set_attr "type" "arith")])
3157 (define_insn "*andsi3_media"
3158 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160 (match_operand:SI 2 "logical_operand" "r,I10")))]
3165 [(set_attr "type" "arith_media")])
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3170 (define_expand "andsi3"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "")
3172 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173 (match_operand:SI 2 "logical_operand" "")))]
3178 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3180 emit_insn (gen_zero_extendqisi2 (operands[0],
3181 gen_lowpart (QImode, operands[1])));
3186 (define_insn_and_split "anddi3"
3187 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3196 && ! logical_operand (operands[2], DImode)"
3200 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3203 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3206 [(set_attr "type" "arith_media")])
3208 (define_insn "andcsi3"
3209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3214 [(set_attr "type" "arith_media")])
3216 (define_insn "andcdi3"
3217 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3222 [(set_attr "type" "arith_media")])
3224 (define_expand "iorsi3"
3225 [(set (match_operand:SI 0 "arith_reg_operand" "")
3226 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227 (match_operand:SI 2 "logical_operand" "")))]
3231 (define_insn "*iorsi3_compact"
3232 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234 (match_operand:SI 2 "logical_operand" "r,K08")))]
3237 [(set_attr "type" "arith")])
3239 (define_insn "*iorsi3_media"
3240 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242 (match_operand:SI 2 "logical_operand" "r,I10")))]
3247 [(set_attr "type" "arith_media")])
3249 (define_insn "iordi3"
3250 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252 (match_operand:DI 2 "logical_operand" "r,I10")))]
3257 [(set_attr "type" "arith_media")])
3259 (define_insn_and_split "*logical_sidi3"
3260 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3266 "&& reload_completed"
3267 [(set (match_dup 0) (match_dup 3))]
3271 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3276 (define_insn_and_split "*logical_sidisi3"
3277 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278 (truncate:SI (sign_extend:DI
3279 (match_operator:SI 3 "logical_operator"
3280 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3285 [(set (match_dup 0) (match_dup 3))])
3287 (define_insn_and_split "*logical_sidi3_2"
3288 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289 (sign_extend:DI (truncate:SI (sign_extend:DI
3290 (match_operator:SI 3 "logical_operator"
3291 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3296 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3298 (define_expand "xorsi3"
3299 [(set (match_operand:SI 0 "arith_reg_operand" "")
3300 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301 (match_operand:SI 2 "xor_operand" "")))]
3305 (define_insn "*xorsi3_compact"
3306 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308 (match_operand:SI 2 "logical_operand" "K08,r")))]
3311 [(set_attr "type" "arith")])
3313 (define_insn "*xorsi3_media"
3314 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316 (match_operand:SI 2 "xor_operand" "r,I06")))]
3321 [(set_attr "type" "arith_media")])
3323 (define_insn "xordi3"
3324 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326 (match_operand:DI 2 "xor_operand" "r,I06")))]
3331 [(set_attr "type" "arith_media")])
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3336 [(set (match_operand:DI 0 "arith_reg_dest" "")
3337 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338 [(match_operand 1 "any_register_operand" "")
3339 (match_operand 2 "any_register_operand" "")])))]
3341 [(set (match_dup 5) (match_dup 4))
3342 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3345 enum machine_mode inmode = GET_MODE (operands[1]);
3348 if (GET_CODE (operands[0]) == SUBREG)
3350 offset = SUBREG_BYTE (operands[0]);
3351 operands[0] = SUBREG_REG (operands[0]);
3353 gcc_assert (GET_CODE (operands[0]) == REG);
3354 if (! TARGET_LITTLE_ENDIAN)
3355 offset += 8 - GET_MODE_SIZE (inmode);
3356 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3363 (define_expand "rotldi3"
3364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3368 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3370 (define_insn "rotldi3_mextr"
3371 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3377 static char templ[16];
3379 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380 8 - (int) (INTVAL (operands[2]) >> 3));
3383 [(set_attr "type" "arith_media")])
3385 (define_expand "rotrdi3"
3386 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3390 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3392 (define_insn "rotrdi3_mextr"
3393 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3399 static char templ[16];
3401 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3404 [(set_attr "type" "arith_media")])
3407 [(set (match_operand:DI 0 "arith_reg_dest" "")
3408 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409 "ua_address_operand" "")))
3410 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3412 (clobber (match_operand:DI 3 "register_operand" ""))]
3414 [(match_dup 4) (match_dup 5)]
3417 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418 (operands[3], operands[1]));
3419 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3420 GEN_INT (56), GEN_INT (8));
3423 (define_insn "rotlsi3_1"
3424 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3425 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3431 [(set_attr "type" "arith")])
3433 (define_insn "rotlsi3_31"
3434 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3437 (clobber (reg:SI T_REG))]
3440 [(set_attr "type" "arith")])
3442 (define_insn "rotlsi3_16"
3443 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3444 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3448 [(set_attr "type" "arith")])
3450 (define_expand "rotlsi3"
3451 [(set (match_operand:SI 0 "arith_reg_dest" "")
3452 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3453 (match_operand:SI 2 "immediate_operand" "")))]
3457 static const char rot_tab[] = {
3458 000, 000, 000, 000, 000, 000, 010, 001,
3459 001, 001, 011, 013, 003, 003, 003, 003,
3460 003, 003, 003, 003, 003, 013, 012, 002,
3461 002, 002, 010, 000, 000, 000, 000, 000,
3466 if (GET_CODE (operands[2]) != CONST_INT)
3468 count = INTVAL (operands[2]);
3469 choice = rot_tab[count];
3470 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3476 emit_move_insn (operands[0], operands[1]);
3477 count -= (count & 16) * 2;
3480 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3487 parts[0] = gen_reg_rtx (SImode);
3488 parts[1] = gen_reg_rtx (SImode);
3489 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3490 emit_move_insn (parts[choice-1], operands[1]);
3491 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3492 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3493 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3494 count = (count & ~16) - 8;
3498 for (; count > 0; count--)
3499 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3500 for (; count < 0; count++)
3501 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3506 (define_insn "*rotlhi3_8"
3507 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3508 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3512 [(set_attr "type" "arith")])
3514 (define_expand "rotlhi3"
3515 [(set (match_operand:HI 0 "arith_reg_operand" "")
3516 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3517 (match_operand:HI 2 "immediate_operand" "")))]
3521 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3528 (define_insn "ashlsi3_sh2a"
3529 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531 (match_operand:SI 2 "arith_reg_operand" "r")))]
3534 [(set_attr "type" "arith")
3535 (set_attr "length" "4")])
3537 ;; This pattern is used by init_expmed for computing the costs of shift
3540 (define_insn_and_split "ashlsi3_std"
3541 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3542 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3543 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3544 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3546 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3554 && GET_CODE (operands[2]) == CONST_INT
3555 && ! satisfies_constraint_P27 (operands[2])"
3556 [(set (match_dup 3) (match_dup 2))
3558 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3559 (clobber (match_dup 4))])]
3560 "operands[4] = gen_rtx_SCRATCH (SImode);"
3561 [(set_attr "length" "*,*,*,4")
3562 (set_attr "type" "dyn_shift,arith,arith,arith")])
3564 (define_insn "ashlhi3_k"
3565 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3566 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3567 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3568 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3572 [(set_attr "type" "arith")])
3574 (define_insn "ashlsi3_n"
3575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577 (match_operand:SI 2 "const_int_operand" "n")))
3578 (clobber (reg:SI T_REG))]
3579 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3581 [(set (attr "length")
3582 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3584 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3586 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3588 (const_string "8")))
3589 (set_attr "type" "arith")])
3592 [(set (match_operand:SI 0 "arith_reg_dest" "")
3593 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3594 (match_operand:SI 2 "const_int_operand" "")))
3595 (clobber (reg:SI T_REG))]
3596 "TARGET_SH1 && reload_completed"
3597 [(use (reg:SI R0_REG))]
3600 gen_shifty_op (ASHIFT, operands);
3604 (define_insn "ashlsi3_media"
3605 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3606 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3607 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3612 [(set_attr "type" "arith_media")
3613 (set_attr "highpart" "ignore")])
3615 (define_expand "ashlsi3"
3616 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3617 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3618 (match_operand:SI 2 "nonmemory_operand" "")))
3619 (clobber (reg:SI T_REG))])]
3625 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3628 if (GET_CODE (operands[2]) == CONST_INT
3629 && sh_dynamicalize_shift_p (operands[2]))
3630 operands[2] = force_reg (SImode, operands[2]);
3633 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3636 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3640 (define_insn "*ashlhi3_n"
3641 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3642 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3643 (match_operand:HI 2 "const_int_operand" "n")))
3644 (clobber (reg:SI T_REG))]
3647 [(set (attr "length")
3648 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3650 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3652 (const_string "6")))
3653 (set_attr "type" "arith")])
3655 (define_expand "ashlhi3"
3656 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3657 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3658 (match_operand:SI 2 "nonmemory_operand" "")))
3659 (clobber (reg:SI T_REG))])]
3663 if (GET_CODE (operands[2]) != CONST_INT)
3665 /* It may be possible to call gen_ashlhi3 directly with more generic
3666 operands. Make sure operands[1] is a HImode register here. */
3667 if (!arith_reg_operand (operands[1], HImode))
3668 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3672 [(set (match_operand:HI 0 "arith_reg_dest" "")
3673 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3674 (match_operand:HI 2 "const_int_operand" "")))
3675 (clobber (reg:SI T_REG))]
3676 "TARGET_SH1 && reload_completed"
3677 [(use (reg:SI R0_REG))]
3680 gen_shifty_hi_op (ASHIFT, operands);
3685 ; arithmetic shift right
3688 (define_insn "ashrsi3_sh2a"
3689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694 [(set_attr "type" "dyn_shift")
3695 (set_attr "length" "4")])
3697 (define_insn "ashrsi3_k"
3698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3700 (match_operand:SI 2 "const_int_operand" "M")))
3701 (clobber (reg:SI T_REG))]
3702 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3704 [(set_attr "type" "arith")])
3706 ;; We can't do HImode right shifts correctly unless we start out with an
3707 ;; explicit zero / sign extension; doing that would result in worse overall
3708 ;; code, so just let the machine independent code widen the mode.
3709 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3712 ;; ??? This should be a define expand.
3714 (define_insn "ashrsi2_16"
3715 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3716 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3720 [(set_attr "length" "4")])
3723 [(set (match_operand:SI 0 "arith_reg_dest" "")
3724 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3727 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3728 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3729 "operands[2] = gen_lowpart (HImode, operands[0]);")
3731 ;; ??? This should be a define expand.
3733 (define_insn "ashrsi2_31"
3734 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3737 (clobber (reg:SI T_REG))]
3740 [(set_attr "length" "4")])
3743 [(set (match_operand:SI 0 "arith_reg_dest" "")
3744 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3746 (clobber (reg:SI T_REG))]
3751 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3752 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3757 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3759 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3761 && peep2_reg_dead_p (2, operands[0])
3762 && peep2_reg_dead_p (2, operands[1])"
3766 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3770 (define_insn "ashlsi_c"
3771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3774 (lt:SI (match_dup 1) (const_int 0)))]
3777 [(set_attr "type" "arith")])
3779 (define_insn "*ashlsi_c_void"
3780 [(set (reg:SI T_REG)
3781 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3782 (clobber (match_scratch:SI 1 "=0"))]
3783 "TARGET_SH1 && cse_not_expected"
3785 [(set_attr "type" "arith")])
3787 (define_insn "ashrsi3_d"
3788 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3789 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3790 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3793 [(set_attr "type" "dyn_shift")])
3795 (define_insn "ashrsi3_n"
3796 [(set (reg:SI R4_REG)
3797 (ashiftrt:SI (reg:SI R4_REG)
3798 (match_operand:SI 0 "const_int_operand" "i")))
3799 (clobber (reg:SI T_REG))
3800 (clobber (reg:SI PR_REG))
3801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3804 [(set_attr "type" "sfunc")
3805 (set_attr "needs_delay_slot" "yes")])
3807 (define_insn "ashrsi3_media"
3808 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3809 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3810 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3815 [(set_attr "type" "arith_media")
3816 (set_attr "highpart" "ignore")])
3818 (define_expand "ashrsi3"
3819 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3820 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3821 (match_operand:SI 2 "nonmemory_operand" "")))
3822 (clobber (reg:SI T_REG))])]
3828 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3831 if (expand_ashiftrt (operands))
3837 ;; logical shift right
3839 (define_insn "lshrsi3_sh2a"
3840 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3841 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3842 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3845 [(set_attr "type" "dyn_shift")
3846 (set_attr "length" "4")])
3848 (define_insn "lshrsi3_d"
3849 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3850 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3851 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3854 [(set_attr "type" "dyn_shift")])
3856 ;; Only the single bit shift clobbers the T bit.
3858 (define_insn "lshrsi3_m"
3859 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3860 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3861 (match_operand:SI 2 "const_int_operand" "M")))
3862 (clobber (reg:SI T_REG))]
3863 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3865 [(set_attr "type" "arith")])
3867 (define_insn "lshrsi3_k"
3868 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3869 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3870 (match_operand:SI 2 "const_int_operand" "P27")))]
3871 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3872 && ! satisfies_constraint_M (operands[2])"
3874 [(set_attr "type" "arith")])
3876 (define_insn "lshrsi3_n"
3877 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879 (match_operand:SI 2 "const_int_operand" "n")))
3880 (clobber (reg:SI T_REG))]
3881 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3883 [(set (attr "length")
3884 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3886 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3888 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3890 (const_string "8")))
3891 (set_attr "type" "arith")])
3894 [(set (match_operand:SI 0 "arith_reg_dest" "")
3895 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3896 (match_operand:SI 2 "const_int_operand" "")))
3897 (clobber (reg:SI T_REG))]
3898 "TARGET_SH1 && reload_completed"
3899 [(use (reg:SI R0_REG))]
3902 gen_shifty_op (LSHIFTRT, operands);
3906 (define_insn "lshrsi3_media"
3907 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3909 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3914 [(set_attr "type" "arith_media")
3915 (set_attr "highpart" "ignore")])
3917 (define_expand "lshrsi3"
3918 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3919 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3920 (match_operand:SI 2 "nonmemory_operand" "")))
3921 (clobber (reg:SI T_REG))])]
3927 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3930 if (GET_CODE (operands[2]) == CONST_INT
3931 && sh_dynamicalize_shift_p (operands[2]))
3932 operands[2] = force_reg (SImode, operands[2]);
3933 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3935 rtx count = copy_to_mode_reg (SImode, operands[2]);
3936 emit_insn (gen_negsi2 (count, count));
3937 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3940 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3944 ;; ??? This should be a define expand.
3946 (define_insn "ashldi3_k"
3947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3950 (clobber (reg:SI T_REG))]
3952 "shll %R0\;rotcl %S0"
3953 [(set_attr "length" "4")
3954 (set_attr "type" "arith")])
3956 (define_insn "ashldi3_media"
3957 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3958 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3964 [(set_attr "type" "arith_media")])
3966 (define_insn "*ashldisi3_media"
3967 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3968 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3969 (match_operand:DI 2 "const_int_operand" "n")))]
3970 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3971 "shlli.l %1, %2, %0"
3972 [(set_attr "type" "arith_media")
3973 (set_attr "highpart" "ignore")])
3975 (define_expand "ashldi3"
3976 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3977 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3978 (match_operand:DI 2 "immediate_operand" "")))
3979 (clobber (reg:SI T_REG))])]
3985 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3988 if (GET_CODE (operands[2]) != CONST_INT
3989 || INTVAL (operands[2]) != 1)
3993 ;; ??? This should be a define expand.
3995 (define_insn "lshrdi3_k"
3996 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3997 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3999 (clobber (reg:SI T_REG))]
4001 "shlr %S0\;rotcr %R0"
4002 [(set_attr "length" "4")
4003 (set_attr "type" "arith")])
4005 (define_insn "lshrdi3_media"
4006 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4007 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4008 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4010 && (arith_reg_dest (operands[0], DImode)
4011 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4015 [(set_attr "type" "arith_media")])
4017 (define_insn "*lshrdisi3_media"
4018 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4019 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4020 (match_operand:DI 2 "const_int_operand" "n")))]
4021 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4022 "shlri.l %1, %2, %0"
4023 [(set_attr "type" "arith_media")
4024 (set_attr "highpart" "ignore")])
4026 (define_expand "lshrdi3"
4027 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4028 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4029 (match_operand:DI 2 "immediate_operand" "")))
4030 (clobber (reg:SI T_REG))])]
4036 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4039 if (GET_CODE (operands[2]) != CONST_INT
4040 || INTVAL (operands[2]) != 1)
4044 ;; ??? This should be a define expand.
4046 (define_insn "ashrdi3_k"
4047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4048 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4050 (clobber (reg:SI T_REG))]
4052 "shar %S0\;rotcr %R0"
4053 [(set_attr "length" "4")
4054 (set_attr "type" "arith")])
4056 (define_insn "ashrdi3_media"
4057 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4058 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4059 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4061 && (arith_reg_dest (operands[0], DImode)
4062 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4066 [(set_attr "type" "arith_media")])
4068 (define_insn "*ashrdisi3_media"
4069 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4070 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4071 (match_operand:DI 2 "const_int_operand" "n")))]
4072 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4073 "shari.l %1, %2, %0"
4074 [(set_attr "type" "arith_media")
4075 (set_attr "highpart" "ignore")])
4077 (define_insn "ashrdisi3_media_high"
4078 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4080 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4081 (match_operand:DI 2 "const_int_operand" "n"))))]
4082 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4084 [(set_attr "type" "arith_media")])
4086 (define_insn "ashrdisi3_media_opaque"
4087 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4088 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4089 (match_operand:DI 2 "const_int_operand" "n")]
4093 [(set_attr "type" "arith_media")])
4095 (define_expand "ashrdi3"
4096 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4097 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4098 (match_operand:DI 2 "immediate_operand" "")))
4099 (clobber (reg:SI T_REG))])]
4105 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4108 if (GET_CODE (operands[2]) != CONST_INT
4109 || INTVAL (operands[2]) != 1)
4113 ;; combined left/right shift
4116 [(set (match_operand:SI 0 "register_operand" "")
4117 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4118 (match_operand:SI 2 "const_int_operand" ""))
4119 (match_operand:SI 3 "const_int_operand" "")))]
4120 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4121 [(use (reg:SI R0_REG))]
4122 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4126 [(set (match_operand:SI 0 "register_operand" "")
4127 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4128 (match_operand:SI 2 "const_int_operand" ""))
4129 (match_operand:SI 3 "const_int_operand" "")))
4130 (clobber (reg:SI T_REG))]
4131 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4132 [(use (reg:SI R0_REG))]
4133 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4137 [(set (match_operand:SI 0 "register_operand" "=r")
4138 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4139 (match_operand:SI 2 "const_int_operand" "n"))
4140 (match_operand:SI 3 "const_int_operand" "n")))
4141 (clobber (reg:SI T_REG))]
4142 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4144 [(set (attr "length")
4145 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4147 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4149 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4151 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4153 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4155 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4157 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4158 (const_string "16")]
4159 (const_string "18")))
4160 (set_attr "type" "arith")])
4163 [(set (match_operand:SI 0 "register_operand" "=z")
4164 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4165 (match_operand:SI 2 "const_int_operand" "n"))
4166 (match_operand:SI 3 "const_int_operand" "n")))
4167 (clobber (reg:SI T_REG))]
4168 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4170 [(set (attr "length")
4171 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4173 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4175 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4177 (const_string "10")))
4178 (set_attr "type" "arith")])
4180 ;; shift left / and combination with a scratch register: The combine pass
4181 ;; does not accept the individual instructions, even though they are
4182 ;; cheap. But it needs a precise description so that it is usable after
4184 (define_insn "and_shl_scratch"
4185 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4189 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4190 (match_operand:SI 2 "const_int_operand" "N,n"))
4191 (match_operand:SI 3 "" "0,r"))
4192 (match_operand:SI 4 "const_int_operand" "n,n"))
4193 (match_operand:SI 5 "const_int_operand" "n,n")))
4194 (clobber (reg:SI T_REG))]
4197 [(set (attr "length")
4198 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4200 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4202 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4204 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4205 (const_string "10")]
4206 (const_string "12")))
4207 (set_attr "type" "arith")])
4210 [(set (match_operand:SI 0 "register_operand" "")
4214 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4215 (match_operand:SI 2 "const_int_operand" ""))
4216 (match_operand:SI 3 "register_operand" ""))
4217 (match_operand:SI 4 "const_int_operand" ""))
4218 (match_operand:SI 5 "const_int_operand" "")))
4219 (clobber (reg:SI T_REG))]
4221 [(use (reg:SI R0_REG))]
4224 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4226 if (INTVAL (operands[2]))
4228 gen_shifty_op (LSHIFTRT, operands);
4230 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4231 operands[2] = operands[4];
4232 gen_shifty_op (ASHIFT, operands);
4233 if (INTVAL (operands[5]))
4235 operands[2] = operands[5];
4236 gen_shifty_op (LSHIFTRT, operands);
4241 ;; signed left/right shift combination.
4243 [(set (match_operand:SI 0 "register_operand" "")
4245 (ashift:SI (match_operand:SI 1 "register_operand" "")
4246 (match_operand:SI 2 "const_int_operand" ""))
4247 (match_operand:SI 3 "const_int_operand" "")
4249 (clobber (reg:SI T_REG))]
4251 [(use (reg:SI R0_REG))]
4252 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4255 (define_insn "shl_sext_ext"
4256 [(set (match_operand:SI 0 "register_operand" "=r")
4258 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4259 (match_operand:SI 2 "const_int_operand" "n"))
4260 (match_operand:SI 3 "const_int_operand" "n")
4262 (clobber (reg:SI T_REG))]
4263 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4265 [(set (attr "length")
4266 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4268 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4270 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4272 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4274 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4276 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4278 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4280 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4281 (const_string "16")]
4282 (const_string "18")))
4283 (set_attr "type" "arith")])
4285 (define_insn "shl_sext_sub"
4286 [(set (match_operand:SI 0 "register_operand" "=z")
4288 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4289 (match_operand:SI 2 "const_int_operand" "n"))
4290 (match_operand:SI 3 "const_int_operand" "n")
4292 (clobber (reg:SI T_REG))]
4293 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4295 [(set (attr "length")
4296 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4298 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4300 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4302 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4303 (const_string "12")]
4304 (const_string "14")))
4305 (set_attr "type" "arith")])
4307 ;; These patterns are found in expansions of DImode shifts by 16, and
4308 ;; allow the xtrct instruction to be generated from C source.
4310 (define_insn "xtrct_left"
4311 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4312 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4314 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4318 [(set_attr "type" "arith")])
4320 (define_insn "xtrct_right"
4321 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4322 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4324 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4328 [(set_attr "type" "arith")])
4330 ;; -------------------------------------------------------------------------
4332 ;; -------------------------------------------------------------------------
4335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336 (neg:SI (plus:SI (reg:SI T_REG)
4337 (match_operand:SI 1 "arith_reg_operand" "r"))))
4339 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4343 [(set_attr "type" "arith")])
4345 (define_insn "*negdi_media"
4346 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4347 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4350 [(set_attr "type" "arith_media")])
4352 (define_expand "negdi2"
4353 [(set (match_operand:DI 0 "arith_reg_operand" "")
4354 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4360 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4361 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4363 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4364 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4366 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4367 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4369 emit_insn (gen_clrt ());
4370 emit_insn (gen_negc (low_dst, low_src));
4371 emit_insn (gen_negc (high_dst, high_src));
4376 (define_insn "negsi2"
4377 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4378 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4381 [(set_attr "type" "arith")])
4383 (define_insn "one_cmplsi2"
4384 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4385 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4388 [(set_attr "type" "arith")])
4390 (define_expand "one_cmpldi2"
4391 [(set (match_operand:DI 0 "arith_reg_dest" "")
4392 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4394 "TARGET_SHMEDIA" "")
4396 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4397 This can be used as some kind of conditional execution, which is useful
4400 [(set (match_operand:SI 0 "arith_reg_dest" "")
4401 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4402 (match_operand:SI 1 "arith_reg_operand" ""))
4406 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4407 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4411 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4412 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4413 (match_operand:SI 1 "arith_reg_operand" "0")
4414 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4416 "bf 0f\;neg %2,%0\\n0:"
4417 [(set_attr "type" "arith") ;; poor approximation
4418 (set_attr "length" "4")])
4421 ;; -------------------------------------------------------------------------
4422 ;; Zero extension instructions
4423 ;; -------------------------------------------------------------------------
4425 (define_insn "zero_extendsidi2"
4426 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4427 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4429 "addz.l %1, r63, %0"
4430 [(set_attr "type" "arith_media")
4431 (set_attr "highpart" "extend")])
4433 (define_insn "zero_extendhidi2"
4434 [(set (match_operand:DI 0 "register_operand" "=r,r")
4435 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4440 [(set_attr "type" "*,load_media")
4441 (set (attr "highpart")
4442 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4443 (const_string "user")]
4444 (const_string "ignore")))])
4447 [(set (match_operand:DI 0 "register_operand" "")
4448 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4449 "TARGET_SHMEDIA && reload_completed"
4450 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4451 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4454 if (GET_CODE (operands[1]) == TRUNCATE)
4455 operands[1] = XEXP (operands[1], 0);
4458 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4459 ;; reload the entire truncate expression.
4460 (define_insn_and_split "*loaddi_trunc"
4461 [(set (match_operand 0 "any_register_operand" "=r")
4462 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4463 "TARGET_SHMEDIA && reload_completed"
4465 "TARGET_SHMEDIA && reload_completed"
4466 [(set (match_dup 0) (match_dup 1))]
4467 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4469 (define_insn "zero_extendqidi2"
4470 [(set (match_operand:DI 0 "register_operand" "=r,r")
4471 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4476 [(set_attr "type" "arith_media,load_media")
4477 (set (attr "highpart")
4478 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4479 (const_string "user")]
4480 (const_string "ignore")))])
4482 (define_expand "zero_extendhisi2"
4483 [(set (match_operand:SI 0 "arith_reg_operand" "")
4484 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4488 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4489 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4492 (define_insn "*zero_extendhisi2_compact"
4493 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4494 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4497 [(set_attr "type" "arith")])
4499 (define_insn "*zero_extendhisi2_media"
4500 [(set (match_operand:SI 0 "register_operand" "=r,r")
4501 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4506 [(set_attr "type" "arith_media,load_media")
4507 (set (attr "highpart")
4508 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4509 (const_string "user")]
4510 (const_string "ignore")))])
4513 [(set (match_operand:SI 0 "register_operand" "")
4514 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4515 "TARGET_SHMEDIA && reload_completed"
4516 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4517 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4520 rtx op1 = operands[1];
4522 if (GET_CODE (op1) == TRUNCATE)
4523 op1 = XEXP (op1, 0);
4525 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4526 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4529 (define_expand "zero_extendqisi2"
4530 [(set (match_operand:SI 0 "arith_reg_operand" "")
4531 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4535 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4536 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4539 (define_insn "*zero_extendqisi2_compact"
4540 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4541 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4544 [(set_attr "type" "arith")])
4546 (define_insn "*zero_extendqisi2_media"
4547 [(set (match_operand:SI 0 "register_operand" "=r,r")
4548 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4553 [(set_attr "type" "arith_media,load_media")
4554 (set (attr "highpart")
4555 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4556 (const_string "user")]
4557 (const_string "ignore")))])
4559 (define_insn "zero_extendqihi2"
4560 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4561 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4564 [(set_attr "type" "arith")])
4566 ;; -------------------------------------------------------------------------
4567 ;; Sign extension instructions
4568 ;; -------------------------------------------------------------------------
4570 ;; ??? This should be a define expand.
4571 ;; ??? Or perhaps it should be dropped?
4573 ;; convert_move generates good code for SH[1-4].
4574 (define_insn "extendsidi2"
4575 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4576 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4582 [(set_attr "type" "arith_media,load_media,fpconv_media")
4583 (set (attr "highpart")
4584 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4585 (const_string "user")]
4586 (const_string "extend")))])
4588 (define_insn "extendhidi2"
4589 [(set (match_operand:DI 0 "register_operand" "=r,r")
4590 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4595 [(set_attr "type" "*,load_media")
4596 (set (attr "highpart")
4597 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4598 (const_string "user")]
4599 (const_string "ignore")))])
4602 [(set (match_operand:DI 0 "register_operand" "")
4603 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4604 "TARGET_SHMEDIA && reload_completed"
4605 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4606 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4609 if (GET_CODE (operands[1]) == TRUNCATE)
4610 operands[1] = XEXP (operands[1], 0);
4613 (define_insn "extendqidi2"
4614 [(set (match_operand:DI 0 "register_operand" "=r,r")
4615 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4620 [(set_attr "type" "*,load_media")
4621 (set (attr "highpart")
4622 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4623 (const_string "user")]
4624 (const_string "ignore")))])
4627 [(set (match_operand:DI 0 "register_operand" "")
4628 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4629 "TARGET_SHMEDIA && reload_completed"
4630 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4631 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4634 if (GET_CODE (operands[1]) == TRUNCATE)
4635 operands[1] = XEXP (operands[1], 0);
4638 (define_expand "extendhisi2"
4639 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4640 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4644 (define_insn "*extendhisi2_compact"
4645 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4646 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4651 [(set_attr "type" "arith,load")])
4653 (define_insn "*extendhisi2_media"
4654 [(set (match_operand:SI 0 "register_operand" "=r,r")
4655 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4660 [(set_attr "type" "arith_media,load_media")
4661 (set (attr "highpart")
4662 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4663 (const_string "user")]
4664 (const_string "ignore")))])
4667 [(set (match_operand:SI 0 "register_operand" "")
4668 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4669 "TARGET_SHMEDIA && reload_completed"
4670 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4671 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4674 rtx op1 = operands[1];
4675 if (GET_CODE (op1) == TRUNCATE)
4676 op1 = XEXP (op1, 0);
4678 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4679 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4682 (define_expand "extendqisi2"
4683 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4684 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4688 (define_insn "*extendqisi2_compact"
4689 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4690 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4695 [(set_attr "type" "arith,load")])
4697 (define_insn "*extendqisi2_media"
4698 [(set (match_operand:SI 0 "register_operand" "=r,r")
4699 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4704 [(set_attr "type" "arith_media,load_media")
4705 (set (attr "highpart")
4706 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4707 (const_string "user")]
4708 (const_string "ignore")))])
4711 [(set (match_operand:SI 0 "register_operand" "")
4712 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4713 "TARGET_SHMEDIA && reload_completed"
4714 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4715 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4718 rtx op1 = operands[1];
4719 if (GET_CODE (op1) == TRUNCATE)
4720 op1 = XEXP (op1, 0);
4722 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4723 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4726 (define_insn "extendqihi2"
4727 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4728 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4733 [(set_attr "type" "arith,load")])
4735 /* It would seem useful to combine the truncXi patterns into the movXi
4736 patterns, but unary operators are ignored when matching constraints,
4737 so we need separate patterns. */
4738 (define_insn "truncdisi2"
4739 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4740 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4749 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4750 (set (attr "highpart")
4751 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4752 (const_string "user")]
4753 (const_string "extend")))])
4755 (define_insn "truncdihi2"
4756 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4757 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4760 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4762 [(set_attr "type" "arith_media,store_media")
4763 (set_attr "length" "8,4")
4764 (set (attr "highpart")
4765 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4766 (const_string "user")]
4767 (const_string "extend")))])
4769 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4770 ; Because we use zero extension, we can't provide signed QImode compares
4771 ; using a simple compare or conditional branch insn.
4772 (define_insn "truncdiqi2"
4773 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4774 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4779 [(set_attr "type" "arith_media,store")
4780 (set (attr "highpart")
4781 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4782 (const_string "user")]
4783 (const_string "extend")))])
4784 ;; -------------------------------------------------------------------------
4785 ;; Move instructions
4786 ;; -------------------------------------------------------------------------
4788 ;; define push and pop so it is easy for sh.c
4789 ;; We can't use push and pop on SHcompact because the stack must always
4790 ;; be 8-byte aligned.
4792 (define_expand "push"
4793 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4794 (match_operand:SI 0 "register_operand" "r,l,x"))]
4795 "TARGET_SH1 && ! TARGET_SH5"
4798 (define_expand "pop"
4799 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4800 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4801 "TARGET_SH1 && ! TARGET_SH5"
4804 (define_expand "push_e"
4805 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4806 (match_operand:SF 0 "" ""))
4807 (use (reg:PSI FPSCR_REG))
4808 (clobber (scratch:SI))])]
4809 "TARGET_SH1 && ! TARGET_SH5"
4812 (define_insn "push_fpul"
4813 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4814 "TARGET_SH2E && ! TARGET_SH5"
4816 [(set_attr "type" "fstore")
4817 (set_attr "late_fp_use" "yes")
4818 (set_attr "hit_stack" "yes")])
4820 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4822 (define_expand "push_4"
4823 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4824 (match_operand:DF 0 "" ""))
4825 (use (reg:PSI FPSCR_REG))
4826 (clobber (scratch:SI))])]
4827 "TARGET_SH1 && ! TARGET_SH5"
4830 (define_expand "pop_e"
4831 [(parallel [(set (match_operand:SF 0 "" "")
4832 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4833 (use (reg:PSI FPSCR_REG))
4834 (clobber (scratch:SI))])]
4835 "TARGET_SH1 && ! TARGET_SH5"
4838 (define_insn "pop_fpul"
4839 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4840 "TARGET_SH2E && ! TARGET_SH5"
4842 [(set_attr "type" "load")
4843 (set_attr "hit_stack" "yes")])
4845 (define_expand "pop_4"
4846 [(parallel [(set (match_operand:DF 0 "" "")
4847 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4848 (use (reg:PSI FPSCR_REG))
4849 (clobber (scratch:SI))])]
4850 "TARGET_SH1 && ! TARGET_SH5"
4853 (define_expand "push_fpscr"
4858 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4859 gen_rtx_PRE_DEC (Pmode,
4860 stack_pointer_rtx)),
4862 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4866 (define_expand "pop_fpscr"
4871 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4872 gen_frame_mem (PSImode,
4873 gen_rtx_POST_INC (Pmode,
4874 stack_pointer_rtx))));
4875 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4879 ;; These two patterns can happen as the result of optimization, when
4880 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4881 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4884 [(set (reg:SI T_REG) (const_int 0))]
4889 [(set (reg:SI T_REG) (const_int 1))]
4893 ;; t/r must come after r/r, lest reload will try to reload stuff like
4894 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4895 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4896 (define_insn "movsi_i"
4897 [(set (match_operand:SI 0 "general_movdst_operand"
4898 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4899 (match_operand:SI 1 "general_movsrc_operand"
4900 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4904 && (register_operand (operands[0], SImode)
4905 || register_operand (operands[1], SImode))"
4923 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4924 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4926 ;; t/r must come after r/r, lest reload will try to reload stuff like
4927 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4928 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4929 ;; will require a reload.
4930 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4931 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4932 (define_insn "movsi_ie"
4933 [(set (match_operand:SI 0 "general_movdst_operand"
4934 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4935 (match_operand:SI 1 "general_movsrc_operand"
4936 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4937 "(TARGET_SH2E || TARGET_SH2A)
4938 && (register_operand (operands[0], SImode)
4939 || register_operand (operands[1], SImode))"
4965 ! move optimized away"
4966 [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4967 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4968 (set_attr_alternative "length"
4975 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4976 (const_int 4) (const_int 2))
4981 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4982 (const_int 4) (const_int 2))
4999 (define_insn "movsi_i_lowpart"
5000 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5001 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5003 && (register_operand (operands[0], SImode)
5004 || register_operand (operands[1], SImode))"
5015 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5017 (define_insn_and_split "load_ra"
5018 [(set (match_operand:SI 0 "general_movdst_operand" "")
5019 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5022 "&& ! currently_expanding_to_rtl"
5023 [(set (match_dup 0) (match_dup 1))]
5026 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5027 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5030 ;; The '?'s in the following constraints may not reflect the time taken
5031 ;; to perform the move. They are there to discourage the use of floating-
5032 ;; point registers for storing integer values.
5033 (define_insn "*movsi_media"
5034 [(set (match_operand:SI 0 "general_movdst_operand"
5035 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5036 (match_operand:SI 1 "general_movsrc_operand"
5037 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5039 && (register_operand (operands[0], SImode)
5040 || sh_register_operand (operands[1], SImode)
5041 || GET_CODE (operands[1]) == TRUNCATE)"
5056 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5057 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5058 (set (attr "highpart")
5059 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5060 (const_string "user")]
5061 (const_string "ignore")))])
5063 (define_insn "*movsi_media_nofpu"
5064 [(set (match_operand:SI 0 "general_movdst_operand"
5065 "=r,r,r,r,m,*b,r,*b")
5066 (match_operand:SI 1 "general_movsrc_operand"
5067 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5069 && (register_operand (operands[0], SImode)
5070 || sh_register_operand (operands[1], SImode)
5071 || GET_CODE (operands[1]) == TRUNCATE)"
5081 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5082 (set_attr "length" "4,4,8,4,4,4,4,12")
5083 (set (attr "highpart")
5084 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5085 (const_string "user")]
5086 (const_string "ignore")))])
5088 (define_expand "movsi_const"
5089 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5090 (const:SI (sign_extend:SI
5093 (match_operand:DI 1 "immediate_operand" "s")
5096 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5099 (truncate:HI (match_dup 1))))))]
5100 "TARGET_SHMEDIA && reload_completed
5101 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5104 if (GET_CODE (operands[1]) == LABEL_REF
5105 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5106 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5107 else if (GOTOFF_P (operands[1]))
5109 rtx unspec = XEXP (operands[1], 0);
5111 if (! UNSPEC_GOTOFF_P (unspec))
5113 unspec = XEXP (unspec, 0);
5114 if (! UNSPEC_GOTOFF_P (unspec))
5117 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5118 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5119 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5123 (define_expand "movsi_const_16bit"
5124 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5125 (const:SI (sign_extend:SI
5127 (match_operand:DI 1 "immediate_operand" "s")))))]
5128 "TARGET_SHMEDIA && flag_pic && reload_completed
5129 && GET_CODE (operands[1]) == SYMBOL_REF"
5133 [(set (match_operand:SI 0 "arith_reg_dest" "")
5134 (match_operand:SI 1 "immediate_operand" ""))]
5135 "TARGET_SHMEDIA && reload_completed
5136 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5140 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5142 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5148 [(set (match_operand:SI 0 "register_operand" "")
5149 (match_operand:SI 1 "immediate_operand" ""))]
5150 "TARGET_SHMEDIA && reload_completed
5151 && ((GET_CODE (operands[1]) == CONST_INT
5152 && ! satisfies_constraint_I16 (operands[1]))
5153 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5154 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5156 (define_expand "movsi"
5157 [(set (match_operand:SI 0 "general_movdst_operand" "")
5158 (match_operand:SI 1 "general_movsrc_operand" ""))]
5160 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5162 (define_expand "ic_invalidate_line"
5163 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5164 (match_dup 1)] UNSPEC_ICACHE)
5165 (clobber (scratch:SI))])]
5166 "TARGET_HARD_SH4 || TARGET_SH5"
5171 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5174 else if (TARGET_SHCOMPACT)
5176 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5177 operands[1] = force_reg (Pmode, operands[1]);
5178 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5181 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5183 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5186 operands[0] = force_reg (Pmode, operands[0]);
5187 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5191 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5192 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5193 ;; the requirement *1*00 for associative address writes. The alignment of
5194 ;; %0 implies that its least significant bit is cleared,
5195 ;; thus we clear the V bit of a matching entry if there is one.
5196 (define_insn "ic_invalidate_line_i"
5197 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5198 (match_operand:SI 1 "register_operand" "r")]
5200 (clobber (match_scratch:SI 2 "=&r"))]
5202 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5203 [(set_attr "length" "8")
5204 (set_attr "type" "cwb")])
5206 (define_insn "ic_invalidate_line_sh4a"
5207 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5209 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5210 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5211 [(set_attr "length" "16")
5212 (set_attr "type" "cwb")])
5214 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5215 ;; an add in the code that calculates the address.
5216 (define_insn "ic_invalidate_line_media"
5217 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5220 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5221 [(set_attr "length" "16")
5222 (set_attr "type" "invalidate_line_media")])
5224 (define_insn "ic_invalidate_line_compact"
5225 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5226 (match_operand:SI 1 "register_operand" "r")]
5228 (clobber (reg:SI PR_REG))]
5231 [(set_attr "type" "sfunc")
5232 (set_attr "needs_delay_slot" "yes")])
5234 (define_expand "initialize_trampoline"
5235 [(match_operand:SI 0 "" "")
5236 (match_operand:SI 1 "" "")
5237 (match_operand:SI 2 "" "")]
5243 tramp = force_reg (Pmode, operands[0]);
5244 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5246 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5247 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5249 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5253 (define_insn "initialize_trampoline_compact"
5254 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5255 (match_operand:SI 1 "register_operand" "r")
5256 (reg:SI R2_REG) (reg:SI R3_REG)]
5259 (clobber (reg:SI PR_REG))]
5262 [(set_attr "type" "sfunc")
5263 (set_attr "needs_delay_slot" "yes")])
5265 (define_insn "movqi_i"
5266 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5267 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5269 && (arith_reg_operand (operands[0], QImode)
5270 || arith_reg_operand (operands[1], QImode))"
5279 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5281 (define_insn "*movqi_media"
5282 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5283 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5285 && (arith_reg_operand (operands[0], QImode)
5286 || extend_reg_or_0_operand (operands[1], QImode))"
5292 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5293 (set (attr "highpart")
5294 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5295 (const_string "user")]
5296 (const_string "ignore")))])
5298 (define_expand "movqi"
5299 [(set (match_operand:QI 0 "general_operand" "")
5300 (match_operand:QI 1 "general_operand" ""))]
5302 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5304 (define_expand "reload_inqi"
5305 [(set (match_operand:SI 2 "" "=&r")
5306 (match_operand:QI 1 "inqhi_operand" ""))
5307 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5308 (truncate:QI (match_dup 3)))]
5312 rtx inner = XEXP (operands[1], 0);
5313 int regno = REGNO (inner);
5315 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5316 operands[1] = gen_rtx_REG (SImode, regno);
5317 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5320 /* When storing r0, we have to avoid reg+reg addressing. */
5321 (define_insn "movhi_i"
5322 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5323 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5325 && (arith_reg_operand (operands[0], HImode)
5326 || arith_reg_operand (operands[1], HImode))
5327 && (GET_CODE (operands[0]) != MEM
5328 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5329 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5330 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5340 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5342 (define_insn "*movhi_media"
5343 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5344 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5346 && (arith_reg_operand (operands[0], HImode)
5347 || arith_reg_or_0_operand (operands[1], HImode))"
5354 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5355 (set (attr "highpart")
5356 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5357 (const_string "user")]
5358 (const_string "ignore")))])
5361 [(set (match_operand:HI 0 "register_operand" "")
5362 (match_operand:HI 1 "immediate_operand" ""))]
5363 "TARGET_SHMEDIA && reload_completed
5364 && ! satisfies_constraint_I16 (operands[1])"
5365 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5367 (define_expand "movhi"
5368 [(set (match_operand:HI 0 "general_movdst_operand" "")
5369 (match_operand:HI 1 "general_movsrc_operand" ""))]
5371 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5373 (define_expand "reload_inhi"
5374 [(set (match_operand:SI 2 "" "=&r")
5375 (match_operand:HI 1 "inqhi_operand" ""))
5376 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5377 (truncate:HI (match_dup 3)))]
5381 rtx inner = XEXP (operands[1], 0);
5382 int regno = REGNO (inner);
5384 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5385 operands[1] = gen_rtx_REG (SImode, regno);
5386 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5389 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5390 ;; compiled with -m2 -ml -O3 -funroll-loops
5391 (define_insn "*movdi_i"
5392 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5393 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5395 && (arith_reg_operand (operands[0], DImode)
5396 || arith_reg_operand (operands[1], DImode))"
5397 "* return output_movedouble (insn, operands, DImode);"
5398 [(set_attr "length" "4")
5399 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5401 ;; If the output is a register and the input is memory or a register, we have
5402 ;; to be careful and see which word needs to be loaded first.
5405 [(set (match_operand:DI 0 "general_movdst_operand" "")
5406 (match_operand:DI 1 "general_movsrc_operand" ""))]
5407 "TARGET_SH1 && reload_completed"
5408 [(set (match_dup 2) (match_dup 3))
5409 (set (match_dup 4) (match_dup 5))]
5414 if ((GET_CODE (operands[0]) == MEM
5415 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5416 || (GET_CODE (operands[1]) == MEM
5417 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5420 switch (GET_CODE (operands[0]))
5423 regno = REGNO (operands[0]);
5426 regno = subreg_regno (operands[0]);
5436 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5438 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5439 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5440 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5441 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5445 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5446 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5447 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5448 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5451 if (operands[2] == 0 || operands[3] == 0
5452 || operands[4] == 0 || operands[5] == 0)
5456 ;; The '?'s in the following constraints may not reflect the time taken
5457 ;; to perform the move. They are there to discourage the use of floating-
5458 ;; point registers for storing integer values.
5459 (define_insn "*movdi_media"
5460 [(set (match_operand:DI 0 "general_movdst_operand"
5461 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5462 (match_operand:DI 1 "general_movsrc_operand"
5463 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5465 && (register_operand (operands[0], DImode)
5466 || sh_register_operand (operands[1], DImode))"
5481 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5482 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5484 (define_insn "*movdi_media_nofpu"
5485 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5486 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5488 && (register_operand (operands[0], DImode)
5489 || sh_register_operand (operands[1], DImode))"
5499 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5500 (set_attr "length" "4,4,16,4,4,4,4,*")])
5502 (define_insn "*movdi_media_I16"
5503 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5504 (match_operand:DI 1 "const_int_operand" "I16"))]
5505 "TARGET_SHMEDIA && reload_completed"
5507 [(set_attr "type" "arith_media")
5508 (set_attr "length" "4")])
5511 [(set (match_operand:DI 0 "arith_reg_dest" "")
5512 (match_operand:DI 1 "immediate_operand" ""))]
5513 "TARGET_SHMEDIA && reload_completed
5514 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5515 [(set (match_dup 0) (match_dup 1))]
5520 if (TARGET_SHMEDIA64)
5521 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5523 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5525 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5530 (define_expand "movdi_const"
5531 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5532 (const:DI (sign_extend:DI
5535 (match_operand:DI 1 "immediate_operand" "s")
5538 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5544 (const_int 32)))))))
5546 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5552 (const_int 16)))))))
5554 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5559 "TARGET_SHMEDIA64 && reload_completed
5560 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5563 sh_mark_label (operands[1], 4);
5566 (define_expand "movdi_const_32bit"
5567 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5568 (const:DI (sign_extend:DI
5571 (match_operand:DI 1 "immediate_operand" "s")
5574 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5579 "TARGET_SHMEDIA32 && reload_completed
5580 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5583 sh_mark_label (operands[1], 2);
5586 (define_expand "movdi_const_16bit"
5587 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5588 (const:DI (sign_extend:DI
5590 (match_operand:DI 1 "immediate_operand" "s")))))]
5591 "TARGET_SHMEDIA && flag_pic && reload_completed
5592 && GET_CODE (operands[1]) == SYMBOL_REF"
5596 [(set (match_operand:DI 0 "ext_dest_operand" "")
5597 (match_operand:DI 1 "immediate_operand" ""))]
5598 "TARGET_SHMEDIA && reload_completed
5599 && GET_CODE (operands[1]) == CONST_INT
5600 && ! satisfies_constraint_I16 (operands[1])"
5601 [(set (match_dup 0) (match_dup 2))
5605 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5606 unsigned HOST_WIDE_INT low = val;
5607 unsigned HOST_WIDE_INT high = val;
5608 unsigned HOST_WIDE_INT sign;
5609 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5611 /* Zero-extend the 16 least-significant bits. */
5614 /* Arithmetic shift right the word by 16 bits. */
5616 if (GET_CODE (operands[0]) == SUBREG
5617 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5626 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5632 /* If we can't generate the constant with a two-insn movi / shori
5633 sequence, try some other strategies. */
5634 if (! CONST_OK_FOR_I16 (high))
5636 /* Try constant load / left shift. We know VAL != 0. */
5637 val2 = val ^ (val-1);
5640 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5642 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5643 || (! CONST_OK_FOR_I16 (high >> 16)
5644 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5646 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5647 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5648 GEN_INT (trailing_zeroes));
5652 /* Try constant load / right shift. */
5653 val2 = (val >> 15) + 1;
5654 if (val2 == (val2 & -val2))
5656 int shift = 49 - exact_log2 (val2);
5658 val2 = trunc_int_for_mode (val << shift, DImode);
5659 if (CONST_OK_FOR_I16 (val2))
5661 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5667 val2 = val & 0xffff;
5668 if ((val >> 16 & 0xffff) == val2
5669 && (val >> 32 & 0xffff) == val2
5670 && (val >> 48 & 0xffff) == val2)
5672 val2 = (HOST_WIDE_INT) val >> 48;
5673 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5674 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5677 /* Try movi / mshflo.l */
5678 val2 = (HOST_WIDE_INT) val >> 32;
5679 if (val2 == ((unsigned HOST_WIDE_INT)
5680 trunc_int_for_mode (val, SImode)))
5682 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5686 /* Try movi / mshflo.l w/ r63. */
5687 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5688 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5690 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5696 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5699 operands[2] = GEN_INT (val2);
5703 [(set (match_operand:DI 0 "ext_dest_operand" "")
5704 (match_operand:DI 1 "immediate_operand" ""))]
5705 "TARGET_SHMEDIA && reload_completed
5706 && GET_CODE (operands[1]) == CONST_DOUBLE"
5707 [(set (match_dup 0) (match_dup 2))
5709 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5712 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5713 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5714 unsigned HOST_WIDE_INT val = low;
5715 unsigned HOST_WIDE_INT sign;
5717 /* Zero-extend the 16 least-significant bits. */
5719 operands[1] = GEN_INT (val);
5721 /* Arithmetic shift right the double-word by 16 bits. */
5723 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5726 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5730 /* This will only be true if high is a sign-extension of low, i.e.,
5731 it must be either 0 or (unsigned)-1, and be zero iff the
5732 most-significant bit of low is set. */
5733 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5734 operands[2] = GEN_INT (low);
5736 operands[2] = immed_double_const (low, high, DImode);
5739 (define_insn "shori_media"
5740 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5741 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5743 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5744 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5748 [(set_attr "type" "arith_media,*")])
5750 (define_insn "*shori_media_si"
5751 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5752 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5754 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5758 (define_expand "movdi"
5759 [(set (match_operand:DI 0 "general_movdst_operand" "")
5760 (match_operand:DI 1 "general_movsrc_operand" ""))]
5762 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5764 (define_insn "movdf_media"
5765 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5766 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5768 && (register_operand (operands[0], DFmode)
5769 || sh_register_operand (operands[1], DFmode))"
5780 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5782 (define_insn "movdf_media_nofpu"
5783 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5784 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5786 && (register_operand (operands[0], DFmode)
5787 || sh_register_operand (operands[1], DFmode))"
5793 [(set_attr "type" "arith_media,*,load_media,store_media")])
5796 [(set (match_operand:DF 0 "arith_reg_dest" "")
5797 (match_operand:DF 1 "immediate_operand" ""))]
5798 "TARGET_SHMEDIA && reload_completed"
5799 [(set (match_dup 3) (match_dup 2))]
5802 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5804 REAL_VALUE_TYPE value;
5806 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5807 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5809 if (HOST_BITS_PER_WIDE_INT >= 64)
5810 operands[2] = immed_double_const ((unsigned long) values[endian]
5811 | ((HOST_WIDE_INT) values[1 - endian]
5815 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5816 operands[2] = immed_double_const (values[endian], values[1 - endian],
5820 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5823 ;; ??? This should be a define expand.
5825 (define_insn "movdf_k"
5826 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5827 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5829 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5830 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5831 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5832 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5833 && (arith_reg_operand (operands[0], DFmode)
5834 || arith_reg_operand (operands[1], DFmode))"
5835 "* return output_movedouble (insn, operands, DFmode);"
5836 [(set_attr "length" "4")
5837 (set_attr "type" "move,pcload,load,store")])
5839 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5840 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5841 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5842 ;; the d/m/c/X alternative, which is split later into single-precision
5843 ;; instructions. And when not optimizing, no splits are done before fixing
5844 ;; up pcloads, so we need usable length information for that.
5845 (define_insn "movdf_i4"
5846 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5847 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5848 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5849 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5850 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5851 && (arith_reg_operand (operands[0], DFmode)
5852 || arith_reg_operand (operands[1], DFmode))"
5864 [(set_attr_alternative "length"
5865 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5867 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5868 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5869 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5871 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5872 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5873 ;; increment or decrement r15 explicitly.
5875 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5876 (const_int 10) (const_int 8))
5878 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5879 (const_int 10) (const_int 8))])
5880 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5881 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5882 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5883 (const_string "double")
5884 (const_string "none")))])
5886 ;; Moving DFmode between fp/general registers through memory
5887 ;; (the top of the stack) is faster than moving through fpul even for
5888 ;; little endian. Because the type of an instruction is important for its
5889 ;; scheduling, it is beneficial to split these operations, rather than
5890 ;; emitting them in one single chunk, even if this will expose a stack
5891 ;; use that will prevent scheduling of other stack accesses beyond this
5894 [(set (match_operand:DF 0 "register_operand" "")
5895 (match_operand:DF 1 "register_operand" ""))
5896 (use (match_operand:PSI 2 "fpscr_operand" ""))
5897 (clobber (match_scratch:SI 3 "=X"))]
5898 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5899 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5905 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5907 emit_move_insn (stack_pointer_rtx,
5908 plus_constant (stack_pointer_rtx, -8));
5909 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5912 tos = gen_tmp_stack_mem (DFmode,
5913 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5914 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5915 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5916 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5917 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5918 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5920 tos = gen_tmp_stack_mem (DFmode,
5921 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5922 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5923 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5924 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5926 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5930 ;; local-alloc sometimes allocates scratch registers even when not required,
5931 ;; so we must be prepared to handle these.
5933 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5935 [(set (match_operand:DF 0 "general_movdst_operand" "")
5936 (match_operand:DF 1 "general_movsrc_operand" ""))
5937 (use (match_operand:PSI 2 "fpscr_operand" ""))
5938 (clobber (match_scratch:SI 3 ""))]
5939 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5941 && true_regnum (operands[0]) < 16
5942 && true_regnum (operands[1]) < 16"
5943 [(set (match_dup 0) (match_dup 1))]
5946 /* If this was a reg <-> mem operation with base + index reg addressing,
5947 we have to handle this in a special way. */
5948 rtx mem = operands[0];
5950 if (! memory_operand (mem, DFmode))
5955 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5956 mem = SUBREG_REG (mem);
5957 if (GET_CODE (mem) == MEM)
5959 rtx addr = XEXP (mem, 0);
5960 if (GET_CODE (addr) == PLUS
5961 && GET_CODE (XEXP (addr, 0)) == REG
5962 && GET_CODE (XEXP (addr, 1)) == REG)
5965 rtx reg0 = gen_rtx_REG (Pmode, 0);
5966 rtx regop = operands[store_p], word0 ,word1;
5968 if (GET_CODE (regop) == SUBREG)
5969 alter_subreg (®op);
5970 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5974 mem = copy_rtx (mem);
5975 PUT_MODE (mem, SImode);
5976 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5977 alter_subreg (&word0);
5978 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5979 alter_subreg (&word1);
5980 if (store_p || ! refers_to_regno_p (REGNO (word0),
5981 REGNO (word0) + 1, addr, 0))
5984 ? gen_movsi_ie (mem, word0)
5985 : gen_movsi_ie (word0, mem));
5986 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5987 mem = copy_rtx (mem);
5989 ? gen_movsi_ie (mem, word1)
5990 : gen_movsi_ie (word1, mem));
5991 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5995 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5996 emit_insn (gen_movsi_ie (word1, mem));
5997 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5998 mem = copy_rtx (mem);
5999 emit_insn (gen_movsi_ie (word0, mem));
6006 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6008 [(set (match_operand:DF 0 "register_operand" "")
6009 (match_operand:DF 1 "memory_operand" ""))
6010 (use (match_operand:PSI 2 "fpscr_operand" ""))
6011 (clobber (reg:SI R0_REG))]
6012 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6013 [(parallel [(set (match_dup 0) (match_dup 1))
6015 (clobber (scratch:SI))])]
6018 (define_expand "reload_indf__frn"
6019 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6020 (match_operand:DF 1 "immediate_operand" "FQ"))
6021 (use (reg:PSI FPSCR_REG))
6022 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6026 (define_expand "reload_outdf__RnFRm"
6027 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6028 (match_operand:DF 1 "register_operand" "af,r"))
6029 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6033 ;; Simplify no-op moves.
6035 [(set (match_operand:SF 0 "register_operand" "")
6036 (match_operand:SF 1 "register_operand" ""))
6037 (use (match_operand:PSI 2 "fpscr_operand" ""))
6038 (clobber (match_scratch:SI 3 ""))]
6039 "TARGET_SH2E && reload_completed
6040 && true_regnum (operands[0]) == true_regnum (operands[1])"
6041 [(set (match_dup 0) (match_dup 0))]
6044 ;; fmovd substitute post-reload splits
6046 [(set (match_operand:DF 0 "register_operand" "")
6047 (match_operand:DF 1 "register_operand" ""))
6048 (use (match_operand:PSI 2 "fpscr_operand" ""))
6049 (clobber (match_scratch:SI 3 ""))]
6050 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6051 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6052 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6056 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6057 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6058 gen_rtx_REG (SFmode, src), operands[2]));
6059 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6060 gen_rtx_REG (SFmode, src + 1), operands[2]));
6065 [(set (match_operand:DF 0 "register_operand" "")
6066 (mem:DF (match_operand:SI 1 "register_operand" "")))
6067 (use (match_operand:PSI 2 "fpscr_operand" ""))
6068 (clobber (match_scratch:SI 3 ""))]
6069 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6070 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6071 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6075 int regno = true_regnum (operands[0]);
6077 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6079 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6080 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6081 regno + !! TARGET_LITTLE_ENDIAN),
6082 mem2, operands[2]));
6083 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6084 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6085 regno + ! TARGET_LITTLE_ENDIAN),
6086 change_address (mem, SFmode, NULL_RTX),
6092 [(set (match_operand:DF 0 "register_operand" "")
6093 (match_operand:DF 1 "memory_operand" ""))
6094 (use (match_operand:PSI 2 "fpscr_operand" ""))
6095 (clobber (match_scratch:SI 3 ""))]
6096 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6097 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6101 int regno = true_regnum (operands[0]);
6102 rtx addr, insn, adjust = NULL_RTX;
6103 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6104 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6105 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6107 operands[1] = copy_rtx (mem2);
6108 addr = XEXP (mem2, 0);
6109 if (GET_CODE (addr) != POST_INC)
6111 /* If we have to modify the stack pointer, the value that we have
6112 read with post-increment might be modified by an interrupt,
6113 so write it back. */
6114 if (REGNO (addr) == STACK_POINTER_REGNUM)
6115 adjust = gen_push_e (reg0);
6117 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6118 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6120 addr = XEXP (addr, 0);
6121 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6122 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6123 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6127 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6132 [(set (match_operand:DF 0 "memory_operand" "")
6133 (match_operand:DF 1 "register_operand" ""))
6134 (use (match_operand:PSI 2 "fpscr_operand" ""))
6135 (clobber (match_scratch:SI 3 ""))]
6136 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6137 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6141 int regno = true_regnum (operands[1]);
6142 rtx insn, addr, adjust = NULL_RTX;
6144 operands[0] = copy_rtx (operands[0]);
6145 PUT_MODE (operands[0], SFmode);
6146 insn = emit_insn (gen_movsf_ie (operands[0],
6147 gen_rtx_REG (SFmode,
6148 regno + ! TARGET_LITTLE_ENDIAN),
6150 operands[0] = copy_rtx (operands[0]);
6151 addr = XEXP (operands[0], 0);
6152 if (GET_CODE (addr) != PRE_DEC)
6154 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6155 emit_insn_before (adjust, insn);
6156 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6158 addr = XEXP (addr, 0);
6160 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6161 insn = emit_insn (gen_movsf_ie (operands[0],
6162 gen_rtx_REG (SFmode,
6163 regno + !! TARGET_LITTLE_ENDIAN),
6165 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6169 ;; If the output is a register and the input is memory or a register, we have
6170 ;; to be careful and see which word needs to be loaded first.
6173 [(set (match_operand:DF 0 "general_movdst_operand" "")
6174 (match_operand:DF 1 "general_movsrc_operand" ""))]
6175 "TARGET_SH1 && reload_completed"
6176 [(set (match_dup 2) (match_dup 3))
6177 (set (match_dup 4) (match_dup 5))]
6182 if ((GET_CODE (operands[0]) == MEM
6183 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6184 || (GET_CODE (operands[1]) == MEM
6185 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6188 switch (GET_CODE (operands[0]))
6191 regno = REGNO (operands[0]);
6194 regno = subreg_regno (operands[0]);
6204 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6206 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6207 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6208 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6209 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6213 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6214 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6215 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6216 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6219 if (operands[2] == 0 || operands[3] == 0
6220 || operands[4] == 0 || operands[5] == 0)
6224 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6225 ;; used only once, let combine add in the index again.
6228 [(set (match_operand:SI 0 "register_operand" "")
6229 (match_operand:SI 1 "" ""))
6230 (clobber (match_operand 2 "register_operand" ""))]
6231 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6232 && ALLOW_INDEXED_ADDRESS"
6233 [(use (reg:SI R0_REG))]
6236 rtx addr, reg, const_int;
6238 if (GET_CODE (operands[1]) != MEM)
6240 addr = XEXP (operands[1], 0);
6241 if (GET_CODE (addr) != PLUS)
6243 reg = XEXP (addr, 0);
6244 const_int = XEXP (addr, 1);
6245 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6246 && GET_CODE (const_int) == CONST_INT))
6248 emit_move_insn (operands[2], const_int);
6249 emit_move_insn (operands[0],
6250 change_address (operands[1], VOIDmode,
6251 gen_rtx_PLUS (SImode, reg, operands[2])));
6256 [(set (match_operand:SI 1 "" "")
6257 (match_operand:SI 0 "register_operand" ""))
6258 (clobber (match_operand 2 "register_operand" ""))]
6259 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6260 && ALLOW_INDEXED_ADDRESS"
6261 [(use (reg:SI R0_REG))]
6264 rtx addr, reg, const_int;
6266 if (GET_CODE (operands[1]) != MEM)
6268 addr = XEXP (operands[1], 0);
6269 if (GET_CODE (addr) != PLUS)
6271 reg = XEXP (addr, 0);
6272 const_int = XEXP (addr, 1);
6273 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6274 && GET_CODE (const_int) == CONST_INT))
6276 emit_move_insn (operands[2], const_int);
6277 emit_move_insn (change_address (operands[1], VOIDmode,
6278 gen_rtx_PLUS (SImode, reg, operands[2])),
6283 (define_expand "movdf"
6284 [(set (match_operand:DF 0 "general_movdst_operand" "")
6285 (match_operand:DF 1 "general_movsrc_operand" ""))]
6289 if (prepare_move_operands (operands, DFmode)) DONE;
6292 if (TARGET_SHMEDIA_FPU)
6293 emit_insn (gen_movdf_media (operands[0], operands[1]));
6295 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6298 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6300 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6305 ;;This is incompatible with the way gcc uses subregs.
6306 ;;(define_insn "movv2sf_i"
6307 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6308 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6309 ;; "TARGET_SHMEDIA_FPU
6310 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6311 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6315 ;; fst%M0.p %m0, %1"
6316 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6318 (define_insn_and_split "movv2sf_i"
6319 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6320 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6321 "TARGET_SHMEDIA_FPU"
6323 "TARGET_SHMEDIA_FPU && reload_completed"
6324 [(set (match_dup 0) (match_dup 1))]
6327 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6328 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6331 (define_expand "movv2sf"
6332 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6333 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6334 "TARGET_SHMEDIA_FPU"
6337 if (prepare_move_operands (operands, V2SFmode))
6341 (define_expand "addv2sf3"
6342 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6343 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6344 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6345 "TARGET_SHMEDIA_FPU"
6348 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6352 (define_expand "subv2sf3"
6353 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6354 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6355 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6356 "TARGET_SHMEDIA_FPU"
6359 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6363 (define_expand "mulv2sf3"
6364 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6365 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6366 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6367 "TARGET_SHMEDIA_FPU"
6370 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6374 (define_expand "divv2sf3"
6375 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6376 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6377 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6378 "TARGET_SHMEDIA_FPU"
6381 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6385 (define_insn_and_split "*movv4sf_i"
6386 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6387 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6388 "TARGET_SHMEDIA_FPU"
6390 "&& reload_completed"
6396 for (i = 0; i < 4/2; i++)
6400 if (GET_CODE (operands[0]) == MEM)
6401 x = adjust_address (operands[0], V2SFmode,
6402 i * GET_MODE_SIZE (V2SFmode));
6404 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6406 if (GET_CODE (operands[1]) == MEM)
6407 y = adjust_address (operands[1], V2SFmode,
6408 i * GET_MODE_SIZE (V2SFmode));
6410 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6412 emit_insn (gen_movv2sf_i (x, y));
6417 [(set_attr "length" "8")])
6419 (define_expand "movv4sf"
6420 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6421 (match_operand:V4SF 1 "general_operand" ""))]
6422 "TARGET_SHMEDIA_FPU"
6425 if (prepare_move_operands (operands, V4SFmode))
6429 (define_insn_and_split "*movv16sf_i"
6430 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6431 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6432 "TARGET_SHMEDIA_FPU"
6434 "&& reload_completed"
6440 for (i = 0; i < 16/2; i++)
6444 if (GET_CODE (operands[0]) == MEM)
6445 x = adjust_address (operands[0], V2SFmode,
6446 i * GET_MODE_SIZE (V2SFmode));
6449 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6453 if (GET_CODE (operands[1]) == MEM)
6454 y = adjust_address (operands[1], V2SFmode,
6455 i * GET_MODE_SIZE (V2SFmode));
6458 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6462 emit_insn (gen_movv2sf_i (x, y));
6467 [(set_attr "length" "32")])
6469 (define_expand "movv16sf"
6470 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6471 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6472 "TARGET_SHMEDIA_FPU"
6475 if (prepare_move_operands (operands, V16SFmode))
6479 (define_insn "movsf_media"
6480 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6481 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6483 && (register_operand (operands[0], SFmode)
6484 || sh_register_operand (operands[1], SFmode))"
6495 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6496 (set (attr "highpart")
6497 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6498 (const_string "user")]
6499 (const_string "ignore")))])
6501 (define_insn "movsf_media_nofpu"
6502 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6503 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6505 && (register_operand (operands[0], SFmode)
6506 || sh_register_operand (operands[1], SFmode))"
6512 [(set_attr "type" "arith_media,*,load_media,store_media")
6513 (set (attr "highpart")
6514 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6515 (const_string "user")]
6516 (const_string "ignore")))])
6519 [(set (match_operand:SF 0 "arith_reg_dest" "")
6520 (match_operand:SF 1 "immediate_operand" ""))]
6521 "TARGET_SHMEDIA && reload_completed
6522 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6523 [(set (match_dup 3) (match_dup 2))]
6527 REAL_VALUE_TYPE value;
6529 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6530 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6531 operands[2] = GEN_INT (values);
6533 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6536 (define_insn "movsf_i"
6537 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6538 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6541 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6542 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6543 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6544 && (arith_reg_operand (operands[0], SFmode)
6545 || arith_reg_operand (operands[1], SFmode))"
6554 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6556 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6557 ;; update_flow_info would not know where to put REG_EQUAL notes
6558 ;; when the destination changes mode.
6559 (define_insn "movsf_ie"
6560 [(set (match_operand:SF 0 "general_movdst_operand"
6561 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6562 (match_operand:SF 1 "general_movsrc_operand"
6563 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6564 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
6565 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6568 && (arith_reg_operand (operands[0], SFmode)
6569 || arith_reg_operand (operands[1], SFmode)
6570 || arith_reg_operand (operands[3], SImode)
6571 || (fpul_operand (operands[0], SFmode)
6572 && memory_operand (operands[1], SFmode)
6573 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6574 || (fpul_operand (operands[1], SFmode)
6575 && memory_operand (operands[0], SFmode)
6576 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6596 ! move optimized away"
6597 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6598 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6599 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6600 (set_attr_alternative "length"
6607 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6608 (const_int 4) (const_int 2))
6610 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6611 (const_int 4) (const_int 2))
6624 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6625 (const_string "single")
6626 (const_string "none")))])
6629 [(set (match_operand:SF 0 "register_operand" "")
6630 (match_operand:SF 1 "register_operand" ""))
6631 (use (match_operand:PSI 2 "fpscr_operand" ""))
6632 (clobber (reg:SI FPUL_REG))]
6634 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6636 (clobber (scratch:SI))])
6637 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6639 (clobber (scratch:SI))])]
6642 (define_expand "movsf"
6643 [(set (match_operand:SF 0 "general_movdst_operand" "")
6644 (match_operand:SF 1 "general_movsrc_operand" ""))]
6648 if (prepare_move_operands (operands, SFmode))
6652 if (TARGET_SHMEDIA_FPU)
6653 emit_insn (gen_movsf_media (operands[0], operands[1]));
6655 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6660 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6665 (define_insn "mov_nop"
6666 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6669 [(set_attr "length" "0")
6670 (set_attr "type" "nil")])
6672 (define_expand "reload_insf__frn"
6673 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6674 (match_operand:SF 1 "immediate_operand" "FQ"))
6675 (use (reg:PSI FPSCR_REG))
6676 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6680 (define_expand "reload_insi__i_fpul"
6681 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6682 (match_operand:SI 1 "immediate_operand" "i"))
6683 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6687 (define_expand "ptabs"
6688 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6692 if (!TARGET_PT_FIXED)
6694 rtx eq = operands[1];
6696 /* ??? For canonical RTL we really should remove any CONST from EQ
6697 before wrapping it in the AND, and finally wrap the EQ into a
6698 const if is constant. However, for reload we must expose the
6699 input register or symbolic constant, and we can't have
6700 different insn structures outside of the operands for different
6701 alternatives of the same pattern. */
6702 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6705 = (gen_rtx_IF_THEN_ELSE
6708 gen_rtx_MEM (PDImode, operands[1]),
6709 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6710 PDImode, operands[1])));
6714 ;; expanded by ptabs expander.
6715 (define_insn "*extendsipdi_media"
6716 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6717 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6721 (mem:PDI (match_dup 1))
6722 (sign_extend:PDI (match_dup 1))))]
6723 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6727 [(set_attr "type" "ptabs_media,pt_media")
6728 (set_attr "length" "4,*")])
6730 (define_insn "*truncdipdi_media"
6731 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6732 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6736 (mem:PDI (match_dup 1))
6737 (truncate:PDI (match_dup 1))))]
6738 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6742 [(set_attr "type" "ptabs_media,pt_media")
6743 (set_attr "length" "4,*")])
6745 (define_insn "*movsi_y"
6746 [(set (match_operand:SI 0 "register_operand" "=y,y")
6747 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6748 (clobber (match_scratch:SI 2 "=&z,r"))]
6750 && (reload_in_progress || reload_completed)"
6752 [(set_attr "length" "4")
6753 (set_attr "type" "pcload,move")])
6756 [(set (match_operand:SI 0 "register_operand" "")
6757 (match_operand:SI 1 "immediate_operand" ""))
6758 (clobber (match_operand:SI 2 "register_operand" ""))]
6760 [(set (match_dup 2) (match_dup 1))
6761 (set (match_dup 0) (match_dup 2))]
6765 [(set (match_operand:SI 0 "register_operand" "")
6766 (match_operand:SI 1 "memory_operand" ""))
6767 (clobber (reg:SI R0_REG))]
6769 [(set (match_dup 0) (match_dup 1))]
6772 ;; ------------------------------------------------------------------------
6773 ;; Define the real conditional branch instructions.
6774 ;; ------------------------------------------------------------------------
6776 (define_insn "branch_true"
6777 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6778 (label_ref (match_operand 0 "" ""))
6781 "* return output_branch (1, insn, operands);"
6782 [(set_attr "type" "cbranch")])
6784 (define_insn "branch_false"
6785 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6786 (label_ref (match_operand 0 "" ""))
6789 "* return output_branch (0, insn, operands);"
6790 [(set_attr "type" "cbranch")])
6792 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6793 ;; which destination is too far away.
6794 ;; The const_int_operand is distinct for each branch target; it avoids
6795 ;; unwanted matches with redundant_insn.
6796 (define_insn "block_branch_redirect"
6797 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6800 [(set_attr "length" "0")])
6802 ;; This one has the additional purpose to record a possible scratch register
6803 ;; for the following branch.
6804 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6805 ;; because the insn then might be deemed dead and deleted. And we can't
6806 ;; make the use in the jump insn explicit because that would disable
6807 ;; delay slot scheduling from the target.
6808 (define_insn "indirect_jump_scratch"
6809 [(set (match_operand:SI 0 "register_operand" "=r")
6810 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6811 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6814 [(set_attr "length" "0")])
6816 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6817 ;; being pulled into the delay slot of a condbranch that has been made to
6818 ;; jump around the unconditional jump because it was out of range.
6819 (define_insn "stuff_delay_slot"
6821 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6822 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6825 [(set_attr "length" "0")
6826 (set_attr "cond_delay_slot" "yes")])
6828 ;; Conditional branch insns
6830 (define_expand "beq_media"
6832 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6833 (match_operand:DI 2 "arith_operand" "r,I06"))
6834 (match_operand 0 "" "")
6837 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6839 (define_insn "*beq_media_i"
6841 (if_then_else (match_operator 3 "equality_comparison_operator"
6842 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6843 (match_operand:DI 2 "arith_operand" "r,I06")])
6844 (match_operand 0 "target_operand" "b,b")
6849 b%o3i%' %1, %2, %0%>"
6850 [(set_attr "type" "cbranch_media")])
6852 (define_insn "*beq_media_i32"
6854 (if_then_else (match_operator 3 "equality_comparison_operator"
6855 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6856 (match_operand:SI 2 "arith_operand" "r,I06")])
6857 (match_operand 0 "target_operand" "b,b")
6862 b%o3i%' %1, %2, %0%>"
6863 [(set_attr "type" "cbranch_media")])
6865 (define_expand "bne_media"
6867 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6868 (match_operand:DI 2 "arith_operand" "r,I06"))
6869 (match_operand 0 "" "")
6872 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6874 (define_expand "bgt_media"
6876 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6877 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6878 (match_operand 0 "" "")
6881 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6883 (define_expand "bge_media"
6885 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6886 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6887 (match_operand 0 "" "")
6890 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6892 (define_expand "bgtu_media"
6894 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6895 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6896 (match_operand 0 "" "")
6899 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6901 (define_expand "bgeu_media"
6903 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6904 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6905 (match_operand 0 "" "")
6908 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6910 (define_insn "*bgt_media_i"
6912 (if_then_else (match_operator 3 "greater_comparison_operator"
6913 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6914 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6915 (match_operand 0 "target_operand" "b")
6918 "b%o3%' %N1, %N2, %0%>"
6919 [(set_attr "type" "cbranch_media")])
6921 (define_insn "*bgt_media_i32"
6923 (if_then_else (match_operator 3 "greater_comparison_operator"
6924 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6925 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6926 (match_operand 0 "target_operand" "b")
6929 "b%o3%' %N1, %N2, %0%>"
6930 [(set_attr "type" "cbranch_media")])
6932 ;; These are only needed to make invert_jump() happy - otherwise, jump
6933 ;; optimization will be silently disabled.
6934 (define_insn "*blt_media_i"
6936 (if_then_else (match_operator 3 "less_comparison_operator"
6937 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6938 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6939 (match_operand 0 "target_operand" "b")
6942 "b%o3%' %N2, %N1, %0%>"
6943 [(set_attr "type" "cbranch_media")])
6945 (define_insn "*blt_media_i32"
6947 (if_then_else (match_operator 3 "less_comparison_operator"
6948 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6949 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6950 (match_operand 0 "target_operand" "b")
6953 "b%o3%' %N2, %N1, %0%>"
6954 [(set_attr "type" "cbranch_media")])
6956 (define_expand "beq"
6958 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6959 (label_ref (match_operand 0 "" ""))
6966 enum machine_mode mode = GET_MODE (sh_compare_op0);
6968 if (mode != DImode && mode != SImode)
6970 rtx tmp = gen_reg_rtx (DImode);
6972 emit_insn (gen_seq (tmp));
6973 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6977 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6978 if (CONSTANT_P (sh_compare_op1)
6979 && (! satisfies_constraint_I06 (sh_compare_op1)))
6980 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6981 emit_jump_insn (gen_beq_media (operands[0],
6982 sh_compare_op0, sh_compare_op1));
6986 from_compare (operands, EQ);
6989 (define_expand "bne"
6991 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6992 (label_ref (match_operand 0 "" ""))
6999 enum machine_mode mode = GET_MODE (sh_compare_op0);
7001 if (mode != DImode && mode != SImode)
7003 rtx tmp = gen_reg_rtx (DImode);
7005 emit_insn (gen_seq (tmp));
7006 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7010 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7011 if (CONSTANT_P (sh_compare_op1)
7012 && (! satisfies_constraint_I06 (sh_compare_op1)))
7013 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7014 emit_jump_insn (gen_bne_media (operands[0],
7015 sh_compare_op0, sh_compare_op1));
7019 from_compare (operands, EQ);
7022 (define_expand "bgt"
7024 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7025 (label_ref (match_operand 0 "" ""))
7032 enum machine_mode mode = GET_MODE (sh_compare_op0);
7034 if (mode != DImode && mode != SImode)
7036 rtx tmp = gen_reg_rtx (DImode);
7038 emit_insn (gen_sgt (tmp));
7039 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7043 if (sh_compare_op0 != const0_rtx)
7044 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7045 if (sh_compare_op1 != const0_rtx)
7046 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7047 emit_jump_insn (gen_bgt_media (operands[0],
7048 sh_compare_op0, sh_compare_op1));
7052 from_compare (operands, GT);
7055 (define_expand "blt"
7057 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7058 (label_ref (match_operand 0 "" ""))
7065 enum machine_mode mode = GET_MODE (sh_compare_op0);
7067 if (mode != DImode && mode != SImode)
7069 rtx tmp = gen_reg_rtx (DImode);
7071 emit_insn (gen_slt (tmp));
7072 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7076 if (sh_compare_op0 != const0_rtx)
7077 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7078 if (sh_compare_op1 != const0_rtx)
7079 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7080 emit_jump_insn (gen_bgt_media (operands[0],
7081 sh_compare_op1, sh_compare_op0));
7085 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7087 rtx tmp = sh_compare_op0;
7088 sh_compare_op0 = sh_compare_op1;
7089 sh_compare_op1 = tmp;
7090 emit_insn (gen_bgt (operands[0]));
7093 from_compare (operands, GE);
7096 (define_expand "ble"
7098 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7099 (label_ref (match_operand 0 "" ""))
7106 enum machine_mode mode = GET_MODE (sh_compare_op0);
7108 if (mode != DImode && mode != SImode)
7110 rtx tmp = gen_reg_rtx (DImode);
7112 emit_insn (gen_sle (tmp));
7113 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7117 if (sh_compare_op0 != const0_rtx)
7118 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7119 if (sh_compare_op1 != const0_rtx)
7120 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7121 emit_jump_insn (gen_bge_media (operands[0],
7122 sh_compare_op1, sh_compare_op0));
7128 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7130 rtx tmp = sh_compare_op0;
7131 sh_compare_op0 = sh_compare_op1;
7132 sh_compare_op1 = tmp;
7133 emit_insn (gen_bge (operands[0]));
7136 from_compare (operands, GT);
7139 (define_expand "bge"
7141 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7142 (label_ref (match_operand 0 "" ""))
7149 enum machine_mode mode = GET_MODE (sh_compare_op0);
7151 if (mode != DImode && mode != SImode)
7153 rtx tmp = gen_reg_rtx (DImode);
7155 emit_insn (gen_sge (tmp));
7156 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7160 if (sh_compare_op0 != const0_rtx)
7161 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7162 if (sh_compare_op1 != const0_rtx)
7163 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7164 emit_jump_insn (gen_bge_media (operands[0],
7165 sh_compare_op0, sh_compare_op1));
7171 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7173 rtx tmp = sh_compare_op0;
7174 sh_compare_op0 = sh_compare_op1;
7175 sh_compare_op1 = tmp;
7176 emit_insn (gen_ble (operands[0]));
7179 from_compare (operands, GE);
7182 (define_expand "bgtu"
7184 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7185 (label_ref (match_operand 0 "" ""))
7192 enum machine_mode mode = GET_MODE (sh_compare_op0);
7194 if (sh_compare_op0 != const0_rtx)
7195 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7196 if (sh_compare_op1 != const0_rtx)
7197 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7198 emit_jump_insn (gen_bgtu_media (operands[0],
7199 sh_compare_op0, sh_compare_op1));
7203 from_compare (operands, GTU);
7206 (define_expand "bltu"
7208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7209 (label_ref (match_operand 0 "" ""))
7216 enum machine_mode mode = GET_MODE (sh_compare_op0);
7218 if (sh_compare_op0 != const0_rtx)
7219 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7220 if (sh_compare_op1 != const0_rtx)
7221 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7222 emit_jump_insn (gen_bgtu_media (operands[0],
7223 sh_compare_op1, sh_compare_op0));
7227 from_compare (operands, GEU);
7230 (define_expand "bgeu"
7232 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7233 (label_ref (match_operand 0 "" ""))
7240 enum machine_mode mode = GET_MODE (sh_compare_op0);
7242 if (sh_compare_op0 != const0_rtx)
7243 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7244 if (sh_compare_op1 != const0_rtx)
7245 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7246 emit_jump_insn (gen_bgeu_media (operands[0],
7247 sh_compare_op0, sh_compare_op1));
7251 from_compare (operands, GEU);
7254 (define_expand "bleu"
7256 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7257 (label_ref (match_operand 0 "" ""))
7264 enum machine_mode mode = GET_MODE (sh_compare_op0);
7266 if (sh_compare_op0 != const0_rtx)
7267 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7268 if (sh_compare_op1 != const0_rtx)
7269 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7270 emit_jump_insn (gen_bgeu_media (operands[0],
7271 sh_compare_op1, sh_compare_op0));
7275 from_compare (operands, GTU);
7278 (define_expand "bunordered"
7279 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7281 (if_then_else (ne (match_dup 1) (const_int 0))
7282 (match_operand 0 "" "")
7287 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7288 operands[1] = gen_reg_rtx (SImode);
7289 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7290 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7293 ;; combiner splitter for test-and-branch on single bit in register. This
7294 ;; is endian dependent because the non-paradoxical subreg looks different
7299 (match_operator 3 "equality_comparison_operator"
7300 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7301 "extend_reg_operand" "")
7305 "const_int_operand" "")) 0)
7307 (match_operand 0 "target_operand" "")
7309 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7310 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7311 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7312 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7316 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7317 operands[6] = (GET_CODE (operands[3]) == EQ
7318 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7319 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7322 ; operand 0 is the loop count pseudo register
7323 ; operand 1 is the number of loop iterations or 0 if it is unknown
7324 ; operand 2 is the maximum number of loop iterations
7325 ; operand 3 is the number of levels of enclosed loops
7326 ; operand 4 is the label to jump to at the top of the loop
7328 (define_expand "doloop_end"
7329 [(parallel [(set (pc) (if_then_else
7330 (ne:SI (match_operand:SI 0 "" "")
7332 (label_ref (match_operand 4 "" ""))
7335 (plus:SI (match_dup 0) (const_int -1)))
7336 (clobber (reg:SI T_REG))])]
7340 if (GET_MODE (operands[0]) != SImode)
7345 (define_insn_and_split "doloop_end_split"
7347 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7349 (label_ref (match_operand 1 "" ""))
7352 (plus (match_dup 0) (const_int -1)))
7353 (clobber (reg:SI T_REG))]
7357 [(parallel [(set (reg:SI T_REG)
7358 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7360 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7361 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7362 (label_ref (match_operand 1 "" ""))
7365 [(set_attr "type" "cbranch")])
7368 ;; ------------------------------------------------------------------------
7369 ;; Jump and linkage insns
7370 ;; ------------------------------------------------------------------------
7372 (define_insn "jump_compact"
7374 (label_ref (match_operand 0 "" "")))]
7378 /* The length is 16 if the delay slot is unfilled. */
7379 if (get_attr_length(insn) > 4)
7380 return output_far_jump(insn, operands[0]);
7382 return \"bra %l0%#\";
7384 [(set_attr "type" "jump")
7385 (set_attr "needs_delay_slot" "yes")])
7387 ;; ??? It would be much saner to explicitly use the scratch register
7388 ;; in the jump insn, and have indirect_jump_scratch only set it,
7389 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7390 ;; from the target then, as it uses simplejump_p.
7391 ;;(define_insn "jump_compact_far"
7393 ;; (label_ref (match_operand 0 "" "")))
7394 ;; (use (match_operand 1 "register_operand" "r")]
7396 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7397 ;; [(set_attr "type" "jump")
7398 ;; (set_attr "needs_delay_slot" "yes")])
7400 (define_insn "jump_media"
7402 (match_operand 0 "target_operand" "b"))]
7405 [(set_attr "type" "jump_media")])
7407 (define_expand "jump"
7409 (label_ref (match_operand 0 "" "")))]
7414 emit_jump_insn (gen_jump_compact (operands[0]));
7415 else if (TARGET_SHMEDIA)
7417 if (reload_in_progress || reload_completed)
7419 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7425 (define_insn "force_mode_for_call"
7426 [(use (reg:PSI FPSCR_REG))]
7429 [(set_attr "length" "0")
7430 (set (attr "fp_mode")
7431 (if_then_else (eq_attr "fpu_single" "yes")
7432 (const_string "single") (const_string "double")))])
7434 (define_insn "calli"
7435 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7436 (match_operand 1 "" ""))
7437 (use (reg:PSI FPSCR_REG))
7438 (clobber (reg:SI PR_REG))]
7441 [(set_attr "type" "call")
7442 (set (attr "fp_mode")
7443 (if_then_else (eq_attr "fpu_single" "yes")
7444 (const_string "single") (const_string "double")))
7445 (set_attr "needs_delay_slot" "yes")
7446 (set_attr "fp_set" "unknown")])
7448 ;; This is a pc-rel call, using bsrf, for use with PIC.
7450 (define_insn "calli_pcrel"
7451 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7452 (match_operand 1 "" ""))
7453 (use (reg:PSI FPSCR_REG))
7454 (use (reg:SI PIC_REG))
7455 (use (match_operand 2 "" ""))
7456 (clobber (reg:SI PR_REG))]
7459 [(set_attr "type" "call")
7460 (set (attr "fp_mode")
7461 (if_then_else (eq_attr "fpu_single" "yes")
7462 (const_string "single") (const_string "double")))
7463 (set_attr "needs_delay_slot" "yes")
7464 (set_attr "fp_set" "unknown")])
7466 (define_insn_and_split "call_pcrel"
7467 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7468 (match_operand 1 "" ""))
7469 (use (reg:PSI FPSCR_REG))
7470 (use (reg:SI PIC_REG))
7471 (clobber (reg:SI PR_REG))
7472 (clobber (match_scratch:SI 2 "=r"))]
7479 rtx lab = PATTERN (gen_call_site ());
7481 if (SYMBOL_REF_LOCAL_P (operands[0]))
7482 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7484 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7485 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7488 [(set_attr "type" "call")
7489 (set (attr "fp_mode")
7490 (if_then_else (eq_attr "fpu_single" "yes")
7491 (const_string "single") (const_string "double")))
7492 (set_attr "needs_delay_slot" "yes")
7493 (set_attr "fp_set" "unknown")])
7495 (define_insn "call_compact"
7496 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7497 (match_operand 1 "" ""))
7498 (match_operand 2 "immediate_operand" "n")
7499 (use (reg:SI R0_REG))
7500 (use (reg:SI R1_REG))
7501 (use (reg:PSI FPSCR_REG))
7502 (clobber (reg:SI PR_REG))]
7503 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7505 [(set_attr "type" "call")
7506 (set (attr "fp_mode")
7507 (if_then_else (eq_attr "fpu_single" "yes")
7508 (const_string "single") (const_string "double")))
7509 (set_attr "needs_delay_slot" "yes")])
7511 (define_insn "call_compact_rettramp"
7512 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7513 (match_operand 1 "" ""))
7514 (match_operand 2 "immediate_operand" "n")
7515 (use (reg:SI R0_REG))
7516 (use (reg:SI R1_REG))
7517 (use (reg:PSI FPSCR_REG))
7518 (clobber (reg:SI R10_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7528 (define_insn "call_media"
7529 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7530 (match_operand 1 "" ""))
7531 (clobber (reg:DI PR_MEDIA_REG))]
7534 [(set_attr "type" "jump_media")])
7536 (define_insn "call_valuei"
7537 [(set (match_operand 0 "" "=rf")
7538 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7539 (match_operand 2 "" "")))
7540 (use (reg:PSI FPSCR_REG))
7541 (clobber (reg:SI PR_REG))]
7544 [(set_attr "type" "call")
7545 (set (attr "fp_mode")
7546 (if_then_else (eq_attr "fpu_single" "yes")
7547 (const_string "single") (const_string "double")))
7548 (set_attr "needs_delay_slot" "yes")
7549 (set_attr "fp_set" "unknown")])
7551 (define_insn "call_valuei_pcrel"
7552 [(set (match_operand 0 "" "=rf")
7553 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7554 (match_operand 2 "" "")))
7555 (use (reg:PSI FPSCR_REG))
7556 (use (reg:SI PIC_REG))
7557 (use (match_operand 3 "" ""))
7558 (clobber (reg:SI PR_REG))]
7561 [(set_attr "type" "call")
7562 (set (attr "fp_mode")
7563 (if_then_else (eq_attr "fpu_single" "yes")
7564 (const_string "single") (const_string "double")))
7565 (set_attr "needs_delay_slot" "yes")
7566 (set_attr "fp_set" "unknown")])
7568 (define_insn_and_split "call_value_pcrel"
7569 [(set (match_operand 0 "" "=rf")
7570 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7571 (match_operand 2 "" "")))
7572 (use (reg:PSI FPSCR_REG))
7573 (use (reg:SI PIC_REG))
7574 (clobber (reg:SI PR_REG))
7575 (clobber (match_scratch:SI 3 "=r"))]
7582 rtx lab = PATTERN (gen_call_site ());
7584 if (SYMBOL_REF_LOCAL_P (operands[1]))
7585 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7587 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7588 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7589 operands[2], copy_rtx (lab)));
7592 [(set_attr "type" "call")
7593 (set (attr "fp_mode")
7594 (if_then_else (eq_attr "fpu_single" "yes")
7595 (const_string "single") (const_string "double")))
7596 (set_attr "needs_delay_slot" "yes")
7597 (set_attr "fp_set" "unknown")])
7599 (define_insn "call_value_compact"
7600 [(set (match_operand 0 "" "=rf")
7601 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7602 (match_operand 2 "" "")))
7603 (match_operand 3 "immediate_operand" "n")
7604 (use (reg:SI R0_REG))
7605 (use (reg:SI R1_REG))
7606 (use (reg:PSI FPSCR_REG))
7607 (clobber (reg:SI PR_REG))]
7608 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7610 [(set_attr "type" "call")
7611 (set (attr "fp_mode")
7612 (if_then_else (eq_attr "fpu_single" "yes")
7613 (const_string "single") (const_string "double")))
7614 (set_attr "needs_delay_slot" "yes")])
7616 (define_insn "call_value_compact_rettramp"
7617 [(set (match_operand 0 "" "=rf")
7618 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7619 (match_operand 2 "" "")))
7620 (match_operand 3 "immediate_operand" "n")
7621 (use (reg:SI R0_REG))
7622 (use (reg:SI R1_REG))
7623 (use (reg:PSI FPSCR_REG))
7624 (clobber (reg:SI R10_REG))
7625 (clobber (reg:SI PR_REG))]
7626 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7628 [(set_attr "type" "call")
7629 (set (attr "fp_mode")
7630 (if_then_else (eq_attr "fpu_single" "yes")
7631 (const_string "single") (const_string "double")))
7632 (set_attr "needs_delay_slot" "yes")])
7634 (define_insn "call_value_media"
7635 [(set (match_operand 0 "" "=rf")
7636 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7637 (match_operand 2 "" "")))
7638 (clobber (reg:DI PR_MEDIA_REG))]
7641 [(set_attr "type" "jump_media")])
7643 (define_expand "call"
7644 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7645 (match_operand 1 "" ""))
7646 (match_operand 2 "" "")
7647 (use (reg:PSI FPSCR_REG))
7648 (clobber (reg:SI PR_REG))])]
7654 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7655 emit_call_insn (gen_call_media (operands[0], operands[1]));
7658 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7660 rtx cookie_rtx = operands[2];
7661 long cookie = INTVAL (cookie_rtx);
7662 rtx func = XEXP (operands[0], 0);
7667 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7669 rtx reg = gen_reg_rtx (Pmode);
7671 emit_insn (gen_symGOTPLT2reg (reg, func));
7675 func = legitimize_pic_address (func, Pmode, 0);
7678 r0 = gen_rtx_REG (SImode, R0_REG);
7679 r1 = gen_rtx_REG (SImode, R1_REG);
7681 /* Since such a call function may use all call-clobbered
7682 registers, we force a mode switch earlier, so that we don't
7683 run out of registers when adjusting fpscr for the call. */
7684 emit_insn (gen_force_mode_for_call ());
7687 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7689 operands[0] = force_reg (SImode, operands[0]);
7691 emit_move_insn (r0, func);
7692 emit_move_insn (r1, cookie_rtx);
7694 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7695 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7698 emit_call_insn (gen_call_compact (operands[0], operands[1],
7703 else if (TARGET_SHCOMPACT && flag_pic
7704 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7705 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7707 rtx reg = gen_reg_rtx (Pmode);
7709 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7710 XEXP (operands[0], 0) = reg;
7712 if (flag_pic && TARGET_SH2
7713 && GET_CODE (operands[0]) == MEM
7714 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7716 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7721 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7722 operands[1] = operands[2];
7725 emit_call_insn (gen_calli (operands[0], operands[1]));
7729 (define_insn "call_pop_compact"
7730 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7731 (match_operand 1 "" ""))
7732 (match_operand 2 "immediate_operand" "n")
7733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7734 (match_operand 3 "immediate_operand" "n")))
7735 (use (reg:SI R0_REG))
7736 (use (reg:SI R1_REG))
7737 (use (reg:PSI FPSCR_REG))
7738 (clobber (reg:SI PR_REG))]
7739 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7741 [(set_attr "type" "call")
7742 (set (attr "fp_mode")
7743 (if_then_else (eq_attr "fpu_single" "yes")
7744 (const_string "single") (const_string "double")))
7745 (set_attr "needs_delay_slot" "yes")])
7747 (define_insn "call_pop_compact_rettramp"
7748 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7749 (match_operand 1 "" ""))
7750 (match_operand 2 "immediate_operand" "n")
7751 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7752 (match_operand 3 "immediate_operand" "n")))
7753 (use (reg:SI R0_REG))
7754 (use (reg:SI R1_REG))
7755 (use (reg:PSI FPSCR_REG))
7756 (clobber (reg:SI R10_REG))
7757 (clobber (reg:SI PR_REG))]
7758 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7760 [(set_attr "type" "call")
7761 (set (attr "fp_mode")
7762 (if_then_else (eq_attr "fpu_single" "yes")
7763 (const_string "single") (const_string "double")))
7764 (set_attr "needs_delay_slot" "yes")])
7766 (define_expand "call_pop"
7767 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7768 (match_operand 1 "" ""))
7769 (match_operand 2 "" "")
7770 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7771 (match_operand 3 "" "")))])]
7780 gcc_assert (operands[2] && INTVAL (operands[2]));
7781 cookie_rtx = operands[2];
7782 cookie = INTVAL (cookie_rtx);
7783 func = XEXP (operands[0], 0);
7787 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7789 rtx reg = gen_reg_rtx (Pmode);
7790 emit_insn (gen_symGOTPLT2reg (reg, func));
7794 func = legitimize_pic_address (func, Pmode, 0);
7797 r0 = gen_rtx_REG (SImode, R0_REG);
7798 r1 = gen_rtx_REG (SImode, R1_REG);
7800 /* Since such a call function may use all call-clobbered
7801 registers, we force a mode switch earlier, so that we don't
7802 run out of registers when adjusting fpscr for the call. */
7803 emit_insn (gen_force_mode_for_call ());
7805 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7807 operands[0] = force_reg (SImode, operands[0]);
7809 emit_move_insn (r0, func);
7810 emit_move_insn (r1, cookie_rtx);
7812 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7813 emit_call_insn (gen_call_pop_compact_rettramp
7814 (operands[0], operands[1], operands[2], operands[3]));
7816 emit_call_insn (gen_call_pop_compact
7817 (operands[0], operands[1], operands[2], operands[3]));
7822 (define_expand "call_value"
7823 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7824 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7825 (match_operand 2 "" "")))
7826 (match_operand 3 "" "")
7827 (use (reg:PSI FPSCR_REG))
7828 (clobber (reg:SI PR_REG))])]
7834 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7835 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7839 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7841 rtx cookie_rtx = operands[3];
7842 long cookie = INTVAL (cookie_rtx);
7843 rtx func = XEXP (operands[1], 0);
7848 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7850 rtx reg = gen_reg_rtx (Pmode);
7852 emit_insn (gen_symGOTPLT2reg (reg, func));
7856 func = legitimize_pic_address (func, Pmode, 0);
7859 r0 = gen_rtx_REG (SImode, R0_REG);
7860 r1 = gen_rtx_REG (SImode, R1_REG);
7862 /* Since such a call function may use all call-clobbered
7863 registers, we force a mode switch earlier, so that we don't
7864 run out of registers when adjusting fpscr for the call. */
7865 emit_insn (gen_force_mode_for_call ());
7868 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7870 operands[1] = force_reg (SImode, operands[1]);
7872 emit_move_insn (r0, func);
7873 emit_move_insn (r1, cookie_rtx);
7875 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7876 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7881 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7882 operands[2], operands[3]));
7886 else if (TARGET_SHCOMPACT && flag_pic
7887 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7888 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7890 rtx reg = gen_reg_rtx (Pmode);
7892 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7893 XEXP (operands[1], 0) = reg;
7895 if (flag_pic && TARGET_SH2
7896 && GET_CODE (operands[1]) == MEM
7897 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7899 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7904 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7906 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7910 (define_insn "sibcalli"
7911 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7912 (match_operand 1 "" ""))
7913 (use (reg:PSI FPSCR_REG))
7917 [(set_attr "needs_delay_slot" "yes")
7918 (set (attr "fp_mode")
7919 (if_then_else (eq_attr "fpu_single" "yes")
7920 (const_string "single") (const_string "double")))
7921 (set_attr "type" "jump_ind")])
7923 (define_insn "sibcalli_pcrel"
7924 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7925 (match_operand 1 "" ""))
7926 (use (match_operand 2 "" ""))
7927 (use (reg:PSI FPSCR_REG))
7931 [(set_attr "needs_delay_slot" "yes")
7932 (set (attr "fp_mode")
7933 (if_then_else (eq_attr "fpu_single" "yes")
7934 (const_string "single") (const_string "double")))
7935 (set_attr "type" "jump_ind")])
7937 ;; This uses an unspec to describe that the symbol_ref is very close.
7938 (define_insn "sibcalli_thunk"
7939 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7941 (match_operand 1 "" ""))
7942 (use (reg:PSI FPSCR_REG))
7946 [(set_attr "needs_delay_slot" "yes")
7947 (set (attr "fp_mode")
7948 (if_then_else (eq_attr "fpu_single" "yes")
7949 (const_string "single") (const_string "double")))
7950 (set_attr "type" "jump")
7951 (set_attr "length" "2")])
7953 (define_insn_and_split "sibcall_pcrel"
7954 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7955 (match_operand 1 "" ""))
7956 (use (reg:PSI FPSCR_REG))
7957 (clobber (match_scratch:SI 2 "=k"))
7965 rtx lab = PATTERN (gen_call_site ());
7968 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7969 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7971 SIBLING_CALL_P (call_insn) = 1;
7974 [(set_attr "needs_delay_slot" "yes")
7975 (set (attr "fp_mode")
7976 (if_then_else (eq_attr "fpu_single" "yes")
7977 (const_string "single") (const_string "double")))
7978 (set_attr "type" "jump_ind")])
7980 (define_insn "sibcall_compact"
7981 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7982 (match_operand 1 "" ""))
7984 (use (match_operand:SI 2 "register_operand" "z,x"))
7985 (use (reg:SI R1_REG))
7986 (use (reg:PSI FPSCR_REG))
7987 ;; We want to make sure the `x' above will only match MACH_REG
7988 ;; because sibcall_epilogue may clobber MACL_REG.
7989 (clobber (reg:SI MACL_REG))]
7993 jmp @%0\\n sts %2, r0"
7994 [(set_attr "needs_delay_slot" "yes,no")
7995 (set_attr "length" "2,4")
7996 (set (attr "fp_mode") (const_string "single"))
7997 (set_attr "type" "jump_ind")])
7999 (define_insn "sibcall_media"
8000 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8001 (match_operand 1 "" ""))
8002 (use (reg:SI PR_MEDIA_REG))
8006 [(set_attr "type" "jump_media")])
8008 (define_expand "sibcall"
8010 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8011 (match_operand 1 "" ""))
8012 (match_operand 2 "" "")
8013 (use (reg:PSI FPSCR_REG))
8020 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8021 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8024 else if (TARGET_SHCOMPACT && operands[2]
8025 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8027 rtx cookie_rtx = operands[2];
8028 long cookie = INTVAL (cookie_rtx);
8029 rtx func = XEXP (operands[0], 0);
8034 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8036 rtx reg = gen_reg_rtx (Pmode);
8038 emit_insn (gen_symGOT2reg (reg, func));
8042 func = legitimize_pic_address (func, Pmode, 0);
8045 /* FIXME: if we could tell whether all argument registers are
8046 already taken, we could decide whether to force the use of
8047 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8048 simple way to tell. We could use the CALL_COOKIE, but we
8049 can't currently tell a register used for regular argument
8050 passing from one that is unused. If we leave it up to reload
8051 to decide which register to use, it seems to always choose
8052 R0_REG, which leaves no available registers in SIBCALL_REGS
8053 to hold the address of the trampoline. */
8054 mach = gen_rtx_REG (SImode, MACH_REG);
8055 r1 = gen_rtx_REG (SImode, R1_REG);
8057 /* Since such a call function may use all call-clobbered
8058 registers, we force a mode switch earlier, so that we don't
8059 run out of registers when adjusting fpscr for the call. */
8060 emit_insn (gen_force_mode_for_call ());
8063 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8065 operands[0] = force_reg (SImode, operands[0]);
8067 /* We don't need a return trampoline, since the callee will
8068 return directly to the upper caller. */
8069 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8071 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8072 cookie_rtx = GEN_INT (cookie);
8075 emit_move_insn (mach, func);
8076 emit_move_insn (r1, cookie_rtx);
8078 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8081 else if (TARGET_SHCOMPACT && flag_pic
8082 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8083 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8085 rtx reg = gen_reg_rtx (Pmode);
8087 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8088 XEXP (operands[0], 0) = reg;
8090 if (flag_pic && TARGET_SH2
8091 && GET_CODE (operands[0]) == MEM
8092 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8093 /* The PLT needs the PIC register, but the epilogue would have
8094 to restore it, so we can only use PC-relative PIC calls for
8095 static functions. */
8096 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8098 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8102 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8104 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8108 (define_insn "sibcall_valuei"
8109 [(set (match_operand 0 "" "=rf")
8110 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8111 (match_operand 2 "" "")))
8112 (use (reg:PSI FPSCR_REG))
8116 [(set_attr "needs_delay_slot" "yes")
8117 (set (attr "fp_mode")
8118 (if_then_else (eq_attr "fpu_single" "yes")
8119 (const_string "single") (const_string "double")))
8120 (set_attr "type" "jump_ind")])
8122 (define_insn "sibcall_valuei_pcrel"
8123 [(set (match_operand 0 "" "=rf")
8124 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8125 (match_operand 2 "" "")))
8126 (use (match_operand 3 "" ""))
8127 (use (reg:PSI FPSCR_REG))
8131 [(set_attr "needs_delay_slot" "yes")
8132 (set (attr "fp_mode")
8133 (if_then_else (eq_attr "fpu_single" "yes")
8134 (const_string "single") (const_string "double")))
8135 (set_attr "type" "jump_ind")])
8137 (define_insn_and_split "sibcall_value_pcrel"
8138 [(set (match_operand 0 "" "=rf")
8139 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8140 (match_operand 2 "" "")))
8141 (use (reg:PSI FPSCR_REG))
8142 (clobber (match_scratch:SI 3 "=k"))
8150 rtx lab = PATTERN (gen_call_site ());
8153 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8154 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8158 SIBLING_CALL_P (call_insn) = 1;
8161 [(set_attr "needs_delay_slot" "yes")
8162 (set (attr "fp_mode")
8163 (if_then_else (eq_attr "fpu_single" "yes")
8164 (const_string "single") (const_string "double")))
8165 (set_attr "type" "jump_ind")])
8167 (define_insn "sibcall_value_compact"
8168 [(set (match_operand 0 "" "=rf,rf")
8169 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8170 (match_operand 2 "" "")))
8172 (use (match_operand:SI 3 "register_operand" "z,x"))
8173 (use (reg:SI R1_REG))
8174 (use (reg:PSI FPSCR_REG))
8175 ;; We want to make sure the `x' above will only match MACH_REG
8176 ;; because sibcall_epilogue may clobber MACL_REG.
8177 (clobber (reg:SI MACL_REG))]
8181 jmp @%1\\n sts %3, r0"
8182 [(set_attr "needs_delay_slot" "yes,no")
8183 (set_attr "length" "2,4")
8184 (set (attr "fp_mode") (const_string "single"))
8185 (set_attr "type" "jump_ind")])
8187 (define_insn "sibcall_value_media"
8188 [(set (match_operand 0 "" "=rf")
8189 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8190 (match_operand 2 "" "")))
8191 (use (reg:SI PR_MEDIA_REG))
8195 [(set_attr "type" "jump_media")])
8197 (define_expand "sibcall_value"
8199 [(set (match_operand 0 "arith_reg_operand" "")
8200 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8201 (match_operand 2 "" "")))
8202 (match_operand 3 "" "")
8203 (use (reg:PSI FPSCR_REG))
8210 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8211 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8215 else if (TARGET_SHCOMPACT && operands[3]
8216 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8218 rtx cookie_rtx = operands[3];
8219 long cookie = INTVAL (cookie_rtx);
8220 rtx func = XEXP (operands[1], 0);
8225 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8227 rtx reg = gen_reg_rtx (Pmode);
8229 emit_insn (gen_symGOT2reg (reg, func));
8233 func = legitimize_pic_address (func, Pmode, 0);
8236 /* FIXME: if we could tell whether all argument registers are
8237 already taken, we could decide whether to force the use of
8238 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8239 simple way to tell. We could use the CALL_COOKIE, but we
8240 can't currently tell a register used for regular argument
8241 passing from one that is unused. If we leave it up to reload
8242 to decide which register to use, it seems to always choose
8243 R0_REG, which leaves no available registers in SIBCALL_REGS
8244 to hold the address of the trampoline. */
8245 mach = gen_rtx_REG (SImode, MACH_REG);
8246 r1 = gen_rtx_REG (SImode, R1_REG);
8248 /* Since such a call function may use all call-clobbered
8249 registers, we force a mode switch earlier, so that we don't
8250 run out of registers when adjusting fpscr for the call. */
8251 emit_insn (gen_force_mode_for_call ());
8254 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8256 operands[1] = force_reg (SImode, operands[1]);
8258 /* We don't need a return trampoline, since the callee will
8259 return directly to the upper caller. */
8260 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8262 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8263 cookie_rtx = GEN_INT (cookie);
8266 emit_move_insn (mach, func);
8267 emit_move_insn (r1, cookie_rtx);
8269 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8270 operands[2], mach));
8273 else if (TARGET_SHCOMPACT && flag_pic
8274 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8275 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8277 rtx reg = gen_reg_rtx (Pmode);
8279 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8280 XEXP (operands[1], 0) = reg;
8282 if (flag_pic && TARGET_SH2
8283 && GET_CODE (operands[1]) == MEM
8284 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8285 /* The PLT needs the PIC register, but the epilogue would have
8286 to restore it, so we can only use PC-relative PIC calls for
8287 static functions. */
8288 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8290 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8291 XEXP (operands[1], 0),
8296 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8298 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8302 (define_insn "call_value_pop_compact"
8303 [(set (match_operand 0 "" "=rf")
8304 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8305 (match_operand 2 "" "")))
8306 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8307 (match_operand 4 "immediate_operand" "n")))
8308 (match_operand 3 "immediate_operand" "n")
8309 (use (reg:SI R0_REG))
8310 (use (reg:SI R1_REG))
8311 (use (reg:PSI FPSCR_REG))
8312 (clobber (reg:SI PR_REG))]
8313 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8315 [(set_attr "type" "call")
8316 (set (attr "fp_mode")
8317 (if_then_else (eq_attr "fpu_single" "yes")
8318 (const_string "single") (const_string "double")))
8319 (set_attr "needs_delay_slot" "yes")])
8321 (define_insn "call_value_pop_compact_rettramp"
8322 [(set (match_operand 0 "" "=rf")
8323 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8324 (match_operand 2 "" "")))
8325 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8326 (match_operand 4 "immediate_operand" "n")))
8327 (match_operand 3 "immediate_operand" "n")
8328 (use (reg:SI R0_REG))
8329 (use (reg:SI R1_REG))
8330 (use (reg:PSI FPSCR_REG))
8331 (clobber (reg:SI R10_REG))
8332 (clobber (reg:SI PR_REG))]
8333 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8335 [(set_attr "type" "call")
8336 (set (attr "fp_mode")
8337 (if_then_else (eq_attr "fpu_single" "yes")
8338 (const_string "single") (const_string "double")))
8339 (set_attr "needs_delay_slot" "yes")])
8341 (define_expand "call_value_pop"
8342 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8343 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8344 (match_operand 2 "" "")))
8345 (match_operand 3 "" "")
8346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8347 (match_operand 4 "" "")))])]
8356 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8357 cookie_rtx = operands[3];
8358 cookie = INTVAL (cookie_rtx);
8359 func = XEXP (operands[1], 0);
8363 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8365 rtx reg = gen_reg_rtx (Pmode);
8367 emit_insn (gen_symGOTPLT2reg (reg, func));
8371 func = legitimize_pic_address (func, Pmode, 0);
8374 r0 = gen_rtx_REG (SImode, R0_REG);
8375 r1 = gen_rtx_REG (SImode, R1_REG);
8377 /* Since such a call function may use all call-clobbered
8378 registers, we force a mode switch earlier, so that we don't
8379 run out of registers when adjusting fpscr for the call. */
8380 emit_insn (gen_force_mode_for_call ());
8382 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8384 operands[1] = force_reg (SImode, operands[1]);
8386 emit_move_insn (r0, func);
8387 emit_move_insn (r1, cookie_rtx);
8389 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8390 emit_call_insn (gen_call_value_pop_compact_rettramp
8391 (operands[0], operands[1], operands[2],
8392 operands[3], operands[4]));
8394 emit_call_insn (gen_call_value_pop_compact
8395 (operands[0], operands[1], operands[2],
8396 operands[3], operands[4]));
8401 (define_expand "sibcall_epilogue"
8406 sh_expand_epilogue (1);
8407 if (TARGET_SHCOMPACT)
8411 /* If epilogue clobbers r0, preserve it in macl. */
8412 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8413 if ((set = single_set (insn))
8414 && GET_CODE (SET_DEST (set)) == REG
8415 && REGNO (SET_DEST (set)) == R0_REG)
8417 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8418 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8420 /* We can't tell at this point whether the sibcall is a
8421 sibcall_compact and, if it is, whether it uses r0 or
8422 mach as operand 2, so let the instructions that
8423 preserve r0 be optimized away if r0 turns out to be
8425 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8426 emit_move_insn (r0, tmp);
8433 (define_insn "indirect_jump_compact"
8435 (match_operand:SI 0 "arith_reg_operand" "r"))]
8438 [(set_attr "needs_delay_slot" "yes")
8439 (set_attr "type" "jump_ind")])
8441 (define_expand "indirect_jump"
8443 (match_operand 0 "register_operand" ""))]
8447 if (GET_MODE (operands[0]) != Pmode)
8448 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8451 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8452 ;; which can be present in structured code from indirect jumps which can not
8453 ;; be present in structured code. This allows -fprofile-arcs to work.
8455 ;; For SH1 processors.
8456 (define_insn "casesi_jump_1"
8458 (match_operand:SI 0 "register_operand" "r"))
8459 (use (label_ref (match_operand 1 "" "")))]
8462 [(set_attr "needs_delay_slot" "yes")
8463 (set_attr "type" "jump_ind")])
8465 ;; For all later processors.
8466 (define_insn "casesi_jump_2"
8467 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8468 (label_ref (match_operand 1 "" ""))))
8469 (use (label_ref (match_operand 2 "" "")))]
8471 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8473 [(set_attr "needs_delay_slot" "yes")
8474 (set_attr "type" "jump_ind")])
8476 (define_insn "casesi_jump_media"
8477 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8478 (use (label_ref (match_operand 1 "" "")))]
8481 [(set_attr "type" "jump_media")])
8483 ;; Call subroutine returning any type.
8484 ;; ??? This probably doesn't work.
8486 (define_expand "untyped_call"
8487 [(parallel [(call (match_operand 0 "" "")
8489 (match_operand 1 "" "")
8490 (match_operand 2 "" "")])]
8491 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8496 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8498 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8500 rtx set = XVECEXP (operands[2], 0, i);
8501 emit_move_insn (SET_DEST (set), SET_SRC (set));
8504 /* The optimizer does not know that the call sets the function value
8505 registers we stored in the result block. We avoid problems by
8506 claiming that all hard registers are used and clobbered at this
8508 emit_insn (gen_blockage ());
8513 ;; ------------------------------------------------------------------------
8515 ;; ------------------------------------------------------------------------
8518 [(set (reg:SI T_REG)
8519 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8520 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8523 [(set_attr "type" "arith")])
8530 ;; Load address of a label. This is only generated by the casesi expand,
8531 ;; and by machine_dependent_reorg (fixing up fp moves).
8532 ;; This must use unspec, because this only works for labels that are
8536 [(set (reg:SI R0_REG)
8537 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8540 [(set_attr "in_delay_slot" "no")
8541 (set_attr "type" "arith")])
8543 ;; machine_dependent_reorg will make this a `mova'.
8544 (define_insn "mova_const"
8545 [(set (reg:SI R0_REG)
8546 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8549 [(set_attr "in_delay_slot" "no")
8550 (set_attr "type" "arith")])
8552 (define_expand "GOTaddr2picreg"
8553 [(set (reg:SI R0_REG)
8554 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8556 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8557 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8560 if (TARGET_VXWORKS_RTP)
8562 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8563 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8564 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8568 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8569 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8573 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8574 rtx pic = operands[0];
8575 rtx lab = PATTERN (gen_call_site ());
8578 equiv = operands[1];
8579 operands[1] = gen_rtx_MINUS (Pmode,
8583 gen_rtx_MINUS (Pmode,
8584 gen_rtx_CONST (Pmode,
8587 operands[1] = gen_sym2PIC (operands[1]);
8588 PUT_MODE (operands[1], Pmode);
8590 if (Pmode == SImode)
8592 emit_insn (gen_movsi_const (pic, operands[1]));
8593 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8597 emit_insn (gen_movdi_const (pic, operands[1]));
8598 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8601 insn = emit_move_insn (operands[0], tr);
8603 set_unique_reg_note (insn, REG_EQUAL, equiv);
8610 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8613 (define_expand "vxworks_picreg"
8614 [(set (reg:SI PIC_REG)
8615 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8616 (set (reg:SI R0_REG)
8617 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8618 (set (reg:SI PIC_REG)
8619 (mem:SI (reg:SI PIC_REG)))
8620 (set (reg:SI PIC_REG)
8621 (mem:SI (plus:SI (reg:SI PIC_REG)
8623 "TARGET_VXWORKS_RTP")
8626 [(set (match_operand 0 "target_reg_operand" "=b")
8627 (const (unspec [(match_operand 1 "" "Csy")]
8628 UNSPEC_DATALABEL)))]
8629 "TARGET_SHMEDIA && flag_pic
8630 && satisfies_constraint_Csy (operands[1])"
8631 "ptb/u datalabel %1, %0"
8632 [(set_attr "type" "ptabs_media")
8633 (set_attr "length" "*")])
8635 (define_insn "ptrel_si"
8636 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8637 (plus:SI (match_operand:SI 1 "register_operand" "r")
8639 (match_operand:SI 2 "" "")]
8641 "%O2: ptrel/u %1, %0"
8642 [(set_attr "type" "ptabs_media")])
8644 (define_insn "ptrel_di"
8645 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8646 (plus:DI (match_operand:DI 1 "register_operand" "r")
8648 (match_operand:DI 2 "" "")]
8650 "%O2: ptrel/u %1, %0"
8651 [(set_attr "type" "ptabs_media")])
8653 (define_expand "builtin_setjmp_receiver"
8654 [(match_operand 0 "" "")]
8658 emit_insn (gen_GOTaddr2picreg ());
8662 (define_expand "call_site"
8663 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8667 static HOST_WIDE_INT i = 0;
8668 operands[0] = GEN_INT (i);
8672 (define_expand "sym_label2reg"
8673 [(set (match_operand:SI 0 "" "")
8676 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8679 (match_operand:SI 2 "" "")
8683 (define_expand "symGOT_load"
8684 [(set (match_dup 2) (match_operand 1 "" ""))
8685 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8686 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8692 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8693 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8697 rtx reg = operands[2];
8699 if (Pmode == DImode)
8702 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8704 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8709 emit_insn (gen_movsi_const (reg, operands[1]));
8711 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8715 emit_move_insn (operands[2], operands[1]);
8717 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8719 gen_rtx_REG (Pmode, PIC_REG)));
8721 /* When stack protector inserts codes after the result is set to
8722 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8723 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8724 when rX is a GOT address for the guard symbol. Ugly but doesn't
8725 matter because this is a rare situation. */
8727 && flag_stack_protect
8728 && GET_CODE (operands[1]) == CONST
8729 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8730 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8731 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8732 \"__stack_chk_guard\") == 0)
8733 emit_insn (gen_blockage ());
8735 /* N.B. This is not constant for a GOTPLT relocation. */
8736 mem = gen_rtx_MEM (Pmode, operands[3]);
8737 MEM_NOTRAP_P (mem) = 1;
8738 /* ??? Should we have a special alias set for the GOT? */
8739 insn = emit_move_insn (operands[0], mem);
8741 set_unique_reg_note (insn, REG_EQUAL,
8742 XVECEXP (XEXP (operands[1], 0), 0, 0));
8747 (define_expand "sym2GOT"
8748 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8752 (define_expand "symGOT2reg"
8753 [(match_operand 0 "" "") (match_operand 1 "" "")]
8759 gotsym = gen_sym2GOT (operands[1]);
8760 PUT_MODE (gotsym, Pmode);
8761 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8763 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8768 (define_expand "symGOTPLT2reg"
8769 [(match_operand 0 "" "") (match_operand 1 "" "")]
8773 rtx pltsym = gen_rtx_CONST (Pmode,
8774 gen_rtx_UNSPEC (Pmode,
8775 gen_rtvec (1, operands[1]),
8777 emit_insn (gen_symGOT_load (operands[0], pltsym));
8781 (define_expand "sym2GOTOFF"
8782 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8786 (define_expand "symGOTOFF2reg"
8787 [(match_operand 0 "" "") (match_operand 1 "" "")]
8791 rtx gotoffsym, insn;
8792 rtx t = (!can_create_pseudo_p ()
8794 : gen_reg_rtx (GET_MODE (operands[0])));
8796 gotoffsym = gen_sym2GOTOFF (operands[1]);
8797 PUT_MODE (gotoffsym, Pmode);
8798 emit_move_insn (t, gotoffsym);
8799 insn = emit_move_insn (operands[0],
8800 gen_rtx_PLUS (Pmode, t,
8801 gen_rtx_REG (Pmode, PIC_REG)));
8803 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8808 (define_expand "symPLT_label2reg"
8809 [(set (match_operand:SI 0 "" "")
8812 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8816 (match_operand:SI 2 "" "")
8818 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8819 ;; Even though the PIC register is not really used by the call
8820 ;; sequence in which this is expanded, the PLT code assumes the PIC
8821 ;; register is set, so we must not skip its initialization. Since
8822 ;; we only use this expand as part of calling sequences, and never
8823 ;; to take the address of a function, this is the best point to
8824 ;; insert the (use). Using the PLT to take the address of a
8825 ;; function would be wrong, not only because the PLT entry could
8826 ;; then be called from a function that doesn't initialize the PIC
8827 ;; register to the proper GOT, but also because pointers to the
8828 ;; same function might not compare equal, should they be set by
8829 ;; different shared libraries.
8830 (use (reg:SI PIC_REG))]
8834 (define_expand "sym2PIC"
8835 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8839 ;; TLS code generation.
8840 ;; ??? this should be a define_insn_and_split
8841 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8842 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8845 (define_insn "tls_global_dynamic"
8846 [(set (match_operand:SI 0 "register_operand" "=&z")
8847 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8850 (use (reg:PSI FPSCR_REG))
8851 (use (reg:SI PIC_REG))
8852 (clobber (reg:SI PR_REG))
8853 (clobber (scratch:SI))]
8859 \\tmova\\t2f,r0\\n\\
8860 \\tmov.l\\t2f,r1\\n\\
8863 \\tadd\\tr12,r4\\n\\
8867 1:\\t.long\\t%a1@TLSGD\\n\\
8868 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8871 [(set_attr "type" "tls_load")
8872 (set_attr "length" "26")])
8874 (define_insn "tls_local_dynamic"
8875 [(set (match_operand:SI 0 "register_operand" "=&z")
8876 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8879 (use (reg:PSI FPSCR_REG))
8880 (use (reg:SI PIC_REG))
8881 (clobber (reg:SI PR_REG))
8882 (clobber (scratch:SI))]
8888 \\tmova\\t2f,r0\\n\\
8889 \\tmov.l\\t2f,r1\\n\\
8892 \\tadd\\tr12,r4\\n\\
8896 1:\\t.long\\t%a1@TLSLDM\\n\\
8897 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8900 [(set_attr "type" "tls_load")
8901 (set_attr "length" "26")])
8903 (define_expand "sym2DTPOFF"
8904 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8908 (define_expand "symDTPOFF2reg"
8909 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8913 rtx dtpoffsym, insn;
8914 rtx t = (!can_create_pseudo_p ()
8916 : gen_reg_rtx (GET_MODE (operands[0])));
8918 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8919 PUT_MODE (dtpoffsym, Pmode);
8920 emit_move_insn (t, dtpoffsym);
8921 insn = emit_move_insn (operands[0],
8922 gen_rtx_PLUS (Pmode, t, operands[2]));
8926 (define_expand "sym2GOTTPOFF"
8927 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8931 (define_insn "tls_initial_exec"
8932 [(set (match_operand:SI 0 "register_operand" "=&r")
8933 (unspec:SI [(match_operand:SI 1 "" "")]
8935 (use (reg:SI GBR_REG))
8936 (use (reg:SI PIC_REG))
8937 (clobber (reg:SI R0_REG))]
8943 \\tstc\\tgbr,%0\\n\\
8944 \\tmov.l\\t@(r0,r12),r0\\n\\
8948 1:\\t.long\\t%a1\\n\\
8951 [(set_attr "type" "tls_load")
8952 (set_attr "length" "16")])
8954 (define_expand "sym2TPOFF"
8955 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8959 (define_expand "symTPOFF2reg"
8960 [(match_operand 0 "" "") (match_operand 1 "" "")]
8966 tpoffsym = gen_sym2TPOFF (operands[1]);
8967 PUT_MODE (tpoffsym, Pmode);
8968 insn = emit_move_insn (operands[0], tpoffsym);
8972 (define_insn "load_gbr"
8973 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8974 (use (reg:SI GBR_REG))]
8977 [(set_attr "type" "tls_load")])
8979 ;; case instruction for switch statements.
8981 ;; Operand 0 is index
8982 ;; operand 1 is the minimum bound
8983 ;; operand 2 is the maximum bound - minimum bound + 1
8984 ;; operand 3 is CODE_LABEL for the table;
8985 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8987 (define_expand "casesi"
8988 [(match_operand:SI 0 "arith_reg_operand" "")
8989 (match_operand:SI 1 "arith_reg_operand" "")
8990 (match_operand:SI 2 "arith_reg_operand" "")
8991 (match_operand 3 "" "") (match_operand 4 "" "")]
8995 rtx reg = gen_reg_rtx (SImode);
8996 rtx reg2 = gen_reg_rtx (SImode);
8999 rtx reg = gen_reg_rtx (DImode);
9000 rtx reg2 = gen_reg_rtx (DImode);
9001 rtx reg3 = gen_reg_rtx (Pmode);
9002 rtx reg4 = gen_reg_rtx (Pmode);
9003 rtx reg5 = gen_reg_rtx (Pmode);
9006 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9007 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9008 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9010 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9011 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9012 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9013 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9014 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9015 (Pmode, operands[3])));
9016 /* Messy: can we subreg to clean this up? */
9017 if (Pmode == DImode)
9018 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9020 load = gen_casesi_load_media (reg4,
9021 gen_rtx_SUBREG (DImode, reg3, 0),
9023 PUT_MODE (SET_SRC (load), Pmode);
9025 /* ??? The following add could be eliminated if we used ptrel. */
9026 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9027 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9031 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9032 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9033 /* If optimizing, casesi_worker depends on the mode of the instruction
9034 before label it 'uses' - operands[3]. */
9035 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9037 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9039 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9041 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9042 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9043 operands[3], but to lab. We will fix this up in
9044 machine_dependent_reorg. */
9049 (define_expand "casesi_0"
9050 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9051 (set (match_dup 4) (minus:SI (match_dup 4)
9052 (match_operand:SI 1 "arith_operand" "")))
9054 (gtu:SI (match_dup 4)
9055 (match_operand:SI 2 "arith_reg_operand" "")))
9057 (if_then_else (ne (reg:SI T_REG)
9059 (label_ref (match_operand 3 "" ""))
9064 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9065 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9066 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9068 (define_insn "casesi_worker_0"
9069 [(set (match_operand:SI 0 "register_operand" "=r,r")
9070 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9071 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9072 (clobber (match_scratch:SI 3 "=X,1"))
9073 (clobber (match_scratch:SI 4 "=&z,z"))]
9078 [(set (match_operand:SI 0 "register_operand" "")
9079 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9080 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9081 (clobber (match_scratch:SI 3 ""))
9082 (clobber (match_scratch:SI 4 ""))]
9083 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9084 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9085 (parallel [(set (match_dup 0)
9086 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9087 (label_ref (match_dup 2))] UNSPEC_CASESI))
9088 (clobber (match_dup 3))])
9089 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9093 [(set (match_operand:SI 0 "register_operand" "")
9094 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9095 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9096 (clobber (match_scratch:SI 3 ""))
9097 (clobber (match_scratch:SI 4 ""))]
9098 "TARGET_SH2 && reload_completed"
9099 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9100 (parallel [(set (match_dup 0)
9101 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9102 (label_ref (match_dup 2))] UNSPEC_CASESI))
9103 (clobber (match_dup 3))])]
9104 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9106 (define_insn "casesi_worker_1"
9107 [(set (match_operand:SI 0 "register_operand" "=r,r")
9108 (unspec:SI [(reg:SI R0_REG)
9109 (match_operand:SI 1 "register_operand" "0,r")
9110 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9111 (clobber (match_scratch:SI 3 "=X,1"))]
9115 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9117 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9119 switch (GET_MODE (diff_vec))
9122 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9124 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9126 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9127 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9128 return \"mov.b @(r0,%1),%0\";
9133 [(set_attr "length" "4")])
9135 (define_insn "casesi_worker_2"
9136 [(set (match_operand:SI 0 "register_operand" "=r,r")
9137 (unspec:SI [(reg:SI R0_REG)
9138 (match_operand:SI 1 "register_operand" "0,r")
9139 (label_ref (match_operand 2 "" ""))
9140 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9141 (clobber (match_operand:SI 4 "" "=X,1"))]
9142 "TARGET_SH2 && reload_completed && flag_pic"
9145 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9148 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9150 switch (GET_MODE (diff_vec))
9153 output_asm_insn (\"shll2 %1\", operands);
9154 load = \"mov.l @(r0,%1),%0\"; break;
9156 output_asm_insn (\"add %1,%1\", operands);
9157 load = \"mov.w @(r0,%1),%0\"; break;
9159 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9160 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9162 load = \"mov.b @(r0,%1),%0\";
9167 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9170 [(set_attr "length" "8")])
9172 (define_insn "casesi_shift_media"
9173 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9174 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9175 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9180 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9182 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9184 switch (GET_MODE (diff_vec))
9187 return \"shlli %1, 2, %0\";
9189 return \"shlli %1, 1, %0\";
9191 if (rtx_equal_p (operands[0], operands[1]))
9193 return \"add %1, r63, %0\";
9198 [(set_attr "type" "arith_media")])
9200 (define_insn "casesi_load_media"
9201 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9202 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9203 (match_operand:DI 2 "arith_reg_operand" "r")
9204 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9208 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9210 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9212 switch (GET_MODE (diff_vec))
9215 return \"ldx.l %1, %2, %0\";
9218 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9219 return \"ldx.uw %1, %2, %0\";
9221 return \"ldx.w %1, %2, %0\";
9223 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9224 return \"ldx.ub %1, %2, %0\";
9225 return \"ldx.b %1, %2, %0\";
9230 [(set_attr "type" "load_media")])
9232 (define_expand "return"
9234 "reload_completed && ! sh_need_epilogue ()"
9239 emit_jump_insn (gen_return_media ());
9243 if (TARGET_SHCOMPACT
9244 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9246 emit_jump_insn (gen_shcompact_return_tramp ());
9251 (define_insn "*return_i"
9253 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9254 && (current_function_args_info.call_cookie
9255 & CALL_COOKIE_RET_TRAMP (1)))
9257 && lookup_attribute (\"trap_exit\",
9258 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9260 [(set_attr "type" "return")
9261 (set_attr "needs_delay_slot" "yes")])
9263 ;; trapa has no delay slot.
9264 (define_insn "*return_trapa"
9266 "TARGET_SH1 && !TARGET_SHCOMPACT
9267 && reload_completed"
9269 [(set_attr "type" "return")])
9271 (define_expand "shcompact_return_tramp"
9274 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9277 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9279 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9280 emit_jump_insn (gen_shcompact_return_tramp_i ());
9284 (define_insn "shcompact_return_tramp_i"
9285 [(parallel [(return) (use (reg:SI R0_REG))])]
9287 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9289 [(set_attr "type" "jump_ind")
9290 (set_attr "needs_delay_slot" "yes")])
9292 (define_insn "return_media_i"
9293 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9294 "TARGET_SHMEDIA && reload_completed"
9296 [(set_attr "type" "jump_media")])
9298 (define_insn "return_media_rte"
9300 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9302 [(set_attr "type" "jump_media")])
9304 (define_expand "return_media"
9306 "TARGET_SHMEDIA && reload_completed"
9309 int tr_regno = sh_media_register_for_return ();
9312 if (current_function_interrupt)
9314 emit_jump_insn (gen_return_media_rte ());
9319 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9321 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9323 tr = gen_rtx_REG (Pmode, tr_regno);
9324 emit_move_insn (tr, r18);
9327 tr = gen_rtx_REG (Pmode, tr_regno);
9329 emit_jump_insn (gen_return_media_i (tr));
9333 (define_insn "shcompact_preserve_incoming_args"
9334 [(set (match_operand:SI 0 "register_operand" "+r")
9335 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9338 [(set_attr "length" "0")])
9340 (define_insn "shcompact_incoming_args"
9341 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9342 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9343 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9344 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9345 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9346 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9347 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9349 (set (mem:BLK (reg:SI MACL_REG))
9350 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9351 (use (reg:SI R0_REG))
9352 (clobber (reg:SI R0_REG))
9353 (clobber (reg:SI MACL_REG))
9354 (clobber (reg:SI MACH_REG))
9355 (clobber (reg:SI PR_REG))]
9358 [(set_attr "needs_delay_slot" "yes")])
9360 (define_insn "shmedia_save_restore_regs_compact"
9361 [(set (reg:SI SP_REG)
9362 (plus:SI (reg:SI SP_REG)
9363 (match_operand:SI 0 "immediate_operand" "i")))
9364 (use (reg:SI R0_REG))
9365 (clobber (reg:SI PR_REG))]
9367 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9368 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9370 [(set_attr "needs_delay_slot" "yes")])
9372 (define_expand "prologue"
9375 "sh_expand_prologue (); DONE;")
9377 (define_expand "epilogue"
9382 sh_expand_epilogue (0);
9383 emit_jump_insn (gen_return ());
9387 (define_expand "eh_return"
9388 [(use (match_operand 0 "register_operand" ""))]
9391 rtx ra = operands[0];
9393 if (TARGET_SHMEDIA64)
9394 emit_insn (gen_eh_set_ra_di (ra));
9396 emit_insn (gen_eh_set_ra_si (ra));
9401 ;; Clobber the return address on the stack. We can't expand this
9402 ;; until we know where it will be put in the stack frame.
9404 (define_insn "eh_set_ra_si"
9405 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9407 (clobber (match_scratch:SI 1 "=&r"))]
9408 "! TARGET_SHMEDIA64"
9411 (define_insn "eh_set_ra_di"
9412 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9414 (clobber (match_scratch:DI 1 "=&r"))]
9419 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9421 (clobber (match_scratch 1 ""))]
9426 sh_set_return_address (operands[0], operands[1]);
9430 (define_insn "blockage"
9431 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9434 [(set_attr "length" "0")])
9436 ;; ------------------------------------------------------------------------
9438 ;; ------------------------------------------------------------------------
9441 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9442 (eq:SI (reg:SI T_REG) (const_int 1)))]
9445 [(set_attr "type" "arith")])
9447 (define_expand "seq"
9448 [(set (match_operand:SI 0 "arith_reg_dest" "")
9457 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9458 if (sh_compare_op1 != const0_rtx)
9459 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9460 ? GET_MODE (sh_compare_op0)
9461 : GET_MODE (sh_compare_op1),
9463 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9465 if (GET_MODE (operands[0]) != SImode)
9466 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9468 switch (GET_MODE (sh_compare_op0))
9471 emit_insn (gen_cmpeqsi_media (operands[0],
9472 sh_compare_op0, sh_compare_op1));
9476 emit_insn (gen_cmpeqdi_media (operands[0],
9477 sh_compare_op0, sh_compare_op1));
9481 if (! TARGET_SHMEDIA_FPU)
9483 emit_insn (gen_cmpeqsf_media (operands[0],
9484 sh_compare_op0, sh_compare_op1));
9488 if (! TARGET_SHMEDIA_FPU)
9490 emit_insn (gen_cmpeqdf_media (operands[0],
9491 sh_compare_op0, sh_compare_op1));
9501 if (GET_MODE (operands[0]) != SImode)
9502 reg = (!can_create_pseudo_p ()
9503 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9504 : gen_reg_rtx (SImode));
9506 switch (GET_MODE (sh_compare_op0))
9509 emit_insn (gen_cmpeqsi_media (reg,
9510 sh_compare_op0, sh_compare_op1));
9514 emit_insn (gen_cmpeqdi_media (reg,
9515 sh_compare_op0, sh_compare_op1));
9519 if (! TARGET_SHMEDIA_FPU)
9521 emit_insn (gen_cmpeqsf_media (reg,
9522 sh_compare_op0, sh_compare_op1));
9526 if (! TARGET_SHMEDIA_FPU)
9528 emit_insn (gen_cmpeqdf_media (reg,
9529 sh_compare_op0, sh_compare_op1));
9536 if (GET_MODE (operands[0]) == DImode)
9537 emit_insn (gen_extendsidi2 (operands[0], reg));
9541 if (sh_expand_t_scc (EQ, operands[0]))
9543 if (! currently_expanding_to_rtl)
9545 operands[1] = prepare_scc_operands (EQ);
9548 (define_expand "slt"
9549 [(set (match_operand:SI 0 "arith_reg_operand" "")
9558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9559 if (sh_compare_op1 != const0_rtx)
9560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9561 ? GET_MODE (sh_compare_op0)
9562 : GET_MODE (sh_compare_op1),
9566 if (GET_MODE (operands[0]) != SImode)
9567 reg = (!can_create_pseudo_p ()
9568 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9569 : gen_reg_rtx (SImode));
9571 switch (GET_MODE (sh_compare_op0))
9574 emit_insn (gen_cmpgtsi_media (reg,
9575 sh_compare_op1, sh_compare_op0));
9579 emit_insn (gen_cmpgtdi_media (reg,
9580 sh_compare_op1, sh_compare_op0));
9584 if (! TARGET_SHMEDIA_FPU)
9586 emit_insn (gen_cmpgtsf_media (reg,
9587 sh_compare_op1, sh_compare_op0));
9591 if (! TARGET_SHMEDIA_FPU)
9593 emit_insn (gen_cmpgtdf_media (reg,
9594 sh_compare_op1, sh_compare_op0));
9601 if (GET_MODE (operands[0]) == DImode)
9602 emit_insn (gen_extendsidi2 (operands[0], reg));
9606 if (! currently_expanding_to_rtl)
9608 operands[1] = prepare_scc_operands (LT);
9611 (define_expand "sle"
9612 [(match_operand:SI 0 "arith_reg_operand" "")]
9616 rtx tmp = sh_compare_op0;
9622 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9623 if (sh_compare_op1 != const0_rtx)
9624 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9625 ? GET_MODE (sh_compare_op0)
9626 : GET_MODE (sh_compare_op1),
9630 if (GET_MODE (operands[0]) != SImode)
9631 reg = (!can_create_pseudo_p ()
9632 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9633 : gen_reg_rtx (SImode));
9635 switch (GET_MODE (sh_compare_op0))
9639 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9641 emit_insn (gen_cmpgtsi_media (tmp,
9642 sh_compare_op0, sh_compare_op1));
9643 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9649 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9651 emit_insn (gen_cmpgtdi_media (tmp,
9652 sh_compare_op0, sh_compare_op1));
9653 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9658 if (! TARGET_SHMEDIA_FPU)
9660 emit_insn (gen_cmpgesf_media (reg,
9661 sh_compare_op1, sh_compare_op0));
9665 if (! TARGET_SHMEDIA_FPU)
9667 emit_insn (gen_cmpgedf_media (reg,
9668 sh_compare_op1, sh_compare_op0));
9675 if (GET_MODE (operands[0]) == DImode)
9676 emit_insn (gen_extendsidi2 (operands[0], reg));
9681 sh_compare_op0 = sh_compare_op1;
9682 sh_compare_op1 = tmp;
9683 emit_insn (gen_sge (operands[0]));
9687 (define_expand "sgt"
9688 [(set (match_operand:SI 0 "arith_reg_operand" "")
9698 if (GET_MODE (operands[0]) != SImode)
9699 reg = (!can_create_pseudo_p () ?
9700 gen_rtx_SUBREG (SImode, operands[0], 0)
9701 : gen_reg_rtx (SImode));
9702 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9703 if (sh_compare_op1 != const0_rtx)
9704 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9705 ? GET_MODE (sh_compare_op0)
9706 : GET_MODE (sh_compare_op1),
9709 switch (GET_MODE (sh_compare_op0))
9712 emit_insn (gen_cmpgtsi_media (reg,
9713 sh_compare_op0, sh_compare_op1));
9717 emit_insn (gen_cmpgtdi_media (reg,
9718 sh_compare_op0, sh_compare_op1));
9722 if (! TARGET_SHMEDIA_FPU)
9724 emit_insn (gen_cmpgtsf_media (reg,
9725 sh_compare_op0, sh_compare_op1));
9729 if (! TARGET_SHMEDIA_FPU)
9731 emit_insn (gen_cmpgtdf_media (reg,
9732 sh_compare_op0, sh_compare_op1));
9739 if (GET_MODE (operands[0]) == DImode)
9740 emit_insn (gen_extendsidi2 (operands[0], reg));
9744 if (! currently_expanding_to_rtl)
9746 operands[1] = prepare_scc_operands (GT);
9749 (define_expand "sge"
9750 [(set (match_operand:SI 0 "arith_reg_operand" "")
9758 enum machine_mode mode = GET_MODE (sh_compare_op0);
9760 if ((mode) == VOIDmode)
9761 mode = GET_MODE (sh_compare_op1);
9763 if (GET_MODE (operands[0]) != SImode)
9764 reg = (!can_create_pseudo_p ()
9765 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9766 : gen_reg_rtx (SImode));
9767 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9768 if (sh_compare_op1 != const0_rtx)
9769 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9775 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9777 emit_insn (gen_cmpgtsi_media (tmp,
9778 sh_compare_op1, sh_compare_op0));
9779 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9785 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9787 emit_insn (gen_cmpgtdi_media (tmp,
9788 sh_compare_op1, sh_compare_op0));
9789 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9794 if (! TARGET_SHMEDIA_FPU)
9796 emit_insn (gen_cmpgesf_media (reg,
9797 sh_compare_op0, sh_compare_op1));
9801 if (! TARGET_SHMEDIA_FPU)
9803 emit_insn (gen_cmpgedf_media (reg,
9804 sh_compare_op0, sh_compare_op1));
9811 if (GET_MODE (operands[0]) == DImode)
9812 emit_insn (gen_extendsidi2 (operands[0], reg));
9817 if (! currently_expanding_to_rtl)
9819 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9823 rtx lab = gen_label_rtx ();
9824 prepare_scc_operands (EQ);
9825 emit_jump_insn (gen_branch_true (lab));
9826 prepare_scc_operands (GT);
9828 emit_insn (gen_movt (operands[0]));
9831 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9834 operands[1] = prepare_scc_operands (GE);
9837 (define_expand "sgtu"
9838 [(set (match_operand:SI 0 "arith_reg_operand" "")
9848 if (GET_MODE (operands[0]) == DImode)
9849 reg = (!can_create_pseudo_p ()
9850 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9851 : gen_reg_rtx (SImode));
9852 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9853 if (sh_compare_op1 != const0_rtx)
9854 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9855 ? GET_MODE (sh_compare_op0)
9856 : GET_MODE (sh_compare_op1),
9859 emit_insn (gen_cmpgtudi_media (reg,
9860 sh_compare_op0, sh_compare_op1));
9861 if (GET_MODE (operands[0]) == DImode)
9862 emit_insn (gen_extendsidi2 (operands[0], reg));
9866 if (! currently_expanding_to_rtl)
9868 operands[1] = prepare_scc_operands (GTU);
9871 (define_expand "sltu"
9872 [(set (match_operand:SI 0 "arith_reg_operand" "")
9882 if (GET_MODE (operands[0]) == DImode)
9883 reg = (!can_create_pseudo_p ()
9884 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9885 : gen_reg_rtx (SImode));
9886 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9887 if (sh_compare_op1 != const0_rtx)
9888 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9889 ? GET_MODE (sh_compare_op0)
9890 : GET_MODE (sh_compare_op1),
9893 emit_insn (gen_cmpgtudi_media (reg,
9894 sh_compare_op1, sh_compare_op0));
9895 if (GET_MODE (operands[0]) == DImode)
9896 emit_insn (gen_extendsidi2 (operands[0], reg));
9900 if (! currently_expanding_to_rtl)
9902 operands[1] = prepare_scc_operands (LTU);
9905 (define_expand "sleu"
9906 [(set (match_operand:SI 0 "arith_reg_operand" "")
9916 if (GET_MODE (operands[0]) != SImode)
9917 reg = (!can_create_pseudo_p ()
9918 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9919 : gen_reg_rtx (SImode));
9920 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9921 if (sh_compare_op1 != const0_rtx)
9922 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9923 ? GET_MODE (sh_compare_op0)
9924 : GET_MODE (sh_compare_op1),
9927 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9929 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9930 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9931 if (GET_MODE (operands[0]) == DImode)
9932 emit_insn (gen_extendsidi2 (operands[0], reg));
9936 if (! currently_expanding_to_rtl)
9938 operands[1] = prepare_scc_operands (LEU);
9941 (define_expand "sgeu"
9942 [(set (match_operand:SI 0 "arith_reg_operand" "")
9952 if (GET_MODE (operands[0]) != SImode)
9953 reg = (!can_create_pseudo_p ()
9954 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9955 : gen_reg_rtx (SImode));
9956 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9957 if (sh_compare_op1 != const0_rtx)
9958 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9959 ? GET_MODE (sh_compare_op0)
9960 : GET_MODE (sh_compare_op1),
9963 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
9965 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9966 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9967 if (GET_MODE (operands[0]) == DImode)
9968 emit_insn (gen_extendsidi2 (operands[0], reg));
9973 if (! currently_expanding_to_rtl)
9975 operands[1] = prepare_scc_operands (GEU);
9978 ;; sne moves the complement of the T reg to DEST like this:
9982 ;; This is better than xoring compare result with 1 because it does
9983 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9986 (define_expand "sne"
9987 [(set (match_dup 2) (const_int -1))
9988 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9989 (neg:SI (plus:SI (match_dup 1)
9992 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10002 if (GET_MODE (operands[0]) != SImode)
10003 reg = (!can_create_pseudo_p ()
10004 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10005 : gen_reg_rtx (SImode));
10006 if (! TARGET_SHMEDIA_FPU
10007 && GET_MODE (sh_compare_op0) != DImode
10008 && GET_MODE (sh_compare_op0) != SImode)
10011 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10012 if (sh_compare_op1 != const0_rtx)
10013 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10014 ? GET_MODE (sh_compare_op0)
10015 : GET_MODE (sh_compare_op1),
10018 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10020 emit_insn (gen_seq (tmp));
10021 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10022 if (GET_MODE (operands[0]) == DImode)
10023 emit_insn (gen_extendsidi2 (operands[0], reg));
10028 if (sh_expand_t_scc (NE, operands[0]))
10030 if (! currently_expanding_to_rtl)
10032 operands[1] = prepare_scc_operands (EQ);
10033 operands[2] = gen_reg_rtx (SImode);
10036 (define_expand "sunordered"
10037 [(set (match_operand:SI 0 "arith_reg_operand" "")
10038 (unordered:SI (match_dup 1) (match_dup 2)))]
10039 "TARGET_SHMEDIA_FPU"
10042 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10043 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10046 ;; Use the same trick for FP sle / sge
10048 ;; Apart from the constant use and the T setting, this is like movt,
10049 ;; except that it uses the logically negated value of T, i.e.
10050 ;; operand[0] := T ? 0 : 1.
10051 (define_expand "movnegt"
10052 [(set (match_dup 2) (const_int -1))
10053 (parallel [(set (match_operand 0 "" "")
10054 (neg:SI (plus:SI (match_dup 1)
10056 (set (reg:SI T_REG)
10057 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10060 "operands[2] = gen_reg_rtx (SImode);")
10062 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10063 ;; This prevents a regression that occurred when we switched from xor to
10064 ;; mov/neg for sne.
10067 [(set (match_operand:SI 0 "arith_reg_dest" "")
10068 (plus:SI (reg:SI T_REG)
10071 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10072 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10075 ;; -------------------------------------------------------------------------
10076 ;; Instructions to cope with inline literal tables
10077 ;; -------------------------------------------------------------------------
10079 ; 2 byte integer in line
10081 (define_insn "consttable_2"
10082 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10083 (match_operand 1 "" "")]
10088 if (operands[1] != const0_rtx)
10089 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10092 [(set_attr "length" "2")
10093 (set_attr "in_delay_slot" "no")])
10095 ; 4 byte integer in line
10097 (define_insn "consttable_4"
10098 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10099 (match_operand 1 "" "")]
10104 if (operands[1] != const0_rtx)
10105 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10108 [(set_attr "length" "4")
10109 (set_attr "in_delay_slot" "no")])
10111 ; 8 byte integer in line
10113 (define_insn "consttable_8"
10114 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10115 (match_operand 1 "" "")]
10120 if (operands[1] != const0_rtx)
10121 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10124 [(set_attr "length" "8")
10125 (set_attr "in_delay_slot" "no")])
10127 ; 4 byte floating point
10129 (define_insn "consttable_sf"
10130 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10131 (match_operand 1 "" "")]
10136 if (operands[1] != const0_rtx)
10139 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10140 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10144 [(set_attr "length" "4")
10145 (set_attr "in_delay_slot" "no")])
10147 ; 8 byte floating point
10149 (define_insn "consttable_df"
10150 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10151 (match_operand 1 "" "")]
10156 if (operands[1] != const0_rtx)
10159 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10160 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10164 [(set_attr "length" "8")
10165 (set_attr "in_delay_slot" "no")])
10167 ;; Alignment is needed for some constant tables; it may also be added for
10168 ;; Instructions at the start of loops, or after unconditional branches.
10169 ;; ??? We would get more accurate lengths if we did instruction
10170 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10171 ;; here is too conservative.
10173 ; align to a two byte boundary
10175 (define_expand "align_2"
10176 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10180 ; align to a four byte boundary
10181 ;; align_4 and align_log are instructions for the starts of loops, or
10182 ;; after unconditional branches, which may take up extra room.
10184 (define_expand "align_4"
10185 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10189 ; align to a cache line boundary
10191 (define_insn "align_log"
10192 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10195 [(set_attr "length" "0")
10196 (set_attr "in_delay_slot" "no")])
10198 ; emitted at the end of the literal table, used to emit the
10199 ; 32bit branch labels if needed.
10201 (define_insn "consttable_end"
10202 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10204 "* return output_jump_label_table ();"
10205 [(set_attr "in_delay_slot" "no")])
10207 ; emitted at the end of the window in the literal table.
10209 (define_insn "consttable_window_end"
10210 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10213 [(set_attr "length" "0")
10214 (set_attr "in_delay_slot" "no")])
10216 ;; -------------------------------------------------------------------------
10218 ;; -------------------------------------------------------------------------
10220 ;; String/block move insn.
10222 (define_expand "movmemsi"
10223 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10224 (mem:BLK (match_operand:BLK 1 "" "")))
10225 (use (match_operand:SI 2 "nonmemory_operand" ""))
10226 (use (match_operand:SI 3 "immediate_operand" ""))
10227 (clobber (reg:SI PR_REG))
10228 (clobber (reg:SI R4_REG))
10229 (clobber (reg:SI R5_REG))
10230 (clobber (reg:SI R0_REG))])]
10231 "TARGET_SH1 && ! TARGET_SH5"
10234 if(expand_block_move (operands))
10239 (define_insn "block_move_real"
10240 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10241 (mem:BLK (reg:SI R5_REG)))
10242 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10243 (clobber (reg:SI PR_REG))
10244 (clobber (reg:SI R0_REG))])]
10245 "TARGET_SH1 && ! TARGET_HARD_SH4"
10247 [(set_attr "type" "sfunc")
10248 (set_attr "needs_delay_slot" "yes")])
10250 (define_insn "block_lump_real"
10251 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10252 (mem:BLK (reg:SI R5_REG)))
10253 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10254 (use (reg:SI R6_REG))
10255 (clobber (reg:SI PR_REG))
10256 (clobber (reg:SI T_REG))
10257 (clobber (reg:SI R4_REG))
10258 (clobber (reg:SI R5_REG))
10259 (clobber (reg:SI R6_REG))
10260 (clobber (reg:SI R0_REG))])]
10261 "TARGET_SH1 && ! TARGET_HARD_SH4"
10263 [(set_attr "type" "sfunc")
10264 (set_attr "needs_delay_slot" "yes")])
10266 (define_insn "block_move_real_i4"
10267 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10268 (mem:BLK (reg:SI R5_REG)))
10269 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10270 (clobber (reg:SI PR_REG))
10271 (clobber (reg:SI R0_REG))
10272 (clobber (reg:SI R1_REG))
10273 (clobber (reg:SI R2_REG))])]
10276 [(set_attr "type" "sfunc")
10277 (set_attr "needs_delay_slot" "yes")])
10279 (define_insn "block_lump_real_i4"
10280 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10281 (mem:BLK (reg:SI R5_REG)))
10282 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10283 (use (reg:SI R6_REG))
10284 (clobber (reg:SI PR_REG))
10285 (clobber (reg:SI T_REG))
10286 (clobber (reg:SI R4_REG))
10287 (clobber (reg:SI R5_REG))
10288 (clobber (reg:SI R6_REG))
10289 (clobber (reg:SI R0_REG))
10290 (clobber (reg:SI R1_REG))
10291 (clobber (reg:SI R2_REG))
10292 (clobber (reg:SI R3_REG))])]
10295 [(set_attr "type" "sfunc")
10296 (set_attr "needs_delay_slot" "yes")])
10298 ;; -------------------------------------------------------------------------
10299 ;; Floating point instructions.
10300 ;; -------------------------------------------------------------------------
10302 ;; ??? All patterns should have a type attribute.
10304 (define_expand "movpsi"
10305 [(set (match_operand:PSI 0 "register_operand" "")
10306 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10307 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10310 ;; The c / m alternative is a fake to guide reload to load directly into
10311 ;; fpscr, since reload doesn't know how to use post-increment.
10312 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10313 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10314 ;; predicate after reload.
10315 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10316 ;; like a mac -> gpr move.
10317 (define_insn "fpu_switch"
10318 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10319 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10321 && (! reload_completed
10322 || true_regnum (operands[0]) != FPSCR_REG
10323 || GET_CODE (operands[1]) != MEM
10324 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10326 ! precision stays the same
10335 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10336 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10339 [(set (reg:PSI FPSCR_REG)
10340 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10341 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10344 rtx fpscr, mem, new_insn;
10346 fpscr = SET_DEST (PATTERN (curr_insn));
10347 mem = SET_SRC (PATTERN (curr_insn));
10348 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10350 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10351 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10356 [(set (reg:PSI FPSCR_REG)
10357 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10359 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10362 rtx fpscr, mem, new_insn;
10364 fpscr = SET_DEST (PATTERN (curr_insn));
10365 mem = SET_SRC (PATTERN (curr_insn));
10366 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10368 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10369 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10371 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10372 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10376 ;; ??? This uses the fp unit, but has no type indicating that.
10377 ;; If we did that, this would either give a bogus latency or introduce
10378 ;; a bogus FIFO constraint.
10379 ;; Since this insn is currently only used for prologues/epilogues,
10380 ;; it is probably best to claim no function unit, which matches the
10381 ;; current setting.
10382 (define_insn "toggle_sz"
10383 [(set (reg:PSI FPSCR_REG)
10384 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10385 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10387 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10389 ;; There's no way we can use it today, since optimize mode switching
10390 ;; doesn't enable us to know from which mode we're switching to the
10391 ;; mode it requests, to tell whether we can use a relative mode switch
10392 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10394 (define_insn "toggle_pr"
10395 [(set (reg:PSI FPSCR_REG)
10396 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10397 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10399 [(set_attr "type" "fpscr_toggle")])
10401 (define_expand "addsf3"
10402 [(set (match_operand:SF 0 "arith_reg_operand" "")
10403 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10404 (match_operand:SF 2 "arith_reg_operand" "")))]
10405 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10410 expand_sf_binop (&gen_addsf3_i, operands);
10415 (define_insn "*addsf3_media"
10416 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10417 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10418 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10419 "TARGET_SHMEDIA_FPU"
10420 "fadd.s %1, %2, %0"
10421 [(set_attr "type" "fparith_media")])
10423 (define_insn_and_split "unary_sf_op"
10424 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10429 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10430 (match_operator:SF 2 "unary_float_operator"
10431 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10432 (parallel [(match_operand 4
10433 "const_int_operand" "n")]))]))
10434 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10435 "TARGET_SHMEDIA_FPU"
10437 "TARGET_SHMEDIA_FPU && reload_completed"
10438 [(set (match_dup 5) (match_dup 6))]
10441 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10442 rtx op1 = gen_rtx_REG (SFmode,
10443 (true_regnum (operands[1])
10444 + (INTVAL (operands[4]) ^ endian)));
10446 operands[7] = gen_rtx_REG (SFmode,
10447 (true_regnum (operands[0])
10448 + (INTVAL (operands[3]) ^ endian)));
10449 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10451 [(set_attr "type" "fparith_media")])
10453 (define_insn_and_split "binary_sf_op"
10454 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10459 (parallel [(match_operand 7 "const_int_operand" "n")]))
10460 (match_operator:SF 3 "binary_float_operator"
10461 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10462 (parallel [(match_operand 5
10463 "const_int_operand" "n")]))
10464 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10465 (parallel [(match_operand 6
10466 "const_int_operand" "n")]))]))
10467 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10468 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10470 "&& reload_completed"
10471 [(set (match_dup 8) (match_dup 9))]
10474 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10475 rtx op1 = gen_rtx_REG (SFmode,
10476 (true_regnum (operands[1])
10477 + (INTVAL (operands[5]) ^ endian)));
10478 rtx op2 = gen_rtx_REG (SFmode,
10479 (true_regnum (operands[2])
10480 + (INTVAL (operands[6]) ^ endian)));
10482 operands[8] = gen_rtx_REG (SFmode,
10483 (true_regnum (operands[0])
10484 + (INTVAL (operands[4]) ^ endian)));
10485 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10487 [(set_attr "type" "fparith_media")])
10489 (define_insn "addsf3_i"
10490 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10491 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10492 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10493 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10496 [(set_attr "type" "fp")
10497 (set_attr "fp_mode" "single")])
10499 (define_expand "subsf3"
10500 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10501 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10502 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10503 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10508 expand_sf_binop (&gen_subsf3_i, operands);
10513 (define_insn "*subsf3_media"
10514 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10515 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10516 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10517 "TARGET_SHMEDIA_FPU"
10518 "fsub.s %1, %2, %0"
10519 [(set_attr "type" "fparith_media")])
10521 (define_insn "subsf3_i"
10522 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10523 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10524 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10525 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10528 [(set_attr "type" "fp")
10529 (set_attr "fp_mode" "single")])
10531 (define_expand "mulsf3"
10532 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10533 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10534 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10535 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10538 (define_insn "*mulsf3_media"
10539 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10540 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10541 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10542 "TARGET_SHMEDIA_FPU"
10543 "fmul.s %1, %2, %0"
10544 [(set_attr "type" "fparith_media")])
10546 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10547 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10548 ;; we start out with a mulsf pattern that does not depend on fpscr.
10549 ;; This is split after combine to introduce the dependency, in order to
10550 ;; get mode switching and scheduling right.
10551 (define_insn_and_split "mulsf3_ie"
10552 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10553 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10554 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10557 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10561 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10562 get_fpscr_rtx ()));
10565 [(set_attr "type" "fp")])
10567 (define_insn "mulsf3_i4"
10568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10569 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10570 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10571 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10574 [(set_attr "type" "fp")
10575 (set_attr "fp_mode" "single")])
10577 (define_insn "mac_media"
10578 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10580 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10581 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10582 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10583 "fmac.s %1, %2, %0"
10584 [(set_attr "type" "fparith_media")])
10586 (define_insn "*macsf3"
10587 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10588 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10589 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10590 (match_operand:SF 3 "arith_reg_operand" "0")))
10591 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10592 "TARGET_SH2E && TARGET_FMAC"
10594 [(set_attr "type" "fp")
10595 (set_attr "fp_mode" "single")])
10597 (define_expand "divsf3"
10598 [(set (match_operand:SF 0 "arith_reg_operand" "")
10599 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10600 (match_operand:SF 2 "arith_reg_operand" "")))]
10601 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10606 expand_sf_binop (&gen_divsf3_i, operands);
10611 (define_insn "*divsf3_media"
10612 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10613 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10614 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10615 "TARGET_SHMEDIA_FPU"
10616 "fdiv.s %1, %2, %0"
10617 [(set_attr "type" "fdiv_media")])
10619 (define_insn "divsf3_i"
10620 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10621 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10622 (match_operand:SF 2 "arith_reg_operand" "f")))
10623 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10626 [(set_attr "type" "fdiv")
10627 (set_attr "fp_mode" "single")])
10629 (define_insn "floatdisf2"
10630 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10631 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10632 "TARGET_SHMEDIA_FPU"
10634 [(set_attr "type" "fpconv_media")])
10636 (define_expand "floatsisf2"
10637 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10638 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10639 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10642 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10644 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10649 (define_insn "*floatsisf2_media"
10650 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10651 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10652 "TARGET_SHMEDIA_FPU"
10654 [(set_attr "type" "fpconv_media")])
10656 (define_insn "floatsisf2_i4"
10657 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10658 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10659 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10660 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10662 [(set_attr "type" "fp")
10663 (set_attr "fp_mode" "single")])
10665 (define_insn "*floatsisf2_ie"
10666 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10667 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10668 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10670 [(set_attr "type" "fp")])
10672 (define_insn "fix_truncsfdi2"
10673 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10674 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10675 "TARGET_SHMEDIA_FPU"
10677 [(set_attr "type" "fpconv_media")])
10679 (define_expand "fix_truncsfsi2"
10680 [(set (match_operand:SI 0 "fpul_operand" "=y")
10681 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10682 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10685 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10687 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10692 (define_insn "*fix_truncsfsi2_media"
10693 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10694 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10695 "TARGET_SHMEDIA_FPU"
10697 [(set_attr "type" "fpconv_media")])
10699 (define_insn "fix_truncsfsi2_i4"
10700 [(set (match_operand:SI 0 "fpul_operand" "=y")
10701 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10702 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10703 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10705 [(set_attr "type" "ftrc_s")
10706 (set_attr "fp_mode" "single")])
10708 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10709 ;; fix_truncsfsi2_i4.
10710 ;; (define_insn "fix_truncsfsi2_i4_2"
10711 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10712 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10713 ;; (use (reg:PSI FPSCR_REG))
10714 ;; (clobber (reg:SI FPUL_REG))]
10717 ;; [(set_attr "length" "4")
10718 ;; (set_attr "fp_mode" "single")])
10721 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10722 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10723 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10724 ;; (clobber (reg:SI FPUL_REG))]
10726 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10727 ;; (use (match_dup 2))])
10728 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10730 (define_insn "*fixsfsi"
10731 [(set (match_operand:SI 0 "fpul_operand" "=y")
10732 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10733 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10735 [(set_attr "type" "fp")])
10737 (define_insn "cmpgtsf_t"
10738 [(set (reg:SI T_REG)
10739 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10740 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10741 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10743 [(set_attr "type" "fp_cmp")
10744 (set_attr "fp_mode" "single")])
10746 (define_insn "cmpeqsf_t"
10747 [(set (reg:SI T_REG)
10748 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10749 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10750 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10752 [(set_attr "type" "fp_cmp")
10753 (set_attr "fp_mode" "single")])
10755 (define_insn "ieee_ccmpeqsf_t"
10756 [(set (reg:SI T_REG)
10757 (ior:SI (reg:SI T_REG)
10758 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10759 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10760 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10761 "* return output_ieee_ccmpeq (insn, operands);"
10762 [(set_attr "length" "4")])
10765 (define_insn "cmpgtsf_t_i4"
10766 [(set (reg:SI T_REG)
10767 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10768 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10769 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10770 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10772 [(set_attr "type" "fp_cmp")
10773 (set_attr "fp_mode" "single")])
10775 (define_insn "cmpeqsf_t_i4"
10776 [(set (reg:SI T_REG)
10777 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10778 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10779 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10780 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10782 [(set_attr "type" "fp_cmp")
10783 (set_attr "fp_mode" "single")])
10785 (define_insn "*ieee_ccmpeqsf_t_4"
10786 [(set (reg:SI T_REG)
10787 (ior:SI (reg:SI T_REG)
10788 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10789 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10790 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10791 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10792 "* return output_ieee_ccmpeq (insn, operands);"
10793 [(set_attr "length" "4")
10794 (set_attr "fp_mode" "single")])
10796 (define_insn "cmpeqsf_media"
10797 [(set (match_operand:SI 0 "register_operand" "=r")
10798 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10799 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10800 "TARGET_SHMEDIA_FPU"
10801 "fcmpeq.s %1, %2, %0"
10802 [(set_attr "type" "fcmp_media")])
10804 (define_insn "cmpgtsf_media"
10805 [(set (match_operand:SI 0 "register_operand" "=r")
10806 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10807 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10808 "TARGET_SHMEDIA_FPU"
10809 "fcmpgt.s %1, %2, %0"
10810 [(set_attr "type" "fcmp_media")])
10812 (define_insn "cmpgesf_media"
10813 [(set (match_operand:SI 0 "register_operand" "=r")
10814 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10815 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10816 "TARGET_SHMEDIA_FPU"
10817 "fcmpge.s %1, %2, %0"
10818 [(set_attr "type" "fcmp_media")])
10820 (define_insn "cmpunsf_media"
10821 [(set (match_operand:SI 0 "register_operand" "=r")
10822 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10823 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10824 "TARGET_SHMEDIA_FPU"
10825 "fcmpun.s %1, %2, %0"
10826 [(set_attr "type" "fcmp_media")])
10828 (define_expand "cmpsf"
10829 [(set (reg:SI T_REG)
10830 (compare (match_operand:SF 0 "arith_operand" "")
10831 (match_operand:SF 1 "arith_operand" "")))]
10832 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10835 sh_compare_op0 = operands[0];
10836 sh_compare_op1 = operands[1];
10840 (define_expand "negsf2"
10841 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10842 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10843 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10848 expand_sf_unop (&gen_negsf2_i, operands);
10853 (define_insn "*negsf2_media"
10854 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10855 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10856 "TARGET_SHMEDIA_FPU"
10858 [(set_attr "type" "fmove_media")])
10860 (define_insn "negsf2_i"
10861 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10862 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10863 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10866 [(set_attr "type" "fmove")
10867 (set_attr "fp_mode" "single")])
10869 (define_expand "sqrtsf2"
10870 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10871 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10872 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10877 expand_sf_unop (&gen_sqrtsf2_i, operands);
10882 (define_insn "*sqrtsf2_media"
10883 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10884 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10885 "TARGET_SHMEDIA_FPU"
10887 [(set_attr "type" "fdiv_media")])
10889 (define_insn "sqrtsf2_i"
10890 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10891 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10892 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10895 [(set_attr "type" "fdiv")
10896 (set_attr "fp_mode" "single")])
10898 (define_insn "rsqrtsf2"
10899 [(set (match_operand:SF 0 "register_operand" "=f")
10900 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10901 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10902 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10903 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10904 && operands[1] == CONST1_RTX (SFmode)"
10906 [(set_attr "type" "fsrra")
10907 (set_attr "fp_mode" "single")])
10909 (define_insn "fsca"
10910 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10912 (unspec:SF [(mult:SF
10913 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10914 (match_operand:SF 2 "immediate_operand" "i"))
10916 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10918 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10919 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10920 && operands[2] == sh_fsca_int2sf ()"
10922 [(set_attr "type" "fsca")
10923 (set_attr "fp_mode" "single")])
10925 (define_expand "sinsf2"
10926 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10927 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10929 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10932 rtx scaled = gen_reg_rtx (SFmode);
10933 rtx truncated = gen_reg_rtx (SImode);
10934 rtx fsca = gen_reg_rtx (V2SFmode);
10935 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10937 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10938 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10939 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10940 get_fpscr_rtx ()));
10941 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10945 (define_expand "cossf2"
10946 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10947 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10949 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10952 rtx scaled = gen_reg_rtx (SFmode);
10953 rtx truncated = gen_reg_rtx (SImode);
10954 rtx fsca = gen_reg_rtx (V2SFmode);
10955 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10957 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10958 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10959 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10960 get_fpscr_rtx ()));
10961 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10965 (define_expand "sindf2"
10966 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10967 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10969 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10972 rtx scaled = gen_reg_rtx (DFmode);
10973 rtx truncated = gen_reg_rtx (SImode);
10974 rtx fsca = gen_reg_rtx (V2SFmode);
10975 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10976 rtx sfresult = gen_reg_rtx (SFmode);
10978 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10979 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10980 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10981 get_fpscr_rtx ()));
10982 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10983 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10987 (define_expand "cosdf2"
10988 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10989 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10991 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10994 rtx scaled = gen_reg_rtx (DFmode);
10995 rtx truncated = gen_reg_rtx (SImode);
10996 rtx fsca = gen_reg_rtx (V2SFmode);
10997 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10998 rtx sfresult = gen_reg_rtx (SFmode);
11000 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11001 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11002 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11003 get_fpscr_rtx ()));
11004 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11005 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11009 (define_expand "abssf2"
11010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11011 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11012 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11017 expand_sf_unop (&gen_abssf2_i, operands);
11022 (define_insn "*abssf2_media"
11023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11024 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11025 "TARGET_SHMEDIA_FPU"
11027 [(set_attr "type" "fmove_media")])
11029 (define_insn "abssf2_i"
11030 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11031 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11032 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11035 [(set_attr "type" "fmove")
11036 (set_attr "fp_mode" "single")])
11038 (define_expand "adddf3"
11039 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11040 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11041 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11045 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11047 expand_df_binop (&gen_adddf3_i, operands);
11052 (define_insn "*adddf3_media"
11053 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11054 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11055 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11056 "TARGET_SHMEDIA_FPU"
11057 "fadd.d %1, %2, %0"
11058 [(set_attr "type" "dfparith_media")])
11060 (define_insn "adddf3_i"
11061 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11062 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11063 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11064 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11065 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11067 [(set_attr "type" "dfp_arith")
11068 (set_attr "fp_mode" "double")])
11070 (define_expand "subdf3"
11071 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11072 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11073 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11074 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11077 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11079 expand_df_binop (&gen_subdf3_i, operands);
11084 (define_insn "*subdf3_media"
11085 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11086 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11087 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11088 "TARGET_SHMEDIA_FPU"
11089 "fsub.d %1, %2, %0"
11090 [(set_attr "type" "dfparith_media")])
11092 (define_insn "subdf3_i"
11093 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11094 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11095 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11096 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11097 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11099 [(set_attr "type" "dfp_arith")
11100 (set_attr "fp_mode" "double")])
11102 (define_expand "muldf3"
11103 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11104 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11105 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11106 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11109 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11111 expand_df_binop (&gen_muldf3_i, operands);
11116 (define_insn "*muldf3_media"
11117 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11118 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11119 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11120 "TARGET_SHMEDIA_FPU"
11121 "fmul.d %1, %2, %0"
11122 [(set_attr "type" "dfmul_media")])
11124 (define_insn "muldf3_i"
11125 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11126 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11127 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11128 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11129 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11131 [(set_attr "type" "dfp_mul")
11132 (set_attr "fp_mode" "double")])
11134 (define_expand "divdf3"
11135 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11136 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11137 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11138 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11141 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11143 expand_df_binop (&gen_divdf3_i, operands);
11148 (define_insn "*divdf3_media"
11149 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11150 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11151 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11152 "TARGET_SHMEDIA_FPU"
11153 "fdiv.d %1, %2, %0"
11154 [(set_attr "type" "dfdiv_media")])
11156 (define_insn "divdf3_i"
11157 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11158 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11159 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11160 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11161 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11163 [(set_attr "type" "dfdiv")
11164 (set_attr "fp_mode" "double")])
11166 (define_insn "floatdidf2"
11167 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11168 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11169 "TARGET_SHMEDIA_FPU"
11171 [(set_attr "type" "dfpconv_media")])
11173 (define_expand "floatsidf2"
11174 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11175 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11176 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11179 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11181 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11182 get_fpscr_rtx ()));
11187 (define_insn "*floatsidf2_media"
11188 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11189 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11190 "TARGET_SHMEDIA_FPU"
11192 [(set_attr "type" "dfpconv_media")])
11194 (define_insn "floatsidf2_i"
11195 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11196 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11197 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11198 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11200 [(set_attr "type" "dfp_conv")
11201 (set_attr "fp_mode" "double")])
11203 (define_insn "fix_truncdfdi2"
11204 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11205 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11206 "TARGET_SHMEDIA_FPU"
11208 [(set_attr "type" "dfpconv_media")])
11210 (define_expand "fix_truncdfsi2"
11211 [(set (match_operand:SI 0 "fpul_operand" "")
11212 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11213 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11216 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11218 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11219 get_fpscr_rtx ()));
11224 (define_insn "*fix_truncdfsi2_media"
11225 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11226 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11227 "TARGET_SHMEDIA_FPU"
11229 [(set_attr "type" "dfpconv_media")])
11231 (define_insn "fix_truncdfsi2_i"
11232 [(set (match_operand:SI 0 "fpul_operand" "=y")
11233 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11234 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11235 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11237 [(set_attr "type" "dfp_conv")
11238 (set_attr "dfp_comp" "no")
11239 (set_attr "fp_mode" "double")])
11241 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11242 ;; fix_truncdfsi2_i.
11243 ;; (define_insn "fix_truncdfsi2_i4"
11244 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11245 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11246 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11247 ;; (clobber (reg:SI FPUL_REG))]
11250 ;; [(set_attr "length" "4")
11251 ;; (set_attr "fp_mode" "double")])
11254 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11255 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11256 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11257 ;; (clobber (reg:SI FPUL_REG))]
11259 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11260 ;; (use (match_dup 2))])
11261 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11263 (define_insn "cmpgtdf_t"
11264 [(set (reg:SI T_REG)
11265 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11266 (match_operand:DF 1 "arith_reg_operand" "f")))
11267 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11268 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11270 [(set_attr "type" "dfp_cmp")
11271 (set_attr "fp_mode" "double")])
11273 (define_insn "cmpeqdf_t"
11274 [(set (reg:SI T_REG)
11275 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11276 (match_operand:DF 1 "arith_reg_operand" "f")))
11277 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11278 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11280 [(set_attr "type" "dfp_cmp")
11281 (set_attr "fp_mode" "double")])
11283 (define_insn "*ieee_ccmpeqdf_t"
11284 [(set (reg:SI T_REG)
11285 (ior:SI (reg:SI T_REG)
11286 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11287 (match_operand:DF 1 "arith_reg_operand" "f"))))
11288 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11289 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11290 "* return output_ieee_ccmpeq (insn, operands);"
11291 [(set_attr "length" "4")
11292 (set_attr "fp_mode" "double")])
11294 (define_insn "cmpeqdf_media"
11295 [(set (match_operand:SI 0 "register_operand" "=r")
11296 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11297 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11298 "TARGET_SHMEDIA_FPU"
11299 "fcmpeq.d %1,%2,%0"
11300 [(set_attr "type" "fcmp_media")])
11302 (define_insn "cmpgtdf_media"
11303 [(set (match_operand:SI 0 "register_operand" "=r")
11304 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11305 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11306 "TARGET_SHMEDIA_FPU"
11307 "fcmpgt.d %1,%2,%0"
11308 [(set_attr "type" "fcmp_media")])
11310 (define_insn "cmpgedf_media"
11311 [(set (match_operand:SI 0 "register_operand" "=r")
11312 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11313 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11314 "TARGET_SHMEDIA_FPU"
11315 "fcmpge.d %1,%2,%0"
11316 [(set_attr "type" "fcmp_media")])
11318 (define_insn "cmpundf_media"
11319 [(set (match_operand:SI 0 "register_operand" "=r")
11320 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11321 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11322 "TARGET_SHMEDIA_FPU"
11323 "fcmpun.d %1,%2,%0"
11324 [(set_attr "type" "fcmp_media")])
11326 (define_expand "cmpdf"
11327 [(set (reg:SI T_REG)
11328 (compare (match_operand:DF 0 "arith_operand" "")
11329 (match_operand:DF 1 "arith_operand" "")))]
11330 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11333 sh_compare_op0 = operands[0];
11334 sh_compare_op1 = operands[1];
11338 (define_expand "negdf2"
11339 [(set (match_operand:DF 0 "arith_reg_operand" "")
11340 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11341 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11344 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11346 expand_df_unop (&gen_negdf2_i, operands);
11351 (define_insn "*negdf2_media"
11352 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11353 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11354 "TARGET_SHMEDIA_FPU"
11356 [(set_attr "type" "fmove_media")])
11358 (define_insn "negdf2_i"
11359 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11360 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11361 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11362 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11364 [(set_attr "type" "fmove")
11365 (set_attr "fp_mode" "double")])
11367 (define_expand "sqrtdf2"
11368 [(set (match_operand:DF 0 "arith_reg_operand" "")
11369 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11370 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11373 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11375 expand_df_unop (&gen_sqrtdf2_i, operands);
11380 (define_insn "*sqrtdf2_media"
11381 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11382 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11383 "TARGET_SHMEDIA_FPU"
11385 [(set_attr "type" "dfdiv_media")])
11387 (define_insn "sqrtdf2_i"
11388 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11389 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11390 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11391 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11393 [(set_attr "type" "dfdiv")
11394 (set_attr "fp_mode" "double")])
11396 (define_expand "absdf2"
11397 [(set (match_operand:DF 0 "arith_reg_operand" "")
11398 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11399 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11402 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11404 expand_df_unop (&gen_absdf2_i, operands);
11409 (define_insn "*absdf2_media"
11410 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11411 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11412 "TARGET_SHMEDIA_FPU"
11414 [(set_attr "type" "fmove_media")])
11416 (define_insn "absdf2_i"
11417 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11418 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11419 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11420 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11422 [(set_attr "type" "fmove")
11423 (set_attr "fp_mode" "double")])
11425 (define_expand "extendsfdf2"
11426 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11427 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11428 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11431 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11433 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11434 get_fpscr_rtx ()));
11439 (define_insn "*extendsfdf2_media"
11440 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11441 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11442 "TARGET_SHMEDIA_FPU"
11444 [(set_attr "type" "dfpconv_media")])
11446 (define_insn "extendsfdf2_i4"
11447 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11448 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11449 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11450 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11452 [(set_attr "type" "fp")
11453 (set_attr "fp_mode" "double")])
11455 (define_expand "truncdfsf2"
11456 [(set (match_operand:SF 0 "fpul_operand" "")
11457 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11458 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11461 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11463 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11464 get_fpscr_rtx ()));
11469 (define_insn "*truncdfsf2_media"
11470 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11471 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11472 "TARGET_SHMEDIA_FPU"
11474 [(set_attr "type" "dfpconv_media")])
11476 (define_insn "truncdfsf2_i4"
11477 [(set (match_operand:SF 0 "fpul_operand" "=y")
11478 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11479 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11480 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11482 [(set_attr "type" "fp")
11483 (set_attr "fp_mode" "double")])
11485 ;; Bit field extract patterns. These give better code for packed bitfields,
11486 ;; because they allow auto-increment addresses to be generated.
11488 (define_expand "insv"
11489 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11490 (match_operand:SI 1 "immediate_operand" "")
11491 (match_operand:SI 2 "immediate_operand" ""))
11492 (match_operand:SI 3 "general_operand" ""))]
11493 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11496 rtx addr_target, orig_address, shift_reg, qi_val;
11497 HOST_WIDE_INT bitsize, size, v = 0;
11498 rtx x = operands[3];
11500 /* ??? expmed doesn't care for non-register predicates. */
11501 if (! memory_operand (operands[0], VOIDmode)
11502 || ! immediate_operand (operands[1], VOIDmode)
11503 || ! immediate_operand (operands[2], VOIDmode)
11504 || ! general_operand (x, VOIDmode))
11506 /* If this isn't a 16 / 24 / 32 bit field, or if
11507 it doesn't start on a byte boundary, then fail. */
11508 bitsize = INTVAL (operands[1]);
11509 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11510 || (INTVAL (operands[2]) % 8) != 0)
11513 size = bitsize / 8;
11514 orig_address = XEXP (operands[0], 0);
11515 shift_reg = gen_reg_rtx (SImode);
11516 if (GET_CODE (x) == CONST_INT)
11519 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11523 emit_insn (gen_movsi (shift_reg, operands[3]));
11524 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11526 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11528 operands[0] = replace_equiv_address (operands[0], addr_target);
11529 emit_insn (gen_movqi (operands[0], qi_val));
11533 if (GET_CODE (x) == CONST_INT)
11535 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11538 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11539 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11541 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11542 emit_insn (gen_movqi (operands[0], qi_val));
11548 (define_insn "movua"
11549 [(set (match_operand:SI 0 "register_operand" "=z")
11550 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11554 [(set_attr "type" "movua")])
11556 ;; We shouldn't need this, but cse replaces increments with references
11557 ;; to other regs before flow has a chance to create post_inc
11558 ;; addressing modes, and only postreload's cse_move2add brings the
11559 ;; increments back to a usable form.
11561 [(set (match_operand:SI 0 "register_operand" "")
11562 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11563 (const_int 32) (const_int 0)))
11564 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11565 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11566 [(set (match_operand:SI 0 "register_operand" "")
11567 (sign_extract:SI (mem:SI (post_inc:SI
11568 (match_operand:SI 1 "register_operand" "")))
11569 (const_int 32) (const_int 0)))]
11572 (define_expand "extv"
11573 [(set (match_operand:SI 0 "register_operand" "")
11574 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11575 (match_operand 2 "const_int_operand" "")
11576 (match_operand 3 "const_int_operand" "")))]
11579 if (TARGET_SH4A_ARCH
11580 && INTVAL (operands[2]) == 32
11581 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11582 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11584 rtx src = adjust_address (operands[1], BLKmode, 0);
11585 set_mem_size (src, GEN_INT (4));
11586 emit_insn (gen_movua (operands[0], src));
11593 (define_expand "extzv"
11594 [(set (match_operand:SI 0 "register_operand" "")
11595 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11596 (match_operand 2 "const_int_operand" "")
11597 (match_operand 3 "const_int_operand" "")))]
11600 if (TARGET_SH4A_ARCH
11601 && INTVAL (operands[2]) == 32
11602 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11603 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11605 rtx src = adjust_address (operands[1], BLKmode, 0);
11606 set_mem_size (src, GEN_INT (4));
11607 emit_insn (gen_movua (operands[0], src));
11615 ;; -------------------------------------------------------------------------
11617 ;; -------------------------------------------------------------------------
11619 ;; This matches cases where a stack pointer increment at the start of the
11620 ;; epilogue combines with a stack slot read loading the return value.
11623 [(set (match_operand:SI 0 "arith_reg_operand" "")
11624 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11625 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11626 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11629 ;; See the comment on the dt combiner pattern above.
11632 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11633 (plus:SI (match_dup 0)
11635 (set (reg:SI T_REG)
11636 (eq:SI (match_dup 0)
11641 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11642 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11643 ;; reload when the constant is too large for a reg+offset address.
11645 ;; ??? We would get much better code if this was done in reload. This would
11646 ;; require modifying find_reloads_address to recognize that if the constant
11647 ;; is out-of-range for an immediate add, then we get better code by reloading
11648 ;; the constant into a register than by reloading the sum into a register,
11649 ;; since the former is one instruction shorter if the address does not need
11650 ;; to be offsettable. Unfortunately this does not work, because there is
11651 ;; only one register, r0, that can be used as an index register. This register
11652 ;; is also the function return value register. So, if we try to force reload
11653 ;; to use double-reg addresses, then we end up with some instructions that
11654 ;; need to use r0 twice. The only way to fix this is to change the calling
11655 ;; convention so that r0 is not used to return values.
11658 [(set (match_operand:SI 0 "register_operand" "=r")
11659 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11660 (set (mem:SI (match_dup 0))
11661 (match_operand:SI 2 "general_movsrc_operand" ""))]
11662 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11663 "mov.l %2,@(%0,%1)")
11666 [(set (match_operand:SI 0 "register_operand" "=r")
11667 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11668 (set (match_operand:SI 2 "general_movdst_operand" "")
11669 (mem:SI (match_dup 0)))]
11670 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11671 "mov.l @(%0,%1),%2")
11674 [(set (match_operand:SI 0 "register_operand" "=r")
11675 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11676 (set (mem:HI (match_dup 0))
11677 (match_operand:HI 2 "general_movsrc_operand" ""))]
11678 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11679 "mov.w %2,@(%0,%1)")
11682 [(set (match_operand:SI 0 "register_operand" "=r")
11683 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11684 (set (match_operand:HI 2 "general_movdst_operand" "")
11685 (mem:HI (match_dup 0)))]
11686 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11687 "mov.w @(%0,%1),%2")
11690 [(set (match_operand:SI 0 "register_operand" "=r")
11691 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11692 (set (mem:QI (match_dup 0))
11693 (match_operand:QI 2 "general_movsrc_operand" ""))]
11694 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11695 "mov.b %2,@(%0,%1)")
11698 [(set (match_operand:SI 0 "register_operand" "=r")
11699 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11700 (set (match_operand:QI 2 "general_movdst_operand" "")
11701 (mem:QI (match_dup 0)))]
11702 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11703 "mov.b @(%0,%1),%2")
11706 [(set (match_operand:SI 0 "register_operand" "=r")
11707 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11708 (set (mem:SF (match_dup 0))
11709 (match_operand:SF 2 "general_movsrc_operand" ""))]
11710 "TARGET_SH1 && REGNO (operands[0]) == 0
11711 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11712 || (GET_CODE (operands[2]) == SUBREG
11713 && REGNO (SUBREG_REG (operands[2])) < 16))
11714 && reg_unused_after (operands[0], insn)"
11715 "mov.l %2,@(%0,%1)")
11718 [(set (match_operand:SI 0 "register_operand" "=r")
11719 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11720 (set (match_operand:SF 2 "general_movdst_operand" "")
11722 (mem:SF (match_dup 0)))]
11723 "TARGET_SH1 && REGNO (operands[0]) == 0
11724 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11725 || (GET_CODE (operands[2]) == SUBREG
11726 && REGNO (SUBREG_REG (operands[2])) < 16))
11727 && reg_unused_after (operands[0], insn)"
11728 "mov.l @(%0,%1),%2")
11731 [(set (match_operand:SI 0 "register_operand" "=r")
11732 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11733 (set (mem:SF (match_dup 0))
11734 (match_operand:SF 2 "general_movsrc_operand" ""))]
11735 "TARGET_SH2E && REGNO (operands[0]) == 0
11736 && ((GET_CODE (operands[2]) == REG
11737 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11738 || (GET_CODE (operands[2]) == SUBREG
11739 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11740 && reg_unused_after (operands[0], insn)"
11741 "fmov{.s|} %2,@(%0,%1)")
11744 [(set (match_operand:SI 0 "register_operand" "=r")
11745 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11746 (set (match_operand:SF 2 "general_movdst_operand" "")
11748 (mem:SF (match_dup 0)))]
11749 "TARGET_SH2E && REGNO (operands[0]) == 0
11750 && ((GET_CODE (operands[2]) == REG
11751 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11752 || (GET_CODE (operands[2]) == SUBREG
11753 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11754 && reg_unused_after (operands[0], insn)"
11755 "fmov{.s|} @(%0,%1),%2")
11757 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11758 (define_insn "sp_switch_1"
11759 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11763 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11764 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11765 return \"mov r0,r15\";
11767 [(set_attr "length" "10")])
11769 ;; Switch back to the original stack for interrupt functions with the
11770 ;; sp_switch attribute. */
11771 (define_insn "sp_switch_2"
11774 "mov.l @r15+,r15\;mov.l @r15+,r0"
11775 [(set_attr "length" "4")])
11777 ;; Integer vector moves
11779 (define_expand "movv8qi"
11780 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11781 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11783 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11785 (define_insn "movv8qi_i"
11786 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11787 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11789 && (register_operand (operands[0], V8QImode)
11790 || sh_register_operand (operands[1], V8QImode))"
11797 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11798 (set_attr "length" "4,4,16,4,4")])
11801 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11802 (subreg:V8QI (const_int 0) 0))]
11804 [(set (match_dup 0)
11805 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11806 (const_int 0) (const_int 0) (const_int 0)
11807 (const_int 0) (const_int 0)]))])
11810 [(set (match_operand 0 "arith_reg_dest" "")
11811 (match_operand 1 "sh_rep_vec" ""))]
11812 "TARGET_SHMEDIA && reload_completed
11813 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11814 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11815 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11816 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11817 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11818 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11819 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11820 [(set (match_dup 0) (match_dup 1))
11824 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11825 rtx elt1 = XVECEXP (operands[1], 0, 1);
11828 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11832 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11833 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11835 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11836 operands[1] = XVECEXP (operands[1], 0, 0);
11839 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11841 = GEN_INT (TARGET_LITTLE_ENDIAN
11842 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11843 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11846 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11848 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11854 [(set (match_operand 0 "arith_reg_dest" "")
11855 (match_operand 1 "sh_const_vec" ""))]
11856 "TARGET_SHMEDIA && reload_completed
11857 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11858 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11859 [(set (match_dup 0) (match_dup 1))]
11862 rtx v = operands[1];
11863 enum machine_mode new_mode
11864 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11866 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11868 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11871 (define_expand "movv2hi"
11872 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11873 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11875 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11877 (define_insn "movv2hi_i"
11878 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11879 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11881 && (register_operand (operands[0], V2HImode)
11882 || sh_register_operand (operands[1], V2HImode))"
11889 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11890 (set_attr "length" "4,4,16,4,4")
11891 (set (attr "highpart")
11892 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11893 (const_string "user")]
11894 (const_string "ignore")))])
11896 (define_expand "movv4hi"
11897 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11898 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11900 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11902 (define_insn "movv4hi_i"
11903 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11904 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11906 && (register_operand (operands[0], V4HImode)
11907 || sh_register_operand (operands[1], V4HImode))"
11914 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11915 (set_attr "length" "4,4,16,4,4")
11916 (set_attr "highpart" "depend")])
11918 (define_expand "movv2si"
11919 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11920 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11922 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11924 (define_insn "movv2si_i"
11925 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11926 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11928 && (register_operand (operands[0], V2SImode)
11929 || sh_register_operand (operands[1], V2SImode))"
11936 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11937 (set_attr "length" "4,4,16,4,4")
11938 (set_attr "highpart" "depend")])
11940 ;; Multimedia Intrinsics
11942 (define_insn "absv2si2"
11943 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11944 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11947 [(set_attr "type" "mcmp_media")
11948 (set_attr "highpart" "depend")])
11950 (define_insn "absv4hi2"
11951 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11952 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11955 [(set_attr "type" "mcmp_media")
11956 (set_attr "highpart" "depend")])
11958 (define_insn "addv2si3"
11959 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11960 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11961 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11963 "madd.l %1, %2, %0"
11964 [(set_attr "type" "arith_media")
11965 (set_attr "highpart" "depend")])
11967 (define_insn "addv4hi3"
11968 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11969 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11970 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11972 "madd.w %1, %2, %0"
11973 [(set_attr "type" "arith_media")
11974 (set_attr "highpart" "depend")])
11976 (define_insn_and_split "addv2hi3"
11977 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11978 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11979 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11986 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11987 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11988 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11989 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11990 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11992 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11993 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11996 [(set_attr "highpart" "must_split")])
11998 (define_insn "ssaddv2si3"
11999 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12000 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12001 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12003 "madds.l %1, %2, %0"
12004 [(set_attr "type" "mcmp_media")
12005 (set_attr "highpart" "depend")])
12007 (define_insn "usaddv8qi3"
12008 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12009 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12010 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12012 "madds.ub %1, %2, %0"
12013 [(set_attr "type" "mcmp_media")
12014 (set_attr "highpart" "depend")])
12016 (define_insn "ssaddv4hi3"
12017 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12018 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12019 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12021 "madds.w %1, %2, %0"
12022 [(set_attr "type" "mcmp_media")
12023 (set_attr "highpart" "depend")])
12025 (define_insn "negcmpeqv8qi"
12026 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12027 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12028 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12030 "mcmpeq.b %N1, %N2, %0"
12031 [(set_attr "type" "mcmp_media")
12032 (set_attr "highpart" "depend")])
12034 (define_insn "negcmpeqv2si"
12035 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12036 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12037 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12039 "mcmpeq.l %N1, %N2, %0"
12040 [(set_attr "type" "mcmp_media")
12041 (set_attr "highpart" "depend")])
12043 (define_insn "negcmpeqv4hi"
12044 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12045 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12046 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12048 "mcmpeq.w %N1, %N2, %0"
12049 [(set_attr "type" "mcmp_media")
12050 (set_attr "highpart" "depend")])
12052 (define_insn "negcmpgtuv8qi"
12053 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12054 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12055 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12057 "mcmpgt.ub %N1, %N2, %0"
12058 [(set_attr "type" "mcmp_media")
12059 (set_attr "highpart" "depend")])
12061 (define_insn "negcmpgtv2si"
12062 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12063 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12064 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12066 "mcmpgt.l %N1, %N2, %0"
12067 [(set_attr "type" "mcmp_media")
12068 (set_attr "highpart" "depend")])
12070 (define_insn "negcmpgtv4hi"
12071 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12072 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12073 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12075 "mcmpgt.w %N1, %N2, %0"
12076 [(set_attr "type" "mcmp_media")
12077 (set_attr "highpart" "depend")])
12079 (define_insn "mcmv"
12080 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12081 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12082 (match_operand:DI 2 "arith_reg_operand" "r"))
12083 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12084 (not:DI (match_dup 2)))))]
12087 [(set_attr "type" "arith_media")
12088 (set_attr "highpart" "depend")])
12090 (define_insn "mcnvs_lw"
12091 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12093 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12094 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12096 "mcnvs.lw %N1, %N2, %0"
12097 [(set_attr "type" "mcmp_media")])
12099 (define_insn "mcnvs_wb"
12100 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12102 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12103 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12105 "mcnvs.wb %N1, %N2, %0"
12106 [(set_attr "type" "mcmp_media")])
12108 (define_insn "mcnvs_wub"
12109 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12111 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12112 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12114 "mcnvs.wub %N1, %N2, %0"
12115 [(set_attr "type" "mcmp_media")])
12117 (define_insn "mextr_rl"
12118 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12119 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12120 (match_operand:HI 3 "mextr_bit_offset" "i"))
12121 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12122 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12123 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12126 static char templ[21];
12128 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12129 (int) INTVAL (operands[3]) >> 3);
12132 [(set_attr "type" "arith_media")])
12134 (define_insn "*mextr_lr"
12135 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12136 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12137 (match_operand:HI 3 "mextr_bit_offset" "i"))
12138 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12139 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12140 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12143 static char templ[21];
12145 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12146 (int) INTVAL (operands[4]) >> 3);
12149 [(set_attr "type" "arith_media")])
12151 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12152 ; vector then varies depending on endianness.
12153 (define_expand "mextr1"
12154 [(match_operand:DI 0 "arith_reg_dest" "")
12155 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12156 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12160 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12161 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12165 (define_expand "mextr2"
12166 [(match_operand:DI 0 "arith_reg_dest" "")
12167 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12168 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12172 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12173 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12177 (define_expand "mextr3"
12178 [(match_operand:DI 0 "arith_reg_dest" "")
12179 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12180 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12184 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12185 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12189 (define_expand "mextr4"
12190 [(match_operand:DI 0 "arith_reg_dest" "")
12191 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12192 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12196 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12197 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12201 (define_expand "mextr5"
12202 [(match_operand:DI 0 "arith_reg_dest" "")
12203 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12204 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12208 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12209 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12213 (define_expand "mextr6"
12214 [(match_operand:DI 0 "arith_reg_dest" "")
12215 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12216 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12220 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12221 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12225 (define_expand "mextr7"
12226 [(match_operand:DI 0 "arith_reg_dest" "")
12227 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12228 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12232 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12233 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12237 (define_expand "mmacfx_wl"
12238 [(match_operand:V2SI 0 "arith_reg_dest" "")
12239 (match_operand:V2HI 1 "extend_reg_operand" "")
12240 (match_operand:V2HI 2 "extend_reg_operand" "")
12241 (match_operand:V2SI 3 "arith_reg_operand" "")]
12245 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12246 operands[1], operands[2]));
12250 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12252 (define_insn "mmacfx_wl_i"
12253 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12255 (match_operand:V2SI 1 "arith_reg_operand" "0")
12260 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12261 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12264 "mmacfx.wl %2, %3, %0"
12265 [(set_attr "type" "mac_media")
12266 (set_attr "highpart" "depend")])
12268 (define_expand "mmacnfx_wl"
12269 [(match_operand:V2SI 0 "arith_reg_dest" "")
12270 (match_operand:V2HI 1 "extend_reg_operand" "")
12271 (match_operand:V2HI 2 "extend_reg_operand" "")
12272 (match_operand:V2SI 3 "arith_reg_operand" "")]
12276 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12277 operands[1], operands[2]));
12281 (define_insn "mmacnfx_wl_i"
12282 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12284 (match_operand:V2SI 1 "arith_reg_operand" "0")
12289 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12290 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12293 "mmacnfx.wl %2, %3, %0"
12294 [(set_attr "type" "mac_media")
12295 (set_attr "highpart" "depend")])
12297 (define_insn "mulv2si3"
12298 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12299 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12300 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12302 "mmul.l %1, %2, %0"
12303 [(set_attr "type" "d2mpy_media")
12304 (set_attr "highpart" "depend")])
12306 (define_insn "mulv4hi3"
12307 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12308 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12309 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12311 "mmul.w %1, %2, %0"
12312 [(set_attr "type" "dmpy_media")
12313 (set_attr "highpart" "depend")])
12315 (define_insn "mmulfx_l"
12316 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12320 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12321 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12324 "mmulfx.l %1, %2, %0"
12325 [(set_attr "type" "d2mpy_media")
12326 (set_attr "highpart" "depend")])
12328 (define_insn "mmulfx_w"
12329 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12333 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12334 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12337 "mmulfx.w %1, %2, %0"
12338 [(set_attr "type" "dmpy_media")
12339 (set_attr "highpart" "depend")])
12341 (define_insn "mmulfxrp_w"
12342 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12347 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12348 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12352 "mmulfxrp.w %1, %2, %0"
12353 [(set_attr "type" "dmpy_media")
12354 (set_attr "highpart" "depend")])
12357 (define_expand "mmulhi_wl"
12358 [(match_operand:V2SI 0 "arith_reg_dest" "")
12359 (match_operand:V4HI 1 "arith_reg_operand" "")
12360 (match_operand:V4HI 2 "arith_reg_operand" "")]
12364 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12365 (operands[0], operands[1], operands[2]));
12369 (define_expand "mmullo_wl"
12370 [(match_operand:V2SI 0 "arith_reg_dest" "")
12371 (match_operand:V4HI 1 "arith_reg_operand" "")
12372 (match_operand:V4HI 2 "arith_reg_operand" "")]
12376 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12377 (operands[0], operands[1], operands[2]));
12381 (define_insn "mmul23_wl"
12382 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12385 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12386 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12387 (parallel [(const_int 2) (const_int 3)])))]
12389 "* return (TARGET_LITTLE_ENDIAN
12390 ? \"mmulhi.wl %1, %2, %0\"
12391 : \"mmullo.wl %1, %2, %0\");"
12392 [(set_attr "type" "dmpy_media")
12393 (set (attr "highpart")
12394 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12395 (const_string "user")))])
12397 (define_insn "mmul01_wl"
12398 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12401 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12402 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12403 (parallel [(const_int 0) (const_int 1)])))]
12405 "* return (TARGET_LITTLE_ENDIAN
12406 ? \"mmullo.wl %1, %2, %0\"
12407 : \"mmulhi.wl %1, %2, %0\");"
12408 [(set_attr "type" "dmpy_media")
12409 (set (attr "highpart")
12410 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12411 (const_string "user")))])
12414 (define_expand "mmulsum_wq"
12415 [(match_operand:DI 0 "arith_reg_dest" "")
12416 (match_operand:V4HI 1 "arith_reg_operand" "")
12417 (match_operand:V4HI 2 "arith_reg_operand" "")
12418 (match_operand:DI 3 "arith_reg_operand" "")]
12422 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12423 operands[1], operands[2]));
12427 (define_insn "mmulsum_wq_i"
12428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12429 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12434 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12435 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12436 (parallel [(const_int 0)]))
12437 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12438 (sign_extend:V4DI (match_dup 3)))
12439 (parallel [(const_int 1)])))
12441 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12442 (sign_extend:V4DI (match_dup 3)))
12443 (parallel [(const_int 2)]))
12444 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12445 (sign_extend:V4DI (match_dup 3)))
12446 (parallel [(const_int 3)]))))))]
12448 "mmulsum.wq %2, %3, %0"
12449 [(set_attr "type" "mac_media")])
12451 (define_expand "mperm_w"
12452 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12453 (match_operand:V4HI 1 "arith_reg_operand" "r")
12454 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12458 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12459 (operands[0], operands[1], operands[2]));
12463 ; This use of vec_select isn't exactly correct according to rtl.texi
12464 ; (because not constant), but it seems a straightforward extension.
12465 (define_insn "mperm_w_little"
12466 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12468 (match_operand:V4HI 1 "arith_reg_operand" "r")
12470 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12471 (const_int 2) (const_int 0))
12472 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12473 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12474 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12475 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12476 "mperm.w %1, %N2, %0"
12477 [(set_attr "type" "arith_media")])
12479 (define_insn "mperm_w_big"
12480 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12482 (match_operand:V4HI 1 "arith_reg_operand" "r")
12484 [(zero_extract:QI (not:QI (match_operand:QI 2
12485 "extend_reg_or_0_operand" "rZ"))
12486 (const_int 2) (const_int 0))
12487 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12488 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12489 (zero_extract:QI (not:QI (match_dup 2))
12490 (const_int 2) (const_int 6))])))]
12491 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12492 "mperm.w %1, %N2, %0"
12493 [(set_attr "type" "arith_media")])
12495 (define_insn "mperm_w0"
12496 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12497 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12498 "trunc_hi_operand" "r"))))]
12500 "mperm.w %1, r63, %0"
12501 [(set_attr "type" "arith_media")
12502 (set_attr "highpart" "ignore")])
12504 (define_expand "msad_ubq"
12505 [(match_operand:DI 0 "arith_reg_dest" "")
12506 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12507 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12508 (match_operand:DI 3 "arith_reg_operand" "")]
12512 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12513 operands[1], operands[2]));
12517 (define_insn "msad_ubq_i"
12518 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12523 (match_operand:DI 1 "arith_reg_operand" "0")
12524 (abs:DI (vec_select:DI
12527 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12529 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12530 (parallel [(const_int 0)]))))
12531 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12532 (zero_extend:V8DI (match_dup 3)))
12533 (parallel [(const_int 1)]))))
12535 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12536 (zero_extend:V8DI (match_dup 3)))
12537 (parallel [(const_int 2)])))
12538 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12539 (zero_extend:V8DI (match_dup 3)))
12540 (parallel [(const_int 3)])))))
12543 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12544 (zero_extend:V8DI (match_dup 3)))
12545 (parallel [(const_int 4)])))
12546 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12547 (zero_extend:V8DI (match_dup 3)))
12548 (parallel [(const_int 5)]))))
12550 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12551 (zero_extend:V8DI (match_dup 3)))
12552 (parallel [(const_int 6)])))
12553 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12554 (zero_extend:V8DI (match_dup 3)))
12555 (parallel [(const_int 7)])))))))]
12557 "msad.ubq %N2, %N3, %0"
12558 [(set_attr "type" "mac_media")])
12560 (define_insn "mshalds_l"
12561 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12564 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12565 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12566 (const_int 31)))))]
12568 "mshalds.l %1, %2, %0"
12569 [(set_attr "type" "mcmp_media")
12570 (set_attr "highpart" "depend")])
12572 (define_insn "mshalds_w"
12573 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12576 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12577 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12578 (const_int 15)))))]
12580 "mshalds.w %1, %2, %0"
12581 [(set_attr "type" "mcmp_media")
12582 (set_attr "highpart" "depend")])
12584 (define_insn "ashrv2si3"
12585 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12586 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12587 (match_operand:DI 2 "arith_reg_operand" "r")))]
12589 "mshard.l %1, %2, %0"
12590 [(set_attr "type" "arith_media")
12591 (set_attr "highpart" "depend")])
12593 (define_insn "ashrv4hi3"
12594 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12595 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12596 (match_operand:DI 2 "arith_reg_operand" "r")))]
12598 "mshard.w %1, %2, %0"
12599 [(set_attr "type" "arith_media")
12600 (set_attr "highpart" "depend")])
12602 (define_insn "mshards_q"
12603 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12605 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12606 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12608 "mshards.q %1, %N2, %0"
12609 [(set_attr "type" "mcmp_media")])
12611 (define_expand "mshfhi_b"
12612 [(match_operand:V8QI 0 "arith_reg_dest" "")
12613 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12614 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12618 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12619 (operands[0], operands[1], operands[2]));
12623 (define_expand "mshflo_b"
12624 [(match_operand:V8QI 0 "arith_reg_dest" "")
12625 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12626 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12630 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12631 (operands[0], operands[1], operands[2]));
12635 (define_insn "mshf4_b"
12637 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12639 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12640 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12641 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12642 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12644 "* return (TARGET_LITTLE_ENDIAN
12645 ? \"mshfhi.b %N1, %N2, %0\"
12646 : \"mshflo.b %N1, %N2, %0\");"
12647 [(set_attr "type" "arith_media")
12648 (set (attr "highpart")
12649 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12650 (const_string "user")))])
12652 (define_insn "mshf0_b"
12654 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12656 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12657 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12658 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12659 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12661 "* return (TARGET_LITTLE_ENDIAN
12662 ? \"mshflo.b %N1, %N2, %0\"
12663 : \"mshfhi.b %N1, %N2, %0\");"
12664 [(set_attr "type" "arith_media")
12665 (set (attr "highpart")
12666 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12667 (const_string "user")))])
12669 (define_expand "mshfhi_l"
12670 [(match_operand:V2SI 0 "arith_reg_dest" "")
12671 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12672 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12676 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12677 (operands[0], operands[1], operands[2]));
12681 (define_expand "mshflo_l"
12682 [(match_operand:V2SI 0 "arith_reg_dest" "")
12683 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12684 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12688 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12689 (operands[0], operands[1], operands[2]));
12693 (define_insn "mshf4_l"
12694 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12696 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12697 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12698 (parallel [(const_int 1) (const_int 3)])))]
12700 "* return (TARGET_LITTLE_ENDIAN
12701 ? \"mshfhi.l %N1, %N2, %0\"
12702 : \"mshflo.l %N1, %N2, %0\");"
12703 [(set_attr "type" "arith_media")
12704 (set (attr "highpart")
12705 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12706 (const_string "user")))])
12708 (define_insn "mshf0_l"
12709 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12711 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12712 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12713 (parallel [(const_int 0) (const_int 2)])))]
12715 "* return (TARGET_LITTLE_ENDIAN
12716 ? \"mshflo.l %N1, %N2, %0\"
12717 : \"mshfhi.l %N1, %N2, %0\");"
12718 [(set_attr "type" "arith_media")
12719 (set (attr "highpart")
12720 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12721 (const_string "user")))])
12723 (define_expand "mshfhi_w"
12724 [(match_operand:V4HI 0 "arith_reg_dest" "")
12725 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12726 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12730 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12731 (operands[0], operands[1], operands[2]));
12735 (define_expand "mshflo_w"
12736 [(match_operand:V4HI 0 "arith_reg_dest" "")
12737 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12738 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12742 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12743 (operands[0], operands[1], operands[2]));
12747 (define_insn "mshf4_w"
12748 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12750 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12751 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12752 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12754 "* return (TARGET_LITTLE_ENDIAN
12755 ? \"mshfhi.w %N1, %N2, %0\"
12756 : \"mshflo.w %N1, %N2, %0\");"
12757 [(set_attr "type" "arith_media")
12758 (set (attr "highpart")
12759 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12760 (const_string "user")))])
12762 (define_insn "mshf0_w"
12763 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12765 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12766 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12767 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12769 "* return (TARGET_LITTLE_ENDIAN
12770 ? \"mshflo.w %N1, %N2, %0\"
12771 : \"mshfhi.w %N1, %N2, %0\");"
12772 [(set_attr "type" "arith_media")
12773 (set (attr "highpart")
12774 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12775 (const_string "user")))])
12777 (define_insn "mshflo_w_x"
12778 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12780 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12781 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12782 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12784 "mshflo.w %N1, %N2, %0"
12785 [(set_attr "type" "arith_media")
12786 (set_attr "highpart" "ignore")])
12788 /* These are useful to expand ANDs and as combiner patterns. */
12789 (define_insn_and_split "mshfhi_l_di"
12790 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12791 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12793 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12794 (const_int -4294967296))))]
12797 mshfhi.l %N1, %N2, %0
12799 "TARGET_SHMEDIA && reload_completed
12800 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12801 [(set (match_dup 3) (match_dup 4))
12802 (set (match_dup 5) (match_dup 6))]
12805 operands[3] = gen_lowpart (SImode, operands[0]);
12806 operands[4] = gen_highpart (SImode, operands[1]);
12807 operands[5] = gen_highpart (SImode, operands[0]);
12808 operands[6] = gen_highpart (SImode, operands[2]);
12810 [(set_attr "type" "arith_media")])
12812 (define_insn "*mshfhi_l_di_rev"
12813 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12814 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12815 (const_int -4294967296))
12816 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12819 "mshfhi.l %N2, %N1, %0"
12820 [(set_attr "type" "arith_media")])
12823 [(set (match_operand:DI 0 "arith_reg_dest" "")
12824 (ior:DI (zero_extend:DI (match_operand:SI 1
12825 "extend_reg_or_0_operand" ""))
12826 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12827 (const_int -4294967296))))
12828 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12833 emit_insn (gen_ashldi3_media (operands[3],
12834 simplify_gen_subreg (DImode, operands[1],
12837 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12841 (define_insn "mshflo_l_di"
12842 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12843 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12844 (const_int 4294967295))
12845 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12849 "mshflo.l %N1, %N2, %0"
12850 [(set_attr "type" "arith_media")
12851 (set_attr "highpart" "ignore")])
12853 (define_insn "*mshflo_l_di_rev"
12854 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12855 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12857 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12858 (const_int 4294967295))))]
12861 "mshflo.l %N2, %N1, %0"
12862 [(set_attr "type" "arith_media")
12863 (set_attr "highpart" "ignore")])
12865 ;; Combiner pattern for trampoline initialization.
12866 (define_insn_and_split "*double_shori"
12867 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12868 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12870 (match_operand:DI 2 "const_int_operand" "n")))]
12872 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12874 "rtx_equal_p (operands[0], operands[1])"
12878 HOST_WIDE_INT v = INTVAL (operands[2]);
12880 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12881 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12884 [(set_attr "highpart" "ignore")])
12887 (define_insn "*mshflo_l_di_x"
12888 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12889 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12891 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12895 "mshflo.l %N1, %N2, %0"
12896 [(set_attr "type" "arith_media")
12897 (set_attr "highpart" "ignore")])
12899 (define_insn_and_split "concat_v2sf"
12900 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12901 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12902 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12903 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12907 mshflo.l %N1, %N2, %0
12910 "TARGET_SHMEDIA && reload_completed
12911 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12912 [(set (match_dup 3) (match_dup 1))
12913 (set (match_dup 4) (match_dup 2))]
12916 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12917 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12919 [(set_attr "type" "arith_media")
12920 (set_attr "highpart" "ignore")])
12922 (define_insn "*mshflo_l_di_x_rev"
12923 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12924 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12926 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12929 "mshflo.l %N2, %N1, %0"
12930 [(set_attr "type" "arith_media")
12931 (set_attr "highpart" "ignore")])
12933 (define_insn "ashlv2si3"
12934 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12935 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12936 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12938 "mshlld.l %1, %2, %0"
12939 [(set_attr "type" "arith_media")
12940 (set_attr "highpart" "depend")])
12943 [(set (match_operand 0 "any_register_operand" "")
12944 (match_operator 3 "shift_operator"
12945 [(match_operand 1 "any_register_operand" "")
12946 (match_operand 2 "shift_count_reg_operand" "")]))]
12947 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12948 [(set (match_dup 0) (match_dup 3))]
12951 rtx count = operands[2];
12952 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12954 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12955 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12956 || GET_CODE (count) == TRUNCATE)
12957 count = XEXP (count, 0);
12958 inner_mode = GET_MODE (count);
12959 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12960 subreg_lowpart_offset (outer_mode, inner_mode));
12961 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12962 operands[1], count);
12965 (define_insn "ashlv4hi3"
12966 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12967 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12968 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12970 "mshlld.w %1, %2, %0"
12971 [(set_attr "type" "arith_media")
12972 (set_attr "highpart" "depend")])
12974 (define_insn "lshrv2si3"
12975 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12976 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12977 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12979 "mshlrd.l %1, %2, %0"
12980 [(set_attr "type" "arith_media")
12981 (set_attr "highpart" "depend")])
12983 (define_insn "lshrv4hi3"
12984 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12985 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12986 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12988 "mshlrd.w %1, %2, %0"
12989 [(set_attr "type" "arith_media")
12990 (set_attr "highpart" "depend")])
12992 (define_insn "subv2si3"
12993 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12994 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12995 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12997 "msub.l %N1, %2, %0"
12998 [(set_attr "type" "arith_media")
12999 (set_attr "highpart" "depend")])
13001 (define_insn "subv4hi3"
13002 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13003 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13004 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13006 "msub.w %N1, %2, %0"
13007 [(set_attr "type" "arith_media")
13008 (set_attr "highpart" "depend")])
13010 (define_insn_and_split "subv2hi3"
13011 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13012 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13013 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13020 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13021 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13022 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13023 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13024 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13026 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13027 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13030 [(set_attr "highpart" "must_split")])
13032 (define_insn "sssubv2si3"
13033 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13034 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13035 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13037 "msubs.l %N1, %2, %0"
13038 [(set_attr "type" "mcmp_media")
13039 (set_attr "highpart" "depend")])
13041 (define_insn "ussubv8qi3"
13042 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13043 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13044 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13046 "msubs.ub %N1, %2, %0"
13047 [(set_attr "type" "mcmp_media")
13048 (set_attr "highpart" "depend")])
13050 (define_insn "sssubv4hi3"
13051 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13052 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13053 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13055 "msubs.w %N1, %2, %0"
13056 [(set_attr "type" "mcmp_media")
13057 (set_attr "highpart" "depend")])
13059 ;; Floating Point Intrinsics
13061 (define_insn "fcosa_s"
13062 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13063 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13067 [(set_attr "type" "atrans_media")])
13069 (define_insn "fsina_s"
13070 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13071 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13075 [(set_attr "type" "atrans_media")])
13077 (define_insn "fipr"
13078 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13079 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13080 "fp_arith_reg_operand" "f")
13081 (match_operand:V4SF 2
13082 "fp_arith_reg_operand" "f"))
13083 (parallel [(const_int 0)]))
13084 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13085 (parallel [(const_int 1)])))
13086 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13087 (parallel [(const_int 2)]))
13088 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13089 (parallel [(const_int 3)])))))]
13091 "fipr.s %1, %2, %0"
13092 [(set_attr "type" "fparith_media")])
13094 (define_insn "fsrra_s"
13095 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13096 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13100 [(set_attr "type" "atrans_media")])
13102 (define_insn "ftrv"
13103 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13107 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13108 (parallel [(const_int 0) (const_int 5)
13109 (const_int 10) (const_int 15)]))
13110 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13112 (vec_select:V4SF (match_dup 1)
13113 (parallel [(const_int 4) (const_int 9)
13114 (const_int 14) (const_int 3)]))
13115 (vec_select:V4SF (match_dup 2)
13116 (parallel [(const_int 1) (const_int 2)
13117 (const_int 3) (const_int 0)]))))
13120 (vec_select:V4SF (match_dup 1)
13121 (parallel [(const_int 8) (const_int 13)
13122 (const_int 2) (const_int 7)]))
13123 (vec_select:V4SF (match_dup 2)
13124 (parallel [(const_int 2) (const_int 3)
13125 (const_int 0) (const_int 1)])))
13127 (vec_select:V4SF (match_dup 1)
13128 (parallel [(const_int 12) (const_int 1)
13129 (const_int 6) (const_int 11)]))
13130 (vec_select:V4SF (match_dup 2)
13131 (parallel [(const_int 3) (const_int 0)
13132 (const_int 1) (const_int 2)]))))))]
13134 "ftrv.s %1, %2, %0"
13135 [(set_attr "type" "fparith_media")])
13137 (define_insn "ldhi_l"
13138 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13140 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13143 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13147 [(set_attr "type" "load_media")])
13149 (define_insn "ldhi_q"
13150 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13152 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13155 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13159 [(set_attr "type" "load_media")])
13161 (define_insn_and_split "*ldhi_q_comb0"
13162 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13164 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13165 "register_operand" "r")
13166 (match_operand:SI 2
13167 "ua_offset" "I06"))
13170 (plus:SI (and:SI (match_dup 1) (const_int 7))
13173 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13177 "emit_insn (gen_ldhi_q (operands[0],
13178 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13182 (define_insn_and_split "*ldhi_q_comb1"
13183 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13185 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13186 "register_operand" "r")
13187 (match_operand:SI 2
13188 "ua_offset" "I06"))
13191 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13192 "ua_offset" "I06"))
13196 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13197 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13201 "emit_insn (gen_ldhi_q (operands[0],
13202 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13206 (define_insn "ldlo_l"
13207 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13209 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13211 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13212 (and:SI (match_dup 1) (const_int 3))))]
13215 [(set_attr "type" "load_media")])
13217 (define_insn "ldlo_q"
13218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13220 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13222 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13223 (and:SI (match_dup 1) (const_int 7))))]
13226 [(set_attr "type" "load_media")])
13228 (define_insn_and_split "*ldlo_q_comb0"
13229 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13231 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13232 (match_operand:SI 2 "ua_offset" "I06"))
13234 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13235 (and:SI (match_dup 1) (const_int 7))))]
13236 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13240 "emit_insn (gen_ldlo_q (operands[0],
13241 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13244 (define_insn_and_split "*ldlo_q_comb1"
13245 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13247 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13248 (match_operand:SI 2 "ua_offset" "I06"))
13250 (minus:SI (const_int 8)
13251 (and:SI (plus:SI (match_dup 1)
13252 (match_operand:SI 3 "ua_offset" "I06"))
13254 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13255 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13256 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13260 "emit_insn (gen_ldlo_q (operands[0],
13261 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13264 (define_insn "sthi_l"
13265 [(set (zero_extract:SI
13266 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13269 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13271 (match_operand:SI 1 "arith_reg_operand" "r"))]
13274 [(set_attr "type" "ustore_media")])
13276 ;; All unaligned stores are considered to be 'narrow' because they typically
13277 ;; operate on less that a quadword, and when they operate on a full quadword,
13278 ;; the vanilla store high / store low sequence will cause a stall if not
13279 ;; scheduled apart.
13280 (define_insn "sthi_q"
13281 [(set (zero_extract:DI
13282 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13285 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13287 (match_operand:DI 1 "arith_reg_operand" "r"))]
13290 [(set_attr "type" "ustore_media")])
13292 (define_insn_and_split "*sthi_q_comb0"
13293 [(set (zero_extract:DI
13294 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13295 "register_operand" "r")
13296 (match_operand:SI 1 "ua_offset"
13300 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13302 (match_operand:DI 2 "arith_reg_operand" "r"))]
13303 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13307 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13311 (define_insn_and_split "*sthi_q_comb1"
13312 [(set (zero_extract:DI
13313 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13314 "register_operand" "r")
13315 (match_operand:SI 1 "ua_offset"
13319 (plus:SI (and:SI (plus:SI (match_dup 0)
13320 (match_operand:SI 2 "ua_offset" "I06"))
13324 (match_operand:DI 3 "arith_reg_operand" "r"))]
13325 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13326 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13330 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13334 ;; This is highpart user because the address is used as full 64 bit.
13335 (define_insn "stlo_l"
13336 [(set (zero_extract:SI
13337 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13339 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13340 (and:SI (match_dup 0) (const_int 3)))
13341 (match_operand:SI 1 "arith_reg_operand" "r"))]
13344 [(set_attr "type" "ustore_media")])
13346 (define_insn "stlo_q"
13347 [(set (zero_extract:DI
13348 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13350 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13351 (and:SI (match_dup 0) (const_int 7)))
13352 (match_operand:DI 1 "arith_reg_operand" "r"))]
13355 [(set_attr "type" "ustore_media")])
13357 (define_insn_and_split "*stlo_q_comb0"
13358 [(set (zero_extract:DI
13359 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13360 (match_operand:SI 1 "ua_offset" "I06"))
13362 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13363 (and:SI (match_dup 0) (const_int 7)))
13364 (match_operand:DI 2 "arith_reg_operand" "r"))]
13365 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13369 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13373 (define_insn_and_split "*stlo_q_comb1"
13374 [(set (zero_extract:DI
13375 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13376 (match_operand:SI 1 "ua_offset" "I06"))
13378 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13379 (match_operand:SI 2
13380 "ua_offset" "I06"))
13382 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13383 (match_operand:DI 3 "arith_reg_operand" "r"))]
13384 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13388 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13392 (define_insn "ldhi_l64"
13393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13395 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13398 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13402 [(set_attr "type" "load_media")])
13404 (define_insn "ldhi_q64"
13405 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13407 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13410 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13414 [(set_attr "type" "load_media")])
13416 (define_insn "ldlo_l64"
13417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13419 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13421 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13422 (and:DI (match_dup 1) (const_int 3))))]
13425 [(set_attr "type" "load_media")])
13427 (define_insn "ldlo_q64"
13428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13430 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13432 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13433 (and:DI (match_dup 1) (const_int 7))))]
13436 [(set_attr "type" "load_media")])
13438 (define_insn "sthi_l64"
13439 [(set (zero_extract:SI
13440 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13443 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13445 (match_operand:SI 1 "arith_reg_operand" "r"))]
13448 [(set_attr "type" "ustore_media")])
13450 (define_insn "sthi_q64"
13451 [(set (zero_extract:DI
13452 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13455 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13457 (match_operand:DI 1 "arith_reg_operand" "r"))]
13460 [(set_attr "type" "ustore_media")])
13462 (define_insn "stlo_l64"
13463 [(set (zero_extract:SI
13464 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13466 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13467 (and:DI (match_dup 0) (const_int 3)))
13468 (match_operand:SI 1 "arith_reg_operand" "r"))]
13471 [(set_attr "type" "ustore_media")])
13473 (define_insn "stlo_q64"
13474 [(set (zero_extract:DI
13475 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13477 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13478 (and:DI (match_dup 0) (const_int 7)))
13479 (match_operand:DI 1 "arith_reg_operand" "r"))]
13482 [(set_attr "type" "ustore_media")])
13485 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13486 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13490 [(set_attr "type" "arith_media")])
13492 (define_insn "nsbsi"
13493 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13495 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13499 [(set_attr "type" "arith_media")])
13501 (define_insn "nsbdi"
13502 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13504 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13508 [(set_attr "type" "arith_media")])
13510 (define_expand "ffsdi2"
13511 [(set (match_operand:DI 0 "arith_reg_dest" "")
13512 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13516 rtx scratch = gen_reg_rtx (DImode);
13519 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13520 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13521 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13522 emit_insn (gen_nsbdi (scratch, scratch));
13523 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13524 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13525 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13526 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13531 (define_expand "ffssi2"
13532 [(set (match_operand:SI 0 "arith_reg_dest" "")
13533 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13537 rtx scratch = gen_reg_rtx (SImode);
13538 rtx discratch = gen_reg_rtx (DImode);
13541 emit_insn (gen_adddi3 (discratch,
13542 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13544 emit_insn (gen_andcdi3 (discratch,
13545 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13547 emit_insn (gen_nsbsi (scratch, discratch));
13548 last = emit_insn (gen_subsi3 (operands[0],
13549 force_reg (SImode, GEN_INT (63)), scratch));
13550 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13555 (define_insn "byterev"
13556 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13557 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13558 (parallel [(const_int 7) (const_int 6) (const_int 5)
13559 (const_int 4) (const_int 3) (const_int 2)
13560 (const_int 1) (const_int 0)])))]
13563 [(set_attr "type" "arith_media")])
13565 (define_insn "*prefetch_media"
13566 [(prefetch (match_operand:QI 0 "address_operand" "p")
13567 (match_operand:SI 1 "const_int_operand" "n")
13568 (match_operand:SI 2 "const_int_operand" "n"))]
13572 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13573 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13576 [(set_attr "type" "other")])
13578 (define_insn "*prefetch_i4"
13579 [(prefetch (match_operand:SI 0 "register_operand" "r")
13580 (match_operand:SI 1 "const_int_operand" "n")
13581 (match_operand:SI 2 "const_int_operand" "n"))]
13582 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13585 return \"pref @%0\";
13587 [(set_attr "type" "other")])
13589 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13590 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13591 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13592 (define_expand "prefetch"
13593 [(prefetch (match_operand 0 "address_operand" "p")
13594 (match_operand:SI 1 "const_int_operand" "n")
13595 (match_operand:SI 2 "const_int_operand" "n"))]
13596 "(TARGET_HARD_SH4 || TARGET_SH5) && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP)"
13599 if (GET_MODE (operands[0]) != Pmode
13600 || GET_CODE (operands[1]) != CONST_INT
13601 || GET_CODE (operands[2]) != CONST_INT)
13603 if (! TARGET_SHMEDIA)
13604 operands[0] = force_reg (Pmode, operands[0]);
13607 (define_insn "alloco_i"
13608 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13609 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13615 if (GET_CODE (operands[0]) == PLUS)
13617 xops[0] = XEXP (operands[0], 0);
13618 xops[1] = XEXP (operands[0], 1);
13622 xops[0] = operands[0];
13623 xops[1] = const0_rtx;
13625 output_asm_insn (\"alloco %0, %1\", xops);
13628 [(set_attr "type" "other")])
13631 [(set (match_operand 0 "any_register_operand" "")
13632 (match_operand 1 "" ""))]
13633 "TARGET_SHMEDIA && reload_completed"
13634 [(set (match_dup 0) (match_dup 1))]
13639 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13644 ; Stack Protector Patterns
13646 (define_expand "stack_protect_set"
13647 [(set (match_operand 0 "memory_operand" "")
13648 (match_operand 1 "memory_operand" ""))]
13651 if (TARGET_SHMEDIA)
13653 if (TARGET_SHMEDIA64)
13654 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13656 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13659 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13664 (define_insn "stack_protect_set_si"
13665 [(set (match_operand:SI 0 "memory_operand" "=m")
13666 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13667 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13669 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13670 [(set_attr "type" "other")
13671 (set_attr "length" "6")])
13673 (define_insn "stack_protect_set_si_media"
13674 [(set (match_operand:SI 0 "memory_operand" "=m")
13675 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13676 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13678 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13679 [(set_attr "type" "other")
13680 (set_attr "length" "12")])
13682 (define_insn "stack_protect_set_di_media"
13683 [(set (match_operand:DI 0 "memory_operand" "=m")
13684 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13685 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13687 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13688 [(set_attr "type" "other")
13689 (set_attr "length" "12")])
13691 (define_expand "stack_protect_test"
13692 [(match_operand 0 "memory_operand" "")
13693 (match_operand 1 "memory_operand" "")
13694 (match_operand 2 "" "")]
13697 if (TARGET_SHMEDIA)
13699 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13701 if (TARGET_SHMEDIA64)
13702 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13705 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13708 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13712 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13713 emit_jump_insn (gen_branch_true (operands[2]));
13719 (define_insn "stack_protect_test_si"
13720 [(set (reg:SI T_REG)
13721 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13722 (match_operand:SI 1 "memory_operand" "m")]
13724 (set (match_scratch:SI 2 "=&r") (const_int 0))
13725 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13727 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13728 [(set_attr "type" "other")
13729 (set_attr "length" "10")])
13731 (define_insn "stack_protect_test_si_media"
13732 [(set (match_operand:SI 0 "register_operand" "=&r")
13733 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13734 (match_operand:SI 2 "memory_operand" "m")]
13736 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13738 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13739 [(set_attr "type" "other")
13740 (set_attr "length" "16")])
13742 (define_insn "stack_protect_test_di_media"
13743 [(set (match_operand:DI 0 "register_operand" "=&r")
13744 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13745 (match_operand:DI 2 "memory_operand" "m")]
13747 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13749 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13750 [(set_attr "type" "other")
13751 (set_attr "length" "16")])