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 if (satisfies_constraint_N (dividend))
2476 emit_move_insn (result, dividend);
2480 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2481 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2482 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2483 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2484 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2485 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2486 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2490 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2491 ;; inv1: tab_base, tab_ix, norm32
2492 ;; inv2: norm32, inv1, i92
2493 (define_insn_and_split "divsi_inv_m1_3"
2494 [(set (match_operand:SI 0 "register_operand" "=r")
2495 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2496 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2497 (match_operand:DI 3 "register_operand" "r")
2498 (match_operand:SI 4 "register_operand" "r")]
2500 (unspec:SI [(match_dup 4)
2501 (unspec:SI [(match_dup 2)
2503 (match_dup 4)] UNSPEC_DIV_INV_M1)
2504 (match_operand:SI 5 "" "")]
2506 (match_operand:DI 6 "register_operand" "r")
2507 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2508 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2510 (clobber (match_operand:DI 9 "register_operand" "=r"))
2511 (clobber (match_operand:DI 10 "register_operand" "=r"))
2512 (clobber (match_operand:DI 11 "register_operand" "=r"))
2513 (clobber (match_operand:DI 12 "register_operand" "=r"))
2514 (clobber (match_operand:SI 13 "register_operand" "=r"))
2515 (clobber (match_operand:SI 14 "register_operand" "=r"))
2516 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2518 && (TARGET_DIVIDE_INV_MINLAT
2519 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2521 "&& !can_create_pseudo_p ()"
2525 rtx result = operands[0];
2526 rtx dividend = operands[1];
2527 rtx tab_base = operands[2];
2528 rtx tab_ix = operands[3];
2529 rtx norm32 = operands[4];
2530 /* rtx i92 = operands[5]; */
2531 rtx shift = operands[6];
2532 rtx i2p27 = operands[7];
2533 rtx i43 = operands[8];
2534 rtx scratch0 = operands[9];
2535 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2536 rtx scratch1 = operands[10];
2537 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2538 rtx scratch2 = operands[11];
2539 rtx scratch3 = operands[12];
2540 rtx scratch4 = operands[13];
2541 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2542 rtx scratch5 = operands[14];
2543 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2544 rtx scratch6 = operands[15];
2546 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2547 scratch0, scratch1));
2548 /* inv0 == scratch4 */
2549 if (! TARGET_DIVIDE_INV20U)
2551 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2553 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2557 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2558 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2560 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2561 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2562 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2563 /* inv1 == scratch4 */
2565 if (TARGET_DIVIDE_INV_MINLAT)
2567 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2568 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2569 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2570 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2571 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2572 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2573 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2574 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2575 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2576 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2577 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2581 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2582 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2583 emit_insn (gen_nsbdi (scratch6,
2584 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2585 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2586 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2587 emit_insn (gen_divsi_inv20 (scratch2,
2588 norm32, scratch4, dividend,
2589 scratch6, scratch3, i43,
2590 /* scratch0 may be shared with i2p27. */
2591 scratch0, scratch1, scratch5,
2592 label, label, i2p27));
2594 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2595 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2599 (define_insn "divsi_inv20"
2600 [(set (match_operand:DI 0 "register_operand" "=&r")
2601 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2602 (match_operand:SI 2 "register_operand" "r")
2603 (match_operand:SI 3 "register_operand" "r")
2604 (match_operand:DI 4 "register_operand" "r")
2605 (match_operand:DI 5 "register_operand" "r")
2606 (match_operand:DI 6 "register_operand" "r")
2607 (match_operand:DI 12 "register_operand" "r")
2608 (match_operand 10 "target_operand" "b")
2609 (match_operand 11 "immediate_operand" "i")]
2611 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2612 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2613 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2615 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2618 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2619 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2620 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2621 %10 label (tr), %11 label (imm)
2623 muls.l inv1, norm32, scratch0 // s2.60
2624 muls.l inv1, dividend, result // s32.30
2625 xor i2p27, result_sign, round_scratch
2626 bge/u dividend_nsb, i43, tr.. (label)
2627 shari scratch0, 16, scratch0 // s-16.44
2628 muls.l sratch0_si, inv1, scratch0 // s-16.74
2629 sub result, round_scratch, result
2630 shari dividend, 14, scratch1 // s19.-14
2631 shari scratch0, 30, scratch0 // s-16.44
2632 muls.l scratch0, scratch1, round_scratch // s15.30
2634 sub result, round_scratch, result */
2636 int likely = TARGET_DIVIDE_INV20L;
2638 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2639 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2640 output_asm_insn (likely
2641 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2642 : \"bge/u\t%4, %6, %10\", operands);
2643 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2644 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2645 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2647 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2648 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2651 (define_insn_and_split "divsi_inv_fp"
2652 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2653 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2654 (match_operand:SI 2 "register_operand" "rf")))
2655 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2656 (clobber (match_operand:SI 4 "register_operand" "=r"))
2657 (clobber (match_operand:SI 5 "register_operand" "=r"))
2658 (clobber (match_operand:DF 6 "register_operand" "=r"))
2659 (clobber (match_operand:DF 7 "register_operand" "=r"))
2660 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2661 "TARGET_SHMEDIA_FPU"
2663 "&& (high_life_started || reload_completed)"
2664 [(set (match_dup 0) (match_dup 3))]
2666 [(set_attr "highpart" "must_split")])
2668 ;; If a matching group of divide-by-inverse instructions is in the same
2669 ;; basic block after gcse & loop optimizations, we want to transform them
2670 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2671 (define_insn_and_split "*divsi_inv_fp_combine"
2672 [(set (match_operand:SI 0 "register_operand" "=f")
2673 (div:SI (match_operand:SI 1 "register_operand" "f")
2674 (match_operand:SI 2 "register_operand" "f")))
2675 (use (unspec:SI [(match_dup 1)
2676 (match_operand:SI 3 "" "")
2677 (unspec:SI [(match_operand:SI 4 "" "")
2679 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2680 (match_operand:DI 6 "" "")
2682 (const_int 0)] UNSPEC_DIV_INV_M3))
2683 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2684 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2685 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2686 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2687 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2688 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2691 [(set (match_dup 9) (float:DF (match_dup 1)))
2692 (set (match_dup 10) (float:DF (match_dup 2)))
2693 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2695 (fix:SI (match_dup 11)))
2696 (set (match_dup 0) (match_dup 8))]
2699 if (! fp_arith_reg_operand (operands[1], SImode))
2701 emit_move_insn (operands[7], operands[1]);
2702 operands[1] = operands[7];
2704 if (! fp_arith_reg_operand (operands[2], SImode))
2706 emit_move_insn (operands[8], operands[2]);
2707 operands[2] = operands[8];
2710 [(set_attr "highpart" "must_split")])
2712 ;; -------------------------------------------------------------------------
2713 ;; Multiplication instructions
2714 ;; -------------------------------------------------------------------------
2716 (define_insn "umulhisi3_i"
2717 [(set (reg:SI MACL_REG)
2718 (mult:SI (zero_extend:SI
2719 (match_operand:HI 0 "arith_reg_operand" "r"))
2721 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2724 [(set_attr "type" "smpy")])
2726 (define_insn "mulhisi3_i"
2727 [(set (reg:SI MACL_REG)
2728 (mult:SI (sign_extend:SI
2729 (match_operand:HI 0 "arith_reg_operand" "r"))
2731 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2734 [(set_attr "type" "smpy")])
2736 (define_expand "mulhisi3"
2737 [(set (reg:SI MACL_REG)
2738 (mult:SI (sign_extend:SI
2739 (match_operand:HI 1 "arith_reg_operand" ""))
2741 (match_operand:HI 2 "arith_reg_operand" ""))))
2742 (set (match_operand:SI 0 "arith_reg_operand" "")
2749 macl = gen_rtx_REG (SImode, MACL_REG);
2751 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2752 insn = get_insns ();
2754 /* expand_binop can't find a suitable code in umul_widen_optab to
2755 make a REG_EQUAL note from, so make one here.
2756 See also smulsi3_highpart.
2757 ??? Alternatively, we could put this at the calling site of expand_binop,
2758 i.e. expand_expr. */
2759 /* Use emit_libcall_block for loop invariant code motion and to make
2760 a REG_EQUAL note. */
2761 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2766 (define_expand "umulhisi3"
2767 [(set (reg:SI MACL_REG)
2768 (mult:SI (zero_extend:SI
2769 (match_operand:HI 1 "arith_reg_operand" ""))
2771 (match_operand:HI 2 "arith_reg_operand" ""))))
2772 (set (match_operand:SI 0 "arith_reg_operand" "")
2779 macl = gen_rtx_REG (SImode, MACL_REG);
2781 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2782 insn = get_insns ();
2784 /* expand_binop can't find a suitable code in umul_widen_optab to
2785 make a REG_EQUAL note from, so make one here.
2786 See also smulsi3_highpart.
2787 ??? Alternatively, we could put this at the calling site of expand_binop,
2788 i.e. expand_expr. */
2789 /* Use emit_libcall_block for loop invariant code motion and to make
2790 a REG_EQUAL note. */
2791 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2796 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2797 ;; a call to a routine which clobbers known registers.
2800 [(set (match_operand:SI 1 "register_operand" "=z")
2801 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2802 (clobber (reg:SI MACL_REG))
2803 (clobber (reg:SI T_REG))
2804 (clobber (reg:SI PR_REG))
2805 (clobber (reg:SI R3_REG))
2806 (clobber (reg:SI R2_REG))
2807 (clobber (reg:SI R1_REG))
2808 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2811 [(set_attr "type" "sfunc")
2812 (set_attr "needs_delay_slot" "yes")])
2814 (define_expand "mulsi3_call"
2815 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2816 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2817 (parallel[(set (match_operand:SI 0 "register_operand" "")
2818 (mult:SI (reg:SI R4_REG)
2820 (clobber (reg:SI MACL_REG))
2821 (clobber (reg:SI T_REG))
2822 (clobber (reg:SI PR_REG))
2823 (clobber (reg:SI R3_REG))
2824 (clobber (reg:SI R2_REG))
2825 (clobber (reg:SI R1_REG))
2826 (use (match_operand:SI 3 "register_operand" ""))])]
2830 (define_insn "mul_r"
2831 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2832 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2833 (match_operand:SI 2 "arith_reg_operand" "z")))]
2836 [(set_attr "type" "dmpy")])
2838 (define_insn "mul_l"
2839 [(set (reg:SI MACL_REG)
2840 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2841 (match_operand:SI 1 "arith_reg_operand" "r")))]
2844 [(set_attr "type" "dmpy")])
2846 (define_expand "mulsi3"
2847 [(set (reg:SI MACL_REG)
2848 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2849 (match_operand:SI 2 "arith_reg_operand" "")))
2850 (set (match_operand:SI 0 "arith_reg_operand" "")
2857 /* The address must be set outside the libcall,
2858 since it goes into a pseudo. */
2859 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2860 rtx addr = force_reg (SImode, sym);
2861 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2867 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2869 emit_insn (gen_mul_l (operands[1], operands[2]));
2870 /* consec_sets_giv can only recognize the first insn that sets a
2871 giv as the giv insn. So we must tag this also with a REG_EQUAL
2873 emit_insn (gen_movsi_i ((operands[0]), macl));
2878 (define_insn "mulsidi3_i"
2879 [(set (reg:SI MACH_REG)
2883 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2884 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2886 (set (reg:SI MACL_REG)
2887 (mult:SI (match_dup 0)
2891 [(set_attr "type" "dmpy")])
2893 (define_expand "mulsidi3"
2894 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2895 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2896 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2897 "TARGET_SH2 || TARGET_SHMEDIA"
2902 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2908 (define_insn "mulsidi3_media"
2909 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2910 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2911 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2914 [(set_attr "type" "dmpy_media")
2915 (set_attr "highpart" "ignore")])
2917 (define_insn "mulsidi3_compact"
2918 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2920 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2921 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2922 (clobber (reg:SI MACH_REG))
2923 (clobber (reg:SI MACL_REG))]
2928 [(set (match_operand:DI 0 "arith_reg_dest" "")
2930 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2931 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2932 (clobber (reg:SI MACH_REG))
2933 (clobber (reg:SI MACL_REG))]
2938 rtx low_dst = gen_lowpart (SImode, operands[0]);
2939 rtx high_dst = gen_highpart (SImode, operands[0]);
2941 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2943 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2944 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2945 /* We need something to tag the possible REG_EQUAL notes on to. */
2946 emit_move_insn (operands[0], operands[0]);
2950 (define_insn "umulsidi3_i"
2951 [(set (reg:SI MACH_REG)
2955 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2956 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2958 (set (reg:SI MACL_REG)
2959 (mult:SI (match_dup 0)
2963 [(set_attr "type" "dmpy")])
2965 (define_expand "umulsidi3"
2966 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2967 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2968 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2969 "TARGET_SH2 || TARGET_SHMEDIA"
2974 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2980 (define_insn "umulsidi3_media"
2981 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2982 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2983 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2986 [(set_attr "type" "dmpy_media")
2987 (set_attr "highpart" "ignore")])
2989 (define_insn "umulsidi3_compact"
2990 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2992 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2993 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2994 (clobber (reg:SI MACH_REG))
2995 (clobber (reg:SI MACL_REG))]
3000 [(set (match_operand:DI 0 "arith_reg_dest" "")
3001 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3002 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3003 (clobber (reg:SI MACH_REG))
3004 (clobber (reg:SI MACL_REG))]
3009 rtx low_dst = gen_lowpart (SImode, operands[0]);
3010 rtx high_dst = gen_highpart (SImode, operands[0]);
3012 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3014 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3015 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3016 /* We need something to tag the possible REG_EQUAL notes on to. */
3017 emit_move_insn (operands[0], operands[0]);
3021 (define_insn "smulsi3_highpart_i"
3022 [(set (reg:SI MACH_REG)
3026 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3027 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3029 (clobber (reg:SI MACL_REG))]
3032 [(set_attr "type" "dmpy")])
3034 (define_expand "smulsi3_highpart"
3036 [(set (reg:SI MACH_REG)
3040 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3041 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3043 (clobber (reg:SI MACL_REG))])
3044 (set (match_operand:SI 0 "arith_reg_operand" "")
3051 mach = gen_rtx_REG (SImode, MACH_REG);
3053 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3054 insn = get_insns ();
3056 /* expand_binop can't find a suitable code in mul_highpart_optab to
3057 make a REG_EQUAL note from, so make one here.
3058 See also {,u}mulhisi.
3059 ??? Alternatively, we could put this at the calling site of expand_binop,
3060 i.e. expand_mult_highpart. */
3061 /* Use emit_libcall_block for loop invariant code motion and to make
3062 a REG_EQUAL note. */
3063 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3068 (define_insn "umulsi3_highpart_i"
3069 [(set (reg:SI MACH_REG)
3073 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3074 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3076 (clobber (reg:SI MACL_REG))]
3079 [(set_attr "type" "dmpy")])
3081 (define_expand "umulsi3_highpart"
3083 [(set (reg:SI MACH_REG)
3087 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3088 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3090 (clobber (reg:SI MACL_REG))])
3091 (set (match_operand:SI 0 "arith_reg_operand" "")
3098 mach = gen_rtx_REG (SImode, MACH_REG);
3100 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3101 insn = get_insns ();
3103 /* Use emit_libcall_block for loop invariant code motion and to make
3104 a REG_EQUAL note. */
3105 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3110 (define_insn_and_split "muldi3"
3111 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3112 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3113 (match_operand:DI 2 "arith_reg_operand" "r")))
3114 (clobber (match_scratch:DI 3 "=&r"))
3115 (clobber (match_scratch:DI 4 "=r"))]
3122 rtx op3_v2si, op2_v2si;
3124 op3_v2si = operands[3];
3125 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3127 op3_v2si = XEXP (op3_v2si, 0);
3128 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3130 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3131 op2_v2si = operands[2];
3132 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3134 op2_v2si = XEXP (op2_v2si, 0);
3135 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3137 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3138 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3139 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3140 emit_insn (gen_umulsidi3_media (operands[4],
3141 sh_gen_truncate (SImode, operands[1], 0),
3142 sh_gen_truncate (SImode, operands[2], 0)));
3143 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3144 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3145 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3146 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3151 ;; -------------------------------------------------------------------------
3152 ;; Logical operations
3153 ;; -------------------------------------------------------------------------
3155 (define_insn "*andsi3_compact"
3156 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3157 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3158 (match_operand:SI 2 "logical_operand" "r,K08")))]
3161 [(set_attr "type" "arith")])
3163 (define_insn "*andsi3_media"
3164 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3165 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3166 (match_operand:SI 2 "logical_operand" "r,I10")))]
3171 [(set_attr "type" "arith_media")])
3173 ;; If the constant is 255, then emit an extu.b instruction instead of an
3174 ;; and, since that will give better code.
3176 (define_expand "andsi3"
3177 [(set (match_operand:SI 0 "arith_reg_operand" "")
3178 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3179 (match_operand:SI 2 "logical_operand" "")))]
3184 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3186 emit_insn (gen_zero_extendqisi2 (operands[0],
3187 gen_lowpart (QImode, operands[1])));
3192 (define_insn_and_split "anddi3"
3193 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3194 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3195 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3202 && ! logical_operand (operands[2], DImode)"
3206 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3207 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3209 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3212 [(set_attr "type" "arith_media")])
3214 (define_insn "andcsi3"
3215 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3216 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3217 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3220 [(set_attr "type" "arith_media")])
3222 (define_insn "andcdi3"
3223 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3224 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3225 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3228 [(set_attr "type" "arith_media")])
3230 (define_expand "iorsi3"
3231 [(set (match_operand:SI 0 "arith_reg_operand" "")
3232 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3233 (match_operand:SI 2 "logical_operand" "")))]
3237 (define_insn "*iorsi3_compact"
3238 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3239 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3240 (match_operand:SI 2 "logical_operand" "r,K08")))]
3243 [(set_attr "type" "arith")])
3245 (define_insn "*iorsi3_media"
3246 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3247 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3248 (match_operand:SI 2 "logical_operand" "r,I10")))]
3253 [(set_attr "type" "arith_media")])
3255 (define_insn "iordi3"
3256 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3257 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3258 (match_operand:DI 2 "logical_operand" "r,I10")))]
3263 [(set_attr "type" "arith_media")])
3265 (define_insn_and_split "*logical_sidi3"
3266 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3267 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3268 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3269 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3272 "&& reload_completed"
3273 [(set (match_dup 0) (match_dup 3))]
3277 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3278 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3279 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3282 (define_insn_and_split "*logical_sidisi3"
3283 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3284 (truncate:SI (sign_extend:DI
3285 (match_operator:SI 3 "logical_operator"
3286 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3287 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3291 [(set (match_dup 0) (match_dup 3))])
3293 (define_insn_and_split "*logical_sidi3_2"
3294 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295 (sign_extend:DI (truncate:SI (sign_extend:DI
3296 (match_operator:SI 3 "logical_operator"
3297 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3298 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3302 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3304 (define_expand "xorsi3"
3305 [(set (match_operand:SI 0 "arith_reg_operand" "")
3306 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3307 (match_operand:SI 2 "xor_operand" "")))]
3311 (define_insn "*xorsi3_compact"
3312 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3313 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3314 (match_operand:SI 2 "logical_operand" "K08,r")))]
3317 [(set_attr "type" "arith")])
3319 (define_insn "*xorsi3_media"
3320 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3321 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3322 (match_operand:SI 2 "xor_operand" "r,I06")))]
3327 [(set_attr "type" "arith_media")])
3329 (define_insn "xordi3"
3330 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3331 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3332 (match_operand:DI 2 "xor_operand" "r,I06")))]
3337 [(set_attr "type" "arith_media")])
3339 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3340 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3342 [(set (match_operand:DI 0 "arith_reg_dest" "")
3343 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3344 [(match_operand 1 "any_register_operand" "")
3345 (match_operand 2 "any_register_operand" "")])))]
3347 [(set (match_dup 5) (match_dup 4))
3348 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3351 enum machine_mode inmode = GET_MODE (operands[1]);
3354 if (GET_CODE (operands[0]) == SUBREG)
3356 offset = SUBREG_BYTE (operands[0]);
3357 operands[0] = SUBREG_REG (operands[0]);
3359 gcc_assert (GET_CODE (operands[0]) == REG);
3360 if (! TARGET_LITTLE_ENDIAN)
3361 offset += 8 - GET_MODE_SIZE (inmode);
3362 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3365 ;; -------------------------------------------------------------------------
3366 ;; Shifts and rotates
3367 ;; -------------------------------------------------------------------------
3369 (define_expand "rotldi3"
3370 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3371 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3372 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3374 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3376 (define_insn "rotldi3_mextr"
3377 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3378 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3379 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3383 static char templ[16];
3385 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3386 8 - (int) (INTVAL (operands[2]) >> 3));
3389 [(set_attr "type" "arith_media")])
3391 (define_expand "rotrdi3"
3392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3393 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3394 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3396 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3398 (define_insn "rotrdi3_mextr"
3399 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3400 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3401 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3405 static char templ[16];
3407 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3410 [(set_attr "type" "arith_media")])
3413 [(set (match_operand:DI 0 "arith_reg_dest" "")
3414 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3415 "ua_address_operand" "")))
3416 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3418 (clobber (match_operand:DI 3 "register_operand" ""))]
3420 [(match_dup 4) (match_dup 5)]
3423 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3424 (operands[3], operands[1]));
3425 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3426 GEN_INT (56), GEN_INT (8));
3429 (define_insn "rotlsi3_1"
3430 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3431 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3434 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3437 [(set_attr "type" "arith")])
3439 (define_insn "rotlsi3_31"
3440 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3441 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3443 (clobber (reg:SI T_REG))]
3446 [(set_attr "type" "arith")])
3448 (define_insn "rotlsi3_16"
3449 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3450 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3454 [(set_attr "type" "arith")])
3456 (define_expand "rotlsi3"
3457 [(set (match_operand:SI 0 "arith_reg_dest" "")
3458 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3459 (match_operand:SI 2 "immediate_operand" "")))]
3463 static const char rot_tab[] = {
3464 000, 000, 000, 000, 000, 000, 010, 001,
3465 001, 001, 011, 013, 003, 003, 003, 003,
3466 003, 003, 003, 003, 003, 013, 012, 002,
3467 002, 002, 010, 000, 000, 000, 000, 000,
3472 if (GET_CODE (operands[2]) != CONST_INT)
3474 count = INTVAL (operands[2]);
3475 choice = rot_tab[count];
3476 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3482 emit_move_insn (operands[0], operands[1]);
3483 count -= (count & 16) * 2;
3486 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3493 parts[0] = gen_reg_rtx (SImode);
3494 parts[1] = gen_reg_rtx (SImode);
3495 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3496 emit_move_insn (parts[choice-1], operands[1]);
3497 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3498 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3499 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3500 count = (count & ~16) - 8;
3504 for (; count > 0; count--)
3505 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3506 for (; count < 0; count++)
3507 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3512 (define_insn "*rotlhi3_8"
3513 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3514 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3518 [(set_attr "type" "arith")])
3520 (define_expand "rotlhi3"
3521 [(set (match_operand:HI 0 "arith_reg_operand" "")
3522 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3523 (match_operand:HI 2 "immediate_operand" "")))]
3527 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3534 (define_insn "ashlsi3_sh2a"
3535 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3536 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3537 (match_operand:SI 2 "arith_reg_operand" "r")))]
3540 [(set_attr "type" "arith")
3541 (set_attr "length" "4")])
3543 ;; This pattern is used by init_expmed for computing the costs of shift
3546 (define_insn_and_split "ashlsi3_std"
3547 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3548 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3549 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3550 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3552 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3560 && GET_CODE (operands[2]) == CONST_INT
3561 && ! satisfies_constraint_P27 (operands[2])"
3562 [(set (match_dup 3) (match_dup 2))
3564 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3565 (clobber (match_dup 4))])]
3566 "operands[4] = gen_rtx_SCRATCH (SImode);"
3567 [(set_attr "length" "*,*,*,4")
3568 (set_attr "type" "dyn_shift,arith,arith,arith")])
3570 (define_insn "ashlhi3_k"
3571 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3572 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3573 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3574 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3578 [(set_attr "type" "arith")])
3580 (define_insn "ashlsi3_n"
3581 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3582 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3583 (match_operand:SI 2 "const_int_operand" "n")))
3584 (clobber (reg:SI T_REG))]
3585 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3587 [(set (attr "length")
3588 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3590 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3592 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3594 (const_string "8")))
3595 (set_attr "type" "arith")])
3598 [(set (match_operand:SI 0 "arith_reg_dest" "")
3599 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3600 (match_operand:SI 2 "const_int_operand" "")))
3601 (clobber (reg:SI T_REG))]
3602 "TARGET_SH1 && reload_completed"
3603 [(use (reg:SI R0_REG))]
3606 gen_shifty_op (ASHIFT, operands);
3610 (define_insn "ashlsi3_media"
3611 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3612 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3613 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3618 [(set_attr "type" "arith_media")
3619 (set_attr "highpart" "ignore")])
3621 (define_expand "ashlsi3"
3622 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3623 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3624 (match_operand:SI 2 "nonmemory_operand" "")))
3625 (clobber (reg:SI T_REG))])]
3631 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3634 if (GET_CODE (operands[2]) == CONST_INT
3635 && sh_dynamicalize_shift_p (operands[2]))
3636 operands[2] = force_reg (SImode, operands[2]);
3639 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3642 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3646 (define_insn "*ashlhi3_n"
3647 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3648 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3649 (match_operand:HI 2 "const_int_operand" "n")))
3650 (clobber (reg:SI T_REG))]
3653 [(set (attr "length")
3654 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3656 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3658 (const_string "6")))
3659 (set_attr "type" "arith")])
3661 (define_expand "ashlhi3"
3662 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3663 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3664 (match_operand:SI 2 "nonmemory_operand" "")))
3665 (clobber (reg:SI T_REG))])]
3669 if (GET_CODE (operands[2]) != CONST_INT)
3671 /* It may be possible to call gen_ashlhi3 directly with more generic
3672 operands. Make sure operands[1] is a HImode register here. */
3673 if (!arith_reg_operand (operands[1], HImode))
3674 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3678 [(set (match_operand:HI 0 "arith_reg_dest" "")
3679 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3680 (match_operand:HI 2 "const_int_operand" "")))
3681 (clobber (reg:SI T_REG))]
3682 "TARGET_SH1 && reload_completed"
3683 [(use (reg:SI R0_REG))]
3686 gen_shifty_hi_op (ASHIFT, operands);
3691 ; arithmetic shift right
3694 (define_insn "ashrsi3_sh2a"
3695 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3696 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3697 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3700 [(set_attr "type" "dyn_shift")
3701 (set_attr "length" "4")])
3703 (define_insn "ashrsi3_k"
3704 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3705 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3706 (match_operand:SI 2 "const_int_operand" "M")))
3707 (clobber (reg:SI T_REG))]
3708 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3710 [(set_attr "type" "arith")])
3712 ;; We can't do HImode right shifts correctly unless we start out with an
3713 ;; explicit zero / sign extension; doing that would result in worse overall
3714 ;; code, so just let the machine independent code widen the mode.
3715 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3718 ;; ??? This should be a define expand.
3720 (define_insn "ashrsi2_16"
3721 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3722 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3726 [(set_attr "length" "4")])
3729 [(set (match_operand:SI 0 "arith_reg_dest" "")
3730 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3733 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3734 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3735 "operands[2] = gen_lowpart (HImode, operands[0]);")
3737 ;; ??? This should be a define expand.
3739 (define_insn "ashrsi2_31"
3740 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3743 (clobber (reg:SI T_REG))]
3746 [(set_attr "length" "4")])
3749 [(set (match_operand:SI 0 "arith_reg_dest" "")
3750 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3752 (clobber (reg:SI T_REG))]
3757 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3758 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3763 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3765 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3767 && peep2_reg_dead_p (2, operands[0])
3768 && peep2_reg_dead_p (2, operands[1])"
3772 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3776 (define_insn "ashlsi_c"
3777 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3778 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3780 (lt:SI (match_dup 1) (const_int 0)))]
3783 [(set_attr "type" "arith")])
3785 (define_insn "*ashlsi_c_void"
3786 [(set (reg:SI T_REG)
3787 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3788 (clobber (match_scratch:SI 1 "=0"))]
3789 "TARGET_SH1 && cse_not_expected"
3791 [(set_attr "type" "arith")])
3793 (define_insn "ashrsi3_d"
3794 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3795 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3796 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3799 [(set_attr "type" "dyn_shift")])
3801 (define_insn "ashrsi3_n"
3802 [(set (reg:SI R4_REG)
3803 (ashiftrt:SI (reg:SI R4_REG)
3804 (match_operand:SI 0 "const_int_operand" "i")))
3805 (clobber (reg:SI T_REG))
3806 (clobber (reg:SI PR_REG))
3807 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3810 [(set_attr "type" "sfunc")
3811 (set_attr "needs_delay_slot" "yes")])
3813 (define_insn "ashrsi3_media"
3814 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3815 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3816 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3821 [(set_attr "type" "arith_media")
3822 (set_attr "highpart" "ignore")])
3824 (define_expand "ashrsi3"
3825 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3826 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3827 (match_operand:SI 2 "nonmemory_operand" "")))
3828 (clobber (reg:SI T_REG))])]
3834 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3837 if (expand_ashiftrt (operands))
3843 ;; logical shift right
3845 (define_insn "lshrsi3_sh2a"
3846 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3847 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3848 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3851 [(set_attr "type" "dyn_shift")
3852 (set_attr "length" "4")])
3854 (define_insn "lshrsi3_d"
3855 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3856 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3857 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3860 [(set_attr "type" "dyn_shift")])
3862 ;; Only the single bit shift clobbers the T bit.
3864 (define_insn "lshrsi3_m"
3865 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3866 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3867 (match_operand:SI 2 "const_int_operand" "M")))
3868 (clobber (reg:SI T_REG))]
3869 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3871 [(set_attr "type" "arith")])
3873 (define_insn "lshrsi3_k"
3874 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3875 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3876 (match_operand:SI 2 "const_int_operand" "P27")))]
3877 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3878 && ! satisfies_constraint_M (operands[2])"
3880 [(set_attr "type" "arith")])
3882 (define_insn "lshrsi3_n"
3883 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3884 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3885 (match_operand:SI 2 "const_int_operand" "n")))
3886 (clobber (reg:SI T_REG))]
3887 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3889 [(set (attr "length")
3890 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3892 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3894 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3896 (const_string "8")))
3897 (set_attr "type" "arith")])
3900 [(set (match_operand:SI 0 "arith_reg_dest" "")
3901 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3902 (match_operand:SI 2 "const_int_operand" "")))
3903 (clobber (reg:SI T_REG))]
3904 "TARGET_SH1 && reload_completed"
3905 [(use (reg:SI R0_REG))]
3908 gen_shifty_op (LSHIFTRT, operands);
3912 (define_insn "lshrsi3_media"
3913 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3914 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3915 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3920 [(set_attr "type" "arith_media")
3921 (set_attr "highpart" "ignore")])
3923 (define_expand "lshrsi3"
3924 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3925 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3926 (match_operand:SI 2 "nonmemory_operand" "")))
3927 (clobber (reg:SI T_REG))])]
3933 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3936 if (GET_CODE (operands[2]) == CONST_INT
3937 && sh_dynamicalize_shift_p (operands[2]))
3938 operands[2] = force_reg (SImode, operands[2]);
3939 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3941 rtx count = copy_to_mode_reg (SImode, operands[2]);
3942 emit_insn (gen_negsi2 (count, count));
3943 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3946 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3950 ;; ??? This should be a define expand.
3952 (define_insn "ashldi3_k"
3953 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3954 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3956 (clobber (reg:SI T_REG))]
3958 "shll %R0\;rotcl %S0"
3959 [(set_attr "length" "4")
3960 (set_attr "type" "arith")])
3962 (define_insn "ashldi3_media"
3963 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3964 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3965 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3970 [(set_attr "type" "arith_media")])
3972 (define_insn "*ashldisi3_media"
3973 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3974 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3975 (match_operand:DI 2 "const_int_operand" "n")))]
3976 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3977 "shlli.l %1, %2, %0"
3978 [(set_attr "type" "arith_media")
3979 (set_attr "highpart" "ignore")])
3981 (define_expand "ashldi3"
3982 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3983 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3984 (match_operand:DI 2 "immediate_operand" "")))
3985 (clobber (reg:SI T_REG))])]
3991 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3994 if (GET_CODE (operands[2]) != CONST_INT
3995 || INTVAL (operands[2]) != 1)
3999 ;; ??? This should be a define expand.
4001 (define_insn "lshrdi3_k"
4002 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4003 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4005 (clobber (reg:SI T_REG))]
4007 "shlr %S0\;rotcr %R0"
4008 [(set_attr "length" "4")
4009 (set_attr "type" "arith")])
4011 (define_insn "lshrdi3_media"
4012 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4013 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4014 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4016 && (arith_reg_dest (operands[0], DImode)
4017 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4021 [(set_attr "type" "arith_media")])
4023 (define_insn "*lshrdisi3_media"
4024 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4025 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4026 (match_operand:DI 2 "const_int_operand" "n")))]
4027 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4028 "shlri.l %1, %2, %0"
4029 [(set_attr "type" "arith_media")
4030 (set_attr "highpart" "ignore")])
4032 (define_expand "lshrdi3"
4033 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4034 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4035 (match_operand:DI 2 "immediate_operand" "")))
4036 (clobber (reg:SI T_REG))])]
4042 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4045 if (GET_CODE (operands[2]) != CONST_INT
4046 || INTVAL (operands[2]) != 1)
4050 ;; ??? This should be a define expand.
4052 (define_insn "ashrdi3_k"
4053 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4054 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4056 (clobber (reg:SI T_REG))]
4058 "shar %S0\;rotcr %R0"
4059 [(set_attr "length" "4")
4060 (set_attr "type" "arith")])
4062 (define_insn "ashrdi3_media"
4063 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4064 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4065 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4067 && (arith_reg_dest (operands[0], DImode)
4068 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4072 [(set_attr "type" "arith_media")])
4074 (define_insn "*ashrdisi3_media"
4075 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4076 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4077 (match_operand:DI 2 "const_int_operand" "n")))]
4078 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4079 "shari.l %1, %2, %0"
4080 [(set_attr "type" "arith_media")
4081 (set_attr "highpart" "ignore")])
4083 (define_insn "ashrdisi3_media_high"
4084 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4086 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4087 (match_operand:DI 2 "const_int_operand" "n"))))]
4088 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4090 [(set_attr "type" "arith_media")])
4092 (define_insn "ashrdisi3_media_opaque"
4093 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4094 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4095 (match_operand:DI 2 "const_int_operand" "n")]
4099 [(set_attr "type" "arith_media")])
4101 (define_expand "ashrdi3"
4102 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4103 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4104 (match_operand:DI 2 "immediate_operand" "")))
4105 (clobber (reg:SI T_REG))])]
4111 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4114 if (GET_CODE (operands[2]) != CONST_INT
4115 || INTVAL (operands[2]) != 1)
4119 ;; combined left/right shift
4122 [(set (match_operand:SI 0 "register_operand" "")
4123 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4124 (match_operand:SI 2 "const_int_operand" ""))
4125 (match_operand:SI 3 "const_int_operand" "")))]
4126 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4127 [(use (reg:SI R0_REG))]
4128 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4132 [(set (match_operand:SI 0 "register_operand" "")
4133 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4134 (match_operand:SI 2 "const_int_operand" ""))
4135 (match_operand:SI 3 "const_int_operand" "")))
4136 (clobber (reg:SI T_REG))]
4137 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4138 [(use (reg:SI R0_REG))]
4139 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4143 [(set (match_operand:SI 0 "register_operand" "=r")
4144 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4145 (match_operand:SI 2 "const_int_operand" "n"))
4146 (match_operand:SI 3 "const_int_operand" "n")))
4147 (clobber (reg:SI T_REG))]
4148 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4150 [(set (attr "length")
4151 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4153 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4155 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4157 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4159 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4161 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4163 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4164 (const_string "16")]
4165 (const_string "18")))
4166 (set_attr "type" "arith")])
4169 [(set (match_operand:SI 0 "register_operand" "=z")
4170 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4171 (match_operand:SI 2 "const_int_operand" "n"))
4172 (match_operand:SI 3 "const_int_operand" "n")))
4173 (clobber (reg:SI T_REG))]
4174 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4176 [(set (attr "length")
4177 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4179 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4181 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4183 (const_string "10")))
4184 (set_attr "type" "arith")])
4186 ;; shift left / and combination with a scratch register: The combine pass
4187 ;; does not accept the individual instructions, even though they are
4188 ;; cheap. But it needs a precise description so that it is usable after
4190 (define_insn "and_shl_scratch"
4191 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4195 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4196 (match_operand:SI 2 "const_int_operand" "N,n"))
4197 (match_operand:SI 3 "" "0,r"))
4198 (match_operand:SI 4 "const_int_operand" "n,n"))
4199 (match_operand:SI 5 "const_int_operand" "n,n")))
4200 (clobber (reg:SI T_REG))]
4203 [(set (attr "length")
4204 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4206 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4208 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4210 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4211 (const_string "10")]
4212 (const_string "12")))
4213 (set_attr "type" "arith")])
4216 [(set (match_operand:SI 0 "register_operand" "")
4220 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4221 (match_operand:SI 2 "const_int_operand" ""))
4222 (match_operand:SI 3 "register_operand" ""))
4223 (match_operand:SI 4 "const_int_operand" ""))
4224 (match_operand:SI 5 "const_int_operand" "")))
4225 (clobber (reg:SI T_REG))]
4227 [(use (reg:SI R0_REG))]
4230 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4232 if (INTVAL (operands[2]))
4234 gen_shifty_op (LSHIFTRT, operands);
4236 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4237 operands[2] = operands[4];
4238 gen_shifty_op (ASHIFT, operands);
4239 if (INTVAL (operands[5]))
4241 operands[2] = operands[5];
4242 gen_shifty_op (LSHIFTRT, operands);
4247 ;; signed left/right shift combination.
4249 [(set (match_operand:SI 0 "register_operand" "")
4251 (ashift:SI (match_operand:SI 1 "register_operand" "")
4252 (match_operand:SI 2 "const_int_operand" ""))
4253 (match_operand:SI 3 "const_int_operand" "")
4255 (clobber (reg:SI T_REG))]
4257 [(use (reg:SI R0_REG))]
4258 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4261 (define_insn "shl_sext_ext"
4262 [(set (match_operand:SI 0 "register_operand" "=r")
4264 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4265 (match_operand:SI 2 "const_int_operand" "n"))
4266 (match_operand:SI 3 "const_int_operand" "n")
4268 (clobber (reg:SI T_REG))]
4269 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4271 [(set (attr "length")
4272 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4274 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4276 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4278 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4280 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4282 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4284 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4286 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4287 (const_string "16")]
4288 (const_string "18")))
4289 (set_attr "type" "arith")])
4291 (define_insn "shl_sext_sub"
4292 [(set (match_operand:SI 0 "register_operand" "=z")
4294 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4295 (match_operand:SI 2 "const_int_operand" "n"))
4296 (match_operand:SI 3 "const_int_operand" "n")
4298 (clobber (reg:SI T_REG))]
4299 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4301 [(set (attr "length")
4302 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4304 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4306 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4308 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4309 (const_string "12")]
4310 (const_string "14")))
4311 (set_attr "type" "arith")])
4313 ;; These patterns are found in expansions of DImode shifts by 16, and
4314 ;; allow the xtrct instruction to be generated from C source.
4316 (define_insn "xtrct_left"
4317 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4318 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4320 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4324 [(set_attr "type" "arith")])
4326 (define_insn "xtrct_right"
4327 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4328 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4330 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4334 [(set_attr "type" "arith")])
4336 ;; -------------------------------------------------------------------------
4338 ;; -------------------------------------------------------------------------
4341 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4342 (neg:SI (plus:SI (reg:SI T_REG)
4343 (match_operand:SI 1 "arith_reg_operand" "r"))))
4345 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4349 [(set_attr "type" "arith")])
4351 (define_insn "*negdi_media"
4352 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4353 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4356 [(set_attr "type" "arith_media")])
4358 (define_expand "negdi2"
4359 [(set (match_operand:DI 0 "arith_reg_operand" "")
4360 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4366 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4367 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4369 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4370 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4372 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4373 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4375 emit_insn (gen_clrt ());
4376 emit_insn (gen_negc (low_dst, low_src));
4377 emit_insn (gen_negc (high_dst, high_src));
4382 (define_insn "negsi2"
4383 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4384 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4387 [(set_attr "type" "arith")])
4389 (define_insn "one_cmplsi2"
4390 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4391 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4394 [(set_attr "type" "arith")])
4396 (define_expand "one_cmpldi2"
4397 [(set (match_operand:DI 0 "arith_reg_dest" "")
4398 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4400 "TARGET_SHMEDIA" "")
4402 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4403 This can be used as some kind of conditional execution, which is useful
4406 [(set (match_operand:SI 0 "arith_reg_dest" "")
4407 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4408 (match_operand:SI 1 "arith_reg_operand" ""))
4412 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4413 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4418 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4419 (match_operand:SI 1 "arith_reg_operand" "0")
4420 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4422 "bf 0f\;neg %2,%0\\n0:"
4423 [(set_attr "type" "arith") ;; poor approximation
4424 (set_attr "length" "4")])
4427 ;; -------------------------------------------------------------------------
4428 ;; Zero extension instructions
4429 ;; -------------------------------------------------------------------------
4431 (define_insn "zero_extendsidi2"
4432 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4433 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4435 "addz.l %1, r63, %0"
4436 [(set_attr "type" "arith_media")
4437 (set_attr "highpart" "extend")])
4439 (define_insn "zero_extendhidi2"
4440 [(set (match_operand:DI 0 "register_operand" "=r,r")
4441 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4446 [(set_attr "type" "*,load_media")
4447 (set (attr "highpart")
4448 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4449 (const_string "user")]
4450 (const_string "ignore")))])
4453 [(set (match_operand:DI 0 "register_operand" "")
4454 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4455 "TARGET_SHMEDIA && reload_completed"
4456 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4457 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4460 if (GET_CODE (operands[1]) == TRUNCATE)
4461 operands[1] = XEXP (operands[1], 0);
4464 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4465 ;; reload the entire truncate expression.
4466 (define_insn_and_split "*loaddi_trunc"
4467 [(set (match_operand 0 "any_register_operand" "=r")
4468 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4469 "TARGET_SHMEDIA && reload_completed"
4471 "TARGET_SHMEDIA && reload_completed"
4472 [(set (match_dup 0) (match_dup 1))]
4473 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4475 (define_insn "zero_extendqidi2"
4476 [(set (match_operand:DI 0 "register_operand" "=r,r")
4477 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4482 [(set_attr "type" "arith_media,load_media")
4483 (set (attr "highpart")
4484 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4485 (const_string "user")]
4486 (const_string "ignore")))])
4488 (define_expand "zero_extendhisi2"
4489 [(set (match_operand:SI 0 "arith_reg_operand" "")
4490 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4494 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4495 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4498 (define_insn "*zero_extendhisi2_compact"
4499 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4500 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4503 [(set_attr "type" "arith")])
4505 (define_insn "*zero_extendhisi2_media"
4506 [(set (match_operand:SI 0 "register_operand" "=r,r")
4507 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4512 [(set_attr "type" "arith_media,load_media")
4513 (set (attr "highpart")
4514 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4515 (const_string "user")]
4516 (const_string "ignore")))])
4519 [(set (match_operand:SI 0 "register_operand" "")
4520 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4521 "TARGET_SHMEDIA && reload_completed"
4522 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4523 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4526 rtx op1 = operands[1];
4528 if (GET_CODE (op1) == TRUNCATE)
4529 op1 = XEXP (op1, 0);
4531 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4532 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4535 (define_expand "zero_extendqisi2"
4536 [(set (match_operand:SI 0 "arith_reg_operand" "")
4537 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4541 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4542 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4545 (define_insn "*zero_extendqisi2_compact"
4546 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4547 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4550 [(set_attr "type" "arith")])
4552 (define_insn "*zero_extendqisi2_media"
4553 [(set (match_operand:SI 0 "register_operand" "=r,r")
4554 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4559 [(set_attr "type" "arith_media,load_media")
4560 (set (attr "highpart")
4561 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4562 (const_string "user")]
4563 (const_string "ignore")))])
4565 (define_insn "zero_extendqihi2"
4566 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4567 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4570 [(set_attr "type" "arith")])
4572 ;; -------------------------------------------------------------------------
4573 ;; Sign extension instructions
4574 ;; -------------------------------------------------------------------------
4576 ;; ??? This should be a define expand.
4577 ;; ??? Or perhaps it should be dropped?
4579 ;; convert_move generates good code for SH[1-4].
4580 (define_insn "extendsidi2"
4581 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4582 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4588 [(set_attr "type" "arith_media,load_media,fpconv_media")
4589 (set (attr "highpart")
4590 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4591 (const_string "user")]
4592 (const_string "extend")))])
4594 (define_insn "extendhidi2"
4595 [(set (match_operand:DI 0 "register_operand" "=r,r")
4596 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4601 [(set_attr "type" "*,load_media")
4602 (set (attr "highpart")
4603 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4604 (const_string "user")]
4605 (const_string "ignore")))])
4608 [(set (match_operand:DI 0 "register_operand" "")
4609 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4610 "TARGET_SHMEDIA && reload_completed"
4611 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4612 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4615 if (GET_CODE (operands[1]) == TRUNCATE)
4616 operands[1] = XEXP (operands[1], 0);
4619 (define_insn "extendqidi2"
4620 [(set (match_operand:DI 0 "register_operand" "=r,r")
4621 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4626 [(set_attr "type" "*,load_media")
4627 (set (attr "highpart")
4628 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4629 (const_string "user")]
4630 (const_string "ignore")))])
4633 [(set (match_operand:DI 0 "register_operand" "")
4634 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4635 "TARGET_SHMEDIA && reload_completed"
4636 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4637 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4640 if (GET_CODE (operands[1]) == TRUNCATE)
4641 operands[1] = XEXP (operands[1], 0);
4644 (define_expand "extendhisi2"
4645 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4646 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4650 (define_insn "*extendhisi2_compact"
4651 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4652 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4657 [(set_attr "type" "arith,load")])
4659 (define_insn "*extendhisi2_media"
4660 [(set (match_operand:SI 0 "register_operand" "=r,r")
4661 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4666 [(set_attr "type" "arith_media,load_media")
4667 (set (attr "highpart")
4668 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4669 (const_string "user")]
4670 (const_string "ignore")))])
4673 [(set (match_operand:SI 0 "register_operand" "")
4674 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4675 "TARGET_SHMEDIA && reload_completed"
4676 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4677 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4680 rtx op1 = operands[1];
4681 if (GET_CODE (op1) == TRUNCATE)
4682 op1 = XEXP (op1, 0);
4684 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4685 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4688 (define_expand "extendqisi2"
4689 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4690 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4694 (define_insn "*extendqisi2_compact"
4695 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4696 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4701 [(set_attr "type" "arith,load")])
4703 (define_insn "*extendqisi2_media"
4704 [(set (match_operand:SI 0 "register_operand" "=r,r")
4705 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4710 [(set_attr "type" "arith_media,load_media")
4711 (set (attr "highpart")
4712 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4713 (const_string "user")]
4714 (const_string "ignore")))])
4717 [(set (match_operand:SI 0 "register_operand" "")
4718 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4719 "TARGET_SHMEDIA && reload_completed"
4720 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4721 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4724 rtx op1 = operands[1];
4725 if (GET_CODE (op1) == TRUNCATE)
4726 op1 = XEXP (op1, 0);
4728 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4729 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4732 (define_insn "extendqihi2"
4733 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4734 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4739 [(set_attr "type" "arith,load")])
4741 /* It would seem useful to combine the truncXi patterns into the movXi
4742 patterns, but unary operators are ignored when matching constraints,
4743 so we need separate patterns. */
4744 (define_insn "truncdisi2"
4745 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4746 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4755 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4756 (set (attr "highpart")
4757 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4758 (const_string "user")]
4759 (const_string "extend")))])
4761 (define_insn "truncdihi2"
4762 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4763 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4766 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4768 [(set_attr "type" "arith_media,store_media")
4769 (set_attr "length" "8,4")
4770 (set (attr "highpart")
4771 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4772 (const_string "user")]
4773 (const_string "extend")))])
4775 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4776 ; Because we use zero extension, we can't provide signed QImode compares
4777 ; using a simple compare or conditional branch insn.
4778 (define_insn "truncdiqi2"
4779 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4780 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4785 [(set_attr "type" "arith_media,store")
4786 (set (attr "highpart")
4787 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4788 (const_string "user")]
4789 (const_string "extend")))])
4790 ;; -------------------------------------------------------------------------
4791 ;; Move instructions
4792 ;; -------------------------------------------------------------------------
4794 ;; define push and pop so it is easy for sh.c
4795 ;; We can't use push and pop on SHcompact because the stack must always
4796 ;; be 8-byte aligned.
4798 (define_expand "push"
4799 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4800 (match_operand:SI 0 "register_operand" "r,l,x"))]
4801 "TARGET_SH1 && ! TARGET_SH5"
4804 (define_expand "pop"
4805 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4806 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4807 "TARGET_SH1 && ! TARGET_SH5"
4810 (define_expand "push_e"
4811 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4812 (match_operand:SF 0 "" ""))
4813 (use (reg:PSI FPSCR_REG))
4814 (clobber (scratch:SI))])]
4815 "TARGET_SH1 && ! TARGET_SH5"
4818 (define_insn "push_fpul"
4819 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4820 "TARGET_SH2E && ! TARGET_SH5"
4822 [(set_attr "type" "fstore")
4823 (set_attr "late_fp_use" "yes")
4824 (set_attr "hit_stack" "yes")])
4826 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4828 (define_expand "push_4"
4829 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4830 (match_operand:DF 0 "" ""))
4831 (use (reg:PSI FPSCR_REG))
4832 (clobber (scratch:SI))])]
4833 "TARGET_SH1 && ! TARGET_SH5"
4836 (define_expand "pop_e"
4837 [(parallel [(set (match_operand:SF 0 "" "")
4838 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4839 (use (reg:PSI FPSCR_REG))
4840 (clobber (scratch:SI))])]
4841 "TARGET_SH1 && ! TARGET_SH5"
4844 (define_insn "pop_fpul"
4845 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4846 "TARGET_SH2E && ! TARGET_SH5"
4848 [(set_attr "type" "load")
4849 (set_attr "hit_stack" "yes")])
4851 (define_expand "pop_4"
4852 [(parallel [(set (match_operand:DF 0 "" "")
4853 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4854 (use (reg:PSI FPSCR_REG))
4855 (clobber (scratch:SI))])]
4856 "TARGET_SH1 && ! TARGET_SH5"
4859 (define_expand "push_fpscr"
4864 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4865 gen_rtx_PRE_DEC (Pmode,
4866 stack_pointer_rtx)),
4868 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4872 (define_expand "pop_fpscr"
4877 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4878 gen_frame_mem (PSImode,
4879 gen_rtx_POST_INC (Pmode,
4880 stack_pointer_rtx))));
4881 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4885 ;; These two patterns can happen as the result of optimization, when
4886 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4887 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4890 [(set (reg:SI T_REG) (const_int 0))]
4895 [(set (reg:SI T_REG) (const_int 1))]
4899 ;; t/r must come after r/r, lest reload will try to reload stuff like
4900 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4901 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4902 (define_insn "movsi_i"
4903 [(set (match_operand:SI 0 "general_movdst_operand"
4904 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4905 (match_operand:SI 1 "general_movsrc_operand"
4906 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4910 && (register_operand (operands[0], SImode)
4911 || register_operand (operands[1], SImode))"
4929 [(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")
4930 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4932 ;; t/r must come after r/r, lest reload will try to reload stuff like
4933 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4934 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4935 ;; will require a reload.
4936 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4937 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4938 (define_insn "movsi_ie"
4939 [(set (match_operand:SI 0 "general_movdst_operand"
4940 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4941 (match_operand:SI 1 "general_movsrc_operand"
4942 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4943 "(TARGET_SH2E || TARGET_SH2A)
4944 && (register_operand (operands[0], SImode)
4945 || register_operand (operands[1], SImode))"
4971 ! move optimized away"
4972 [(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")
4973 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4974 (set_attr_alternative "length"
4981 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4982 (const_int 4) (const_int 2))
4987 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4988 (const_int 4) (const_int 2))
5005 (define_insn "movsi_i_lowpart"
5006 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5007 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5009 && (register_operand (operands[0], SImode)
5010 || register_operand (operands[1], SImode))"
5021 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5023 (define_insn_and_split "load_ra"
5024 [(set (match_operand:SI 0 "general_movdst_operand" "")
5025 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5028 "&& ! currently_expanding_to_rtl"
5029 [(set (match_dup 0) (match_dup 1))]
5032 if (TARGET_SHCOMPACT && current_function_saves_all_registers)
5033 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5036 ;; The '?'s in the following constraints may not reflect the time taken
5037 ;; to perform the move. They are there to discourage the use of floating-
5038 ;; point registers for storing integer values.
5039 (define_insn "*movsi_media"
5040 [(set (match_operand:SI 0 "general_movdst_operand"
5041 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5042 (match_operand:SI 1 "general_movsrc_operand"
5043 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5045 && (register_operand (operands[0], SImode)
5046 || sh_register_operand (operands[1], SImode)
5047 || GET_CODE (operands[1]) == TRUNCATE)"
5062 [(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")
5063 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5064 (set (attr "highpart")
5065 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5066 (const_string "user")]
5067 (const_string "ignore")))])
5069 (define_insn "*movsi_media_nofpu"
5070 [(set (match_operand:SI 0 "general_movdst_operand"
5071 "=r,r,r,r,m,*b,r,*b")
5072 (match_operand:SI 1 "general_movsrc_operand"
5073 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5075 && (register_operand (operands[0], SImode)
5076 || sh_register_operand (operands[1], SImode)
5077 || GET_CODE (operands[1]) == TRUNCATE)"
5087 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5088 (set_attr "length" "4,4,8,4,4,4,4,12")
5089 (set (attr "highpart")
5090 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5091 (const_string "user")]
5092 (const_string "ignore")))])
5094 (define_expand "movsi_const"
5095 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5096 (const:SI (sign_extend:SI
5099 (match_operand:DI 1 "immediate_operand" "s")
5102 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5105 (truncate:HI (match_dup 1))))))]
5106 "TARGET_SHMEDIA && reload_completed
5107 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5110 if (GET_CODE (operands[1]) == LABEL_REF
5111 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5112 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5113 else if (GOTOFF_P (operands[1]))
5115 rtx unspec = XEXP (operands[1], 0);
5117 if (! UNSPEC_GOTOFF_P (unspec))
5119 unspec = XEXP (unspec, 0);
5120 if (! UNSPEC_GOTOFF_P (unspec))
5123 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5124 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5125 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5129 (define_expand "movsi_const_16bit"
5130 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5131 (const:SI (sign_extend:SI
5133 (match_operand:DI 1 "immediate_operand" "s")))))]
5134 "TARGET_SHMEDIA && flag_pic && reload_completed
5135 && GET_CODE (operands[1]) == SYMBOL_REF"
5139 [(set (match_operand:SI 0 "arith_reg_dest" "")
5140 (match_operand:SI 1 "immediate_operand" ""))]
5141 "TARGET_SHMEDIA && reload_completed
5142 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5146 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5148 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5154 [(set (match_operand:SI 0 "register_operand" "")
5155 (match_operand:SI 1 "immediate_operand" ""))]
5156 "TARGET_SHMEDIA && reload_completed
5157 && ((GET_CODE (operands[1]) == CONST_INT
5158 && ! satisfies_constraint_I16 (operands[1]))
5159 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5160 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5162 (define_expand "movsi"
5163 [(set (match_operand:SI 0 "general_movdst_operand" "")
5164 (match_operand:SI 1 "general_movsrc_operand" ""))]
5166 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5168 (define_expand "ic_invalidate_line"
5169 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5170 (match_dup 1)] UNSPEC_ICACHE)
5171 (clobber (scratch:SI))])]
5172 "TARGET_HARD_SH4 || TARGET_SH5"
5177 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5180 else if (TARGET_SHCOMPACT)
5182 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5183 operands[1] = force_reg (Pmode, operands[1]);
5184 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5187 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5189 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5192 operands[0] = force_reg (Pmode, operands[0]);
5193 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5197 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5198 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5199 ;; the requirement *1*00 for associative address writes. The alignment of
5200 ;; %0 implies that its least significant bit is cleared,
5201 ;; thus we clear the V bit of a matching entry if there is one.
5202 (define_insn "ic_invalidate_line_i"
5203 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5204 (match_operand:SI 1 "register_operand" "r")]
5206 (clobber (match_scratch:SI 2 "=&r"))]
5208 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5209 [(set_attr "length" "8")
5210 (set_attr "type" "cwb")])
5212 (define_insn "ic_invalidate_line_sh4a"
5213 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5215 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5216 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5217 [(set_attr "length" "16")
5218 (set_attr "type" "cwb")])
5220 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5221 ;; an add in the code that calculates the address.
5222 (define_insn "ic_invalidate_line_media"
5223 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5226 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5227 [(set_attr "length" "16")
5228 (set_attr "type" "invalidate_line_media")])
5230 (define_insn "ic_invalidate_line_compact"
5231 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5232 (match_operand:SI 1 "register_operand" "r")]
5234 (clobber (reg:SI PR_REG))]
5237 [(set_attr "type" "sfunc")
5238 (set_attr "needs_delay_slot" "yes")])
5240 (define_expand "initialize_trampoline"
5241 [(match_operand:SI 0 "" "")
5242 (match_operand:SI 1 "" "")
5243 (match_operand:SI 2 "" "")]
5249 tramp = force_reg (Pmode, operands[0]);
5250 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5252 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5253 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5255 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5259 (define_insn "initialize_trampoline_compact"
5260 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5261 (match_operand:SI 1 "register_operand" "r")
5262 (reg:SI R2_REG) (reg:SI R3_REG)]
5265 (clobber (reg:SI PR_REG))]
5268 [(set_attr "type" "sfunc")
5269 (set_attr "needs_delay_slot" "yes")])
5271 (define_insn "movqi_i"
5272 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5273 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5275 && (arith_reg_operand (operands[0], QImode)
5276 || arith_reg_operand (operands[1], QImode))"
5285 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5287 (define_insn "*movqi_media"
5288 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5289 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5291 && (arith_reg_operand (operands[0], QImode)
5292 || extend_reg_or_0_operand (operands[1], QImode))"
5298 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5299 (set (attr "highpart")
5300 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5301 (const_string "user")]
5302 (const_string "ignore")))])
5304 (define_expand "movqi"
5305 [(set (match_operand:QI 0 "general_operand" "")
5306 (match_operand:QI 1 "general_operand" ""))]
5308 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5310 (define_expand "reload_inqi"
5311 [(set (match_operand:SI 2 "" "=&r")
5312 (match_operand:QI 1 "inqhi_operand" ""))
5313 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5314 (truncate:QI (match_dup 3)))]
5318 rtx inner = XEXP (operands[1], 0);
5319 int regno = REGNO (inner);
5321 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5322 operands[1] = gen_rtx_REG (SImode, regno);
5323 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5326 /* When storing r0, we have to avoid reg+reg addressing. */
5327 (define_insn "movhi_i"
5328 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5329 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5331 && (arith_reg_operand (operands[0], HImode)
5332 || arith_reg_operand (operands[1], HImode))
5333 && (GET_CODE (operands[0]) != MEM
5334 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5335 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5336 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5346 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5348 (define_insn "*movhi_media"
5349 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5350 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5352 && (arith_reg_operand (operands[0], HImode)
5353 || arith_reg_or_0_operand (operands[1], HImode))"
5360 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5361 (set (attr "highpart")
5362 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5363 (const_string "user")]
5364 (const_string "ignore")))])
5367 [(set (match_operand:HI 0 "register_operand" "")
5368 (match_operand:HI 1 "immediate_operand" ""))]
5369 "TARGET_SHMEDIA && reload_completed
5370 && ! satisfies_constraint_I16 (operands[1])"
5371 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5373 (define_expand "movhi"
5374 [(set (match_operand:HI 0 "general_movdst_operand" "")
5375 (match_operand:HI 1 "general_movsrc_operand" ""))]
5377 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5379 (define_expand "reload_inhi"
5380 [(set (match_operand:SI 2 "" "=&r")
5381 (match_operand:HI 1 "inqhi_operand" ""))
5382 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5383 (truncate:HI (match_dup 3)))]
5387 rtx inner = XEXP (operands[1], 0);
5388 int regno = REGNO (inner);
5390 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5391 operands[1] = gen_rtx_REG (SImode, regno);
5392 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5395 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5396 ;; compiled with -m2 -ml -O3 -funroll-loops
5397 (define_insn "*movdi_i"
5398 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5399 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5401 && (arith_reg_operand (operands[0], DImode)
5402 || arith_reg_operand (operands[1], DImode))"
5403 "* return output_movedouble (insn, operands, DImode);"
5404 [(set_attr "length" "4")
5405 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5407 ;; If the output is a register and the input is memory or a register, we have
5408 ;; to be careful and see which word needs to be loaded first.
5411 [(set (match_operand:DI 0 "general_movdst_operand" "")
5412 (match_operand:DI 1 "general_movsrc_operand" ""))]
5413 "TARGET_SH1 && reload_completed"
5414 [(set (match_dup 2) (match_dup 3))
5415 (set (match_dup 4) (match_dup 5))]
5420 if ((GET_CODE (operands[0]) == MEM
5421 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5422 || (GET_CODE (operands[1]) == MEM
5423 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5426 switch (GET_CODE (operands[0]))
5429 regno = REGNO (operands[0]);
5432 regno = subreg_regno (operands[0]);
5442 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5444 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5445 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5446 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5447 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5451 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5452 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5453 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5454 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5457 if (operands[2] == 0 || operands[3] == 0
5458 || operands[4] == 0 || operands[5] == 0)
5462 ;; The '?'s in the following constraints may not reflect the time taken
5463 ;; to perform the move. They are there to discourage the use of floating-
5464 ;; point registers for storing integer values.
5465 (define_insn "*movdi_media"
5466 [(set (match_operand:DI 0 "general_movdst_operand"
5467 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5468 (match_operand:DI 1 "general_movsrc_operand"
5469 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5471 && (register_operand (operands[0], DImode)
5472 || sh_register_operand (operands[1], DImode))"
5487 [(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")
5488 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5490 (define_insn "*movdi_media_nofpu"
5491 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5492 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5494 && (register_operand (operands[0], DImode)
5495 || sh_register_operand (operands[1], DImode))"
5505 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5506 (set_attr "length" "4,4,16,4,4,4,4,*")])
5508 (define_insn "*movdi_media_I16"
5509 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5510 (match_operand:DI 1 "const_int_operand" "I16"))]
5511 "TARGET_SHMEDIA && reload_completed"
5513 [(set_attr "type" "arith_media")
5514 (set_attr "length" "4")])
5517 [(set (match_operand:DI 0 "arith_reg_dest" "")
5518 (match_operand:DI 1 "immediate_operand" ""))]
5519 "TARGET_SHMEDIA && reload_completed
5520 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5521 [(set (match_dup 0) (match_dup 1))]
5526 if (TARGET_SHMEDIA64)
5527 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5529 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5531 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5536 (define_expand "movdi_const"
5537 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5538 (const:DI (sign_extend:DI
5541 (match_operand:DI 1 "immediate_operand" "s")
5544 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5550 (const_int 32)))))))
5552 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5558 (const_int 16)))))))
5560 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5565 "TARGET_SHMEDIA64 && reload_completed
5566 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5569 sh_mark_label (operands[1], 4);
5572 (define_expand "movdi_const_32bit"
5573 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5574 (const:DI (sign_extend:DI
5577 (match_operand:DI 1 "immediate_operand" "s")
5580 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5585 "TARGET_SHMEDIA32 && reload_completed
5586 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5589 sh_mark_label (operands[1], 2);
5592 (define_expand "movdi_const_16bit"
5593 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5594 (const:DI (sign_extend:DI
5596 (match_operand:DI 1 "immediate_operand" "s")))))]
5597 "TARGET_SHMEDIA && flag_pic && reload_completed
5598 && GET_CODE (operands[1]) == SYMBOL_REF"
5602 [(set (match_operand:DI 0 "ext_dest_operand" "")
5603 (match_operand:DI 1 "immediate_operand" ""))]
5604 "TARGET_SHMEDIA && reload_completed
5605 && GET_CODE (operands[1]) == CONST_INT
5606 && ! satisfies_constraint_I16 (operands[1])"
5607 [(set (match_dup 0) (match_dup 2))
5611 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5612 unsigned HOST_WIDE_INT low = val;
5613 unsigned HOST_WIDE_INT high = val;
5614 unsigned HOST_WIDE_INT sign;
5615 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5617 /* Zero-extend the 16 least-significant bits. */
5620 /* Arithmetic shift right the word by 16 bits. */
5622 if (GET_CODE (operands[0]) == SUBREG
5623 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5632 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5638 /* If we can't generate the constant with a two-insn movi / shori
5639 sequence, try some other strategies. */
5640 if (! CONST_OK_FOR_I16 (high))
5642 /* Try constant load / left shift. We know VAL != 0. */
5643 val2 = val ^ (val-1);
5646 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5648 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5649 || (! CONST_OK_FOR_I16 (high >> 16)
5650 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5652 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5653 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5654 GEN_INT (trailing_zeroes));
5658 /* Try constant load / right shift. */
5659 val2 = (val >> 15) + 1;
5660 if (val2 == (val2 & -val2))
5662 int shift = 49 - exact_log2 (val2);
5664 val2 = trunc_int_for_mode (val << shift, DImode);
5665 if (CONST_OK_FOR_I16 (val2))
5667 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5673 val2 = val & 0xffff;
5674 if ((val >> 16 & 0xffff) == val2
5675 && (val >> 32 & 0xffff) == val2
5676 && (val >> 48 & 0xffff) == val2)
5678 val2 = (HOST_WIDE_INT) val >> 48;
5679 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5680 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5683 /* Try movi / mshflo.l */
5684 val2 = (HOST_WIDE_INT) val >> 32;
5685 if (val2 == ((unsigned HOST_WIDE_INT)
5686 trunc_int_for_mode (val, SImode)))
5688 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5692 /* Try movi / mshflo.l w/ r63. */
5693 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5694 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5696 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5702 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5705 operands[2] = GEN_INT (val2);
5709 [(set (match_operand:DI 0 "ext_dest_operand" "")
5710 (match_operand:DI 1 "immediate_operand" ""))]
5711 "TARGET_SHMEDIA && reload_completed
5712 && GET_CODE (operands[1]) == CONST_DOUBLE"
5713 [(set (match_dup 0) (match_dup 2))
5715 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5718 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5719 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5720 unsigned HOST_WIDE_INT val = low;
5721 unsigned HOST_WIDE_INT sign;
5723 /* Zero-extend the 16 least-significant bits. */
5725 operands[1] = GEN_INT (val);
5727 /* Arithmetic shift right the double-word by 16 bits. */
5729 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5732 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5736 /* This will only be true if high is a sign-extension of low, i.e.,
5737 it must be either 0 or (unsigned)-1, and be zero iff the
5738 most-significant bit of low is set. */
5739 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5740 operands[2] = GEN_INT (low);
5742 operands[2] = immed_double_const (low, high, DImode);
5745 (define_insn "shori_media"
5746 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5747 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5749 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5750 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5754 [(set_attr "type" "arith_media,*")])
5756 (define_insn "*shori_media_si"
5757 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5758 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5760 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5764 (define_expand "movdi"
5765 [(set (match_operand:DI 0 "general_movdst_operand" "")
5766 (match_operand:DI 1 "general_movsrc_operand" ""))]
5768 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5770 (define_insn "movdf_media"
5771 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5772 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5774 && (register_operand (operands[0], DFmode)
5775 || sh_register_operand (operands[1], DFmode))"
5786 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5788 (define_insn "movdf_media_nofpu"
5789 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5790 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5792 && (register_operand (operands[0], DFmode)
5793 || sh_register_operand (operands[1], DFmode))"
5799 [(set_attr "type" "arith_media,*,load_media,store_media")])
5802 [(set (match_operand:DF 0 "arith_reg_dest" "")
5803 (match_operand:DF 1 "immediate_operand" ""))]
5804 "TARGET_SHMEDIA && reload_completed"
5805 [(set (match_dup 3) (match_dup 2))]
5808 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5810 REAL_VALUE_TYPE value;
5812 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5813 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5815 if (HOST_BITS_PER_WIDE_INT >= 64)
5816 operands[2] = immed_double_const ((unsigned long) values[endian]
5817 | ((HOST_WIDE_INT) values[1 - endian]
5821 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5822 operands[2] = immed_double_const (values[endian], values[1 - endian],
5826 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5829 ;; ??? This should be a define expand.
5831 (define_insn "movdf_k"
5832 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5833 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5835 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5836 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5837 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5838 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5839 && (arith_reg_operand (operands[0], DFmode)
5840 || arith_reg_operand (operands[1], DFmode))"
5841 "* return output_movedouble (insn, operands, DFmode);"
5842 [(set_attr "length" "4")
5843 (set_attr "type" "move,pcload,load,store")])
5845 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5846 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5847 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5848 ;; the d/m/c/X alternative, which is split later into single-precision
5849 ;; instructions. And when not optimizing, no splits are done before fixing
5850 ;; up pcloads, so we need usable length information for that.
5851 (define_insn "movdf_i4"
5852 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5853 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5854 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5855 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5856 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5857 && (arith_reg_operand (operands[0], DFmode)
5858 || arith_reg_operand (operands[1], DFmode))"
5870 [(set_attr_alternative "length"
5871 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5873 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5874 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5875 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5877 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5878 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5879 ;; increment or decrement r15 explicitly.
5881 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5882 (const_int 10) (const_int 8))
5884 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5885 (const_int 10) (const_int 8))])
5886 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5887 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5888 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5889 (const_string "double")
5890 (const_string "none")))])
5892 ;; Moving DFmode between fp/general registers through memory
5893 ;; (the top of the stack) is faster than moving through fpul even for
5894 ;; little endian. Because the type of an instruction is important for its
5895 ;; scheduling, it is beneficial to split these operations, rather than
5896 ;; emitting them in one single chunk, even if this will expose a stack
5897 ;; use that will prevent scheduling of other stack accesses beyond this
5900 [(set (match_operand:DF 0 "register_operand" "")
5901 (match_operand:DF 1 "register_operand" ""))
5902 (use (match_operand:PSI 2 "fpscr_operand" ""))
5903 (clobber (match_scratch:SI 3 "=X"))]
5904 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5905 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5911 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5913 emit_move_insn (stack_pointer_rtx,
5914 plus_constant (stack_pointer_rtx, -8));
5915 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5918 tos = gen_tmp_stack_mem (DFmode,
5919 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5920 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5921 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5922 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5923 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5924 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5926 tos = gen_tmp_stack_mem (DFmode,
5927 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5928 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5929 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5930 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5932 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5936 ;; local-alloc sometimes allocates scratch registers even when not required,
5937 ;; so we must be prepared to handle these.
5939 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5941 [(set (match_operand:DF 0 "general_movdst_operand" "")
5942 (match_operand:DF 1 "general_movsrc_operand" ""))
5943 (use (match_operand:PSI 2 "fpscr_operand" ""))
5944 (clobber (match_scratch:SI 3 ""))]
5945 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5947 && true_regnum (operands[0]) < 16
5948 && true_regnum (operands[1]) < 16"
5949 [(set (match_dup 0) (match_dup 1))]
5952 /* If this was a reg <-> mem operation with base + index reg addressing,
5953 we have to handle this in a special way. */
5954 rtx mem = operands[0];
5956 if (! memory_operand (mem, DFmode))
5961 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5962 mem = SUBREG_REG (mem);
5963 if (GET_CODE (mem) == MEM)
5965 rtx addr = XEXP (mem, 0);
5966 if (GET_CODE (addr) == PLUS
5967 && GET_CODE (XEXP (addr, 0)) == REG
5968 && GET_CODE (XEXP (addr, 1)) == REG)
5971 rtx reg0 = gen_rtx_REG (Pmode, 0);
5972 rtx regop = operands[store_p], word0 ,word1;
5974 if (GET_CODE (regop) == SUBREG)
5975 alter_subreg (®op);
5976 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5980 mem = copy_rtx (mem);
5981 PUT_MODE (mem, SImode);
5982 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5983 alter_subreg (&word0);
5984 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5985 alter_subreg (&word1);
5986 if (store_p || ! refers_to_regno_p (REGNO (word0),
5987 REGNO (word0) + 1, addr, 0))
5990 ? gen_movsi_ie (mem, word0)
5991 : gen_movsi_ie (word0, mem));
5992 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5993 mem = copy_rtx (mem);
5995 ? gen_movsi_ie (mem, word1)
5996 : gen_movsi_ie (word1, mem));
5997 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6001 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6002 emit_insn (gen_movsi_ie (word1, mem));
6003 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6004 mem = copy_rtx (mem);
6005 emit_insn (gen_movsi_ie (word0, mem));
6012 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6014 [(set (match_operand:DF 0 "register_operand" "")
6015 (match_operand:DF 1 "memory_operand" ""))
6016 (use (match_operand:PSI 2 "fpscr_operand" ""))
6017 (clobber (reg:SI R0_REG))]
6018 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6019 [(parallel [(set (match_dup 0) (match_dup 1))
6021 (clobber (scratch:SI))])]
6024 (define_expand "reload_indf__frn"
6025 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6026 (match_operand:DF 1 "immediate_operand" "FQ"))
6027 (use (reg:PSI FPSCR_REG))
6028 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6032 (define_expand "reload_outdf__RnFRm"
6033 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6034 (match_operand:DF 1 "register_operand" "af,r"))
6035 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6039 ;; Simplify no-op moves.
6041 [(set (match_operand:SF 0 "register_operand" "")
6042 (match_operand:SF 1 "register_operand" ""))
6043 (use (match_operand:PSI 2 "fpscr_operand" ""))
6044 (clobber (match_scratch:SI 3 ""))]
6045 "TARGET_SH2E && reload_completed
6046 && true_regnum (operands[0]) == true_regnum (operands[1])"
6047 [(set (match_dup 0) (match_dup 0))]
6050 ;; fmovd substitute post-reload splits
6052 [(set (match_operand:DF 0 "register_operand" "")
6053 (match_operand:DF 1 "register_operand" ""))
6054 (use (match_operand:PSI 2 "fpscr_operand" ""))
6055 (clobber (match_scratch:SI 3 ""))]
6056 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6057 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6058 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6062 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6063 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6064 gen_rtx_REG (SFmode, src), operands[2]));
6065 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6066 gen_rtx_REG (SFmode, src + 1), operands[2]));
6071 [(set (match_operand:DF 0 "register_operand" "")
6072 (mem:DF (match_operand:SI 1 "register_operand" "")))
6073 (use (match_operand:PSI 2 "fpscr_operand" ""))
6074 (clobber (match_scratch:SI 3 ""))]
6075 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6076 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6077 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6081 int regno = true_regnum (operands[0]);
6083 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6085 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6086 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6087 regno + !! TARGET_LITTLE_ENDIAN),
6088 mem2, operands[2]));
6089 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6090 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6091 regno + ! TARGET_LITTLE_ENDIAN),
6092 change_address (mem, SFmode, NULL_RTX),
6098 [(set (match_operand:DF 0 "register_operand" "")
6099 (match_operand:DF 1 "memory_operand" ""))
6100 (use (match_operand:PSI 2 "fpscr_operand" ""))
6101 (clobber (match_scratch:SI 3 ""))]
6102 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6103 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6107 int regno = true_regnum (operands[0]);
6108 rtx addr, insn, adjust = NULL_RTX;
6109 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6110 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6111 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6113 operands[1] = copy_rtx (mem2);
6114 addr = XEXP (mem2, 0);
6115 if (GET_CODE (addr) != POST_INC)
6117 /* If we have to modify the stack pointer, the value that we have
6118 read with post-increment might be modified by an interrupt,
6119 so write it back. */
6120 if (REGNO (addr) == STACK_POINTER_REGNUM)
6121 adjust = gen_push_e (reg0);
6123 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6124 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6126 addr = XEXP (addr, 0);
6127 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6128 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6129 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6133 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6138 [(set (match_operand:DF 0 "memory_operand" "")
6139 (match_operand:DF 1 "register_operand" ""))
6140 (use (match_operand:PSI 2 "fpscr_operand" ""))
6141 (clobber (match_scratch:SI 3 ""))]
6142 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6143 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6147 int regno = true_regnum (operands[1]);
6148 rtx insn, addr, adjust = NULL_RTX;
6150 operands[0] = copy_rtx (operands[0]);
6151 PUT_MODE (operands[0], SFmode);
6152 insn = emit_insn (gen_movsf_ie (operands[0],
6153 gen_rtx_REG (SFmode,
6154 regno + ! TARGET_LITTLE_ENDIAN),
6156 operands[0] = copy_rtx (operands[0]);
6157 addr = XEXP (operands[0], 0);
6158 if (GET_CODE (addr) != PRE_DEC)
6160 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6161 emit_insn_before (adjust, insn);
6162 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6164 addr = XEXP (addr, 0);
6166 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6167 insn = emit_insn (gen_movsf_ie (operands[0],
6168 gen_rtx_REG (SFmode,
6169 regno + !! TARGET_LITTLE_ENDIAN),
6171 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6175 ;; If the output is a register and the input is memory or a register, we have
6176 ;; to be careful and see which word needs to be loaded first.
6179 [(set (match_operand:DF 0 "general_movdst_operand" "")
6180 (match_operand:DF 1 "general_movsrc_operand" ""))]
6181 "TARGET_SH1 && reload_completed"
6182 [(set (match_dup 2) (match_dup 3))
6183 (set (match_dup 4) (match_dup 5))]
6188 if ((GET_CODE (operands[0]) == MEM
6189 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6190 || (GET_CODE (operands[1]) == MEM
6191 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6194 switch (GET_CODE (operands[0]))
6197 regno = REGNO (operands[0]);
6200 regno = subreg_regno (operands[0]);
6210 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6212 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6213 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6214 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6215 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6219 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6220 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6221 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6222 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6225 if (operands[2] == 0 || operands[3] == 0
6226 || operands[4] == 0 || operands[5] == 0)
6230 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6231 ;; used only once, let combine add in the index again.
6234 [(set (match_operand:SI 0 "register_operand" "")
6235 (match_operand:SI 1 "" ""))
6236 (clobber (match_operand 2 "register_operand" ""))]
6237 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6238 && ALLOW_INDEXED_ADDRESS"
6239 [(use (reg:SI R0_REG))]
6242 rtx addr, reg, const_int;
6244 if (GET_CODE (operands[1]) != MEM)
6246 addr = XEXP (operands[1], 0);
6247 if (GET_CODE (addr) != PLUS)
6249 reg = XEXP (addr, 0);
6250 const_int = XEXP (addr, 1);
6251 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6252 && GET_CODE (const_int) == CONST_INT))
6254 emit_move_insn (operands[2], const_int);
6255 emit_move_insn (operands[0],
6256 change_address (operands[1], VOIDmode,
6257 gen_rtx_PLUS (SImode, reg, operands[2])));
6262 [(set (match_operand:SI 1 "" "")
6263 (match_operand:SI 0 "register_operand" ""))
6264 (clobber (match_operand 2 "register_operand" ""))]
6265 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6266 && ALLOW_INDEXED_ADDRESS"
6267 [(use (reg:SI R0_REG))]
6270 rtx addr, reg, const_int;
6272 if (GET_CODE (operands[1]) != MEM)
6274 addr = XEXP (operands[1], 0);
6275 if (GET_CODE (addr) != PLUS)
6277 reg = XEXP (addr, 0);
6278 const_int = XEXP (addr, 1);
6279 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6280 && GET_CODE (const_int) == CONST_INT))
6282 emit_move_insn (operands[2], const_int);
6283 emit_move_insn (change_address (operands[1], VOIDmode,
6284 gen_rtx_PLUS (SImode, reg, operands[2])),
6289 (define_expand "movdf"
6290 [(set (match_operand:DF 0 "general_movdst_operand" "")
6291 (match_operand:DF 1 "general_movsrc_operand" ""))]
6295 if (prepare_move_operands (operands, DFmode)) DONE;
6298 if (TARGET_SHMEDIA_FPU)
6299 emit_insn (gen_movdf_media (operands[0], operands[1]));
6301 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6304 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6306 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6311 ;;This is incompatible with the way gcc uses subregs.
6312 ;;(define_insn "movv2sf_i"
6313 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6314 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6315 ;; "TARGET_SHMEDIA_FPU
6316 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6317 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6321 ;; fst%M0.p %m0, %1"
6322 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6324 (define_insn_and_split "movv2sf_i"
6325 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6326 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6327 "TARGET_SHMEDIA_FPU"
6329 "TARGET_SHMEDIA_FPU && reload_completed"
6330 [(set (match_dup 0) (match_dup 1))]
6333 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6334 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6337 (define_expand "movv2sf"
6338 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6339 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6340 "TARGET_SHMEDIA_FPU"
6343 if (prepare_move_operands (operands, V2SFmode))
6347 (define_expand "addv2sf3"
6348 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6349 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6350 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6351 "TARGET_SHMEDIA_FPU"
6354 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6358 (define_expand "subv2sf3"
6359 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6360 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6361 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6362 "TARGET_SHMEDIA_FPU"
6365 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6369 (define_expand "mulv2sf3"
6370 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6371 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6372 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6373 "TARGET_SHMEDIA_FPU"
6376 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6380 (define_expand "divv2sf3"
6381 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6382 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6383 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6384 "TARGET_SHMEDIA_FPU"
6387 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6391 (define_insn_and_split "*movv4sf_i"
6392 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6393 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6394 "TARGET_SHMEDIA_FPU"
6396 "&& reload_completed"
6402 for (i = 0; i < 4/2; i++)
6406 if (GET_CODE (operands[0]) == MEM)
6407 x = adjust_address (operands[0], V2SFmode,
6408 i * GET_MODE_SIZE (V2SFmode));
6410 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6412 if (GET_CODE (operands[1]) == MEM)
6413 y = adjust_address (operands[1], V2SFmode,
6414 i * GET_MODE_SIZE (V2SFmode));
6416 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6418 emit_insn (gen_movv2sf_i (x, y));
6423 [(set_attr "length" "8")])
6425 (define_expand "movv4sf"
6426 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6427 (match_operand:V4SF 1 "general_operand" ""))]
6428 "TARGET_SHMEDIA_FPU"
6431 if (prepare_move_operands (operands, V4SFmode))
6435 (define_insn_and_split "*movv16sf_i"
6436 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6437 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6438 "TARGET_SHMEDIA_FPU"
6440 "&& reload_completed"
6446 for (i = 0; i < 16/2; i++)
6450 if (GET_CODE (operands[0]) == MEM)
6451 x = adjust_address (operands[0], V2SFmode,
6452 i * GET_MODE_SIZE (V2SFmode));
6455 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6459 if (GET_CODE (operands[1]) == MEM)
6460 y = adjust_address (operands[1], V2SFmode,
6461 i * GET_MODE_SIZE (V2SFmode));
6464 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6468 emit_insn (gen_movv2sf_i (x, y));
6473 [(set_attr "length" "32")])
6475 (define_expand "movv16sf"
6476 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6477 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6478 "TARGET_SHMEDIA_FPU"
6481 if (prepare_move_operands (operands, V16SFmode))
6485 (define_insn "movsf_media"
6486 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6487 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6489 && (register_operand (operands[0], SFmode)
6490 || sh_register_operand (operands[1], SFmode))"
6501 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6502 (set (attr "highpart")
6503 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6504 (const_string "user")]
6505 (const_string "ignore")))])
6507 (define_insn "movsf_media_nofpu"
6508 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6509 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6511 && (register_operand (operands[0], SFmode)
6512 || sh_register_operand (operands[1], SFmode))"
6518 [(set_attr "type" "arith_media,*,load_media,store_media")
6519 (set (attr "highpart")
6520 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6521 (const_string "user")]
6522 (const_string "ignore")))])
6525 [(set (match_operand:SF 0 "arith_reg_dest" "")
6526 (match_operand:SF 1 "immediate_operand" ""))]
6527 "TARGET_SHMEDIA && reload_completed
6528 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6529 [(set (match_dup 3) (match_dup 2))]
6533 REAL_VALUE_TYPE value;
6535 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6536 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6537 operands[2] = GEN_INT (values);
6539 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6542 (define_insn "movsf_i"
6543 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6544 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6547 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6548 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6549 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6550 && (arith_reg_operand (operands[0], SFmode)
6551 || arith_reg_operand (operands[1], SFmode))"
6560 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6562 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6563 ;; update_flow_info would not know where to put REG_EQUAL notes
6564 ;; when the destination changes mode.
6565 (define_insn "movsf_ie"
6566 [(set (match_operand:SF 0 "general_movdst_operand"
6567 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6568 (match_operand:SF 1 "general_movsrc_operand"
6569 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6570 (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"))
6571 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6574 && (arith_reg_operand (operands[0], SFmode)
6575 || arith_reg_operand (operands[1], SFmode)
6576 || arith_reg_operand (operands[3], SImode)
6577 || (fpul_operand (operands[0], SFmode)
6578 && memory_operand (operands[1], SFmode)
6579 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6580 || (fpul_operand (operands[1], SFmode)
6581 && memory_operand (operands[0], SFmode)
6582 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6602 ! move optimized away"
6603 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6604 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6605 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6606 (set_attr_alternative "length"
6613 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6614 (const_int 4) (const_int 2))
6616 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617 (const_int 4) (const_int 2))
6630 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631 (const_string "single")
6632 (const_string "none")))])
6635 [(set (match_operand:SF 0 "register_operand" "")
6636 (match_operand:SF 1 "register_operand" ""))
6637 (use (match_operand:PSI 2 "fpscr_operand" ""))
6638 (clobber (reg:SI FPUL_REG))]
6640 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6642 (clobber (scratch:SI))])
6643 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6645 (clobber (scratch:SI))])]
6648 (define_expand "movsf"
6649 [(set (match_operand:SF 0 "general_movdst_operand" "")
6650 (match_operand:SF 1 "general_movsrc_operand" ""))]
6654 if (prepare_move_operands (operands, SFmode))
6658 if (TARGET_SHMEDIA_FPU)
6659 emit_insn (gen_movsf_media (operands[0], operands[1]));
6661 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6666 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6671 (define_insn "mov_nop"
6672 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6675 [(set_attr "length" "0")
6676 (set_attr "type" "nil")])
6678 (define_expand "reload_insf__frn"
6679 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680 (match_operand:SF 1 "immediate_operand" "FQ"))
6681 (use (reg:PSI FPSCR_REG))
6682 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6686 (define_expand "reload_insi__i_fpul"
6687 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688 (match_operand:SI 1 "immediate_operand" "i"))
6689 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6693 (define_expand "ptabs"
6694 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6698 if (!TARGET_PT_FIXED)
6700 rtx eq = operands[1];
6702 /* ??? For canonical RTL we really should remove any CONST from EQ
6703 before wrapping it in the AND, and finally wrap the EQ into a
6704 const if is constant. However, for reload we must expose the
6705 input register or symbolic constant, and we can't have
6706 different insn structures outside of the operands for different
6707 alternatives of the same pattern. */
6708 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6711 = (gen_rtx_IF_THEN_ELSE
6714 gen_rtx_MEM (PDImode, operands[1]),
6715 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716 PDImode, operands[1])));
6720 ;; expanded by ptabs expander.
6721 (define_insn "*extendsipdi_media"
6722 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6727 (mem:PDI (match_dup 1))
6728 (sign_extend:PDI (match_dup 1))))]
6729 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6733 [(set_attr "type" "ptabs_media,pt_media")
6734 (set_attr "length" "4,*")])
6736 (define_insn "*truncdipdi_media"
6737 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6742 (mem:PDI (match_dup 1))
6743 (truncate:PDI (match_dup 1))))]
6744 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6748 [(set_attr "type" "ptabs_media,pt_media")
6749 (set_attr "length" "4,*")])
6751 (define_insn "*movsi_y"
6752 [(set (match_operand:SI 0 "register_operand" "=y,y")
6753 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754 (clobber (match_scratch:SI 2 "=&z,r"))]
6756 && (reload_in_progress || reload_completed)"
6758 [(set_attr "length" "4")
6759 (set_attr "type" "pcload,move")])
6762 [(set (match_operand:SI 0 "register_operand" "")
6763 (match_operand:SI 1 "immediate_operand" ""))
6764 (clobber (match_operand:SI 2 "register_operand" ""))]
6766 [(set (match_dup 2) (match_dup 1))
6767 (set (match_dup 0) (match_dup 2))]
6771 [(set (match_operand:SI 0 "register_operand" "")
6772 (match_operand:SI 1 "memory_operand" ""))
6773 (clobber (reg:SI R0_REG))]
6775 [(set (match_dup 0) (match_dup 1))]
6778 ;; ------------------------------------------------------------------------
6779 ;; Define the real conditional branch instructions.
6780 ;; ------------------------------------------------------------------------
6782 (define_insn "branch_true"
6783 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784 (label_ref (match_operand 0 "" ""))
6787 "* return output_branch (1, insn, operands);"
6788 [(set_attr "type" "cbranch")])
6790 (define_insn "branch_false"
6791 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792 (label_ref (match_operand 0 "" ""))
6795 "* return output_branch (0, insn, operands);"
6796 [(set_attr "type" "cbranch")])
6798 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799 ;; which destination is too far away.
6800 ;; The const_int_operand is distinct for each branch target; it avoids
6801 ;; unwanted matches with redundant_insn.
6802 (define_insn "block_branch_redirect"
6803 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6806 [(set_attr "length" "0")])
6808 ;; This one has the additional purpose to record a possible scratch register
6809 ;; for the following branch.
6810 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6811 ;; because the insn then might be deemed dead and deleted. And we can't
6812 ;; make the use in the jump insn explicit because that would disable
6813 ;; delay slot scheduling from the target.
6814 (define_insn "indirect_jump_scratch"
6815 [(set (match_operand:SI 0 "register_operand" "=r")
6816 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6820 [(set_attr "length" "0")])
6822 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823 ;; being pulled into the delay slot of a condbranch that has been made to
6824 ;; jump around the unconditional jump because it was out of range.
6825 (define_insn "stuff_delay_slot"
6827 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6828 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6831 [(set_attr "length" "0")
6832 (set_attr "cond_delay_slot" "yes")])
6834 ;; Conditional branch insns
6836 (define_expand "beq_media"
6838 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6839 (match_operand:DI 2 "arith_operand" "r,I06"))
6840 (match_operand 0 "" "")
6843 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6845 (define_insn "*beq_media_i"
6847 (if_then_else (match_operator 3 "equality_comparison_operator"
6848 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6849 (match_operand:DI 2 "arith_operand" "r,I06")])
6850 (match_operand 0 "target_operand" "b,b")
6855 b%o3i%' %1, %2, %0%>"
6856 [(set_attr "type" "cbranch_media")])
6858 (define_insn "*beq_media_i32"
6860 (if_then_else (match_operator 3 "equality_comparison_operator"
6861 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6862 (match_operand:SI 2 "arith_operand" "r,I06")])
6863 (match_operand 0 "target_operand" "b,b")
6868 b%o3i%' %1, %2, %0%>"
6869 [(set_attr "type" "cbranch_media")])
6871 (define_expand "bne_media"
6873 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6874 (match_operand:DI 2 "arith_operand" "r,I06"))
6875 (match_operand 0 "" "")
6878 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6880 (define_expand "bgt_media"
6882 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6883 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6884 (match_operand 0 "" "")
6887 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6889 (define_expand "bge_media"
6891 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6892 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6893 (match_operand 0 "" "")
6896 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6898 (define_expand "bgtu_media"
6900 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6901 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6902 (match_operand 0 "" "")
6905 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6907 (define_expand "bgeu_media"
6909 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6910 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6911 (match_operand 0 "" "")
6914 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6916 (define_insn "*bgt_media_i"
6918 (if_then_else (match_operator 3 "greater_comparison_operator"
6919 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6920 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6921 (match_operand 0 "target_operand" "b")
6924 "b%o3%' %N1, %N2, %0%>"
6925 [(set_attr "type" "cbranch_media")])
6927 (define_insn "*bgt_media_i32"
6929 (if_then_else (match_operator 3 "greater_comparison_operator"
6930 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6931 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6932 (match_operand 0 "target_operand" "b")
6935 "b%o3%' %N1, %N2, %0%>"
6936 [(set_attr "type" "cbranch_media")])
6938 ;; These are only needed to make invert_jump() happy - otherwise, jump
6939 ;; optimization will be silently disabled.
6940 (define_insn "*blt_media_i"
6942 (if_then_else (match_operator 3 "less_comparison_operator"
6943 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6944 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6945 (match_operand 0 "target_operand" "b")
6948 "b%o3%' %N2, %N1, %0%>"
6949 [(set_attr "type" "cbranch_media")])
6951 (define_insn "*blt_media_i32"
6953 (if_then_else (match_operator 3 "less_comparison_operator"
6954 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6955 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6956 (match_operand 0 "target_operand" "b")
6959 "b%o3%' %N2, %N1, %0%>"
6960 [(set_attr "type" "cbranch_media")])
6962 (define_expand "beq"
6964 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6965 (label_ref (match_operand 0 "" ""))
6972 enum machine_mode mode = GET_MODE (sh_compare_op0);
6974 if (mode != DImode && mode != SImode)
6976 rtx tmp = gen_reg_rtx (DImode);
6978 emit_insn (gen_seq (tmp));
6979 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6983 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6984 if (CONSTANT_P (sh_compare_op1)
6985 && (! satisfies_constraint_I06 (sh_compare_op1)))
6986 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6987 emit_jump_insn (gen_beq_media (operands[0],
6988 sh_compare_op0, sh_compare_op1));
6992 from_compare (operands, EQ);
6995 (define_expand "bne"
6997 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6998 (label_ref (match_operand 0 "" ""))
7005 enum machine_mode mode = GET_MODE (sh_compare_op0);
7007 if (mode != DImode && mode != SImode)
7009 rtx tmp = gen_reg_rtx (DImode);
7011 emit_insn (gen_seq (tmp));
7012 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7016 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7017 if (CONSTANT_P (sh_compare_op1)
7018 && (! satisfies_constraint_I06 (sh_compare_op1)))
7019 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7020 emit_jump_insn (gen_bne_media (operands[0],
7021 sh_compare_op0, sh_compare_op1));
7025 from_compare (operands, EQ);
7028 (define_expand "bgt"
7030 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7031 (label_ref (match_operand 0 "" ""))
7038 enum machine_mode mode = GET_MODE (sh_compare_op0);
7040 if (mode != DImode && mode != SImode)
7042 rtx tmp = gen_reg_rtx (DImode);
7044 emit_insn (gen_sgt (tmp));
7045 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7049 if (sh_compare_op0 != const0_rtx)
7050 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7051 if (sh_compare_op1 != const0_rtx)
7052 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7053 emit_jump_insn (gen_bgt_media (operands[0],
7054 sh_compare_op0, sh_compare_op1));
7058 from_compare (operands, GT);
7061 (define_expand "blt"
7063 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7064 (label_ref (match_operand 0 "" ""))
7071 enum machine_mode mode = GET_MODE (sh_compare_op0);
7073 if (mode != DImode && mode != SImode)
7075 rtx tmp = gen_reg_rtx (DImode);
7077 emit_insn (gen_slt (tmp));
7078 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7082 if (sh_compare_op0 != const0_rtx)
7083 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7084 if (sh_compare_op1 != const0_rtx)
7085 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7086 emit_jump_insn (gen_bgt_media (operands[0],
7087 sh_compare_op1, sh_compare_op0));
7091 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7093 rtx tmp = sh_compare_op0;
7094 sh_compare_op0 = sh_compare_op1;
7095 sh_compare_op1 = tmp;
7096 emit_insn (gen_bgt (operands[0]));
7099 from_compare (operands, GE);
7102 (define_expand "ble"
7104 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7105 (label_ref (match_operand 0 "" ""))
7112 enum machine_mode mode = GET_MODE (sh_compare_op0);
7114 if (mode != DImode && mode != SImode)
7116 rtx tmp = gen_reg_rtx (DImode);
7118 emit_insn (gen_sle (tmp));
7119 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7123 if (sh_compare_op0 != const0_rtx)
7124 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7125 if (sh_compare_op1 != const0_rtx)
7126 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7127 emit_jump_insn (gen_bge_media (operands[0],
7128 sh_compare_op1, sh_compare_op0));
7134 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7136 rtx tmp = sh_compare_op0;
7137 sh_compare_op0 = sh_compare_op1;
7138 sh_compare_op1 = tmp;
7139 emit_insn (gen_bge (operands[0]));
7142 from_compare (operands, GT);
7145 (define_expand "bge"
7147 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7148 (label_ref (match_operand 0 "" ""))
7155 enum machine_mode mode = GET_MODE (sh_compare_op0);
7157 if (mode != DImode && mode != SImode)
7159 rtx tmp = gen_reg_rtx (DImode);
7161 emit_insn (gen_sge (tmp));
7162 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7166 if (sh_compare_op0 != const0_rtx)
7167 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7168 if (sh_compare_op1 != const0_rtx)
7169 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7170 emit_jump_insn (gen_bge_media (operands[0],
7171 sh_compare_op0, sh_compare_op1));
7177 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7179 rtx tmp = sh_compare_op0;
7180 sh_compare_op0 = sh_compare_op1;
7181 sh_compare_op1 = tmp;
7182 emit_insn (gen_ble (operands[0]));
7185 from_compare (operands, GE);
7188 (define_expand "bgtu"
7190 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7191 (label_ref (match_operand 0 "" ""))
7198 enum machine_mode mode = GET_MODE (sh_compare_op0);
7200 if (sh_compare_op0 != const0_rtx)
7201 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7202 if (sh_compare_op1 != const0_rtx)
7203 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7204 emit_jump_insn (gen_bgtu_media (operands[0],
7205 sh_compare_op0, sh_compare_op1));
7209 from_compare (operands, GTU);
7212 (define_expand "bltu"
7214 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7215 (label_ref (match_operand 0 "" ""))
7222 enum machine_mode mode = GET_MODE (sh_compare_op0);
7224 if (sh_compare_op0 != const0_rtx)
7225 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7226 if (sh_compare_op1 != const0_rtx)
7227 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7228 emit_jump_insn (gen_bgtu_media (operands[0],
7229 sh_compare_op1, sh_compare_op0));
7233 from_compare (operands, GEU);
7236 (define_expand "bgeu"
7238 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7239 (label_ref (match_operand 0 "" ""))
7246 enum machine_mode mode = GET_MODE (sh_compare_op0);
7248 if (sh_compare_op0 != const0_rtx)
7249 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7250 if (sh_compare_op1 != const0_rtx)
7251 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7252 emit_jump_insn (gen_bgeu_media (operands[0],
7253 sh_compare_op0, sh_compare_op1));
7257 from_compare (operands, GEU);
7260 (define_expand "bleu"
7262 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7263 (label_ref (match_operand 0 "" ""))
7270 enum machine_mode mode = GET_MODE (sh_compare_op0);
7272 if (sh_compare_op0 != const0_rtx)
7273 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7274 if (sh_compare_op1 != const0_rtx)
7275 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7276 emit_jump_insn (gen_bgeu_media (operands[0],
7277 sh_compare_op1, sh_compare_op0));
7281 from_compare (operands, GTU);
7284 (define_expand "bunordered"
7285 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7287 (if_then_else (ne (match_dup 1) (const_int 0))
7288 (match_operand 0 "" "")
7293 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7294 operands[1] = gen_reg_rtx (SImode);
7295 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7296 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7299 ;; combiner splitter for test-and-branch on single bit in register. This
7300 ;; is endian dependent because the non-paradoxical subreg looks different
7305 (match_operator 3 "equality_comparison_operator"
7306 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7307 "extend_reg_operand" "")
7311 "const_int_operand" "")) 0)
7313 (match_operand 0 "target_operand" "")
7315 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7316 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7317 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7318 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7322 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7323 operands[6] = (GET_CODE (operands[3]) == EQ
7324 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7325 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7328 ; operand 0 is the loop count pseudo register
7329 ; operand 1 is the number of loop iterations or 0 if it is unknown
7330 ; operand 2 is the maximum number of loop iterations
7331 ; operand 3 is the number of levels of enclosed loops
7332 ; operand 4 is the label to jump to at the top of the loop
7334 (define_expand "doloop_end"
7335 [(parallel [(set (pc) (if_then_else
7336 (ne:SI (match_operand:SI 0 "" "")
7338 (label_ref (match_operand 4 "" ""))
7341 (plus:SI (match_dup 0) (const_int -1)))
7342 (clobber (reg:SI T_REG))])]
7346 if (GET_MODE (operands[0]) != SImode)
7351 (define_insn_and_split "doloop_end_split"
7353 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7355 (label_ref (match_operand 1 "" ""))
7358 (plus (match_dup 0) (const_int -1)))
7359 (clobber (reg:SI T_REG))]
7363 [(parallel [(set (reg:SI T_REG)
7364 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7366 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7367 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7368 (label_ref (match_operand 1 "" ""))
7371 [(set_attr "type" "cbranch")])
7374 ;; ------------------------------------------------------------------------
7375 ;; Jump and linkage insns
7376 ;; ------------------------------------------------------------------------
7378 (define_insn "jump_compact"
7380 (label_ref (match_operand 0 "" "")))]
7384 /* The length is 16 if the delay slot is unfilled. */
7385 if (get_attr_length(insn) > 4)
7386 return output_far_jump(insn, operands[0]);
7388 return \"bra %l0%#\";
7390 [(set_attr "type" "jump")
7391 (set_attr "needs_delay_slot" "yes")])
7393 ;; ??? It would be much saner to explicitly use the scratch register
7394 ;; in the jump insn, and have indirect_jump_scratch only set it,
7395 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7396 ;; from the target then, as it uses simplejump_p.
7397 ;;(define_insn "jump_compact_far"
7399 ;; (label_ref (match_operand 0 "" "")))
7400 ;; (use (match_operand 1 "register_operand" "r")]
7402 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7403 ;; [(set_attr "type" "jump")
7404 ;; (set_attr "needs_delay_slot" "yes")])
7406 (define_insn "jump_media"
7408 (match_operand 0 "target_operand" "b"))]
7411 [(set_attr "type" "jump_media")])
7413 (define_expand "jump"
7415 (label_ref (match_operand 0 "" "")))]
7420 emit_jump_insn (gen_jump_compact (operands[0]));
7421 else if (TARGET_SHMEDIA)
7423 if (reload_in_progress || reload_completed)
7425 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7431 (define_insn "force_mode_for_call"
7432 [(use (reg:PSI FPSCR_REG))]
7435 [(set_attr "length" "0")
7436 (set (attr "fp_mode")
7437 (if_then_else (eq_attr "fpu_single" "yes")
7438 (const_string "single") (const_string "double")))])
7440 (define_insn "calli"
7441 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7442 (match_operand 1 "" ""))
7443 (use (reg:PSI FPSCR_REG))
7444 (clobber (reg:SI PR_REG))]
7447 [(set_attr "type" "call")
7448 (set (attr "fp_mode")
7449 (if_then_else (eq_attr "fpu_single" "yes")
7450 (const_string "single") (const_string "double")))
7451 (set_attr "needs_delay_slot" "yes")
7452 (set_attr "fp_set" "unknown")])
7454 ;; This is a pc-rel call, using bsrf, for use with PIC.
7456 (define_insn "calli_pcrel"
7457 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7458 (match_operand 1 "" ""))
7459 (use (reg:PSI FPSCR_REG))
7460 (use (reg:SI PIC_REG))
7461 (use (match_operand 2 "" ""))
7462 (clobber (reg:SI PR_REG))]
7465 [(set_attr "type" "call")
7466 (set (attr "fp_mode")
7467 (if_then_else (eq_attr "fpu_single" "yes")
7468 (const_string "single") (const_string "double")))
7469 (set_attr "needs_delay_slot" "yes")
7470 (set_attr "fp_set" "unknown")])
7472 (define_insn_and_split "call_pcrel"
7473 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7474 (match_operand 1 "" ""))
7475 (use (reg:PSI FPSCR_REG))
7476 (use (reg:SI PIC_REG))
7477 (clobber (reg:SI PR_REG))
7478 (clobber (match_scratch:SI 2 "=r"))]
7485 rtx lab = PATTERN (gen_call_site ());
7487 if (SYMBOL_REF_LOCAL_P (operands[0]))
7488 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7490 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7491 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7494 [(set_attr "type" "call")
7495 (set (attr "fp_mode")
7496 (if_then_else (eq_attr "fpu_single" "yes")
7497 (const_string "single") (const_string "double")))
7498 (set_attr "needs_delay_slot" "yes")
7499 (set_attr "fp_set" "unknown")])
7501 (define_insn "call_compact"
7502 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7503 (match_operand 1 "" ""))
7504 (match_operand 2 "immediate_operand" "n")
7505 (use (reg:SI R0_REG))
7506 (use (reg:SI R1_REG))
7507 (use (reg:PSI FPSCR_REG))
7508 (clobber (reg:SI PR_REG))]
7509 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7511 [(set_attr "type" "call")
7512 (set (attr "fp_mode")
7513 (if_then_else (eq_attr "fpu_single" "yes")
7514 (const_string "single") (const_string "double")))
7515 (set_attr "needs_delay_slot" "yes")])
7517 (define_insn "call_compact_rettramp"
7518 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7519 (match_operand 1 "" ""))
7520 (match_operand 2 "immediate_operand" "n")
7521 (use (reg:SI R0_REG))
7522 (use (reg:SI R1_REG))
7523 (use (reg:PSI FPSCR_REG))
7524 (clobber (reg:SI R10_REG))
7525 (clobber (reg:SI PR_REG))]
7526 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7528 [(set_attr "type" "call")
7529 (set (attr "fp_mode")
7530 (if_then_else (eq_attr "fpu_single" "yes")
7531 (const_string "single") (const_string "double")))
7532 (set_attr "needs_delay_slot" "yes")])
7534 (define_insn "call_media"
7535 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7536 (match_operand 1 "" ""))
7537 (clobber (reg:DI PR_MEDIA_REG))]
7540 [(set_attr "type" "jump_media")])
7542 (define_insn "call_valuei"
7543 [(set (match_operand 0 "" "=rf")
7544 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7545 (match_operand 2 "" "")))
7546 (use (reg:PSI FPSCR_REG))
7547 (clobber (reg:SI PR_REG))]
7550 [(set_attr "type" "call")
7551 (set (attr "fp_mode")
7552 (if_then_else (eq_attr "fpu_single" "yes")
7553 (const_string "single") (const_string "double")))
7554 (set_attr "needs_delay_slot" "yes")
7555 (set_attr "fp_set" "unknown")])
7557 (define_insn "call_valuei_pcrel"
7558 [(set (match_operand 0 "" "=rf")
7559 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7560 (match_operand 2 "" "")))
7561 (use (reg:PSI FPSCR_REG))
7562 (use (reg:SI PIC_REG))
7563 (use (match_operand 3 "" ""))
7564 (clobber (reg:SI PR_REG))]
7567 [(set_attr "type" "call")
7568 (set (attr "fp_mode")
7569 (if_then_else (eq_attr "fpu_single" "yes")
7570 (const_string "single") (const_string "double")))
7571 (set_attr "needs_delay_slot" "yes")
7572 (set_attr "fp_set" "unknown")])
7574 (define_insn_and_split "call_value_pcrel"
7575 [(set (match_operand 0 "" "=rf")
7576 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7577 (match_operand 2 "" "")))
7578 (use (reg:PSI FPSCR_REG))
7579 (use (reg:SI PIC_REG))
7580 (clobber (reg:SI PR_REG))
7581 (clobber (match_scratch:SI 3 "=r"))]
7588 rtx lab = PATTERN (gen_call_site ());
7590 if (SYMBOL_REF_LOCAL_P (operands[1]))
7591 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7593 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7594 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7595 operands[2], copy_rtx (lab)));
7598 [(set_attr "type" "call")
7599 (set (attr "fp_mode")
7600 (if_then_else (eq_attr "fpu_single" "yes")
7601 (const_string "single") (const_string "double")))
7602 (set_attr "needs_delay_slot" "yes")
7603 (set_attr "fp_set" "unknown")])
7605 (define_insn "call_value_compact"
7606 [(set (match_operand 0 "" "=rf")
7607 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7608 (match_operand 2 "" "")))
7609 (match_operand 3 "immediate_operand" "n")
7610 (use (reg:SI R0_REG))
7611 (use (reg:SI R1_REG))
7612 (use (reg:PSI FPSCR_REG))
7613 (clobber (reg:SI PR_REG))]
7614 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7616 [(set_attr "type" "call")
7617 (set (attr "fp_mode")
7618 (if_then_else (eq_attr "fpu_single" "yes")
7619 (const_string "single") (const_string "double")))
7620 (set_attr "needs_delay_slot" "yes")])
7622 (define_insn "call_value_compact_rettramp"
7623 [(set (match_operand 0 "" "=rf")
7624 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7625 (match_operand 2 "" "")))
7626 (match_operand 3 "immediate_operand" "n")
7627 (use (reg:SI R0_REG))
7628 (use (reg:SI R1_REG))
7629 (use (reg:PSI FPSCR_REG))
7630 (clobber (reg:SI R10_REG))
7631 (clobber (reg:SI PR_REG))]
7632 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7634 [(set_attr "type" "call")
7635 (set (attr "fp_mode")
7636 (if_then_else (eq_attr "fpu_single" "yes")
7637 (const_string "single") (const_string "double")))
7638 (set_attr "needs_delay_slot" "yes")])
7640 (define_insn "call_value_media"
7641 [(set (match_operand 0 "" "=rf")
7642 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7643 (match_operand 2 "" "")))
7644 (clobber (reg:DI PR_MEDIA_REG))]
7647 [(set_attr "type" "jump_media")])
7649 (define_expand "call"
7650 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7651 (match_operand 1 "" ""))
7652 (match_operand 2 "" "")
7653 (use (reg:PSI FPSCR_REG))
7654 (clobber (reg:SI PR_REG))])]
7660 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7661 emit_call_insn (gen_call_media (operands[0], operands[1]));
7664 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7666 rtx cookie_rtx = operands[2];
7667 long cookie = INTVAL (cookie_rtx);
7668 rtx func = XEXP (operands[0], 0);
7673 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7675 rtx reg = gen_reg_rtx (Pmode);
7677 emit_insn (gen_symGOTPLT2reg (reg, func));
7681 func = legitimize_pic_address (func, Pmode, 0);
7684 r0 = gen_rtx_REG (SImode, R0_REG);
7685 r1 = gen_rtx_REG (SImode, R1_REG);
7687 /* Since such a call function may use all call-clobbered
7688 registers, we force a mode switch earlier, so that we don't
7689 run out of registers when adjusting fpscr for the call. */
7690 emit_insn (gen_force_mode_for_call ());
7693 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7695 operands[0] = force_reg (SImode, operands[0]);
7697 emit_move_insn (r0, func);
7698 emit_move_insn (r1, cookie_rtx);
7700 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7701 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7704 emit_call_insn (gen_call_compact (operands[0], operands[1],
7709 else if (TARGET_SHCOMPACT && flag_pic
7710 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7711 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7713 rtx reg = gen_reg_rtx (Pmode);
7715 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7716 XEXP (operands[0], 0) = reg;
7718 if (flag_pic && TARGET_SH2
7719 && GET_CODE (operands[0]) == MEM
7720 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7722 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7727 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7728 operands[1] = operands[2];
7731 emit_call_insn (gen_calli (operands[0], operands[1]));
7735 (define_insn "call_pop_compact"
7736 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7737 (match_operand 1 "" ""))
7738 (match_operand 2 "immediate_operand" "n")
7739 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7740 (match_operand 3 "immediate_operand" "n")))
7741 (use (reg:SI R0_REG))
7742 (use (reg:SI R1_REG))
7743 (use (reg:PSI FPSCR_REG))
7744 (clobber (reg:SI PR_REG))]
7745 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7747 [(set_attr "type" "call")
7748 (set (attr "fp_mode")
7749 (if_then_else (eq_attr "fpu_single" "yes")
7750 (const_string "single") (const_string "double")))
7751 (set_attr "needs_delay_slot" "yes")])
7753 (define_insn "call_pop_compact_rettramp"
7754 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7755 (match_operand 1 "" ""))
7756 (match_operand 2 "immediate_operand" "n")
7757 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7758 (match_operand 3 "immediate_operand" "n")))
7759 (use (reg:SI R0_REG))
7760 (use (reg:SI R1_REG))
7761 (use (reg:PSI FPSCR_REG))
7762 (clobber (reg:SI R10_REG))
7763 (clobber (reg:SI PR_REG))]
7764 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7766 [(set_attr "type" "call")
7767 (set (attr "fp_mode")
7768 (if_then_else (eq_attr "fpu_single" "yes")
7769 (const_string "single") (const_string "double")))
7770 (set_attr "needs_delay_slot" "yes")])
7772 (define_expand "call_pop"
7773 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7774 (match_operand 1 "" ""))
7775 (match_operand 2 "" "")
7776 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7777 (match_operand 3 "" "")))])]
7786 gcc_assert (operands[2] && INTVAL (operands[2]));
7787 cookie_rtx = operands[2];
7788 cookie = INTVAL (cookie_rtx);
7789 func = XEXP (operands[0], 0);
7793 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7795 rtx reg = gen_reg_rtx (Pmode);
7796 emit_insn (gen_symGOTPLT2reg (reg, func));
7800 func = legitimize_pic_address (func, Pmode, 0);
7803 r0 = gen_rtx_REG (SImode, R0_REG);
7804 r1 = gen_rtx_REG (SImode, R1_REG);
7806 /* Since such a call function may use all call-clobbered
7807 registers, we force a mode switch earlier, so that we don't
7808 run out of registers when adjusting fpscr for the call. */
7809 emit_insn (gen_force_mode_for_call ());
7811 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7813 operands[0] = force_reg (SImode, operands[0]);
7815 emit_move_insn (r0, func);
7816 emit_move_insn (r1, cookie_rtx);
7818 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7819 emit_call_insn (gen_call_pop_compact_rettramp
7820 (operands[0], operands[1], operands[2], operands[3]));
7822 emit_call_insn (gen_call_pop_compact
7823 (operands[0], operands[1], operands[2], operands[3]));
7828 (define_expand "call_value"
7829 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7830 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7831 (match_operand 2 "" "")))
7832 (match_operand 3 "" "")
7833 (use (reg:PSI FPSCR_REG))
7834 (clobber (reg:SI PR_REG))])]
7840 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7841 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7845 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7847 rtx cookie_rtx = operands[3];
7848 long cookie = INTVAL (cookie_rtx);
7849 rtx func = XEXP (operands[1], 0);
7854 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7856 rtx reg = gen_reg_rtx (Pmode);
7858 emit_insn (gen_symGOTPLT2reg (reg, func));
7862 func = legitimize_pic_address (func, Pmode, 0);
7865 r0 = gen_rtx_REG (SImode, R0_REG);
7866 r1 = gen_rtx_REG (SImode, R1_REG);
7868 /* Since such a call function may use all call-clobbered
7869 registers, we force a mode switch earlier, so that we don't
7870 run out of registers when adjusting fpscr for the call. */
7871 emit_insn (gen_force_mode_for_call ());
7874 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7876 operands[1] = force_reg (SImode, operands[1]);
7878 emit_move_insn (r0, func);
7879 emit_move_insn (r1, cookie_rtx);
7881 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7882 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7887 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7888 operands[2], operands[3]));
7892 else if (TARGET_SHCOMPACT && flag_pic
7893 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7894 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7896 rtx reg = gen_reg_rtx (Pmode);
7898 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7899 XEXP (operands[1], 0) = reg;
7901 if (flag_pic && TARGET_SH2
7902 && GET_CODE (operands[1]) == MEM
7903 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7905 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7910 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7912 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7916 (define_insn "sibcalli"
7917 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7918 (match_operand 1 "" ""))
7919 (use (reg:PSI FPSCR_REG))
7923 [(set_attr "needs_delay_slot" "yes")
7924 (set (attr "fp_mode")
7925 (if_then_else (eq_attr "fpu_single" "yes")
7926 (const_string "single") (const_string "double")))
7927 (set_attr "type" "jump_ind")])
7929 (define_insn "sibcalli_pcrel"
7930 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7931 (match_operand 1 "" ""))
7932 (use (match_operand 2 "" ""))
7933 (use (reg:PSI FPSCR_REG))
7937 [(set_attr "needs_delay_slot" "yes")
7938 (set (attr "fp_mode")
7939 (if_then_else (eq_attr "fpu_single" "yes")
7940 (const_string "single") (const_string "double")))
7941 (set_attr "type" "jump_ind")])
7943 ;; This uses an unspec to describe that the symbol_ref is very close.
7944 (define_insn "sibcalli_thunk"
7945 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7947 (match_operand 1 "" ""))
7948 (use (reg:PSI FPSCR_REG))
7952 [(set_attr "needs_delay_slot" "yes")
7953 (set (attr "fp_mode")
7954 (if_then_else (eq_attr "fpu_single" "yes")
7955 (const_string "single") (const_string "double")))
7956 (set_attr "type" "jump")
7957 (set_attr "length" "2")])
7959 (define_insn_and_split "sibcall_pcrel"
7960 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7961 (match_operand 1 "" ""))
7962 (use (reg:PSI FPSCR_REG))
7963 (clobber (match_scratch:SI 2 "=k"))
7971 rtx lab = PATTERN (gen_call_site ());
7974 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7975 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7977 SIBLING_CALL_P (call_insn) = 1;
7980 [(set_attr "needs_delay_slot" "yes")
7981 (set (attr "fp_mode")
7982 (if_then_else (eq_attr "fpu_single" "yes")
7983 (const_string "single") (const_string "double")))
7984 (set_attr "type" "jump_ind")])
7986 (define_insn "sibcall_compact"
7987 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7988 (match_operand 1 "" ""))
7990 (use (match_operand:SI 2 "register_operand" "z,x"))
7991 (use (reg:SI R1_REG))
7992 (use (reg:PSI FPSCR_REG))
7993 ;; We want to make sure the `x' above will only match MACH_REG
7994 ;; because sibcall_epilogue may clobber MACL_REG.
7995 (clobber (reg:SI MACL_REG))]
7999 jmp @%0\\n sts %2, r0"
8000 [(set_attr "needs_delay_slot" "yes,no")
8001 (set_attr "length" "2,4")
8002 (set (attr "fp_mode") (const_string "single"))
8003 (set_attr "type" "jump_ind")])
8005 (define_insn "sibcall_media"
8006 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8007 (match_operand 1 "" ""))
8008 (use (reg:SI PR_MEDIA_REG))
8012 [(set_attr "type" "jump_media")])
8014 (define_expand "sibcall"
8016 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8017 (match_operand 1 "" ""))
8018 (match_operand 2 "" "")
8019 (use (reg:PSI FPSCR_REG))
8026 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8027 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8030 else if (TARGET_SHCOMPACT && operands[2]
8031 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8033 rtx cookie_rtx = operands[2];
8034 long cookie = INTVAL (cookie_rtx);
8035 rtx func = XEXP (operands[0], 0);
8040 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8042 rtx reg = gen_reg_rtx (Pmode);
8044 emit_insn (gen_symGOT2reg (reg, func));
8048 func = legitimize_pic_address (func, Pmode, 0);
8051 /* FIXME: if we could tell whether all argument registers are
8052 already taken, we could decide whether to force the use of
8053 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8054 simple way to tell. We could use the CALL_COOKIE, but we
8055 can't currently tell a register used for regular argument
8056 passing from one that is unused. If we leave it up to reload
8057 to decide which register to use, it seems to always choose
8058 R0_REG, which leaves no available registers in SIBCALL_REGS
8059 to hold the address of the trampoline. */
8060 mach = gen_rtx_REG (SImode, MACH_REG);
8061 r1 = gen_rtx_REG (SImode, R1_REG);
8063 /* Since such a call function may use all call-clobbered
8064 registers, we force a mode switch earlier, so that we don't
8065 run out of registers when adjusting fpscr for the call. */
8066 emit_insn (gen_force_mode_for_call ());
8069 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8071 operands[0] = force_reg (SImode, operands[0]);
8073 /* We don't need a return trampoline, since the callee will
8074 return directly to the upper caller. */
8075 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8077 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8078 cookie_rtx = GEN_INT (cookie);
8081 emit_move_insn (mach, func);
8082 emit_move_insn (r1, cookie_rtx);
8084 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8087 else if (TARGET_SHCOMPACT && flag_pic
8088 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8089 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8091 rtx reg = gen_reg_rtx (Pmode);
8093 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8094 XEXP (operands[0], 0) = reg;
8096 if (flag_pic && TARGET_SH2
8097 && GET_CODE (operands[0]) == MEM
8098 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8099 /* The PLT needs the PIC register, but the epilogue would have
8100 to restore it, so we can only use PC-relative PIC calls for
8101 static functions. */
8102 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8104 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8108 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8110 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8114 (define_insn "sibcall_valuei"
8115 [(set (match_operand 0 "" "=rf")
8116 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8117 (match_operand 2 "" "")))
8118 (use (reg:PSI FPSCR_REG))
8122 [(set_attr "needs_delay_slot" "yes")
8123 (set (attr "fp_mode")
8124 (if_then_else (eq_attr "fpu_single" "yes")
8125 (const_string "single") (const_string "double")))
8126 (set_attr "type" "jump_ind")])
8128 (define_insn "sibcall_valuei_pcrel"
8129 [(set (match_operand 0 "" "=rf")
8130 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8131 (match_operand 2 "" "")))
8132 (use (match_operand 3 "" ""))
8133 (use (reg:PSI FPSCR_REG))
8137 [(set_attr "needs_delay_slot" "yes")
8138 (set (attr "fp_mode")
8139 (if_then_else (eq_attr "fpu_single" "yes")
8140 (const_string "single") (const_string "double")))
8141 (set_attr "type" "jump_ind")])
8143 (define_insn_and_split "sibcall_value_pcrel"
8144 [(set (match_operand 0 "" "=rf")
8145 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8146 (match_operand 2 "" "")))
8147 (use (reg:PSI FPSCR_REG))
8148 (clobber (match_scratch:SI 3 "=k"))
8156 rtx lab = PATTERN (gen_call_site ());
8159 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8160 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8164 SIBLING_CALL_P (call_insn) = 1;
8167 [(set_attr "needs_delay_slot" "yes")
8168 (set (attr "fp_mode")
8169 (if_then_else (eq_attr "fpu_single" "yes")
8170 (const_string "single") (const_string "double")))
8171 (set_attr "type" "jump_ind")])
8173 (define_insn "sibcall_value_compact"
8174 [(set (match_operand 0 "" "=rf,rf")
8175 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8176 (match_operand 2 "" "")))
8178 (use (match_operand:SI 3 "register_operand" "z,x"))
8179 (use (reg:SI R1_REG))
8180 (use (reg:PSI FPSCR_REG))
8181 ;; We want to make sure the `x' above will only match MACH_REG
8182 ;; because sibcall_epilogue may clobber MACL_REG.
8183 (clobber (reg:SI MACL_REG))]
8187 jmp @%1\\n sts %3, r0"
8188 [(set_attr "needs_delay_slot" "yes,no")
8189 (set_attr "length" "2,4")
8190 (set (attr "fp_mode") (const_string "single"))
8191 (set_attr "type" "jump_ind")])
8193 (define_insn "sibcall_value_media"
8194 [(set (match_operand 0 "" "=rf")
8195 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8196 (match_operand 2 "" "")))
8197 (use (reg:SI PR_MEDIA_REG))
8201 [(set_attr "type" "jump_media")])
8203 (define_expand "sibcall_value"
8205 [(set (match_operand 0 "arith_reg_operand" "")
8206 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8207 (match_operand 2 "" "")))
8208 (match_operand 3 "" "")
8209 (use (reg:PSI FPSCR_REG))
8216 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8217 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8221 else if (TARGET_SHCOMPACT && operands[3]
8222 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8224 rtx cookie_rtx = operands[3];
8225 long cookie = INTVAL (cookie_rtx);
8226 rtx func = XEXP (operands[1], 0);
8231 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8233 rtx reg = gen_reg_rtx (Pmode);
8235 emit_insn (gen_symGOT2reg (reg, func));
8239 func = legitimize_pic_address (func, Pmode, 0);
8242 /* FIXME: if we could tell whether all argument registers are
8243 already taken, we could decide whether to force the use of
8244 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8245 simple way to tell. We could use the CALL_COOKIE, but we
8246 can't currently tell a register used for regular argument
8247 passing from one that is unused. If we leave it up to reload
8248 to decide which register to use, it seems to always choose
8249 R0_REG, which leaves no available registers in SIBCALL_REGS
8250 to hold the address of the trampoline. */
8251 mach = gen_rtx_REG (SImode, MACH_REG);
8252 r1 = gen_rtx_REG (SImode, R1_REG);
8254 /* Since such a call function may use all call-clobbered
8255 registers, we force a mode switch earlier, so that we don't
8256 run out of registers when adjusting fpscr for the call. */
8257 emit_insn (gen_force_mode_for_call ());
8260 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8262 operands[1] = force_reg (SImode, operands[1]);
8264 /* We don't need a return trampoline, since the callee will
8265 return directly to the upper caller. */
8266 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8268 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8269 cookie_rtx = GEN_INT (cookie);
8272 emit_move_insn (mach, func);
8273 emit_move_insn (r1, cookie_rtx);
8275 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8276 operands[2], mach));
8279 else if (TARGET_SHCOMPACT && flag_pic
8280 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8281 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8283 rtx reg = gen_reg_rtx (Pmode);
8285 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8286 XEXP (operands[1], 0) = reg;
8288 if (flag_pic && TARGET_SH2
8289 && GET_CODE (operands[1]) == MEM
8290 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8291 /* The PLT needs the PIC register, but the epilogue would have
8292 to restore it, so we can only use PC-relative PIC calls for
8293 static functions. */
8294 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8296 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8297 XEXP (operands[1], 0),
8302 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8304 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8308 (define_insn "call_value_pop_compact"
8309 [(set (match_operand 0 "" "=rf")
8310 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8311 (match_operand 2 "" "")))
8312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8313 (match_operand 4 "immediate_operand" "n")))
8314 (match_operand 3 "immediate_operand" "n")
8315 (use (reg:SI R0_REG))
8316 (use (reg:SI R1_REG))
8317 (use (reg:PSI FPSCR_REG))
8318 (clobber (reg:SI PR_REG))]
8319 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8321 [(set_attr "type" "call")
8322 (set (attr "fp_mode")
8323 (if_then_else (eq_attr "fpu_single" "yes")
8324 (const_string "single") (const_string "double")))
8325 (set_attr "needs_delay_slot" "yes")])
8327 (define_insn "call_value_pop_compact_rettramp"
8328 [(set (match_operand 0 "" "=rf")
8329 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8330 (match_operand 2 "" "")))
8331 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8332 (match_operand 4 "immediate_operand" "n")))
8333 (match_operand 3 "immediate_operand" "n")
8334 (use (reg:SI R0_REG))
8335 (use (reg:SI R1_REG))
8336 (use (reg:PSI FPSCR_REG))
8337 (clobber (reg:SI R10_REG))
8338 (clobber (reg:SI PR_REG))]
8339 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8341 [(set_attr "type" "call")
8342 (set (attr "fp_mode")
8343 (if_then_else (eq_attr "fpu_single" "yes")
8344 (const_string "single") (const_string "double")))
8345 (set_attr "needs_delay_slot" "yes")])
8347 (define_expand "call_value_pop"
8348 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8349 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8350 (match_operand 2 "" "")))
8351 (match_operand 3 "" "")
8352 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8353 (match_operand 4 "" "")))])]
8362 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8363 cookie_rtx = operands[3];
8364 cookie = INTVAL (cookie_rtx);
8365 func = XEXP (operands[1], 0);
8369 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8371 rtx reg = gen_reg_rtx (Pmode);
8373 emit_insn (gen_symGOTPLT2reg (reg, func));
8377 func = legitimize_pic_address (func, Pmode, 0);
8380 r0 = gen_rtx_REG (SImode, R0_REG);
8381 r1 = gen_rtx_REG (SImode, R1_REG);
8383 /* Since such a call function may use all call-clobbered
8384 registers, we force a mode switch earlier, so that we don't
8385 run out of registers when adjusting fpscr for the call. */
8386 emit_insn (gen_force_mode_for_call ());
8388 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8390 operands[1] = force_reg (SImode, operands[1]);
8392 emit_move_insn (r0, func);
8393 emit_move_insn (r1, cookie_rtx);
8395 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8396 emit_call_insn (gen_call_value_pop_compact_rettramp
8397 (operands[0], operands[1], operands[2],
8398 operands[3], operands[4]));
8400 emit_call_insn (gen_call_value_pop_compact
8401 (operands[0], operands[1], operands[2],
8402 operands[3], operands[4]));
8407 (define_expand "sibcall_epilogue"
8412 sh_expand_epilogue (1);
8413 if (TARGET_SHCOMPACT)
8417 /* If epilogue clobbers r0, preserve it in macl. */
8418 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8419 if ((set = single_set (insn))
8420 && GET_CODE (SET_DEST (set)) == REG
8421 && REGNO (SET_DEST (set)) == R0_REG)
8423 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8424 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8426 /* We can't tell at this point whether the sibcall is a
8427 sibcall_compact and, if it is, whether it uses r0 or
8428 mach as operand 2, so let the instructions that
8429 preserve r0 be optimized away if r0 turns out to be
8431 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8432 emit_move_insn (r0, tmp);
8439 (define_insn "indirect_jump_compact"
8441 (match_operand:SI 0 "arith_reg_operand" "r"))]
8444 [(set_attr "needs_delay_slot" "yes")
8445 (set_attr "type" "jump_ind")])
8447 (define_expand "indirect_jump"
8449 (match_operand 0 "register_operand" ""))]
8453 if (GET_MODE (operands[0]) != Pmode)
8454 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8457 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8458 ;; which can be present in structured code from indirect jumps which can not
8459 ;; be present in structured code. This allows -fprofile-arcs to work.
8461 ;; For SH1 processors.
8462 (define_insn "casesi_jump_1"
8464 (match_operand:SI 0 "register_operand" "r"))
8465 (use (label_ref (match_operand 1 "" "")))]
8468 [(set_attr "needs_delay_slot" "yes")
8469 (set_attr "type" "jump_ind")])
8471 ;; For all later processors.
8472 (define_insn "casesi_jump_2"
8473 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8474 (label_ref (match_operand 1 "" ""))))
8475 (use (label_ref (match_operand 2 "" "")))]
8477 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8479 [(set_attr "needs_delay_slot" "yes")
8480 (set_attr "type" "jump_ind")])
8482 (define_insn "casesi_jump_media"
8483 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8484 (use (label_ref (match_operand 1 "" "")))]
8487 [(set_attr "type" "jump_media")])
8489 ;; Call subroutine returning any type.
8490 ;; ??? This probably doesn't work.
8492 (define_expand "untyped_call"
8493 [(parallel [(call (match_operand 0 "" "")
8495 (match_operand 1 "" "")
8496 (match_operand 2 "" "")])]
8497 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8502 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8504 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8506 rtx set = XVECEXP (operands[2], 0, i);
8507 emit_move_insn (SET_DEST (set), SET_SRC (set));
8510 /* The optimizer does not know that the call sets the function value
8511 registers we stored in the result block. We avoid problems by
8512 claiming that all hard registers are used and clobbered at this
8514 emit_insn (gen_blockage ());
8519 ;; ------------------------------------------------------------------------
8521 ;; ------------------------------------------------------------------------
8524 [(set (reg:SI T_REG)
8525 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8526 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8529 [(set_attr "type" "arith")])
8536 ;; Load address of a label. This is only generated by the casesi expand,
8537 ;; and by machine_dependent_reorg (fixing up fp moves).
8538 ;; This must use unspec, because this only works for labels that are
8542 [(set (reg:SI R0_REG)
8543 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8546 [(set_attr "in_delay_slot" "no")
8547 (set_attr "type" "arith")])
8549 ;; machine_dependent_reorg will make this a `mova'.
8550 (define_insn "mova_const"
8551 [(set (reg:SI R0_REG)
8552 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8555 [(set_attr "in_delay_slot" "no")
8556 (set_attr "type" "arith")])
8558 (define_expand "GOTaddr2picreg"
8559 [(set (reg:SI R0_REG)
8560 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8562 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8563 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8566 if (TARGET_VXWORKS_RTP)
8568 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8569 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8570 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8574 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8575 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8579 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8580 rtx pic = operands[0];
8581 rtx lab = PATTERN (gen_call_site ());
8584 equiv = operands[1];
8585 operands[1] = gen_rtx_MINUS (Pmode,
8589 gen_rtx_MINUS (Pmode,
8590 gen_rtx_CONST (Pmode,
8593 operands[1] = gen_sym2PIC (operands[1]);
8594 PUT_MODE (operands[1], Pmode);
8596 if (Pmode == SImode)
8598 emit_insn (gen_movsi_const (pic, operands[1]));
8599 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8603 emit_insn (gen_movdi_const (pic, operands[1]));
8604 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8607 insn = emit_move_insn (operands[0], tr);
8609 set_unique_reg_note (insn, REG_EQUAL, equiv);
8616 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8619 (define_expand "vxworks_picreg"
8620 [(set (reg:SI PIC_REG)
8621 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8622 (set (reg:SI R0_REG)
8623 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8624 (set (reg:SI PIC_REG)
8625 (mem:SI (reg:SI PIC_REG)))
8626 (set (reg:SI PIC_REG)
8627 (mem:SI (plus:SI (reg:SI PIC_REG)
8629 "TARGET_VXWORKS_RTP")
8632 [(set (match_operand 0 "target_reg_operand" "=b")
8633 (const (unspec [(match_operand 1 "" "Csy")]
8634 UNSPEC_DATALABEL)))]
8635 "TARGET_SHMEDIA && flag_pic
8636 && satisfies_constraint_Csy (operands[1])"
8637 "ptb/u datalabel %1, %0"
8638 [(set_attr "type" "ptabs_media")
8639 (set_attr "length" "*")])
8641 (define_insn "ptrel_si"
8642 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8643 (plus:SI (match_operand:SI 1 "register_operand" "r")
8645 (match_operand:SI 2 "" "")]
8647 "%O2: ptrel/u %1, %0"
8648 [(set_attr "type" "ptabs_media")])
8650 (define_insn "ptrel_di"
8651 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8652 (plus:DI (match_operand:DI 1 "register_operand" "r")
8654 (match_operand:DI 2 "" "")]
8656 "%O2: ptrel/u %1, %0"
8657 [(set_attr "type" "ptabs_media")])
8659 (define_expand "builtin_setjmp_receiver"
8660 [(match_operand 0 "" "")]
8664 emit_insn (gen_GOTaddr2picreg ());
8668 (define_expand "call_site"
8669 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8673 static HOST_WIDE_INT i = 0;
8674 operands[0] = GEN_INT (i);
8678 (define_expand "sym_label2reg"
8679 [(set (match_operand:SI 0 "" "")
8682 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8685 (match_operand:SI 2 "" "")
8689 (define_expand "symGOT_load"
8690 [(set (match_dup 2) (match_operand 1 "" ""))
8691 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8692 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8698 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8699 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8703 rtx reg = operands[2];
8705 if (Pmode == DImode)
8708 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8710 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8715 emit_insn (gen_movsi_const (reg, operands[1]));
8717 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8721 emit_move_insn (operands[2], operands[1]);
8723 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8725 gen_rtx_REG (Pmode, PIC_REG)));
8727 /* When stack protector inserts codes after the result is set to
8728 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8729 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8730 when rX is a GOT address for the guard symbol. Ugly but doesn't
8731 matter because this is a rare situation. */
8733 && flag_stack_protect
8734 && GET_CODE (operands[1]) == CONST
8735 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8736 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8737 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8738 \"__stack_chk_guard\") == 0)
8739 emit_insn (gen_blockage ());
8741 /* N.B. This is not constant for a GOTPLT relocation. */
8742 mem = gen_rtx_MEM (Pmode, operands[3]);
8743 MEM_NOTRAP_P (mem) = 1;
8744 /* ??? Should we have a special alias set for the GOT? */
8745 insn = emit_move_insn (operands[0], mem);
8747 set_unique_reg_note (insn, REG_EQUAL,
8748 XVECEXP (XEXP (operands[1], 0), 0, 0));
8753 (define_expand "sym2GOT"
8754 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8758 (define_expand "symGOT2reg"
8759 [(match_operand 0 "" "") (match_operand 1 "" "")]
8765 gotsym = gen_sym2GOT (operands[1]);
8766 PUT_MODE (gotsym, Pmode);
8767 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8769 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8774 (define_expand "symGOTPLT2reg"
8775 [(match_operand 0 "" "") (match_operand 1 "" "")]
8779 rtx pltsym = gen_rtx_CONST (Pmode,
8780 gen_rtx_UNSPEC (Pmode,
8781 gen_rtvec (1, operands[1]),
8783 emit_insn (gen_symGOT_load (operands[0], pltsym));
8787 (define_expand "sym2GOTOFF"
8788 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8792 (define_expand "symGOTOFF2reg"
8793 [(match_operand 0 "" "") (match_operand 1 "" "")]
8797 rtx gotoffsym, insn;
8798 rtx t = (!can_create_pseudo_p ()
8800 : gen_reg_rtx (GET_MODE (operands[0])));
8802 gotoffsym = gen_sym2GOTOFF (operands[1]);
8803 PUT_MODE (gotoffsym, Pmode);
8804 emit_move_insn (t, gotoffsym);
8805 insn = emit_move_insn (operands[0],
8806 gen_rtx_PLUS (Pmode, t,
8807 gen_rtx_REG (Pmode, PIC_REG)));
8809 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8814 (define_expand "symPLT_label2reg"
8815 [(set (match_operand:SI 0 "" "")
8818 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8822 (match_operand:SI 2 "" "")
8824 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8825 ;; Even though the PIC register is not really used by the call
8826 ;; sequence in which this is expanded, the PLT code assumes the PIC
8827 ;; register is set, so we must not skip its initialization. Since
8828 ;; we only use this expand as part of calling sequences, and never
8829 ;; to take the address of a function, this is the best point to
8830 ;; insert the (use). Using the PLT to take the address of a
8831 ;; function would be wrong, not only because the PLT entry could
8832 ;; then be called from a function that doesn't initialize the PIC
8833 ;; register to the proper GOT, but also because pointers to the
8834 ;; same function might not compare equal, should they be set by
8835 ;; different shared libraries.
8836 (use (reg:SI PIC_REG))]
8840 (define_expand "sym2PIC"
8841 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8845 ;; TLS code generation.
8846 ;; ??? this should be a define_insn_and_split
8847 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8848 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8851 (define_insn "tls_global_dynamic"
8852 [(set (match_operand:SI 0 "register_operand" "=&z")
8853 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8856 (use (reg:PSI FPSCR_REG))
8857 (use (reg:SI PIC_REG))
8858 (clobber (reg:SI PR_REG))
8859 (clobber (scratch:SI))]
8865 \\tmova\\t2f,r0\\n\\
8866 \\tmov.l\\t2f,r1\\n\\
8869 \\tadd\\tr12,r4\\n\\
8873 1:\\t.long\\t%a1@TLSGD\\n\\
8874 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8877 [(set_attr "type" "tls_load")
8878 (set_attr "length" "26")])
8880 (define_insn "tls_local_dynamic"
8881 [(set (match_operand:SI 0 "register_operand" "=&z")
8882 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8885 (use (reg:PSI FPSCR_REG))
8886 (use (reg:SI PIC_REG))
8887 (clobber (reg:SI PR_REG))
8888 (clobber (scratch:SI))]
8894 \\tmova\\t2f,r0\\n\\
8895 \\tmov.l\\t2f,r1\\n\\
8898 \\tadd\\tr12,r4\\n\\
8902 1:\\t.long\\t%a1@TLSLDM\\n\\
8903 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8906 [(set_attr "type" "tls_load")
8907 (set_attr "length" "26")])
8909 (define_expand "sym2DTPOFF"
8910 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8914 (define_expand "symDTPOFF2reg"
8915 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8919 rtx dtpoffsym, insn;
8920 rtx t = (!can_create_pseudo_p ()
8922 : gen_reg_rtx (GET_MODE (operands[0])));
8924 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8925 PUT_MODE (dtpoffsym, Pmode);
8926 emit_move_insn (t, dtpoffsym);
8927 insn = emit_move_insn (operands[0],
8928 gen_rtx_PLUS (Pmode, t, operands[2]));
8932 (define_expand "sym2GOTTPOFF"
8933 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8937 (define_insn "tls_initial_exec"
8938 [(set (match_operand:SI 0 "register_operand" "=&r")
8939 (unspec:SI [(match_operand:SI 1 "" "")]
8941 (use (reg:SI GBR_REG))
8942 (use (reg:SI PIC_REG))
8943 (clobber (reg:SI R0_REG))]
8949 \\tstc\\tgbr,%0\\n\\
8950 \\tmov.l\\t@(r0,r12),r0\\n\\
8954 1:\\t.long\\t%a1\\n\\
8957 [(set_attr "type" "tls_load")
8958 (set_attr "length" "16")])
8960 (define_expand "sym2TPOFF"
8961 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8965 (define_expand "symTPOFF2reg"
8966 [(match_operand 0 "" "") (match_operand 1 "" "")]
8972 tpoffsym = gen_sym2TPOFF (operands[1]);
8973 PUT_MODE (tpoffsym, Pmode);
8974 insn = emit_move_insn (operands[0], tpoffsym);
8978 (define_insn "load_gbr"
8979 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8980 (use (reg:SI GBR_REG))]
8983 [(set_attr "type" "tls_load")])
8985 ;; case instruction for switch statements.
8987 ;; Operand 0 is index
8988 ;; operand 1 is the minimum bound
8989 ;; operand 2 is the maximum bound - minimum bound + 1
8990 ;; operand 3 is CODE_LABEL for the table;
8991 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8993 (define_expand "casesi"
8994 [(match_operand:SI 0 "arith_reg_operand" "")
8995 (match_operand:SI 1 "arith_reg_operand" "")
8996 (match_operand:SI 2 "arith_reg_operand" "")
8997 (match_operand 3 "" "") (match_operand 4 "" "")]
9001 rtx reg = gen_reg_rtx (SImode);
9002 rtx reg2 = gen_reg_rtx (SImode);
9005 rtx reg = gen_reg_rtx (DImode);
9006 rtx reg2 = gen_reg_rtx (DImode);
9007 rtx reg3 = gen_reg_rtx (Pmode);
9008 rtx reg4 = gen_reg_rtx (Pmode);
9009 rtx reg5 = gen_reg_rtx (Pmode);
9012 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9013 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9014 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9016 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9017 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9018 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9019 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9020 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9021 (Pmode, operands[3])));
9022 /* Messy: can we subreg to clean this up? */
9023 if (Pmode == DImode)
9024 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9026 load = gen_casesi_load_media (reg4,
9027 gen_rtx_SUBREG (DImode, reg3, 0),
9029 PUT_MODE (SET_SRC (load), Pmode);
9031 /* ??? The following add could be eliminated if we used ptrel. */
9032 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9033 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9037 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9038 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9039 /* If optimizing, casesi_worker depends on the mode of the instruction
9040 before label it 'uses' - operands[3]. */
9041 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9043 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9045 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9047 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9048 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9049 operands[3], but to lab. We will fix this up in
9050 machine_dependent_reorg. */
9055 (define_expand "casesi_0"
9056 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9057 (set (match_dup 4) (minus:SI (match_dup 4)
9058 (match_operand:SI 1 "arith_operand" "")))
9060 (gtu:SI (match_dup 4)
9061 (match_operand:SI 2 "arith_reg_operand" "")))
9063 (if_then_else (ne (reg:SI T_REG)
9065 (label_ref (match_operand 3 "" ""))
9070 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9071 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9072 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9074 (define_insn "casesi_worker_0"
9075 [(set (match_operand:SI 0 "register_operand" "=r,r")
9076 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9077 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9078 (clobber (match_scratch:SI 3 "=X,1"))
9079 (clobber (match_scratch:SI 4 "=&z,z"))]
9084 [(set (match_operand:SI 0 "register_operand" "")
9085 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9086 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9087 (clobber (match_scratch:SI 3 ""))
9088 (clobber (match_scratch:SI 4 ""))]
9089 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9090 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9091 (parallel [(set (match_dup 0)
9092 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9093 (label_ref (match_dup 2))] UNSPEC_CASESI))
9094 (clobber (match_dup 3))])
9095 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9096 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9099 [(set (match_operand:SI 0 "register_operand" "")
9100 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9101 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9102 (clobber (match_scratch:SI 3 ""))
9103 (clobber (match_scratch:SI 4 ""))]
9104 "TARGET_SH2 && reload_completed"
9105 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9106 (parallel [(set (match_dup 0)
9107 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9108 (label_ref (match_dup 2))] UNSPEC_CASESI))
9109 (clobber (match_dup 3))])]
9110 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9112 (define_insn "casesi_worker_1"
9113 [(set (match_operand:SI 0 "register_operand" "=r,r")
9114 (unspec:SI [(reg:SI R0_REG)
9115 (match_operand:SI 1 "register_operand" "0,r")
9116 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9117 (clobber (match_scratch:SI 3 "=X,1"))]
9121 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9123 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9125 switch (GET_MODE (diff_vec))
9128 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9130 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9132 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9133 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9134 return \"mov.b @(r0,%1),%0\";
9139 [(set_attr "length" "4")])
9141 (define_insn "casesi_worker_2"
9142 [(set (match_operand:SI 0 "register_operand" "=r,r")
9143 (unspec:SI [(reg:SI R0_REG)
9144 (match_operand:SI 1 "register_operand" "0,r")
9145 (label_ref (match_operand 2 "" ""))
9146 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9147 (clobber (match_operand:SI 4 "" "=X,1"))]
9148 "TARGET_SH2 && reload_completed && flag_pic"
9151 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9154 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9156 switch (GET_MODE (diff_vec))
9159 output_asm_insn (\"shll2 %1\", operands);
9160 load = \"mov.l @(r0,%1),%0\"; break;
9162 output_asm_insn (\"add %1,%1\", operands);
9163 load = \"mov.w @(r0,%1),%0\"; break;
9165 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9166 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9168 load = \"mov.b @(r0,%1),%0\";
9173 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9176 [(set_attr "length" "8")])
9178 (define_insn "casesi_shift_media"
9179 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9180 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9181 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9186 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9188 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9190 switch (GET_MODE (diff_vec))
9193 return \"shlli %1, 2, %0\";
9195 return \"shlli %1, 1, %0\";
9197 if (rtx_equal_p (operands[0], operands[1]))
9199 return \"add %1, r63, %0\";
9204 [(set_attr "type" "arith_media")])
9206 (define_insn "casesi_load_media"
9207 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9208 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9209 (match_operand:DI 2 "arith_reg_operand" "r")
9210 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9214 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9216 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9218 switch (GET_MODE (diff_vec))
9221 return \"ldx.l %1, %2, %0\";
9224 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9225 return \"ldx.uw %1, %2, %0\";
9227 return \"ldx.w %1, %2, %0\";
9229 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9230 return \"ldx.ub %1, %2, %0\";
9231 return \"ldx.b %1, %2, %0\";
9236 [(set_attr "type" "load_media")])
9238 (define_expand "return"
9240 "reload_completed && ! sh_need_epilogue ()"
9245 emit_jump_insn (gen_return_media ());
9249 if (TARGET_SHCOMPACT
9250 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9252 emit_jump_insn (gen_shcompact_return_tramp ());
9257 (define_insn "*return_i"
9259 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9260 && (current_function_args_info.call_cookie
9261 & CALL_COOKIE_RET_TRAMP (1)))
9263 && lookup_attribute (\"trap_exit\",
9264 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9266 [(set_attr "type" "return")
9267 (set_attr "needs_delay_slot" "yes")])
9269 ;; trapa has no delay slot.
9270 (define_insn "*return_trapa"
9272 "TARGET_SH1 && !TARGET_SHCOMPACT
9273 && reload_completed"
9275 [(set_attr "type" "return")])
9277 (define_expand "shcompact_return_tramp"
9280 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9283 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9285 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9286 emit_jump_insn (gen_shcompact_return_tramp_i ());
9290 (define_insn "shcompact_return_tramp_i"
9291 [(parallel [(return) (use (reg:SI R0_REG))])]
9293 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9295 [(set_attr "type" "jump_ind")
9296 (set_attr "needs_delay_slot" "yes")])
9298 (define_insn "return_media_i"
9299 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9300 "TARGET_SHMEDIA && reload_completed"
9302 [(set_attr "type" "jump_media")])
9304 (define_insn "return_media_rte"
9306 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9308 [(set_attr "type" "jump_media")])
9310 (define_expand "return_media"
9312 "TARGET_SHMEDIA && reload_completed"
9315 int tr_regno = sh_media_register_for_return ();
9318 if (current_function_interrupt)
9320 emit_jump_insn (gen_return_media_rte ());
9325 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9327 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9329 tr = gen_rtx_REG (Pmode, tr_regno);
9330 emit_move_insn (tr, r18);
9333 tr = gen_rtx_REG (Pmode, tr_regno);
9335 emit_jump_insn (gen_return_media_i (tr));
9339 (define_insn "shcompact_preserve_incoming_args"
9340 [(set (match_operand:SI 0 "register_operand" "+r")
9341 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9344 [(set_attr "length" "0")])
9346 (define_insn "shcompact_incoming_args"
9347 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9349 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9350 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9351 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9352 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9353 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9354 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9355 (set (mem:BLK (reg:SI MACL_REG))
9356 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9357 (use (reg:SI R0_REG))
9358 (clobber (reg:SI R0_REG))
9359 (clobber (reg:SI MACL_REG))
9360 (clobber (reg:SI MACH_REG))
9361 (clobber (reg:SI PR_REG))]
9364 [(set_attr "needs_delay_slot" "yes")])
9366 (define_insn "shmedia_save_restore_regs_compact"
9367 [(set (reg:SI SP_REG)
9368 (plus:SI (reg:SI SP_REG)
9369 (match_operand:SI 0 "immediate_operand" "i")))
9370 (use (reg:SI R0_REG))
9371 (clobber (reg:SI PR_REG))]
9373 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9374 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9376 [(set_attr "needs_delay_slot" "yes")])
9378 (define_expand "prologue"
9381 "sh_expand_prologue (); DONE;")
9383 (define_expand "epilogue"
9388 sh_expand_epilogue (0);
9389 emit_jump_insn (gen_return ());
9393 (define_expand "eh_return"
9394 [(use (match_operand 0 "register_operand" ""))]
9397 rtx ra = operands[0];
9399 if (TARGET_SHMEDIA64)
9400 emit_insn (gen_eh_set_ra_di (ra));
9402 emit_insn (gen_eh_set_ra_si (ra));
9407 ;; Clobber the return address on the stack. We can't expand this
9408 ;; until we know where it will be put in the stack frame.
9410 (define_insn "eh_set_ra_si"
9411 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9413 (clobber (match_scratch:SI 1 "=&r"))]
9414 "! TARGET_SHMEDIA64"
9417 (define_insn "eh_set_ra_di"
9418 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9420 (clobber (match_scratch:DI 1 "=&r"))]
9425 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9427 (clobber (match_scratch 1 ""))]
9432 sh_set_return_address (operands[0], operands[1]);
9436 (define_insn "blockage"
9437 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9440 [(set_attr "length" "0")])
9442 ;; ------------------------------------------------------------------------
9444 ;; ------------------------------------------------------------------------
9447 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9448 (eq:SI (reg:SI T_REG) (const_int 1)))]
9451 [(set_attr "type" "arith")])
9453 (define_expand "seq"
9454 [(set (match_operand:SI 0 "arith_reg_dest" "")
9463 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9464 if (sh_compare_op1 != const0_rtx)
9465 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9466 ? GET_MODE (sh_compare_op0)
9467 : GET_MODE (sh_compare_op1),
9469 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9471 if (GET_MODE (operands[0]) != SImode)
9472 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9474 switch (GET_MODE (sh_compare_op0))
9477 emit_insn (gen_cmpeqsi_media (operands[0],
9478 sh_compare_op0, sh_compare_op1));
9482 emit_insn (gen_cmpeqdi_media (operands[0],
9483 sh_compare_op0, sh_compare_op1));
9487 if (! TARGET_SHMEDIA_FPU)
9489 emit_insn (gen_cmpeqsf_media (operands[0],
9490 sh_compare_op0, sh_compare_op1));
9494 if (! TARGET_SHMEDIA_FPU)
9496 emit_insn (gen_cmpeqdf_media (operands[0],
9497 sh_compare_op0, sh_compare_op1));
9507 if (GET_MODE (operands[0]) != SImode)
9508 reg = (!can_create_pseudo_p ()
9509 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9510 : gen_reg_rtx (SImode));
9512 switch (GET_MODE (sh_compare_op0))
9515 emit_insn (gen_cmpeqsi_media (reg,
9516 sh_compare_op0, sh_compare_op1));
9520 emit_insn (gen_cmpeqdi_media (reg,
9521 sh_compare_op0, sh_compare_op1));
9525 if (! TARGET_SHMEDIA_FPU)
9527 emit_insn (gen_cmpeqsf_media (reg,
9528 sh_compare_op0, sh_compare_op1));
9532 if (! TARGET_SHMEDIA_FPU)
9534 emit_insn (gen_cmpeqdf_media (reg,
9535 sh_compare_op0, sh_compare_op1));
9542 if (GET_MODE (operands[0]) == DImode)
9543 emit_insn (gen_extendsidi2 (operands[0], reg));
9547 if (sh_expand_t_scc (EQ, operands[0]))
9549 if (! currently_expanding_to_rtl)
9551 operands[1] = prepare_scc_operands (EQ);
9554 (define_expand "slt"
9555 [(set (match_operand:SI 0 "arith_reg_operand" "")
9564 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9565 if (sh_compare_op1 != const0_rtx)
9566 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9567 ? GET_MODE (sh_compare_op0)
9568 : GET_MODE (sh_compare_op1),
9572 if (GET_MODE (operands[0]) != SImode)
9573 reg = (!can_create_pseudo_p ()
9574 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9575 : gen_reg_rtx (SImode));
9577 switch (GET_MODE (sh_compare_op0))
9580 emit_insn (gen_cmpgtsi_media (reg,
9581 sh_compare_op1, sh_compare_op0));
9585 emit_insn (gen_cmpgtdi_media (reg,
9586 sh_compare_op1, sh_compare_op0));
9590 if (! TARGET_SHMEDIA_FPU)
9592 emit_insn (gen_cmpgtsf_media (reg,
9593 sh_compare_op1, sh_compare_op0));
9597 if (! TARGET_SHMEDIA_FPU)
9599 emit_insn (gen_cmpgtdf_media (reg,
9600 sh_compare_op1, sh_compare_op0));
9607 if (GET_MODE (operands[0]) == DImode)
9608 emit_insn (gen_extendsidi2 (operands[0], reg));
9612 if (! currently_expanding_to_rtl)
9614 operands[1] = prepare_scc_operands (LT);
9617 (define_expand "sle"
9618 [(match_operand:SI 0 "arith_reg_operand" "")]
9622 rtx tmp = sh_compare_op0;
9628 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9629 if (sh_compare_op1 != const0_rtx)
9630 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9631 ? GET_MODE (sh_compare_op0)
9632 : GET_MODE (sh_compare_op1),
9636 if (GET_MODE (operands[0]) != SImode)
9637 reg = (!can_create_pseudo_p ()
9638 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9639 : gen_reg_rtx (SImode));
9641 switch (GET_MODE (sh_compare_op0))
9645 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9647 emit_insn (gen_cmpgtsi_media (tmp,
9648 sh_compare_op0, sh_compare_op1));
9649 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9655 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9657 emit_insn (gen_cmpgtdi_media (tmp,
9658 sh_compare_op0, sh_compare_op1));
9659 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9664 if (! TARGET_SHMEDIA_FPU)
9666 emit_insn (gen_cmpgesf_media (reg,
9667 sh_compare_op1, sh_compare_op0));
9671 if (! TARGET_SHMEDIA_FPU)
9673 emit_insn (gen_cmpgedf_media (reg,
9674 sh_compare_op1, sh_compare_op0));
9681 if (GET_MODE (operands[0]) == DImode)
9682 emit_insn (gen_extendsidi2 (operands[0], reg));
9687 sh_compare_op0 = sh_compare_op1;
9688 sh_compare_op1 = tmp;
9689 emit_insn (gen_sge (operands[0]));
9693 (define_expand "sgt"
9694 [(set (match_operand:SI 0 "arith_reg_operand" "")
9704 if (GET_MODE (operands[0]) != SImode)
9705 reg = (!can_create_pseudo_p () ?
9706 gen_rtx_SUBREG (SImode, operands[0], 0)
9707 : gen_reg_rtx (SImode));
9708 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9709 if (sh_compare_op1 != const0_rtx)
9710 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9711 ? GET_MODE (sh_compare_op0)
9712 : GET_MODE (sh_compare_op1),
9715 switch (GET_MODE (sh_compare_op0))
9718 emit_insn (gen_cmpgtsi_media (reg,
9719 sh_compare_op0, sh_compare_op1));
9723 emit_insn (gen_cmpgtdi_media (reg,
9724 sh_compare_op0, sh_compare_op1));
9728 if (! TARGET_SHMEDIA_FPU)
9730 emit_insn (gen_cmpgtsf_media (reg,
9731 sh_compare_op0, sh_compare_op1));
9735 if (! TARGET_SHMEDIA_FPU)
9737 emit_insn (gen_cmpgtdf_media (reg,
9738 sh_compare_op0, sh_compare_op1));
9745 if (GET_MODE (operands[0]) == DImode)
9746 emit_insn (gen_extendsidi2 (operands[0], reg));
9750 if (! currently_expanding_to_rtl)
9752 operands[1] = prepare_scc_operands (GT);
9755 (define_expand "sge"
9756 [(set (match_operand:SI 0 "arith_reg_operand" "")
9764 enum machine_mode mode = GET_MODE (sh_compare_op0);
9766 if ((mode) == VOIDmode)
9767 mode = GET_MODE (sh_compare_op1);
9769 if (GET_MODE (operands[0]) != SImode)
9770 reg = (!can_create_pseudo_p ()
9771 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9772 : gen_reg_rtx (SImode));
9773 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9774 if (sh_compare_op1 != const0_rtx)
9775 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9781 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9783 emit_insn (gen_cmpgtsi_media (tmp,
9784 sh_compare_op1, sh_compare_op0));
9785 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9791 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9793 emit_insn (gen_cmpgtdi_media (tmp,
9794 sh_compare_op1, sh_compare_op0));
9795 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9800 if (! TARGET_SHMEDIA_FPU)
9802 emit_insn (gen_cmpgesf_media (reg,
9803 sh_compare_op0, sh_compare_op1));
9807 if (! TARGET_SHMEDIA_FPU)
9809 emit_insn (gen_cmpgedf_media (reg,
9810 sh_compare_op0, sh_compare_op1));
9817 if (GET_MODE (operands[0]) == DImode)
9818 emit_insn (gen_extendsidi2 (operands[0], reg));
9823 if (! currently_expanding_to_rtl)
9825 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9829 rtx lab = gen_label_rtx ();
9830 prepare_scc_operands (EQ);
9831 emit_jump_insn (gen_branch_true (lab));
9832 prepare_scc_operands (GT);
9834 emit_insn (gen_movt (operands[0]));
9837 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9840 operands[1] = prepare_scc_operands (GE);
9843 (define_expand "sgtu"
9844 [(set (match_operand:SI 0 "arith_reg_operand" "")
9854 if (GET_MODE (operands[0]) == DImode)
9855 reg = (!can_create_pseudo_p ()
9856 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9857 : gen_reg_rtx (SImode));
9858 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9859 if (sh_compare_op1 != const0_rtx)
9860 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9861 ? GET_MODE (sh_compare_op0)
9862 : GET_MODE (sh_compare_op1),
9865 emit_insn (gen_cmpgtudi_media (reg,
9866 sh_compare_op0, sh_compare_op1));
9867 if (GET_MODE (operands[0]) == DImode)
9868 emit_insn (gen_extendsidi2 (operands[0], reg));
9872 if (! currently_expanding_to_rtl)
9874 operands[1] = prepare_scc_operands (GTU);
9877 (define_expand "sltu"
9878 [(set (match_operand:SI 0 "arith_reg_operand" "")
9888 if (GET_MODE (operands[0]) == DImode)
9889 reg = (!can_create_pseudo_p ()
9890 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9891 : gen_reg_rtx (SImode));
9892 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9893 if (sh_compare_op1 != const0_rtx)
9894 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9895 ? GET_MODE (sh_compare_op0)
9896 : GET_MODE (sh_compare_op1),
9899 emit_insn (gen_cmpgtudi_media (reg,
9900 sh_compare_op1, sh_compare_op0));
9901 if (GET_MODE (operands[0]) == DImode)
9902 emit_insn (gen_extendsidi2 (operands[0], reg));
9906 if (! currently_expanding_to_rtl)
9908 operands[1] = prepare_scc_operands (LTU);
9911 (define_expand "sleu"
9912 [(set (match_operand:SI 0 "arith_reg_operand" "")
9922 if (GET_MODE (operands[0]) != SImode)
9923 reg = (!can_create_pseudo_p ()
9924 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9925 : gen_reg_rtx (SImode));
9926 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9927 if (sh_compare_op1 != const0_rtx)
9928 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9929 ? GET_MODE (sh_compare_op0)
9930 : GET_MODE (sh_compare_op1),
9933 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9935 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9936 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9937 if (GET_MODE (operands[0]) == DImode)
9938 emit_insn (gen_extendsidi2 (operands[0], reg));
9942 if (! currently_expanding_to_rtl)
9944 operands[1] = prepare_scc_operands (LEU);
9947 (define_expand "sgeu"
9948 [(set (match_operand:SI 0 "arith_reg_operand" "")
9958 if (GET_MODE (operands[0]) != SImode)
9959 reg = (!can_create_pseudo_p ()
9960 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9961 : gen_reg_rtx (SImode));
9962 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9963 if (sh_compare_op1 != const0_rtx)
9964 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9965 ? GET_MODE (sh_compare_op0)
9966 : GET_MODE (sh_compare_op1),
9969 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
9971 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9972 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9973 if (GET_MODE (operands[0]) == DImode)
9974 emit_insn (gen_extendsidi2 (operands[0], reg));
9979 if (! currently_expanding_to_rtl)
9981 operands[1] = prepare_scc_operands (GEU);
9984 ;; sne moves the complement of the T reg to DEST like this:
9988 ;; This is better than xoring compare result with 1 because it does
9989 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9992 (define_expand "sne"
9993 [(set (match_dup 2) (const_int -1))
9994 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9995 (neg:SI (plus:SI (match_dup 1)
9998 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10003 if (TARGET_SHMEDIA)
10008 if (GET_MODE (operands[0]) != SImode)
10009 reg = (!can_create_pseudo_p ()
10010 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10011 : gen_reg_rtx (SImode));
10012 if (! TARGET_SHMEDIA_FPU
10013 && GET_MODE (sh_compare_op0) != DImode
10014 && GET_MODE (sh_compare_op0) != SImode)
10017 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10018 if (sh_compare_op1 != const0_rtx)
10019 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10020 ? GET_MODE (sh_compare_op0)
10021 : GET_MODE (sh_compare_op1),
10024 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10026 emit_insn (gen_seq (tmp));
10027 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10028 if (GET_MODE (operands[0]) == DImode)
10029 emit_insn (gen_extendsidi2 (operands[0], reg));
10034 if (sh_expand_t_scc (NE, operands[0]))
10036 if (! currently_expanding_to_rtl)
10038 operands[1] = prepare_scc_operands (EQ);
10039 operands[2] = gen_reg_rtx (SImode);
10042 (define_expand "sunordered"
10043 [(set (match_operand:SI 0 "arith_reg_operand" "")
10044 (unordered:SI (match_dup 1) (match_dup 2)))]
10045 "TARGET_SHMEDIA_FPU"
10048 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10049 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10052 ;; Use the same trick for FP sle / sge
10054 ;; Apart from the constant use and the T setting, this is like movt,
10055 ;; except that it uses the logically negated value of T, i.e.
10056 ;; operand[0] := T ? 0 : 1.
10057 (define_expand "movnegt"
10058 [(set (match_dup 2) (const_int -1))
10059 (parallel [(set (match_operand 0 "" "")
10060 (neg:SI (plus:SI (match_dup 1)
10062 (set (reg:SI T_REG)
10063 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10066 "operands[2] = gen_reg_rtx (SImode);")
10068 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10069 ;; This prevents a regression that occurred when we switched from xor to
10070 ;; mov/neg for sne.
10073 [(set (match_operand:SI 0 "arith_reg_dest" "")
10074 (plus:SI (reg:SI T_REG)
10077 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10078 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10081 ;; -------------------------------------------------------------------------
10082 ;; Instructions to cope with inline literal tables
10083 ;; -------------------------------------------------------------------------
10085 ; 2 byte integer in line
10087 (define_insn "consttable_2"
10088 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10089 (match_operand 1 "" "")]
10094 if (operands[1] != const0_rtx)
10095 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10098 [(set_attr "length" "2")
10099 (set_attr "in_delay_slot" "no")])
10101 ; 4 byte integer in line
10103 (define_insn "consttable_4"
10104 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10105 (match_operand 1 "" "")]
10110 if (operands[1] != const0_rtx)
10111 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10114 [(set_attr "length" "4")
10115 (set_attr "in_delay_slot" "no")])
10117 ; 8 byte integer in line
10119 (define_insn "consttable_8"
10120 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10121 (match_operand 1 "" "")]
10126 if (operands[1] != const0_rtx)
10127 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10130 [(set_attr "length" "8")
10131 (set_attr "in_delay_slot" "no")])
10133 ; 4 byte floating point
10135 (define_insn "consttable_sf"
10136 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10137 (match_operand 1 "" "")]
10142 if (operands[1] != const0_rtx)
10145 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10146 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10150 [(set_attr "length" "4")
10151 (set_attr "in_delay_slot" "no")])
10153 ; 8 byte floating point
10155 (define_insn "consttable_df"
10156 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10157 (match_operand 1 "" "")]
10162 if (operands[1] != const0_rtx)
10165 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10166 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10170 [(set_attr "length" "8")
10171 (set_attr "in_delay_slot" "no")])
10173 ;; Alignment is needed for some constant tables; it may also be added for
10174 ;; Instructions at the start of loops, or after unconditional branches.
10175 ;; ??? We would get more accurate lengths if we did instruction
10176 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10177 ;; here is too conservative.
10179 ; align to a two byte boundary
10181 (define_expand "align_2"
10182 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10186 ; align to a four byte boundary
10187 ;; align_4 and align_log are instructions for the starts of loops, or
10188 ;; after unconditional branches, which may take up extra room.
10190 (define_expand "align_4"
10191 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10195 ; align to a cache line boundary
10197 (define_insn "align_log"
10198 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10201 [(set_attr "length" "0")
10202 (set_attr "in_delay_slot" "no")])
10204 ; emitted at the end of the literal table, used to emit the
10205 ; 32bit branch labels if needed.
10207 (define_insn "consttable_end"
10208 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10210 "* return output_jump_label_table ();"
10211 [(set_attr "in_delay_slot" "no")])
10213 ; emitted at the end of the window in the literal table.
10215 (define_insn "consttable_window_end"
10216 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10219 [(set_attr "length" "0")
10220 (set_attr "in_delay_slot" "no")])
10222 ;; -------------------------------------------------------------------------
10224 ;; -------------------------------------------------------------------------
10226 ;; String/block move insn.
10228 (define_expand "movmemsi"
10229 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10230 (mem:BLK (match_operand:BLK 1 "" "")))
10231 (use (match_operand:SI 2 "nonmemory_operand" ""))
10232 (use (match_operand:SI 3 "immediate_operand" ""))
10233 (clobber (reg:SI PR_REG))
10234 (clobber (reg:SI R4_REG))
10235 (clobber (reg:SI R5_REG))
10236 (clobber (reg:SI R0_REG))])]
10237 "TARGET_SH1 && ! TARGET_SH5"
10240 if(expand_block_move (operands))
10245 (define_insn "block_move_real"
10246 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10247 (mem:BLK (reg:SI R5_REG)))
10248 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10249 (clobber (reg:SI PR_REG))
10250 (clobber (reg:SI R0_REG))])]
10251 "TARGET_SH1 && ! TARGET_HARD_SH4"
10253 [(set_attr "type" "sfunc")
10254 (set_attr "needs_delay_slot" "yes")])
10256 (define_insn "block_lump_real"
10257 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10258 (mem:BLK (reg:SI R5_REG)))
10259 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10260 (use (reg:SI R6_REG))
10261 (clobber (reg:SI PR_REG))
10262 (clobber (reg:SI T_REG))
10263 (clobber (reg:SI R4_REG))
10264 (clobber (reg:SI R5_REG))
10265 (clobber (reg:SI R6_REG))
10266 (clobber (reg:SI R0_REG))])]
10267 "TARGET_SH1 && ! TARGET_HARD_SH4"
10269 [(set_attr "type" "sfunc")
10270 (set_attr "needs_delay_slot" "yes")])
10272 (define_insn "block_move_real_i4"
10273 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10274 (mem:BLK (reg:SI R5_REG)))
10275 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10276 (clobber (reg:SI PR_REG))
10277 (clobber (reg:SI R0_REG))
10278 (clobber (reg:SI R1_REG))
10279 (clobber (reg:SI R2_REG))])]
10282 [(set_attr "type" "sfunc")
10283 (set_attr "needs_delay_slot" "yes")])
10285 (define_insn "block_lump_real_i4"
10286 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10287 (mem:BLK (reg:SI R5_REG)))
10288 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10289 (use (reg:SI R6_REG))
10290 (clobber (reg:SI PR_REG))
10291 (clobber (reg:SI T_REG))
10292 (clobber (reg:SI R4_REG))
10293 (clobber (reg:SI R5_REG))
10294 (clobber (reg:SI R6_REG))
10295 (clobber (reg:SI R0_REG))
10296 (clobber (reg:SI R1_REG))
10297 (clobber (reg:SI R2_REG))
10298 (clobber (reg:SI R3_REG))])]
10301 [(set_attr "type" "sfunc")
10302 (set_attr "needs_delay_slot" "yes")])
10304 ;; -------------------------------------------------------------------------
10305 ;; Floating point instructions.
10306 ;; -------------------------------------------------------------------------
10308 ;; ??? All patterns should have a type attribute.
10310 (define_expand "movpsi"
10311 [(set (match_operand:PSI 0 "register_operand" "")
10312 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10313 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10316 ;; The c / m alternative is a fake to guide reload to load directly into
10317 ;; fpscr, since reload doesn't know how to use post-increment.
10318 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10319 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10320 ;; predicate after reload.
10321 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10322 ;; like a mac -> gpr move.
10323 (define_insn "fpu_switch"
10324 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10325 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10327 && (! reload_completed
10328 || true_regnum (operands[0]) != FPSCR_REG
10329 || GET_CODE (operands[1]) != MEM
10330 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10332 ! precision stays the same
10341 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10342 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10345 [(set (reg:PSI FPSCR_REG)
10346 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10347 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10350 rtx fpscr, mem, new_insn;
10352 fpscr = SET_DEST (PATTERN (curr_insn));
10353 mem = SET_SRC (PATTERN (curr_insn));
10354 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10356 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10357 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10362 [(set (reg:PSI FPSCR_REG)
10363 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10364 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10365 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10368 rtx fpscr, mem, new_insn;
10370 fpscr = SET_DEST (PATTERN (curr_insn));
10371 mem = SET_SRC (PATTERN (curr_insn));
10372 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10374 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10375 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10377 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10378 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10382 ;; ??? This uses the fp unit, but has no type indicating that.
10383 ;; If we did that, this would either give a bogus latency or introduce
10384 ;; a bogus FIFO constraint.
10385 ;; Since this insn is currently only used for prologues/epilogues,
10386 ;; it is probably best to claim no function unit, which matches the
10387 ;; current setting.
10388 (define_insn "toggle_sz"
10389 [(set (reg:PSI FPSCR_REG)
10390 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10391 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10393 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10395 ;; There's no way we can use it today, since optimize mode switching
10396 ;; doesn't enable us to know from which mode we're switching to the
10397 ;; mode it requests, to tell whether we can use a relative mode switch
10398 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10400 (define_insn "toggle_pr"
10401 [(set (reg:PSI FPSCR_REG)
10402 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10403 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10405 [(set_attr "type" "fpscr_toggle")])
10407 (define_expand "addsf3"
10408 [(set (match_operand:SF 0 "arith_reg_operand" "")
10409 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10410 (match_operand:SF 2 "arith_reg_operand" "")))]
10411 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10416 expand_sf_binop (&gen_addsf3_i, operands);
10421 (define_insn "*addsf3_media"
10422 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10423 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10424 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10425 "TARGET_SHMEDIA_FPU"
10426 "fadd.s %1, %2, %0"
10427 [(set_attr "type" "fparith_media")])
10429 (define_insn_and_split "unary_sf_op"
10430 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10435 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10436 (match_operator:SF 2 "unary_float_operator"
10437 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10438 (parallel [(match_operand 4
10439 "const_int_operand" "n")]))]))
10440 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10441 "TARGET_SHMEDIA_FPU"
10443 "TARGET_SHMEDIA_FPU && reload_completed"
10444 [(set (match_dup 5) (match_dup 6))]
10447 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10448 rtx op1 = gen_rtx_REG (SFmode,
10449 (true_regnum (operands[1])
10450 + (INTVAL (operands[4]) ^ endian)));
10452 operands[7] = gen_rtx_REG (SFmode,
10453 (true_regnum (operands[0])
10454 + (INTVAL (operands[3]) ^ endian)));
10455 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10457 [(set_attr "type" "fparith_media")])
10459 (define_insn_and_split "binary_sf_op0"
10460 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10462 (match_operator:SF 3 "binary_float_operator"
10463 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10464 (parallel [(const_int 0)]))
10465 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10466 (parallel [(const_int 0)]))])
10469 (parallel [(const_int 1)]))))]
10470 "TARGET_SHMEDIA_FPU"
10472 "&& reload_completed"
10473 [(set (match_dup 4) (match_dup 5))]
10476 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10477 rtx op1 = gen_rtx_REG (SFmode,
10478 true_regnum (operands[1]) + endian);
10479 rtx op2 = gen_rtx_REG (SFmode,
10480 true_regnum (operands[2]) + endian);
10482 operands[4] = gen_rtx_REG (SFmode,
10483 true_regnum (operands[0]) + endian);
10484 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10486 [(set_attr "type" "fparith_media")])
10488 (define_insn_and_split "binary_sf_op1"
10489 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10493 (parallel [(const_int 0)]))
10494 (match_operator:SF 3 "binary_float_operator"
10495 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10496 (parallel [(const_int 1)]))
10497 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10498 (parallel [(const_int 1)]))])))]
10499 "TARGET_SHMEDIA_FPU"
10501 "&& reload_completed"
10502 [(set (match_dup 4) (match_dup 5))]
10505 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10506 rtx op1 = gen_rtx_REG (SFmode,
10507 true_regnum (operands[1]) + (1 ^ endian));
10508 rtx op2 = gen_rtx_REG (SFmode,
10509 true_regnum (operands[2]) + (1 ^ endian));
10511 operands[4] = gen_rtx_REG (SFmode,
10512 true_regnum (operands[0]) + (1 ^ endian));
10513 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10515 [(set_attr "type" "fparith_media")])
10517 (define_insn "addsf3_i"
10518 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10519 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10520 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10521 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10524 [(set_attr "type" "fp")
10525 (set_attr "fp_mode" "single")])
10527 (define_expand "subsf3"
10528 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10529 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10530 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10531 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10536 expand_sf_binop (&gen_subsf3_i, operands);
10541 (define_insn "*subsf3_media"
10542 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10543 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10544 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10545 "TARGET_SHMEDIA_FPU"
10546 "fsub.s %1, %2, %0"
10547 [(set_attr "type" "fparith_media")])
10549 (define_insn "subsf3_i"
10550 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10551 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10552 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10553 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10556 [(set_attr "type" "fp")
10557 (set_attr "fp_mode" "single")])
10559 (define_expand "mulsf3"
10560 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10561 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10562 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10563 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10566 (define_insn "*mulsf3_media"
10567 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10568 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10569 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10570 "TARGET_SHMEDIA_FPU"
10571 "fmul.s %1, %2, %0"
10572 [(set_attr "type" "fparith_media")])
10574 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10575 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10576 ;; we start out with a mulsf pattern that does not depend on fpscr.
10577 ;; This is split after combine to introduce the dependency, in order to
10578 ;; get mode switching and scheduling right.
10579 (define_insn_and_split "mulsf3_ie"
10580 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10581 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10582 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10585 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10589 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10590 get_fpscr_rtx ()));
10593 [(set_attr "type" "fp")])
10595 (define_insn "mulsf3_i4"
10596 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10597 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10598 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10599 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10602 [(set_attr "type" "fp")
10603 (set_attr "fp_mode" "single")])
10605 (define_insn "mac_media"
10606 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10607 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10608 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10609 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10610 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10611 "fmac.s %1, %2, %0"
10612 [(set_attr "type" "fparith_media")])
10614 (define_insn "*macsf3"
10615 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10616 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10617 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10618 (match_operand:SF 3 "arith_reg_operand" "0")))
10619 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10620 "TARGET_SH2E && TARGET_FMAC"
10622 [(set_attr "type" "fp")
10623 (set_attr "fp_mode" "single")])
10625 (define_expand "divsf3"
10626 [(set (match_operand:SF 0 "arith_reg_operand" "")
10627 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10628 (match_operand:SF 2 "arith_reg_operand" "")))]
10629 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10634 expand_sf_binop (&gen_divsf3_i, operands);
10639 (define_insn "*divsf3_media"
10640 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10641 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10642 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10643 "TARGET_SHMEDIA_FPU"
10644 "fdiv.s %1, %2, %0"
10645 [(set_attr "type" "fdiv_media")])
10647 (define_insn "divsf3_i"
10648 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10649 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10650 (match_operand:SF 2 "arith_reg_operand" "f")))
10651 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10654 [(set_attr "type" "fdiv")
10655 (set_attr "fp_mode" "single")])
10657 (define_insn "floatdisf2"
10658 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10659 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10660 "TARGET_SHMEDIA_FPU"
10662 [(set_attr "type" "fpconv_media")])
10664 (define_expand "floatsisf2"
10665 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10666 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10667 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10670 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10672 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10677 (define_insn "*floatsisf2_media"
10678 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10679 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10680 "TARGET_SHMEDIA_FPU"
10682 [(set_attr "type" "fpconv_media")])
10684 (define_insn "floatsisf2_i4"
10685 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10686 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10687 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10688 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10690 [(set_attr "type" "fp")
10691 (set_attr "fp_mode" "single")])
10693 (define_insn "*floatsisf2_ie"
10694 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10695 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10696 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10698 [(set_attr "type" "fp")])
10700 (define_insn "fix_truncsfdi2"
10701 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10702 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10703 "TARGET_SHMEDIA_FPU"
10705 [(set_attr "type" "fpconv_media")])
10707 (define_expand "fix_truncsfsi2"
10708 [(set (match_operand:SI 0 "fpul_operand" "=y")
10709 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10710 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10713 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10715 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10720 (define_insn "*fix_truncsfsi2_media"
10721 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10722 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10723 "TARGET_SHMEDIA_FPU"
10725 [(set_attr "type" "fpconv_media")])
10727 (define_insn "fix_truncsfsi2_i4"
10728 [(set (match_operand:SI 0 "fpul_operand" "=y")
10729 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10730 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10731 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10733 [(set_attr "type" "ftrc_s")
10734 (set_attr "fp_mode" "single")])
10736 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10737 ;; fix_truncsfsi2_i4.
10738 ;; (define_insn "fix_truncsfsi2_i4_2"
10739 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10740 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10741 ;; (use (reg:PSI FPSCR_REG))
10742 ;; (clobber (reg:SI FPUL_REG))]
10745 ;; [(set_attr "length" "4")
10746 ;; (set_attr "fp_mode" "single")])
10749 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10750 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10751 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10752 ;; (clobber (reg:SI FPUL_REG))]
10754 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10755 ;; (use (match_dup 2))])
10756 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10758 (define_insn "*fixsfsi"
10759 [(set (match_operand:SI 0 "fpul_operand" "=y")
10760 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10761 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10763 [(set_attr "type" "fp")])
10765 (define_insn "cmpgtsf_t"
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 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10771 [(set_attr "type" "fp_cmp")
10772 (set_attr "fp_mode" "single")])
10774 (define_insn "cmpeqsf_t"
10775 [(set (reg:SI T_REG)
10776 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10777 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10778 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10780 [(set_attr "type" "fp_cmp")
10781 (set_attr "fp_mode" "single")])
10783 (define_insn "ieee_ccmpeqsf_t"
10784 [(set (reg:SI T_REG)
10785 (ior:SI (reg:SI T_REG)
10786 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10787 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10788 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10789 "* return output_ieee_ccmpeq (insn, operands);"
10790 [(set_attr "length" "4")])
10793 (define_insn "cmpgtsf_t_i4"
10794 [(set (reg:SI T_REG)
10795 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10796 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10797 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10798 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10800 [(set_attr "type" "fp_cmp")
10801 (set_attr "fp_mode" "single")])
10803 (define_insn "cmpeqsf_t_i4"
10804 [(set (reg:SI T_REG)
10805 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10806 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10807 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10808 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10810 [(set_attr "type" "fp_cmp")
10811 (set_attr "fp_mode" "single")])
10813 (define_insn "*ieee_ccmpeqsf_t_4"
10814 [(set (reg:SI T_REG)
10815 (ior:SI (reg:SI T_REG)
10816 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10817 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10818 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10819 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10820 "* return output_ieee_ccmpeq (insn, operands);"
10821 [(set_attr "length" "4")
10822 (set_attr "fp_mode" "single")])
10824 (define_insn "cmpeqsf_media"
10825 [(set (match_operand:SI 0 "register_operand" "=r")
10826 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10827 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10828 "TARGET_SHMEDIA_FPU"
10829 "fcmpeq.s %1, %2, %0"
10830 [(set_attr "type" "fcmp_media")])
10832 (define_insn "cmpgtsf_media"
10833 [(set (match_operand:SI 0 "register_operand" "=r")
10834 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10835 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10836 "TARGET_SHMEDIA_FPU"
10837 "fcmpgt.s %1, %2, %0"
10838 [(set_attr "type" "fcmp_media")])
10840 (define_insn "cmpgesf_media"
10841 [(set (match_operand:SI 0 "register_operand" "=r")
10842 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10843 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10844 "TARGET_SHMEDIA_FPU"
10845 "fcmpge.s %1, %2, %0"
10846 [(set_attr "type" "fcmp_media")])
10848 (define_insn "cmpunsf_media"
10849 [(set (match_operand:SI 0 "register_operand" "=r")
10850 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10851 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10852 "TARGET_SHMEDIA_FPU"
10853 "fcmpun.s %1, %2, %0"
10854 [(set_attr "type" "fcmp_media")])
10856 (define_expand "cmpsf"
10857 [(set (reg:SI T_REG)
10858 (compare (match_operand:SF 0 "arith_operand" "")
10859 (match_operand:SF 1 "arith_operand" "")))]
10860 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10863 sh_compare_op0 = operands[0];
10864 sh_compare_op1 = operands[1];
10868 (define_expand "negsf2"
10869 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10870 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10871 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10876 expand_sf_unop (&gen_negsf2_i, operands);
10881 (define_insn "*negsf2_media"
10882 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10883 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10884 "TARGET_SHMEDIA_FPU"
10886 [(set_attr "type" "fmove_media")])
10888 (define_insn "negsf2_i"
10889 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10890 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10891 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10894 [(set_attr "type" "fmove")
10895 (set_attr "fp_mode" "single")])
10897 (define_expand "sqrtsf2"
10898 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10899 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10900 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10905 expand_sf_unop (&gen_sqrtsf2_i, operands);
10910 (define_insn "*sqrtsf2_media"
10911 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10912 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10913 "TARGET_SHMEDIA_FPU"
10915 [(set_attr "type" "fdiv_media")])
10917 (define_insn "sqrtsf2_i"
10918 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10919 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10920 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10923 [(set_attr "type" "fdiv")
10924 (set_attr "fp_mode" "single")])
10926 (define_insn "rsqrtsf2"
10927 [(set (match_operand:SF 0 "register_operand" "=f")
10928 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10929 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10930 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10931 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10932 && operands[1] == CONST1_RTX (SFmode)"
10934 [(set_attr "type" "fsrra")
10935 (set_attr "fp_mode" "single")])
10937 (define_insn "fsca"
10938 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10940 (unspec:SF [(mult:SF
10941 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10942 (match_operand:SF 2 "immediate_operand" "i"))
10944 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10946 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10947 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10948 && operands[2] == sh_fsca_int2sf ()"
10950 [(set_attr "type" "fsca")
10951 (set_attr "fp_mode" "single")])
10953 (define_expand "sinsf2"
10954 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10955 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10957 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10960 rtx scaled = gen_reg_rtx (SFmode);
10961 rtx truncated = gen_reg_rtx (SImode);
10962 rtx fsca = gen_reg_rtx (V2SFmode);
10963 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10965 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10966 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10967 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10968 get_fpscr_rtx ()));
10969 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10973 (define_expand "cossf2"
10974 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10975 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10977 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10980 rtx scaled = gen_reg_rtx (SFmode);
10981 rtx truncated = gen_reg_rtx (SImode);
10982 rtx fsca = gen_reg_rtx (V2SFmode);
10983 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10985 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10986 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10987 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10988 get_fpscr_rtx ()));
10989 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10993 (define_expand "sindf2"
10994 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10995 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10997 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11000 rtx scaled = gen_reg_rtx (DFmode);
11001 rtx truncated = gen_reg_rtx (SImode);
11002 rtx fsca = gen_reg_rtx (V2SFmode);
11003 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11004 rtx sfresult = gen_reg_rtx (SFmode);
11006 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11007 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11008 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11009 get_fpscr_rtx ()));
11010 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11011 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11015 (define_expand "cosdf2"
11016 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11017 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11019 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11022 rtx scaled = gen_reg_rtx (DFmode);
11023 rtx truncated = gen_reg_rtx (SImode);
11024 rtx fsca = gen_reg_rtx (V2SFmode);
11025 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11026 rtx sfresult = gen_reg_rtx (SFmode);
11028 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11029 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11030 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11031 get_fpscr_rtx ()));
11032 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11033 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11037 (define_expand "abssf2"
11038 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11039 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11040 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11045 expand_sf_unop (&gen_abssf2_i, operands);
11050 (define_insn "*abssf2_media"
11051 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11052 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11053 "TARGET_SHMEDIA_FPU"
11055 [(set_attr "type" "fmove_media")])
11057 (define_insn "abssf2_i"
11058 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11059 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11060 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11063 [(set_attr "type" "fmove")
11064 (set_attr "fp_mode" "single")])
11066 (define_expand "adddf3"
11067 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11068 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11069 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11070 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11073 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11075 expand_df_binop (&gen_adddf3_i, operands);
11080 (define_insn "*adddf3_media"
11081 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11082 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11083 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11084 "TARGET_SHMEDIA_FPU"
11085 "fadd.d %1, %2, %0"
11086 [(set_attr "type" "dfparith_media")])
11088 (define_insn "adddf3_i"
11089 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11090 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11091 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11092 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11093 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11095 [(set_attr "type" "dfp_arith")
11096 (set_attr "fp_mode" "double")])
11098 (define_expand "subdf3"
11099 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11100 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11101 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11102 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11105 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11107 expand_df_binop (&gen_subdf3_i, operands);
11112 (define_insn "*subdf3_media"
11113 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11114 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11115 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11116 "TARGET_SHMEDIA_FPU"
11117 "fsub.d %1, %2, %0"
11118 [(set_attr "type" "dfparith_media")])
11120 (define_insn "subdf3_i"
11121 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11122 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11123 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11124 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11125 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11127 [(set_attr "type" "dfp_arith")
11128 (set_attr "fp_mode" "double")])
11130 (define_expand "muldf3"
11131 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11132 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11133 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11134 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11137 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11139 expand_df_binop (&gen_muldf3_i, operands);
11144 (define_insn "*muldf3_media"
11145 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11146 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11147 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11148 "TARGET_SHMEDIA_FPU"
11149 "fmul.d %1, %2, %0"
11150 [(set_attr "type" "dfmul_media")])
11152 (define_insn "muldf3_i"
11153 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11154 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11155 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11156 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11157 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11159 [(set_attr "type" "dfp_mul")
11160 (set_attr "fp_mode" "double")])
11162 (define_expand "divdf3"
11163 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11164 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11165 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11166 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11169 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11171 expand_df_binop (&gen_divdf3_i, operands);
11176 (define_insn "*divdf3_media"
11177 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11178 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11179 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11180 "TARGET_SHMEDIA_FPU"
11181 "fdiv.d %1, %2, %0"
11182 [(set_attr "type" "dfdiv_media")])
11184 (define_insn "divdf3_i"
11185 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11186 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11187 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11188 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11189 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11191 [(set_attr "type" "dfdiv")
11192 (set_attr "fp_mode" "double")])
11194 (define_insn "floatdidf2"
11195 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11196 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11197 "TARGET_SHMEDIA_FPU"
11199 [(set_attr "type" "dfpconv_media")])
11201 (define_expand "floatsidf2"
11202 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11203 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11204 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11207 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11209 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11210 get_fpscr_rtx ()));
11215 (define_insn "*floatsidf2_media"
11216 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11217 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11218 "TARGET_SHMEDIA_FPU"
11220 [(set_attr "type" "dfpconv_media")])
11222 (define_insn "floatsidf2_i"
11223 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11224 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11225 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11226 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11228 [(set_attr "type" "dfp_conv")
11229 (set_attr "fp_mode" "double")])
11231 (define_insn "fix_truncdfdi2"
11232 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11233 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11234 "TARGET_SHMEDIA_FPU"
11236 [(set_attr "type" "dfpconv_media")])
11238 (define_expand "fix_truncdfsi2"
11239 [(set (match_operand:SI 0 "fpul_operand" "")
11240 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11241 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11244 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11246 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11247 get_fpscr_rtx ()));
11252 (define_insn "*fix_truncdfsi2_media"
11253 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11254 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11255 "TARGET_SHMEDIA_FPU"
11257 [(set_attr "type" "dfpconv_media")])
11259 (define_insn "fix_truncdfsi2_i"
11260 [(set (match_operand:SI 0 "fpul_operand" "=y")
11261 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11262 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11263 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11265 [(set_attr "type" "dfp_conv")
11266 (set_attr "dfp_comp" "no")
11267 (set_attr "fp_mode" "double")])
11269 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11270 ;; fix_truncdfsi2_i.
11271 ;; (define_insn "fix_truncdfsi2_i4"
11272 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11273 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11274 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11275 ;; (clobber (reg:SI FPUL_REG))]
11278 ;; [(set_attr "length" "4")
11279 ;; (set_attr "fp_mode" "double")])
11282 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11283 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11284 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11285 ;; (clobber (reg:SI FPUL_REG))]
11287 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11288 ;; (use (match_dup 2))])
11289 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11291 (define_insn "cmpgtdf_t"
11292 [(set (reg:SI T_REG)
11293 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11294 (match_operand:DF 1 "arith_reg_operand" "f")))
11295 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11296 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11298 [(set_attr "type" "dfp_cmp")
11299 (set_attr "fp_mode" "double")])
11301 (define_insn "cmpeqdf_t"
11302 [(set (reg:SI T_REG)
11303 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11304 (match_operand:DF 1 "arith_reg_operand" "f")))
11305 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11306 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11308 [(set_attr "type" "dfp_cmp")
11309 (set_attr "fp_mode" "double")])
11311 (define_insn "*ieee_ccmpeqdf_t"
11312 [(set (reg:SI T_REG)
11313 (ior:SI (reg:SI T_REG)
11314 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11315 (match_operand:DF 1 "arith_reg_operand" "f"))))
11316 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11317 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11318 "* return output_ieee_ccmpeq (insn, operands);"
11319 [(set_attr "length" "4")
11320 (set_attr "fp_mode" "double")])
11322 (define_insn "cmpeqdf_media"
11323 [(set (match_operand:SI 0 "register_operand" "=r")
11324 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11325 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11326 "TARGET_SHMEDIA_FPU"
11327 "fcmpeq.d %1,%2,%0"
11328 [(set_attr "type" "fcmp_media")])
11330 (define_insn "cmpgtdf_media"
11331 [(set (match_operand:SI 0 "register_operand" "=r")
11332 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11333 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11334 "TARGET_SHMEDIA_FPU"
11335 "fcmpgt.d %1,%2,%0"
11336 [(set_attr "type" "fcmp_media")])
11338 (define_insn "cmpgedf_media"
11339 [(set (match_operand:SI 0 "register_operand" "=r")
11340 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11341 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11342 "TARGET_SHMEDIA_FPU"
11343 "fcmpge.d %1,%2,%0"
11344 [(set_attr "type" "fcmp_media")])
11346 (define_insn "cmpundf_media"
11347 [(set (match_operand:SI 0 "register_operand" "=r")
11348 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11349 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11350 "TARGET_SHMEDIA_FPU"
11351 "fcmpun.d %1,%2,%0"
11352 [(set_attr "type" "fcmp_media")])
11354 (define_expand "cmpdf"
11355 [(set (reg:SI T_REG)
11356 (compare (match_operand:DF 0 "arith_operand" "")
11357 (match_operand:DF 1 "arith_operand" "")))]
11358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11361 sh_compare_op0 = operands[0];
11362 sh_compare_op1 = operands[1];
11366 (define_expand "negdf2"
11367 [(set (match_operand:DF 0 "arith_reg_operand" "")
11368 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11369 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11372 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11374 expand_df_unop (&gen_negdf2_i, operands);
11379 (define_insn "*negdf2_media"
11380 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11381 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11382 "TARGET_SHMEDIA_FPU"
11384 [(set_attr "type" "fmove_media")])
11386 (define_insn "negdf2_i"
11387 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11388 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11389 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11390 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11392 [(set_attr "type" "fmove")
11393 (set_attr "fp_mode" "double")])
11395 (define_expand "sqrtdf2"
11396 [(set (match_operand:DF 0 "arith_reg_operand" "")
11397 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11398 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11401 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11403 expand_df_unop (&gen_sqrtdf2_i, operands);
11408 (define_insn "*sqrtdf2_media"
11409 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11410 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11411 "TARGET_SHMEDIA_FPU"
11413 [(set_attr "type" "dfdiv_media")])
11415 (define_insn "sqrtdf2_i"
11416 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11417 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11418 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11419 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11421 [(set_attr "type" "dfdiv")
11422 (set_attr "fp_mode" "double")])
11424 (define_expand "absdf2"
11425 [(set (match_operand:DF 0 "arith_reg_operand" "")
11426 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11427 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11430 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11432 expand_df_unop (&gen_absdf2_i, operands);
11437 (define_insn "*absdf2_media"
11438 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11439 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11440 "TARGET_SHMEDIA_FPU"
11442 [(set_attr "type" "fmove_media")])
11444 (define_insn "absdf2_i"
11445 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11446 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11447 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11448 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11450 [(set_attr "type" "fmove")
11451 (set_attr "fp_mode" "double")])
11453 (define_expand "extendsfdf2"
11454 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11455 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11456 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11459 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11461 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11462 get_fpscr_rtx ()));
11467 (define_insn "*extendsfdf2_media"
11468 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11469 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11470 "TARGET_SHMEDIA_FPU"
11472 [(set_attr "type" "dfpconv_media")])
11474 (define_insn "extendsfdf2_i4"
11475 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11476 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11477 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11478 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11480 [(set_attr "type" "fp")
11481 (set_attr "fp_mode" "double")])
11483 (define_expand "truncdfsf2"
11484 [(set (match_operand:SF 0 "fpul_operand" "")
11485 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11486 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11489 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11491 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11492 get_fpscr_rtx ()));
11497 (define_insn "*truncdfsf2_media"
11498 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11499 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11500 "TARGET_SHMEDIA_FPU"
11502 [(set_attr "type" "dfpconv_media")])
11504 (define_insn "truncdfsf2_i4"
11505 [(set (match_operand:SF 0 "fpul_operand" "=y")
11506 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11507 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11508 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11510 [(set_attr "type" "fp")
11511 (set_attr "fp_mode" "double")])
11513 ;; Bit field extract patterns. These give better code for packed bitfields,
11514 ;; because they allow auto-increment addresses to be generated.
11516 (define_expand "insv"
11517 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11518 (match_operand:SI 1 "immediate_operand" "")
11519 (match_operand:SI 2 "immediate_operand" ""))
11520 (match_operand:SI 3 "general_operand" ""))]
11521 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11524 rtx addr_target, orig_address, shift_reg, qi_val;
11525 HOST_WIDE_INT bitsize, size, v = 0;
11526 rtx x = operands[3];
11528 /* ??? expmed doesn't care for non-register predicates. */
11529 if (! memory_operand (operands[0], VOIDmode)
11530 || ! immediate_operand (operands[1], VOIDmode)
11531 || ! immediate_operand (operands[2], VOIDmode)
11532 || ! general_operand (x, VOIDmode))
11534 /* If this isn't a 16 / 24 / 32 bit field, or if
11535 it doesn't start on a byte boundary, then fail. */
11536 bitsize = INTVAL (operands[1]);
11537 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11538 || (INTVAL (operands[2]) % 8) != 0)
11541 size = bitsize / 8;
11542 orig_address = XEXP (operands[0], 0);
11543 shift_reg = gen_reg_rtx (SImode);
11544 if (GET_CODE (x) == CONST_INT)
11547 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11551 emit_insn (gen_movsi (shift_reg, operands[3]));
11552 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11554 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11556 operands[0] = replace_equiv_address (operands[0], addr_target);
11557 emit_insn (gen_movqi (operands[0], qi_val));
11561 if (GET_CODE (x) == CONST_INT)
11563 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11566 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11567 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11569 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11570 emit_insn (gen_movqi (operands[0], qi_val));
11576 (define_insn "movua"
11577 [(set (match_operand:SI 0 "register_operand" "=z")
11578 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11582 [(set_attr "type" "movua")])
11584 ;; We shouldn't need this, but cse replaces increments with references
11585 ;; to other regs before flow has a chance to create post_inc
11586 ;; addressing modes, and only postreload's cse_move2add brings the
11587 ;; increments back to a usable form.
11589 [(set (match_operand:SI 0 "register_operand" "")
11590 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11591 (const_int 32) (const_int 0)))
11592 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11593 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11594 [(set (match_operand:SI 0 "register_operand" "")
11595 (sign_extract:SI (mem:SI (post_inc:SI
11596 (match_operand:SI 1 "register_operand" "")))
11597 (const_int 32) (const_int 0)))]
11600 (define_expand "extv"
11601 [(set (match_operand:SI 0 "register_operand" "")
11602 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11603 (match_operand 2 "const_int_operand" "")
11604 (match_operand 3 "const_int_operand" "")))]
11607 if (TARGET_SH4A_ARCH
11608 && INTVAL (operands[2]) == 32
11609 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11610 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11612 rtx src = adjust_address (operands[1], BLKmode, 0);
11613 set_mem_size (src, GEN_INT (4));
11614 emit_insn (gen_movua (operands[0], src));
11621 (define_expand "extzv"
11622 [(set (match_operand:SI 0 "register_operand" "")
11623 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11624 (match_operand 2 "const_int_operand" "")
11625 (match_operand 3 "const_int_operand" "")))]
11628 if (TARGET_SH4A_ARCH
11629 && INTVAL (operands[2]) == 32
11630 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11631 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11633 rtx src = adjust_address (operands[1], BLKmode, 0);
11634 set_mem_size (src, GEN_INT (4));
11635 emit_insn (gen_movua (operands[0], src));
11643 ;; -------------------------------------------------------------------------
11645 ;; -------------------------------------------------------------------------
11647 ;; This matches cases where a stack pointer increment at the start of the
11648 ;; epilogue combines with a stack slot read loading the return value.
11651 [(set (match_operand:SI 0 "arith_reg_operand" "")
11652 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11653 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11654 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11657 ;; See the comment on the dt combiner pattern above.
11660 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11661 (plus:SI (match_dup 0)
11663 (set (reg:SI T_REG)
11664 (eq:SI (match_dup 0)
11669 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11670 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11671 ;; reload when the constant is too large for a reg+offset address.
11673 ;; ??? We would get much better code if this was done in reload. This would
11674 ;; require modifying find_reloads_address to recognize that if the constant
11675 ;; is out-of-range for an immediate add, then we get better code by reloading
11676 ;; the constant into a register than by reloading the sum into a register,
11677 ;; since the former is one instruction shorter if the address does not need
11678 ;; to be offsettable. Unfortunately this does not work, because there is
11679 ;; only one register, r0, that can be used as an index register. This register
11680 ;; is also the function return value register. So, if we try to force reload
11681 ;; to use double-reg addresses, then we end up with some instructions that
11682 ;; need to use r0 twice. The only way to fix this is to change the calling
11683 ;; convention so that r0 is not used to return values.
11686 [(set (match_operand:SI 0 "register_operand" "=r")
11687 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11688 (set (mem:SI (match_dup 0))
11689 (match_operand:SI 2 "general_movsrc_operand" ""))]
11690 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11691 "mov.l %2,@(%0,%1)")
11694 [(set (match_operand:SI 0 "register_operand" "=r")
11695 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11696 (set (match_operand:SI 2 "general_movdst_operand" "")
11697 (mem:SI (match_dup 0)))]
11698 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11699 "mov.l @(%0,%1),%2")
11702 [(set (match_operand:SI 0 "register_operand" "=r")
11703 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11704 (set (mem:HI (match_dup 0))
11705 (match_operand:HI 2 "general_movsrc_operand" ""))]
11706 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11707 "mov.w %2,@(%0,%1)")
11710 [(set (match_operand:SI 0 "register_operand" "=r")
11711 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11712 (set (match_operand:HI 2 "general_movdst_operand" "")
11713 (mem:HI (match_dup 0)))]
11714 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11715 "mov.w @(%0,%1),%2")
11718 [(set (match_operand:SI 0 "register_operand" "=r")
11719 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11720 (set (mem:QI (match_dup 0))
11721 (match_operand:QI 2 "general_movsrc_operand" ""))]
11722 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11723 "mov.b %2,@(%0,%1)")
11726 [(set (match_operand:SI 0 "register_operand" "=r")
11727 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11728 (set (match_operand:QI 2 "general_movdst_operand" "")
11729 (mem:QI (match_dup 0)))]
11730 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11731 "mov.b @(%0,%1),%2")
11734 [(set (match_operand:SI 0 "register_operand" "=r")
11735 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11736 (set (mem:SF (match_dup 0))
11737 (match_operand:SF 2 "general_movsrc_operand" ""))]
11738 "TARGET_SH1 && REGNO (operands[0]) == 0
11739 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11740 || (GET_CODE (operands[2]) == SUBREG
11741 && REGNO (SUBREG_REG (operands[2])) < 16))
11742 && reg_unused_after (operands[0], insn)"
11743 "mov.l %2,@(%0,%1)")
11746 [(set (match_operand:SI 0 "register_operand" "=r")
11747 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11748 (set (match_operand:SF 2 "general_movdst_operand" "")
11750 (mem:SF (match_dup 0)))]
11751 "TARGET_SH1 && REGNO (operands[0]) == 0
11752 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11753 || (GET_CODE (operands[2]) == SUBREG
11754 && REGNO (SUBREG_REG (operands[2])) < 16))
11755 && reg_unused_after (operands[0], insn)"
11756 "mov.l @(%0,%1),%2")
11759 [(set (match_operand:SI 0 "register_operand" "=r")
11760 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11761 (set (mem:SF (match_dup 0))
11762 (match_operand:SF 2 "general_movsrc_operand" ""))]
11763 "TARGET_SH2E && REGNO (operands[0]) == 0
11764 && ((GET_CODE (operands[2]) == REG
11765 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11766 || (GET_CODE (operands[2]) == SUBREG
11767 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11768 && reg_unused_after (operands[0], insn)"
11769 "fmov{.s|} %2,@(%0,%1)")
11772 [(set (match_operand:SI 0 "register_operand" "=r")
11773 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11774 (set (match_operand:SF 2 "general_movdst_operand" "")
11776 (mem:SF (match_dup 0)))]
11777 "TARGET_SH2E && REGNO (operands[0]) == 0
11778 && ((GET_CODE (operands[2]) == REG
11779 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11780 || (GET_CODE (operands[2]) == SUBREG
11781 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11782 && reg_unused_after (operands[0], insn)"
11783 "fmov{.s|} @(%0,%1),%2")
11785 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11786 (define_insn "sp_switch_1"
11787 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11791 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11792 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11793 return \"mov r0,r15\";
11795 [(set_attr "length" "10")])
11797 ;; Switch back to the original stack for interrupt functions with the
11798 ;; sp_switch attribute. */
11799 (define_insn "sp_switch_2"
11802 "mov.l @r15+,r15\;mov.l @r15+,r0"
11803 [(set_attr "length" "4")])
11805 ;; Integer vector moves
11807 (define_expand "movv8qi"
11808 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11809 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11811 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11813 (define_insn "movv8qi_i"
11814 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11815 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11817 && (register_operand (operands[0], V8QImode)
11818 || sh_register_operand (operands[1], V8QImode))"
11825 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11826 (set_attr "length" "4,4,16,4,4")])
11829 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11830 (subreg:V8QI (const_int 0) 0))]
11832 [(set (match_dup 0)
11833 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11834 (const_int 0) (const_int 0) (const_int 0)
11835 (const_int 0) (const_int 0)]))])
11838 [(set (match_operand 0 "arith_reg_dest" "")
11839 (match_operand 1 "sh_rep_vec" ""))]
11840 "TARGET_SHMEDIA && reload_completed
11841 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11842 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11843 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11844 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11845 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11846 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11847 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11848 [(set (match_dup 0) (match_dup 1))
11852 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11853 rtx elt1 = XVECEXP (operands[1], 0, 1);
11856 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11860 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11861 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11863 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11864 operands[1] = XVECEXP (operands[1], 0, 0);
11867 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11869 = GEN_INT (TARGET_LITTLE_ENDIAN
11870 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11871 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11874 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11876 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11882 [(set (match_operand 0 "arith_reg_dest" "")
11883 (match_operand 1 "sh_const_vec" ""))]
11884 "TARGET_SHMEDIA && reload_completed
11885 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11886 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11887 [(set (match_dup 0) (match_dup 1))]
11890 rtx v = operands[1];
11891 enum machine_mode new_mode
11892 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11894 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11896 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11899 (define_expand "movv2hi"
11900 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11901 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11903 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11905 (define_insn "movv2hi_i"
11906 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11907 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11909 && (register_operand (operands[0], V2HImode)
11910 || sh_register_operand (operands[1], V2HImode))"
11917 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11918 (set_attr "length" "4,4,16,4,4")
11919 (set (attr "highpart")
11920 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11921 (const_string "user")]
11922 (const_string "ignore")))])
11924 (define_expand "movv4hi"
11925 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11926 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11928 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11930 (define_insn "movv4hi_i"
11931 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11932 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11934 && (register_operand (operands[0], V4HImode)
11935 || sh_register_operand (operands[1], V4HImode))"
11942 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11943 (set_attr "length" "4,4,16,4,4")
11944 (set_attr "highpart" "depend")])
11946 (define_expand "movv2si"
11947 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11948 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11950 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11952 (define_insn "movv2si_i"
11953 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11954 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11956 && (register_operand (operands[0], V2SImode)
11957 || sh_register_operand (operands[1], V2SImode))"
11964 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11965 (set_attr "length" "4,4,16,4,4")
11966 (set_attr "highpart" "depend")])
11968 ;; Multimedia Intrinsics
11970 (define_insn "absv2si2"
11971 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11972 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11975 [(set_attr "type" "mcmp_media")
11976 (set_attr "highpart" "depend")])
11978 (define_insn "absv4hi2"
11979 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11980 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11983 [(set_attr "type" "mcmp_media")
11984 (set_attr "highpart" "depend")])
11986 (define_insn "addv2si3"
11987 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11988 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11989 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11991 "madd.l %1, %2, %0"
11992 [(set_attr "type" "arith_media")
11993 (set_attr "highpart" "depend")])
11995 (define_insn "addv4hi3"
11996 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11997 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11998 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12000 "madd.w %1, %2, %0"
12001 [(set_attr "type" "arith_media")
12002 (set_attr "highpart" "depend")])
12004 (define_insn_and_split "addv2hi3"
12005 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12006 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12007 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12014 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12015 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12016 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12017 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12018 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12020 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12021 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12024 [(set_attr "highpart" "must_split")])
12026 (define_insn "ssaddv2si3"
12027 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12028 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12029 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12031 "madds.l %1, %2, %0"
12032 [(set_attr "type" "mcmp_media")
12033 (set_attr "highpart" "depend")])
12035 (define_insn "usaddv8qi3"
12036 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12037 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12038 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12040 "madds.ub %1, %2, %0"
12041 [(set_attr "type" "mcmp_media")
12042 (set_attr "highpart" "depend")])
12044 (define_insn "ssaddv4hi3"
12045 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12046 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12047 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12049 "madds.w %1, %2, %0"
12050 [(set_attr "type" "mcmp_media")
12051 (set_attr "highpart" "depend")])
12053 (define_insn "negcmpeqv8qi"
12054 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12055 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12056 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12058 "mcmpeq.b %N1, %N2, %0"
12059 [(set_attr "type" "mcmp_media")
12060 (set_attr "highpart" "depend")])
12062 (define_insn "negcmpeqv2si"
12063 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12064 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12065 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12067 "mcmpeq.l %N1, %N2, %0"
12068 [(set_attr "type" "mcmp_media")
12069 (set_attr "highpart" "depend")])
12071 (define_insn "negcmpeqv4hi"
12072 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12073 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12074 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12076 "mcmpeq.w %N1, %N2, %0"
12077 [(set_attr "type" "mcmp_media")
12078 (set_attr "highpart" "depend")])
12080 (define_insn "negcmpgtuv8qi"
12081 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12082 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12083 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12085 "mcmpgt.ub %N1, %N2, %0"
12086 [(set_attr "type" "mcmp_media")
12087 (set_attr "highpart" "depend")])
12089 (define_insn "negcmpgtv2si"
12090 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12091 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12092 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12094 "mcmpgt.l %N1, %N2, %0"
12095 [(set_attr "type" "mcmp_media")
12096 (set_attr "highpart" "depend")])
12098 (define_insn "negcmpgtv4hi"
12099 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12100 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12101 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12103 "mcmpgt.w %N1, %N2, %0"
12104 [(set_attr "type" "mcmp_media")
12105 (set_attr "highpart" "depend")])
12107 (define_insn "mcmv"
12108 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12109 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12110 (match_operand:DI 2 "arith_reg_operand" "r"))
12111 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12112 (not:DI (match_dup 2)))))]
12115 [(set_attr "type" "arith_media")
12116 (set_attr "highpart" "depend")])
12118 (define_insn "mcnvs_lw"
12119 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12121 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12122 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12124 "mcnvs.lw %N1, %N2, %0"
12125 [(set_attr "type" "mcmp_media")])
12127 (define_insn "mcnvs_wb"
12128 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12130 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12131 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12133 "mcnvs.wb %N1, %N2, %0"
12134 [(set_attr "type" "mcmp_media")])
12136 (define_insn "mcnvs_wub"
12137 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12139 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12140 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12142 "mcnvs.wub %N1, %N2, %0"
12143 [(set_attr "type" "mcmp_media")])
12145 (define_insn "mextr_rl"
12146 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12147 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12148 (match_operand:HI 3 "mextr_bit_offset" "i"))
12149 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12150 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12151 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12154 static char templ[21];
12156 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12157 (int) INTVAL (operands[3]) >> 3);
12160 [(set_attr "type" "arith_media")])
12162 (define_insn "*mextr_lr"
12163 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12164 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12165 (match_operand:HI 3 "mextr_bit_offset" "i"))
12166 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12167 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12168 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12171 static char templ[21];
12173 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12174 (int) INTVAL (operands[4]) >> 3);
12177 [(set_attr "type" "arith_media")])
12179 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12180 ; vector then varies depending on endianness.
12181 (define_expand "mextr1"
12182 [(match_operand:DI 0 "arith_reg_dest" "")
12183 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12184 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12188 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12189 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12193 (define_expand "mextr2"
12194 [(match_operand:DI 0 "arith_reg_dest" "")
12195 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12196 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12200 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12201 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12205 (define_expand "mextr3"
12206 [(match_operand:DI 0 "arith_reg_dest" "")
12207 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12208 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12212 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12213 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12217 (define_expand "mextr4"
12218 [(match_operand:DI 0 "arith_reg_dest" "")
12219 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12220 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12224 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12225 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12229 (define_expand "mextr5"
12230 [(match_operand:DI 0 "arith_reg_dest" "")
12231 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12232 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12236 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12237 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12241 (define_expand "mextr6"
12242 [(match_operand:DI 0 "arith_reg_dest" "")
12243 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12244 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12248 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12249 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12253 (define_expand "mextr7"
12254 [(match_operand:DI 0 "arith_reg_dest" "")
12255 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12256 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12260 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12261 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12265 (define_expand "mmacfx_wl"
12266 [(match_operand:V2SI 0 "arith_reg_dest" "")
12267 (match_operand:V2HI 1 "extend_reg_operand" "")
12268 (match_operand:V2HI 2 "extend_reg_operand" "")
12269 (match_operand:V2SI 3 "arith_reg_operand" "")]
12273 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12274 operands[1], operands[2]));
12278 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12280 (define_insn "mmacfx_wl_i"
12281 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12283 (match_operand:V2SI 1 "arith_reg_operand" "0")
12288 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12289 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12292 "mmacfx.wl %2, %3, %0"
12293 [(set_attr "type" "mac_media")
12294 (set_attr "highpart" "depend")])
12296 (define_expand "mmacnfx_wl"
12297 [(match_operand:V2SI 0 "arith_reg_dest" "")
12298 (match_operand:V2HI 1 "extend_reg_operand" "")
12299 (match_operand:V2HI 2 "extend_reg_operand" "")
12300 (match_operand:V2SI 3 "arith_reg_operand" "")]
12304 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12305 operands[1], operands[2]));
12309 (define_insn "mmacnfx_wl_i"
12310 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12312 (match_operand:V2SI 1 "arith_reg_operand" "0")
12317 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12318 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12321 "mmacnfx.wl %2, %3, %0"
12322 [(set_attr "type" "mac_media")
12323 (set_attr "highpart" "depend")])
12325 (define_insn "mulv2si3"
12326 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12327 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12328 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12330 "mmul.l %1, %2, %0"
12331 [(set_attr "type" "d2mpy_media")
12332 (set_attr "highpart" "depend")])
12334 (define_insn "mulv4hi3"
12335 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12336 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12337 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12339 "mmul.w %1, %2, %0"
12340 [(set_attr "type" "dmpy_media")
12341 (set_attr "highpart" "depend")])
12343 (define_insn "mmulfx_l"
12344 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12348 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12349 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12352 "mmulfx.l %1, %2, %0"
12353 [(set_attr "type" "d2mpy_media")
12354 (set_attr "highpart" "depend")])
12356 (define_insn "mmulfx_w"
12357 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12361 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12362 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12365 "mmulfx.w %1, %2, %0"
12366 [(set_attr "type" "dmpy_media")
12367 (set_attr "highpart" "depend")])
12369 (define_insn "mmulfxrp_w"
12370 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12375 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12376 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12380 "mmulfxrp.w %1, %2, %0"
12381 [(set_attr "type" "dmpy_media")
12382 (set_attr "highpart" "depend")])
12385 (define_expand "mmulhi_wl"
12386 [(match_operand:V2SI 0 "arith_reg_dest" "")
12387 (match_operand:V4HI 1 "arith_reg_operand" "")
12388 (match_operand:V4HI 2 "arith_reg_operand" "")]
12392 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12393 (operands[0], operands[1], operands[2]));
12397 (define_expand "mmullo_wl"
12398 [(match_operand:V2SI 0 "arith_reg_dest" "")
12399 (match_operand:V4HI 1 "arith_reg_operand" "")
12400 (match_operand:V4HI 2 "arith_reg_operand" "")]
12404 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12405 (operands[0], operands[1], operands[2]));
12409 (define_insn "mmul23_wl"
12410 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12413 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12414 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12415 (parallel [(const_int 2) (const_int 3)])))]
12417 "* return (TARGET_LITTLE_ENDIAN
12418 ? \"mmulhi.wl %1, %2, %0\"
12419 : \"mmullo.wl %1, %2, %0\");"
12420 [(set_attr "type" "dmpy_media")
12421 (set (attr "highpart")
12422 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12423 (const_string "user")))])
12425 (define_insn "mmul01_wl"
12426 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12429 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12430 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12431 (parallel [(const_int 0) (const_int 1)])))]
12433 "* return (TARGET_LITTLE_ENDIAN
12434 ? \"mmullo.wl %1, %2, %0\"
12435 : \"mmulhi.wl %1, %2, %0\");"
12436 [(set_attr "type" "dmpy_media")
12437 (set (attr "highpart")
12438 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12439 (const_string "user")))])
12442 (define_expand "mmulsum_wq"
12443 [(match_operand:DI 0 "arith_reg_dest" "")
12444 (match_operand:V4HI 1 "arith_reg_operand" "")
12445 (match_operand:V4HI 2 "arith_reg_operand" "")
12446 (match_operand:DI 3 "arith_reg_operand" "")]
12450 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12451 operands[1], operands[2]));
12455 (define_insn "mmulsum_wq_i"
12456 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12457 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12462 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12463 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12464 (parallel [(const_int 0)]))
12465 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12466 (sign_extend:V4DI (match_dup 3)))
12467 (parallel [(const_int 1)])))
12469 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12470 (sign_extend:V4DI (match_dup 3)))
12471 (parallel [(const_int 2)]))
12472 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12473 (sign_extend:V4DI (match_dup 3)))
12474 (parallel [(const_int 3)]))))))]
12476 "mmulsum.wq %2, %3, %0"
12477 [(set_attr "type" "mac_media")])
12479 (define_expand "mperm_w"
12480 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12481 (match_operand:V4HI 1 "arith_reg_operand" "r")
12482 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12486 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12487 (operands[0], operands[1], operands[2]));
12491 ; This use of vec_select isn't exactly correct according to rtl.texi
12492 ; (because not constant), but it seems a straightforward extension.
12493 (define_insn "mperm_w_little"
12494 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12496 (match_operand:V4HI 1 "arith_reg_operand" "r")
12498 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12499 (const_int 2) (const_int 0))
12500 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12501 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12502 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12503 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12504 "mperm.w %1, %N2, %0"
12505 [(set_attr "type" "arith_media")])
12507 (define_insn "mperm_w_big"
12508 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12510 (match_operand:V4HI 1 "arith_reg_operand" "r")
12512 [(zero_extract:QI (not:QI (match_operand:QI 2
12513 "extend_reg_or_0_operand" "rZ"))
12514 (const_int 2) (const_int 0))
12515 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12516 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12517 (zero_extract:QI (not:QI (match_dup 2))
12518 (const_int 2) (const_int 6))])))]
12519 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12520 "mperm.w %1, %N2, %0"
12521 [(set_attr "type" "arith_media")])
12523 (define_insn "mperm_w0"
12524 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12525 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12526 "trunc_hi_operand" "r"))))]
12528 "mperm.w %1, r63, %0"
12529 [(set_attr "type" "arith_media")
12530 (set_attr "highpart" "ignore")])
12532 (define_expand "msad_ubq"
12533 [(match_operand:DI 0 "arith_reg_dest" "")
12534 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12535 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12536 (match_operand:DI 3 "arith_reg_operand" "")]
12540 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12541 operands[1], operands[2]));
12545 (define_insn "msad_ubq_i"
12546 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12551 (match_operand:DI 1 "arith_reg_operand" "0")
12552 (abs:DI (vec_select:DI
12555 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12557 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12558 (parallel [(const_int 0)]))))
12559 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12560 (zero_extend:V8DI (match_dup 3)))
12561 (parallel [(const_int 1)]))))
12563 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12564 (zero_extend:V8DI (match_dup 3)))
12565 (parallel [(const_int 2)])))
12566 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12567 (zero_extend:V8DI (match_dup 3)))
12568 (parallel [(const_int 3)])))))
12571 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12572 (zero_extend:V8DI (match_dup 3)))
12573 (parallel [(const_int 4)])))
12574 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12575 (zero_extend:V8DI (match_dup 3)))
12576 (parallel [(const_int 5)]))))
12578 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12579 (zero_extend:V8DI (match_dup 3)))
12580 (parallel [(const_int 6)])))
12581 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12582 (zero_extend:V8DI (match_dup 3)))
12583 (parallel [(const_int 7)])))))))]
12585 "msad.ubq %N2, %N3, %0"
12586 [(set_attr "type" "mac_media")])
12588 (define_insn "mshalds_l"
12589 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12592 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12593 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12594 (const_int 31)))))]
12596 "mshalds.l %1, %2, %0"
12597 [(set_attr "type" "mcmp_media")
12598 (set_attr "highpart" "depend")])
12600 (define_insn "mshalds_w"
12601 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12604 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12605 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12606 (const_int 15)))))]
12608 "mshalds.w %1, %2, %0"
12609 [(set_attr "type" "mcmp_media")
12610 (set_attr "highpart" "depend")])
12612 (define_insn "ashrv2si3"
12613 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12614 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12615 (match_operand:DI 2 "arith_reg_operand" "r")))]
12617 "mshard.l %1, %2, %0"
12618 [(set_attr "type" "arith_media")
12619 (set_attr "highpart" "depend")])
12621 (define_insn "ashrv4hi3"
12622 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12623 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12624 (match_operand:DI 2 "arith_reg_operand" "r")))]
12626 "mshard.w %1, %2, %0"
12627 [(set_attr "type" "arith_media")
12628 (set_attr "highpart" "depend")])
12630 (define_insn "mshards_q"
12631 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12633 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12634 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12636 "mshards.q %1, %N2, %0"
12637 [(set_attr "type" "mcmp_media")])
12639 (define_expand "mshfhi_b"
12640 [(match_operand:V8QI 0 "arith_reg_dest" "")
12641 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12642 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12646 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12647 (operands[0], operands[1], operands[2]));
12651 (define_expand "mshflo_b"
12652 [(match_operand:V8QI 0 "arith_reg_dest" "")
12653 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12654 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12658 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12659 (operands[0], operands[1], operands[2]));
12663 (define_insn "mshf4_b"
12665 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12667 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12668 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12669 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12670 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12672 "* return (TARGET_LITTLE_ENDIAN
12673 ? \"mshfhi.b %N1, %N2, %0\"
12674 : \"mshflo.b %N1, %N2, %0\");"
12675 [(set_attr "type" "arith_media")
12676 (set (attr "highpart")
12677 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12678 (const_string "user")))])
12680 (define_insn "mshf0_b"
12682 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12684 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12685 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12686 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12687 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12689 "* return (TARGET_LITTLE_ENDIAN
12690 ? \"mshflo.b %N1, %N2, %0\"
12691 : \"mshfhi.b %N1, %N2, %0\");"
12692 [(set_attr "type" "arith_media")
12693 (set (attr "highpart")
12694 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12695 (const_string "user")))])
12697 (define_expand "mshfhi_l"
12698 [(match_operand:V2SI 0 "arith_reg_dest" "")
12699 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12700 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12704 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12705 (operands[0], operands[1], operands[2]));
12709 (define_expand "mshflo_l"
12710 [(match_operand:V2SI 0 "arith_reg_dest" "")
12711 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12712 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12716 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12717 (operands[0], operands[1], operands[2]));
12721 (define_insn "mshf4_l"
12722 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12724 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12725 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12726 (parallel [(const_int 1) (const_int 3)])))]
12728 "* return (TARGET_LITTLE_ENDIAN
12729 ? \"mshfhi.l %N1, %N2, %0\"
12730 : \"mshflo.l %N1, %N2, %0\");"
12731 [(set_attr "type" "arith_media")
12732 (set (attr "highpart")
12733 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12734 (const_string "user")))])
12736 (define_insn "mshf0_l"
12737 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12739 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12740 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12741 (parallel [(const_int 0) (const_int 2)])))]
12743 "* return (TARGET_LITTLE_ENDIAN
12744 ? \"mshflo.l %N1, %N2, %0\"
12745 : \"mshfhi.l %N1, %N2, %0\");"
12746 [(set_attr "type" "arith_media")
12747 (set (attr "highpart")
12748 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12749 (const_string "user")))])
12751 (define_expand "mshfhi_w"
12752 [(match_operand:V4HI 0 "arith_reg_dest" "")
12753 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12754 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12758 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12759 (operands[0], operands[1], operands[2]));
12763 (define_expand "mshflo_w"
12764 [(match_operand:V4HI 0 "arith_reg_dest" "")
12765 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12766 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12770 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12771 (operands[0], operands[1], operands[2]));
12775 (define_insn "mshf4_w"
12776 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12778 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12779 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12780 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12782 "* return (TARGET_LITTLE_ENDIAN
12783 ? \"mshfhi.w %N1, %N2, %0\"
12784 : \"mshflo.w %N1, %N2, %0\");"
12785 [(set_attr "type" "arith_media")
12786 (set (attr "highpart")
12787 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12788 (const_string "user")))])
12790 (define_insn "mshf0_w"
12791 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12793 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12794 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12795 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12797 "* return (TARGET_LITTLE_ENDIAN
12798 ? \"mshflo.w %N1, %N2, %0\"
12799 : \"mshfhi.w %N1, %N2, %0\");"
12800 [(set_attr "type" "arith_media")
12801 (set (attr "highpart")
12802 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12803 (const_string "user")))])
12805 (define_insn "mshflo_w_x"
12806 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12808 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12809 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12810 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12812 "mshflo.w %N1, %N2, %0"
12813 [(set_attr "type" "arith_media")
12814 (set_attr "highpart" "ignore")])
12816 /* These are useful to expand ANDs and as combiner patterns. */
12817 (define_insn_and_split "mshfhi_l_di"
12818 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12819 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12821 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12822 (const_int -4294967296))))]
12825 mshfhi.l %N1, %N2, %0
12827 "TARGET_SHMEDIA && reload_completed
12828 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12829 [(set (match_dup 3) (match_dup 4))
12830 (set (match_dup 5) (match_dup 6))]
12833 operands[3] = gen_lowpart (SImode, operands[0]);
12834 operands[4] = gen_highpart (SImode, operands[1]);
12835 operands[5] = gen_highpart (SImode, operands[0]);
12836 operands[6] = gen_highpart (SImode, operands[2]);
12838 [(set_attr "type" "arith_media")])
12840 (define_insn "*mshfhi_l_di_rev"
12841 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12842 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12843 (const_int -4294967296))
12844 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12847 "mshfhi.l %N2, %N1, %0"
12848 [(set_attr "type" "arith_media")])
12851 [(set (match_operand:DI 0 "arith_reg_dest" "")
12852 (ior:DI (zero_extend:DI (match_operand:SI 1
12853 "extend_reg_or_0_operand" ""))
12854 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12855 (const_int -4294967296))))
12856 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12861 emit_insn (gen_ashldi3_media (operands[3],
12862 simplify_gen_subreg (DImode, operands[1],
12865 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12869 (define_insn "mshflo_l_di"
12870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12871 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12872 (const_int 4294967295))
12873 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12877 "mshflo.l %N1, %N2, %0"
12878 [(set_attr "type" "arith_media")
12879 (set_attr "highpart" "ignore")])
12881 (define_insn "*mshflo_l_di_rev"
12882 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12883 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12885 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12886 (const_int 4294967295))))]
12889 "mshflo.l %N2, %N1, %0"
12890 [(set_attr "type" "arith_media")
12891 (set_attr "highpart" "ignore")])
12893 ;; Combiner pattern for trampoline initialization.
12894 (define_insn_and_split "*double_shori"
12895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12896 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12898 (match_operand:DI 2 "const_int_operand" "n")))]
12900 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12902 "rtx_equal_p (operands[0], operands[1])"
12906 HOST_WIDE_INT v = INTVAL (operands[2]);
12908 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12909 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12912 [(set_attr "highpart" "ignore")])
12915 (define_insn "*mshflo_l_di_x"
12916 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12917 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12919 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12923 "mshflo.l %N1, %N2, %0"
12924 [(set_attr "type" "arith_media")
12925 (set_attr "highpart" "ignore")])
12927 (define_insn_and_split "concat_v2sf"
12928 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12929 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12930 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12931 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12935 mshflo.l %N1, %N2, %0
12938 "TARGET_SHMEDIA && reload_completed
12939 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12940 [(set (match_dup 3) (match_dup 1))
12941 (set (match_dup 4) (match_dup 2))]
12944 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12945 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12947 [(set_attr "type" "arith_media")
12948 (set_attr "highpart" "ignore")])
12950 (define_insn "*mshflo_l_di_x_rev"
12951 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12952 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12954 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12957 "mshflo.l %N2, %N1, %0"
12958 [(set_attr "type" "arith_media")
12959 (set_attr "highpart" "ignore")])
12961 (define_insn "ashlv2si3"
12962 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12963 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12964 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12966 "mshlld.l %1, %2, %0"
12967 [(set_attr "type" "arith_media")
12968 (set_attr "highpart" "depend")])
12971 [(set (match_operand 0 "any_register_operand" "")
12972 (match_operator 3 "shift_operator"
12973 [(match_operand 1 "any_register_operand" "")
12974 (match_operand 2 "shift_count_reg_operand" "")]))]
12975 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12976 [(set (match_dup 0) (match_dup 3))]
12979 rtx count = operands[2];
12980 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12982 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12983 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12984 || GET_CODE (count) == TRUNCATE)
12985 count = XEXP (count, 0);
12986 inner_mode = GET_MODE (count);
12987 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12988 subreg_lowpart_offset (outer_mode, inner_mode));
12989 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12990 operands[1], count);
12993 (define_insn "ashlv4hi3"
12994 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12995 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12996 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12998 "mshlld.w %1, %2, %0"
12999 [(set_attr "type" "arith_media")
13000 (set_attr "highpart" "depend")])
13002 (define_insn "lshrv2si3"
13003 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13004 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13005 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13007 "mshlrd.l %1, %2, %0"
13008 [(set_attr "type" "arith_media")
13009 (set_attr "highpart" "depend")])
13011 (define_insn "lshrv4hi3"
13012 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13013 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13014 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13016 "mshlrd.w %1, %2, %0"
13017 [(set_attr "type" "arith_media")
13018 (set_attr "highpart" "depend")])
13020 (define_insn "subv2si3"
13021 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13022 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13023 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13025 "msub.l %N1, %2, %0"
13026 [(set_attr "type" "arith_media")
13027 (set_attr "highpart" "depend")])
13029 (define_insn "subv4hi3"
13030 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13031 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13032 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13034 "msub.w %N1, %2, %0"
13035 [(set_attr "type" "arith_media")
13036 (set_attr "highpart" "depend")])
13038 (define_insn_and_split "subv2hi3"
13039 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13040 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13041 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13048 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13049 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13050 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13051 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13052 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13054 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13055 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13058 [(set_attr "highpart" "must_split")])
13060 (define_insn "sssubv2si3"
13061 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13062 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13063 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13065 "msubs.l %N1, %2, %0"
13066 [(set_attr "type" "mcmp_media")
13067 (set_attr "highpart" "depend")])
13069 (define_insn "ussubv8qi3"
13070 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13071 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13072 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13074 "msubs.ub %N1, %2, %0"
13075 [(set_attr "type" "mcmp_media")
13076 (set_attr "highpart" "depend")])
13078 (define_insn "sssubv4hi3"
13079 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13080 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13081 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13083 "msubs.w %N1, %2, %0"
13084 [(set_attr "type" "mcmp_media")
13085 (set_attr "highpart" "depend")])
13087 ;; Floating Point Intrinsics
13089 (define_insn "fcosa_s"
13090 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13091 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13095 [(set_attr "type" "atrans_media")])
13097 (define_insn "fsina_s"
13098 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13099 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13103 [(set_attr "type" "atrans_media")])
13105 (define_insn "fipr"
13106 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13107 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13108 "fp_arith_reg_operand" "f")
13109 (match_operand:V4SF 2
13110 "fp_arith_reg_operand" "f"))
13111 (parallel [(const_int 0)]))
13112 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13113 (parallel [(const_int 1)])))
13114 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13115 (parallel [(const_int 2)]))
13116 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13117 (parallel [(const_int 3)])))))]
13119 "fipr.s %1, %2, %0"
13120 [(set_attr "type" "fparith_media")])
13122 (define_insn "fsrra_s"
13123 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13124 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13128 [(set_attr "type" "atrans_media")])
13130 (define_insn "ftrv"
13131 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13135 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13136 (parallel [(const_int 0) (const_int 5)
13137 (const_int 10) (const_int 15)]))
13138 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13140 (vec_select:V4SF (match_dup 1)
13141 (parallel [(const_int 4) (const_int 9)
13142 (const_int 14) (const_int 3)]))
13143 (vec_select:V4SF (match_dup 2)
13144 (parallel [(const_int 1) (const_int 2)
13145 (const_int 3) (const_int 0)]))))
13148 (vec_select:V4SF (match_dup 1)
13149 (parallel [(const_int 8) (const_int 13)
13150 (const_int 2) (const_int 7)]))
13151 (vec_select:V4SF (match_dup 2)
13152 (parallel [(const_int 2) (const_int 3)
13153 (const_int 0) (const_int 1)])))
13155 (vec_select:V4SF (match_dup 1)
13156 (parallel [(const_int 12) (const_int 1)
13157 (const_int 6) (const_int 11)]))
13158 (vec_select:V4SF (match_dup 2)
13159 (parallel [(const_int 3) (const_int 0)
13160 (const_int 1) (const_int 2)]))))))]
13162 "ftrv.s %1, %2, %0"
13163 [(set_attr "type" "fparith_media")])
13165 (define_insn "ldhi_l"
13166 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13168 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13171 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13175 [(set_attr "type" "load_media")])
13177 (define_insn "ldhi_q"
13178 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13180 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13183 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13187 [(set_attr "type" "load_media")])
13189 (define_insn_and_split "*ldhi_q_comb0"
13190 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13192 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13193 "register_operand" "r")
13194 (match_operand:SI 2
13195 "ua_offset" "I06"))
13198 (plus:SI (and:SI (match_dup 1) (const_int 7))
13201 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13205 "emit_insn (gen_ldhi_q (operands[0],
13206 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13210 (define_insn_and_split "*ldhi_q_comb1"
13211 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13213 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13214 "register_operand" "r")
13215 (match_operand:SI 2
13216 "ua_offset" "I06"))
13219 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13220 "ua_offset" "I06"))
13224 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13225 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13229 "emit_insn (gen_ldhi_q (operands[0],
13230 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13234 (define_insn "ldlo_l"
13235 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13237 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13239 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13240 (and:SI (match_dup 1) (const_int 3))))]
13243 [(set_attr "type" "load_media")])
13245 (define_insn "ldlo_q"
13246 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13248 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13250 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13251 (and:SI (match_dup 1) (const_int 7))))]
13254 [(set_attr "type" "load_media")])
13256 (define_insn_and_split "*ldlo_q_comb0"
13257 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13259 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13260 (match_operand:SI 2 "ua_offset" "I06"))
13262 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13263 (and:SI (match_dup 1) (const_int 7))))]
13264 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13268 "emit_insn (gen_ldlo_q (operands[0],
13269 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13272 (define_insn_and_split "*ldlo_q_comb1"
13273 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13275 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13276 (match_operand:SI 2 "ua_offset" "I06"))
13278 (minus:SI (const_int 8)
13279 (and:SI (plus:SI (match_dup 1)
13280 (match_operand:SI 3 "ua_offset" "I06"))
13282 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13283 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13284 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13288 "emit_insn (gen_ldlo_q (operands[0],
13289 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13292 (define_insn "sthi_l"
13293 [(set (zero_extract:SI
13294 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13297 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13299 (match_operand:SI 1 "arith_reg_operand" "r"))]
13302 [(set_attr "type" "ustore_media")])
13304 ;; All unaligned stores are considered to be 'narrow' because they typically
13305 ;; operate on less that a quadword, and when they operate on a full quadword,
13306 ;; the vanilla store high / store low sequence will cause a stall if not
13307 ;; scheduled apart.
13308 (define_insn "sthi_q"
13309 [(set (zero_extract:DI
13310 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13313 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13315 (match_operand:DI 1 "arith_reg_operand" "r"))]
13318 [(set_attr "type" "ustore_media")])
13320 (define_insn_and_split "*sthi_q_comb0"
13321 [(set (zero_extract:DI
13322 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13323 "register_operand" "r")
13324 (match_operand:SI 1 "ua_offset"
13328 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13330 (match_operand:DI 2 "arith_reg_operand" "r"))]
13331 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13335 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13339 (define_insn_and_split "*sthi_q_comb1"
13340 [(set (zero_extract:DI
13341 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13342 "register_operand" "r")
13343 (match_operand:SI 1 "ua_offset"
13347 (plus:SI (and:SI (plus:SI (match_dup 0)
13348 (match_operand:SI 2 "ua_offset" "I06"))
13352 (match_operand:DI 3 "arith_reg_operand" "r"))]
13353 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13354 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13358 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13362 ;; This is highpart user because the address is used as full 64 bit.
13363 (define_insn "stlo_l"
13364 [(set (zero_extract:SI
13365 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13367 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13368 (and:SI (match_dup 0) (const_int 3)))
13369 (match_operand:SI 1 "arith_reg_operand" "r"))]
13372 [(set_attr "type" "ustore_media")])
13374 (define_insn "stlo_q"
13375 [(set (zero_extract:DI
13376 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13378 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13379 (and:SI (match_dup 0) (const_int 7)))
13380 (match_operand:DI 1 "arith_reg_operand" "r"))]
13383 [(set_attr "type" "ustore_media")])
13385 (define_insn_and_split "*stlo_q_comb0"
13386 [(set (zero_extract:DI
13387 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13388 (match_operand:SI 1 "ua_offset" "I06"))
13390 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13391 (and:SI (match_dup 0) (const_int 7)))
13392 (match_operand:DI 2 "arith_reg_operand" "r"))]
13393 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13397 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13401 (define_insn_and_split "*stlo_q_comb1"
13402 [(set (zero_extract:DI
13403 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13404 (match_operand:SI 1 "ua_offset" "I06"))
13406 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13407 (match_operand:SI 2
13408 "ua_offset" "I06"))
13410 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13411 (match_operand:DI 3 "arith_reg_operand" "r"))]
13412 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13416 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13420 (define_insn "ldhi_l64"
13421 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13423 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13426 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13430 [(set_attr "type" "load_media")])
13432 (define_insn "ldhi_q64"
13433 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13435 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13438 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13442 [(set_attr "type" "load_media")])
13444 (define_insn "ldlo_l64"
13445 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13447 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13449 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13450 (and:DI (match_dup 1) (const_int 3))))]
13453 [(set_attr "type" "load_media")])
13455 (define_insn "ldlo_q64"
13456 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13458 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13460 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13461 (and:DI (match_dup 1) (const_int 7))))]
13464 [(set_attr "type" "load_media")])
13466 (define_insn "sthi_l64"
13467 [(set (zero_extract:SI
13468 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13471 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13473 (match_operand:SI 1 "arith_reg_operand" "r"))]
13476 [(set_attr "type" "ustore_media")])
13478 (define_insn "sthi_q64"
13479 [(set (zero_extract:DI
13480 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13483 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13485 (match_operand:DI 1 "arith_reg_operand" "r"))]
13488 [(set_attr "type" "ustore_media")])
13490 (define_insn "stlo_l64"
13491 [(set (zero_extract:SI
13492 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13494 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13495 (and:DI (match_dup 0) (const_int 3)))
13496 (match_operand:SI 1 "arith_reg_operand" "r"))]
13499 [(set_attr "type" "ustore_media")])
13501 (define_insn "stlo_q64"
13502 [(set (zero_extract:DI
13503 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13505 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13506 (and:DI (match_dup 0) (const_int 7)))
13507 (match_operand:DI 1 "arith_reg_operand" "r"))]
13510 [(set_attr "type" "ustore_media")])
13513 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13514 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13518 [(set_attr "type" "arith_media")])
13520 (define_insn "nsbsi"
13521 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13523 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13527 [(set_attr "type" "arith_media")])
13529 (define_insn "nsbdi"
13530 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13532 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13536 [(set_attr "type" "arith_media")])
13538 (define_expand "ffsdi2"
13539 [(set (match_operand:DI 0 "arith_reg_dest" "")
13540 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13544 rtx scratch = gen_reg_rtx (DImode);
13547 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13548 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13549 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13550 emit_insn (gen_nsbdi (scratch, scratch));
13551 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13552 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13553 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13554 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13559 (define_expand "ffssi2"
13560 [(set (match_operand:SI 0 "arith_reg_dest" "")
13561 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13565 rtx scratch = gen_reg_rtx (SImode);
13566 rtx discratch = gen_reg_rtx (DImode);
13569 emit_insn (gen_adddi3 (discratch,
13570 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13572 emit_insn (gen_andcdi3 (discratch,
13573 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13575 emit_insn (gen_nsbsi (scratch, discratch));
13576 last = emit_insn (gen_subsi3 (operands[0],
13577 force_reg (SImode, GEN_INT (63)), scratch));
13578 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13583 (define_insn "byterev"
13584 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13585 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13586 (parallel [(const_int 7) (const_int 6) (const_int 5)
13587 (const_int 4) (const_int 3) (const_int 2)
13588 (const_int 1) (const_int 0)])))]
13591 [(set_attr "type" "arith_media")])
13593 (define_insn "*prefetch_media"
13594 [(prefetch (match_operand:QI 0 "address_operand" "p")
13595 (match_operand:SI 1 "const_int_operand" "n")
13596 (match_operand:SI 2 "const_int_operand" "n"))]
13600 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13601 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13604 [(set_attr "type" "other")])
13606 (define_insn "*prefetch_i4"
13607 [(prefetch (match_operand:SI 0 "register_operand" "r")
13608 (match_operand:SI 1 "const_int_operand" "n")
13609 (match_operand:SI 2 "const_int_operand" "n"))]
13610 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13613 return \"pref @%0\";
13615 [(set_attr "type" "other")])
13617 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13618 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13619 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13620 (define_expand "prefetch"
13621 [(prefetch (match_operand 0 "address_operand" "p")
13622 (match_operand:SI 1 "const_int_operand" "n")
13623 (match_operand:SI 2 "const_int_operand" "n"))]
13624 "(TARGET_HARD_SH4 || TARGET_SH5) && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP)"
13627 if (GET_MODE (operands[0]) != Pmode
13628 || GET_CODE (operands[1]) != CONST_INT
13629 || GET_CODE (operands[2]) != CONST_INT)
13631 if (! TARGET_SHMEDIA)
13632 operands[0] = force_reg (Pmode, operands[0]);
13635 (define_insn "alloco_i"
13636 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13637 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13643 if (GET_CODE (operands[0]) == PLUS)
13645 xops[0] = XEXP (operands[0], 0);
13646 xops[1] = XEXP (operands[0], 1);
13650 xops[0] = operands[0];
13651 xops[1] = const0_rtx;
13653 output_asm_insn (\"alloco %0, %1\", xops);
13656 [(set_attr "type" "other")])
13659 [(set (match_operand 0 "any_register_operand" "")
13660 (match_operand 1 "" ""))]
13661 "TARGET_SHMEDIA && reload_completed"
13662 [(set (match_dup 0) (match_dup 1))]
13667 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13672 ; Stack Protector Patterns
13674 (define_expand "stack_protect_set"
13675 [(set (match_operand 0 "memory_operand" "")
13676 (match_operand 1 "memory_operand" ""))]
13679 if (TARGET_SHMEDIA)
13681 if (TARGET_SHMEDIA64)
13682 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13684 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13687 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13692 (define_insn "stack_protect_set_si"
13693 [(set (match_operand:SI 0 "memory_operand" "=m")
13694 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13695 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13697 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13698 [(set_attr "type" "other")
13699 (set_attr "length" "6")])
13701 (define_insn "stack_protect_set_si_media"
13702 [(set (match_operand:SI 0 "memory_operand" "=m")
13703 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13704 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13706 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13707 [(set_attr "type" "other")
13708 (set_attr "length" "12")])
13710 (define_insn "stack_protect_set_di_media"
13711 [(set (match_operand:DI 0 "memory_operand" "=m")
13712 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13713 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13715 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13716 [(set_attr "type" "other")
13717 (set_attr "length" "12")])
13719 (define_expand "stack_protect_test"
13720 [(match_operand 0 "memory_operand" "")
13721 (match_operand 1 "memory_operand" "")
13722 (match_operand 2 "" "")]
13725 if (TARGET_SHMEDIA)
13727 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13729 if (TARGET_SHMEDIA64)
13730 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13733 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13736 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13740 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13741 emit_jump_insn (gen_branch_true (operands[2]));
13747 (define_insn "stack_protect_test_si"
13748 [(set (reg:SI T_REG)
13749 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13750 (match_operand:SI 1 "memory_operand" "m")]
13752 (set (match_scratch:SI 2 "=&r") (const_int 0))
13753 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13755 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13756 [(set_attr "type" "other")
13757 (set_attr "length" "10")])
13759 (define_insn "stack_protect_test_si_media"
13760 [(set (match_operand:SI 0 "register_operand" "=&r")
13761 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13762 (match_operand:SI 2 "memory_operand" "m")]
13764 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13766 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13767 [(set_attr "type" "other")
13768 (set_attr "length" "16")])
13770 (define_insn "stack_protect_test_di_media"
13771 [(set (match_operand:DI 0 "register_operand" "=&r")
13772 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13773 (match_operand:DI 2 "memory_operand" "m")]
13775 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13777 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13778 [(set_attr "type" "other")
13779 (set_attr "length" "16")])