1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences. Especially the sequences for arithmetic right shifts.
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
32 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
33 ;; way to generate them.
35 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
36 ;; for a str* inline function.
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42 ;; Special constraints for SH machine description:
49 ;; Special formats used for outputting SH instructions:
51 ;; %. -- print a .s if insn needs delay slot
52 ;; %@ -- print rte/rts if is/isn't an interrupt function
53 ;; %# -- output a nop if there is nothing to put in the delay slot
54 ;; %O -- print a constant without the #
55 ;; %R -- print the lsw reg of a double
56 ;; %S -- print the msw reg of a double
57 ;; %T -- print next word of a double REG or MEM
59 ;; Special predicates:
61 ;; arith_operand -- operand is valid source for arithmetic op
62 ;; arith_reg_operand -- operand is valid register for arithmetic op
63 ;; general_movdst_operand -- operand is valid move destination
64 ;; general_movsrc_operand -- operand is valid move source
65 ;; logical_operand -- operand is valid source for logical op
67 ;; -------------------------------------------------------------------------
69 ;; -------------------------------------------------------------------------
117 ;; These are used with unspec.
118 (UNSPEC_COMPACT_ARGS 0)
131 (UNSPEC_INIT_TRAMP 13)
144 (UNSPEC_DIV_INV_M0 30)
145 (UNSPEC_DIV_INV_M1 31)
146 (UNSPEC_DIV_INV_M2 32)
147 (UNSPEC_DIV_INV_M3 33)
148 (UNSPEC_DIV_INV20 34)
149 (UNSPEC_DIV_INV_TABLE 37)
156 ;; These are used with unspec_volatile.
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
164 (UNSPECV_EH_RETURN 12)
167 ;; -------------------------------------------------------------------------
169 ;; -------------------------------------------------------------------------
174 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175 (const (symbol_ref "sh_cpu_attr")))
177 (define_attr "endian" "big,little"
178 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179 (const_string "little") (const_string "big"))))
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184 (const_string "yes") (const_string "no"))))
186 (define_attr "fmovd" "yes,no"
187 (const (if_then_else (symbol_ref "TARGET_FMOVD")
188 (const_string "yes") (const_string "no"))))
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
192 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194 (const_string "sh1"))))
196 ;; cbranch conditional branch instructions
197 ;; jump unconditional jumps
198 ;; arith ordinary arithmetic
199 ;; arith3 a compound insn that behaves similarly to a sequence of
200 ;; three insns of type arith
201 ;; arith3b like above, but might end with a redirected branch
203 ;; load_si Likewise, SImode variant for general register.
204 ;; fload Likewise, but load to fp register.
206 ;; fstore floating point register to memory
207 ;; move general purpose register to register
208 ;; movi8 8-bit immediate to general purpose register
209 ;; mt_group other sh4 mt instructions
210 ;; fmove register to register, floating point
211 ;; smpy word precision integer multiply
212 ;; dmpy longword or doublelongword precision integer multiply
214 ;; pload load of pr reg, which can't be put into delay slot of rts
215 ;; prset copy register to pr reg, ditto
216 ;; pstore store of pr reg, which can't be put into delay slot of jsr
217 ;; prget copy pr to register, ditto
218 ;; pcload pc relative load of constant value
219 ;; pcfload Likewise, but load to fp register.
220 ;; pcload_si Likewise, SImode variant for general register.
221 ;; rte return from exception
222 ;; sfunc special function call with known used registers
223 ;; call function call
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv floating point divide (or square root)
227 ;; gp_fpul move from general purpose register to fpul
228 ;; fpul_gp move from fpul to general purpose register
229 ;; mac_gp move from mac[lh] to general purpose register
230 ;; gp_mac move from general purpose register to mac[lh]
231 ;; mac_mem move from mac[lh] to memory
232 ;; mem_mac move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s fix_truncsfsi2_i4
235 ;; dfdiv double precision floating point divide (or square root)
236 ;; cwb ic_invalidate_line_i
237 ;; movua SH4a unaligned load
238 ;; fsrra square root reciprocal approximate
239 ;; fsca sine and cosine approximate
240 ;; tls_load load TLS related address
241 ;; arith_media SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media SHmedia compare instructions
244 ;; dfdiv_media SHmedia double precision divide and square root
245 ;; dfmul_media SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media SHmedia longword multiply
249 ;; fcmp_media SHmedia floating point compare instructions
250 ;; fdiv_media SHmedia single precision divide and square root
251 ;; fload_media SHmedia floating point register load instructions
252 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media SHmedia unconditional branch instructions
259 ;; load_media SHmedia general register load instructions
260 ;; pt_media SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media SHmedia ptabs instruction
262 ;; store_media SHmedia general register store instructions
263 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media SHmedia mac-style fixed point operations
265 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil no-op move, will be deleted.
271 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
272 (const_string "other"))
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
277 ;; mt_group SH4 "mt" group instructions.
279 ;; ex_group SH4 "ex" group instructions.
281 ;; ls_group SH4 "ls" group instructions.
284 (define_attr "insn_class"
285 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289 (eq_attr "type" "cbranch,jump") (const_string "br_group")
290 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291 (const_string "fe_group")
292 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
293 (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long. Something in the
312 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
317 ;; The maximum range used for SImode constant pool entries is 1018. A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table. That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
335 (define_attr "short_cbranch_p" "no,yes"
336 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
338 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
340 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
342 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
344 ] (const_string "no")))
346 (define_attr "med_branch_p" "no,yes"
347 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
350 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
355 ] (const_string "no")))
357 (define_attr "med_cbranch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
361 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
366 ] (const_string "no")))
368 (define_attr "braf_branch_p" "no,yes"
369 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
371 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
374 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
379 ] (const_string "no")))
381 (define_attr "braf_cbranch_p" "no,yes"
382 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
387 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
392 ] (const_string "no")))
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
401 ; All other instructions are two bytes long by default.
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406 (cond [(eq_attr "type" "cbranch")
407 (cond [(eq_attr "short_cbranch_p" "yes")
409 (eq_attr "med_cbranch_p" "yes")
411 (eq_attr "braf_cbranch_p" "yes")
413 ;; ??? using pc is not computed transitively.
414 (ne (match_dup 0) (match_dup 0))
416 (ne (symbol_ref ("flag_pic")) (const_int 0))
419 (eq_attr "type" "jump")
420 (cond [(eq_attr "med_branch_p" "yes")
422 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
424 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
426 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427 (symbol_ref "code_for_indirect_jump_scratch"))))
428 (cond [(eq_attr "braf_branch_p" "yes")
430 (eq (symbol_ref "flag_pic") (const_int 0))
432 (ne (symbol_ref "TARGET_SH2") (const_int 0))
433 (const_int 10)] (const_int 18))
434 (eq_attr "braf_branch_p" "yes")
436 ;; ??? using pc is not computed transitively.
437 (ne (match_dup 0) (match_dup 0))
439 (ne (symbol_ref ("flag_pic")) (const_int 0))
442 (eq_attr "type" "pt_media")
443 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444 (const_int 20) (const_int 12))
445 (and (eq_attr "type" "jump_media")
446 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
448 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
452 ;; DFA descriptions for the pipelines
455 (include "shmedia.md")
458 (include "predicates.md")
459 (include "constraints.md")
461 ;; Definitions for filling delay slots
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465 (define_attr "banked" "yes,no"
466 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
468 (const_string "yes")]
469 (const_string "no")))
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
476 (const_string "yes")))
478 (define_attr "interrupt_function" "no,yes"
479 (const (symbol_ref "current_function_interrupt")))
481 (define_attr "in_delay_slot" "yes,no"
482 (cond [(eq_attr "type" "cbranch") (const_string "no")
483 (eq_attr "type" "pcload,pcload_si") (const_string "no")
484 (eq_attr "needs_delay_slot" "yes") (const_string "no")
485 (eq_attr "length" "2") (const_string "yes")
486 ] (const_string "no")))
488 (define_attr "cond_delay_slot" "yes,no"
489 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490 ] (const_string "no")))
492 (define_attr "is_sfunc" ""
493 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
495 (define_attr "is_mac_media" ""
496 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
498 (define_attr "branch_zero" "yes,no"
499 (cond [(eq_attr "type" "!cbranch") (const_string "no")
500 (ne (symbol_ref "(next_active_insn (insn)\
501 == (prev_active_insn\
502 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503 && get_attr_length (next_active_insn (insn)) == 2")
505 (const_string "yes")]
506 (const_string "no")))
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512 (const_string "no")))
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519 (const_string "yes")]
520 (const_string "no")))
522 (define_attr "any_int_load" "yes,no"
523 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524 (const_string "yes")]
525 (const_string "no")))
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528 (const_string "user"))
531 (eq_attr "needs_delay_slot" "yes")
532 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
543 (eq_attr "type" "return")
544 [(and (eq_attr "in_delay_slot" "yes")
545 (ior (and (eq_attr "interrupt_function" "no")
546 (eq_attr "type" "!pload,prset"))
547 (and (eq_attr "interrupt_function" "yes")
549 (eq (symbol_ref "TARGET_SH3") (const_int 0))
550 (eq_attr "hit_stack" "no")
551 (eq_attr "banked" "no"))))) (nil) (nil)])
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
557 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558 [(and (eq_attr "in_delay_slot" "yes")
559 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
569 (and (eq_attr "type" "cbranch")
570 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571 ;; SH2e has a hardware bug that pretty much prohibits the use of
572 ;; annuled delay slots.
573 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574 (not (eq_attr "cpu" "sh2e"))) (nil)])
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
582 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583 (match_operand:SI 1 "arith_operand" "K08,r"))
587 [(set_attr "type" "mt_group")])
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
595 (define_insn "cmpeqsi_t"
597 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
604 [(set_attr "type" "mt_group")])
606 (define_insn "cmpgtsi_t"
608 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
614 [(set_attr "type" "mt_group")])
616 (define_insn "cmpgesi_t"
618 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
624 [(set_attr "type" "mt_group")])
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
630 (define_expand "cbranchsi4"
632 (if_then_else (match_operator 0 "comparison_operator"
633 [(match_operand:SI 1 "arith_operand" "")
634 (match_operand:SI 2 "arith_operand" "")])
635 (label_ref (match_operand 3 "" ""))
637 (clobber (reg:SI T_REG))]
639 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
645 (define_insn_and_split "cmpgeusi_t"
647 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
651 "&& operands[1] == CONST0_RTX (SImode)"
655 emit_insn (gen_sett ());
658 [(set_attr "type" "mt_group")])
660 (define_insn "cmpgtusi_t"
662 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663 (match_operand:SI 1 "arith_reg_operand" "r")))]
666 [(set_attr "type" "mt_group")])
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
671 (define_expand "cmpsi"
673 (compare (match_operand:SI 0 "cmpsi_operand" "")
674 (match_operand:SI 1 "arith_operand" "")))]
675 "TARGET_SH1 || TARGET_SHMEDIA"
678 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679 && GET_CODE (operands[1]) != CONST_INT)
680 operands[0] = copy_to_mode_reg (SImode, operands[0]);
681 sh_compare_op0 = operands[0];
682 sh_compare_op1 = operands[1];
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
696 (define_expand "cbranchdi4"
698 (if_then_else (match_operator 0 "comparison_operator"
699 [(match_operand:DI 1 "arith_operand" "")
700 (match_operand:DI 2 "arith_operand" "")])
701 (label_ref (match_operand 3 "" ""))
703 (clobber (match_dup 4))
704 (clobber (reg:SI T_REG))]
708 enum rtx_code comparison;
710 if (TARGET_EXPAND_CBRANCHDI4)
712 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
715 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716 if (comparison != GET_CODE (operands[0]))
718 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719 operands[4] = gen_rtx_SCRATCH (SImode);
722 (define_insn_and_split "cbranchdi4_i"
724 (if_then_else (match_operator 0 "comparison_operator"
725 [(match_operand:DI 1 "arith_operand" "r,r")
726 (match_operand:DI 2 "arith_operand" "rN,i")])
727 (label_ref (match_operand 3 "" ""))
729 (clobber (match_scratch:SI 4 "=X,&r"))
730 (clobber (reg:SI T_REG))]
733 "&& reload_completed"
737 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
748 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749 (match_operand:DI 1 "arith_operand" "r"))
752 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
754 [(set_attr "length" "6")
755 (set_attr "type" "arith3b")])
757 (define_insn "cmpeqdi_t"
759 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
763 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
764 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765 [(set_attr "length" "6")
766 (set_attr "type" "arith3b")])
770 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
775 "TARGET_SH1 && reload_completed && optimize"
776 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778 (label_ref (match_dup 6))
780 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
785 = gen_rtx_REG (SImode,
786 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
788 = (operands[1] == const0_rtx
790 : gen_rtx_REG (SImode,
791 true_regnum (operands[1])
792 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793 operands[4] = gen_lowpart (SImode, operands[0]);
794 operands[5] = gen_lowpart (SImode, operands[1]);
795 operands[6] = gen_label_rtx ();
798 (define_insn "cmpgtdi_t"
800 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
804 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806 [(set_attr "length" "8")
807 (set_attr "type" "arith3")])
809 (define_insn "cmpgedi_t"
811 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
815 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
817 [(set_attr "length" "8,2")
818 (set_attr "type" "arith3,mt_group")])
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
824 (define_insn "cmpgeudi_t"
826 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827 (match_operand:DI 1 "arith_reg_operand" "r")))]
829 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830 [(set_attr "length" "8")
831 (set_attr "type" "arith3")])
833 (define_insn "cmpgtudi_t"
835 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836 (match_operand:DI 1 "arith_reg_operand" "r")))]
838 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839 [(set_attr "length" "8")
840 (set_attr "type" "arith3")])
842 (define_insn "cmpeqsi_media"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845 (match_operand:SI 2 "cmp_operand" "Nr")))]
848 [(set_attr "type" "cmp_media")])
850 (define_insn "cmpeqdi_media"
851 [(set (match_operand:SI 0 "register_operand" "=r")
852 (eq:SI (match_operand:DI 1 "register_operand" "%r")
853 (match_operand:DI 2 "cmp_operand" "Nr")))]
856 [(set_attr "type" "cmp_media")])
858 (define_insn "cmpgtsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861 (match_operand:SI 2 "cmp_operand" "rN")))]
864 [(set_attr "type" "cmp_media")])
866 (define_insn "cmpgtdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
872 [(set_attr "type" "cmp_media")])
874 (define_insn "cmpgtusi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
879 "cmpgtu %N1, %N2, %0"
880 [(set_attr "type" "cmp_media")])
882 (define_insn "cmpgtudi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
887 "cmpgtu %N1, %N2, %0"
888 [(set_attr "type" "cmp_media")])
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
896 [(set_attr "type" "cmp_media")])
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
901 (define_expand "cmpdi"
903 (compare (match_operand:DI 0 "arith_operand" "")
904 (match_operand:DI 1 "arith_operand" "")))]
905 "TARGET_SH2 || TARGET_SHMEDIA"
908 sh_compare_op0 = operands[0];
909 sh_compare_op1 = operands[1];
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
919 (define_insn "movdicc_false"
920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
923 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924 (match_operand:DI 3 "arith_reg_operand" "0")))]
927 [(set_attr "type" "arith_media")])
929 (define_insn "movdicc_true"
930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
933 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934 (match_operand:DI 3 "arith_reg_operand" "0")))]
937 [(set_attr "type" "arith_media")])
940 [(set (match_operand:DI 0 "arith_reg_dest" "")
941 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942 [(match_operand:DI 1 "arith_reg_operand" "")
944 (match_operand:DI 2 "arith_reg_dest" "")
946 (set (match_dup 2) (match_dup 0))]
947 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
949 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953 VOIDmode, operands[1], CONST0_RTX (DImode));
957 [(set (match_operand:DI 0 "general_movdst_operand" "")
958 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959 (set (match_operand:DI 2 "arith_reg_dest" "")
960 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961 [(match_operand:DI 3 "arith_reg_operand" "")
965 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
967 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970 (define_expand "movdicc"
971 [(set (match_operand:DI 0 "register_operand" "")
972 (if_then_else:DI (match_operand 1 "comparison_operator" "")
973 (match_operand:DI 2 "register_operand" "")
974 (match_operand:DI 3 "register_operand" "")))]
978 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979 && GET_MODE (sh_compare_op0) == DImode
980 && sh_compare_op1 == const0_rtx)
981 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982 sh_compare_op0, sh_compare_op1);
987 if (!can_create_pseudo_p ())
990 tmp = gen_reg_rtx (DImode);
992 switch (GET_CODE (operands[1]))
995 emit_insn (gen_seq (tmp));
996 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1000 emit_insn (gen_seq (tmp));
1001 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1005 emit_insn (gen_sgt (tmp));
1006 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1010 emit_insn (gen_slt (tmp));
1011 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1015 emit_insn (gen_slt (tmp));
1016 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1020 emit_insn (gen_sgt (tmp));
1021 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1025 emit_insn (gen_sgtu (tmp));
1026 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1030 emit_insn (gen_sltu (tmp));
1031 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1035 emit_insn (gen_sltu (tmp));
1036 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1040 emit_insn (gen_sgtu (tmp));
1041 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1045 emit_insn (gen_sunordered (tmp));
1046 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1050 emit_insn (gen_sunordered (tmp));
1051 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1074 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075 (match_operand:SI 3 "arith_reg_operand" "0")))]
1078 [(set_attr "type" "arith_media")])
1080 (define_insn "movsicc_true"
1081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1084 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085 (match_operand:SI 3 "arith_reg_operand" "0")))]
1088 [(set_attr "type" "arith_media")])
1091 [(set (match_operand:SI 0 "arith_reg_dest" "")
1092 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093 [(match_operand:SI 1 "arith_reg_operand" "")
1095 (match_operand:SI 2 "arith_reg_dest" "")
1097 (set (match_dup 2) (match_dup 0))]
1098 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1100 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1103 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104 VOIDmode, operands[1], CONST0_RTX (SImode));
1108 [(set (match_operand:SI 0 "general_movdst_operand" "")
1109 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110 (set (match_operand:SI 2 "arith_reg_dest" "")
1111 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112 [(match_operand:SI 3 "arith_reg_operand" "")
1116 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1119 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1122 replace_rtx (operands[4], operands[0], operands[1]);
1126 [(set (match_operand 0 "any_register_operand" "")
1127 (match_operand 1 "any_register_operand" ""))
1128 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138 && (REGNO_REG_CLASS (REGNO (operands[0]))
1139 == REGNO_REG_CLASS (REGNO (operands[2])))
1140 && (REGNO_REG_CLASS (REGNO (operands[1]))
1141 == REGNO_REG_CLASS (REGNO (operands[0])))"
1142 [(set (match_dup 0) (match_dup 3))
1143 (set (match_dup 4) (match_dup 5))]
1146 rtx set1, set2, insn2;
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 insn2 = emit (set2);
1177 if (GET_CODE (insn2) == BARRIER)
1179 extract_insn (insn2);
1180 if (! constrain_operands (1))
1184 tmp = replacements[0];
1185 replacements[0] = replacements[1];
1186 replacements[1] = tmp;
1187 tmp = replacements[2];
1188 replacements[2] = replacements[3];
1189 replacements[3] = tmp;
1190 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1191 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1192 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1198 ;; The register allocator is rather clumsy in handling multi-way conditional
1199 ;; moves, so allow the combiner to make them, and we split them up after
1201 (define_insn_and_split "*movsicc_umin"
1202 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1203 (umin:SI (if_then_else:SI
1204 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1206 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1207 (match_operand:SI 3 "register_operand" "0"))
1208 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1209 (clobber (match_scratch:SI 5 "=&r"))]
1210 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1212 "TARGET_SHMEDIA && reload_completed"
1216 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1218 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1219 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1224 (define_insn "*movsicc_t_false"
1225 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1226 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1227 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1228 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1229 "TARGET_PRETEND_CMOVE
1230 && (arith_reg_operand (operands[1], SImode)
1231 || (immediate_operand (operands[1], SImode)
1232 && satisfies_constraint_I08 (operands[1])))"
1233 "bt 0f\;mov %1,%0\\n0:"
1234 [(set_attr "type" "mt_group,arith") ;; poor approximation
1235 (set_attr "length" "4")])
1237 (define_insn "*movsicc_t_true"
1238 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1239 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1240 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1241 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1242 "TARGET_PRETEND_CMOVE
1243 && (arith_reg_operand (operands[1], SImode)
1244 || (immediate_operand (operands[1], SImode)
1245 && satisfies_constraint_I08 (operands[1])))"
1246 "bf 0f\;mov %1,%0\\n0:"
1247 [(set_attr "type" "mt_group,arith") ;; poor approximation
1248 (set_attr "length" "4")])
1250 (define_expand "movsicc"
1251 [(set (match_operand:SI 0 "arith_reg_dest" "")
1252 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1253 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1254 (match_operand:SI 3 "arith_reg_operand" "")))]
1255 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1258 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1259 && GET_MODE (sh_compare_op0) == SImode
1261 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1262 && sh_compare_op1 == const0_rtx)
1263 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1264 sh_compare_op0, sh_compare_op1);
1265 else if (TARGET_PRETEND_CMOVE)
1267 enum rtx_code code = GET_CODE (operands[1]);
1268 enum rtx_code new_code = code;
1271 if (! currently_expanding_to_rtl)
1275 case LT: case LE: case LEU: case LTU:
1276 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1279 new_code = reverse_condition (code);
1281 case EQ: case GT: case GE: case GEU: case GTU:
1286 tmp = prepare_scc_operands (new_code);
1287 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1294 if (!can_create_pseudo_p ())
1297 tmp = gen_reg_rtx (SImode);
1299 switch (GET_CODE (operands[1]))
1302 emit_insn (gen_seq (tmp));
1303 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1307 emit_insn (gen_seq (tmp));
1308 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1312 emit_insn (gen_sgt (tmp));
1313 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1317 emit_insn (gen_slt (tmp));
1318 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1322 emit_insn (gen_slt (tmp));
1323 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1327 emit_insn (gen_sgt (tmp));
1328 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1332 emit_insn (gen_sgtu (tmp));
1333 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1337 emit_insn (gen_sltu (tmp));
1338 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1342 emit_insn (gen_sltu (tmp));
1343 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1347 emit_insn (gen_sgtu (tmp));
1348 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1352 emit_insn (gen_sunordered (tmp));
1353 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1357 emit_insn (gen_sunordered (tmp));
1358 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1375 (define_expand "movqicc"
1376 [(set (match_operand:QI 0 "register_operand" "")
1377 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1378 (match_operand:QI 2 "register_operand" "")
1379 (match_operand:QI 3 "register_operand" "")))]
1383 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1384 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1385 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1386 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1390 ;; -------------------------------------------------------------------------
1391 ;; Addition instructions
1392 ;; -------------------------------------------------------------------------
1394 (define_expand "adddi3"
1395 [(set (match_operand:DI 0 "arith_reg_operand" "")
1396 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1397 (match_operand:DI 2 "arith_operand" "")))]
1403 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1405 operands[2] = force_reg (DImode, operands[2]);
1406 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1411 (define_insn "*adddi3_media"
1412 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1413 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1414 (match_operand:DI 2 "arith_operand" "r,I10")))]
1419 [(set_attr "type" "arith_media")])
1421 (define_insn "*adddisi3_media"
1422 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1423 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1424 (match_operand:DI 2 "arith_operand" "r,I10")))]
1429 [(set_attr "type" "arith_media")
1430 (set_attr "highpart" "ignore")])
1432 (define_insn "adddi3z_media"
1433 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1435 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1436 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1438 "addz.l %1, %N2, %0"
1439 [(set_attr "type" "arith_media")
1440 (set_attr "highpart" "ignore")])
1442 (define_insn "adddi3_compact"
1443 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1444 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1445 (match_operand:DI 2 "arith_reg_operand" "r")))
1446 (clobber (reg:SI T_REG))]
1449 [(set_attr "length" "6")])
1452 [(set (match_operand:DI 0 "arith_reg_dest" "")
1453 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1454 (match_operand:DI 2 "arith_reg_operand" "")))
1455 (clobber (reg:SI T_REG))]
1456 "TARGET_SH1 && reload_completed"
1460 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1461 high0 = gen_rtx_REG (SImode,
1462 true_regnum (operands[0])
1463 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464 high2 = gen_rtx_REG (SImode,
1465 true_regnum (operands[2])
1466 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1467 emit_insn (gen_clrt ());
1468 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1469 emit_insn (gen_addc1 (high0, high0, high2));
1474 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1475 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1476 (match_operand:SI 2 "arith_reg_operand" "r"))
1479 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1482 [(set_attr "type" "arith")])
1484 (define_insn "addc1"
1485 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1486 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1487 (match_operand:SI 2 "arith_reg_operand" "r"))
1489 (clobber (reg:SI T_REG))]
1492 [(set_attr "type" "arith")])
1494 (define_expand "addsi3"
1495 [(set (match_operand:SI 0 "arith_reg_operand" "")
1496 (plus:SI (match_operand:SI 1 "arith_operand" "")
1497 (match_operand:SI 2 "arith_operand" "")))]
1502 operands[1] = force_reg (SImode, operands[1]);
1505 (define_insn "addsi3_media"
1506 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1507 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1508 (match_operand:SI 2 "arith_operand" "r,I10")))]
1513 [(set_attr "type" "arith_media")
1514 (set_attr "highpart" "ignore")])
1516 (define_insn "addsidi3_media"
1517 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1518 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1520 (match_operand:SI 2 "arith_operand"
1526 [(set_attr "type" "arith_media")
1527 (set_attr "highpart" "ignore")])
1529 (define_insn "*addsi3_compact"
1530 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1531 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1532 (match_operand:SI 2 "arith_operand" "rI08")))]
1535 [(set_attr "type" "arith")])
1537 ;; -------------------------------------------------------------------------
1538 ;; Subtraction instructions
1539 ;; -------------------------------------------------------------------------
1541 (define_expand "subdi3"
1542 [(set (match_operand:DI 0 "arith_reg_operand" "")
1543 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1544 (match_operand:DI 2 "arith_reg_operand" "")))]
1550 operands[1] = force_reg (DImode, operands[1]);
1551 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1556 (define_insn "*subdi3_media"
1557 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1558 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1559 (match_operand:DI 2 "arith_reg_operand" "r")))]
1562 [(set_attr "type" "arith_media")])
1564 (define_insn "subdisi3_media"
1565 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1566 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1567 (match_operand:DI 2 "arith_reg_operand" "r")))]
1570 [(set_attr "type" "arith_media")
1571 (set_attr "highpart" "ignore")])
1573 (define_insn "subdi3_compact"
1574 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1575 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1576 (match_operand:DI 2 "arith_reg_operand" "r")))
1577 (clobber (reg:SI T_REG))]
1580 [(set_attr "length" "6")])
1583 [(set (match_operand:DI 0 "arith_reg_dest" "")
1584 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1585 (match_operand:DI 2 "arith_reg_operand" "")))
1586 (clobber (reg:SI T_REG))]
1587 "TARGET_SH1 && reload_completed"
1591 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1592 high0 = gen_rtx_REG (SImode,
1593 true_regnum (operands[0])
1594 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595 high2 = gen_rtx_REG (SImode,
1596 true_regnum (operands[2])
1597 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1598 emit_insn (gen_clrt ());
1599 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1600 emit_insn (gen_subc1 (high0, high0, high2));
1605 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1606 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1607 (match_operand:SI 2 "arith_reg_operand" "r"))
1610 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1615 [(set_attr "type" "arith")])
1617 (define_insn "subc1"
1618 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1619 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1620 (match_operand:SI 2 "arith_reg_operand" "r"))
1622 (clobber (reg:SI T_REG))]
1625 [(set_attr "type" "arith")])
1627 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1628 ;; pattern for this case. This helps multimedia applications that compute
1629 ;; the sum of absolute differences.
1630 (define_insn "mov_neg_si_t"
1631 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1634 [(set_attr "type" "arith")])
1636 (define_insn "*subsi3_internal"
1637 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1638 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1639 (match_operand:SI 2 "arith_reg_operand" "r")))]
1642 [(set_attr "type" "arith")])
1644 (define_insn_and_split "*subsi3_media"
1645 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1646 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1647 (match_operand:SI 2 "extend_reg_operand" "r")))]
1649 && (operands[1] != constm1_rtx
1650 || (GET_CODE (operands[2]) != TRUNCATE
1651 && GET_CODE (operands[2]) != SUBREG))"
1653 "operands[1] == constm1_rtx"
1654 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1656 [(set_attr "type" "arith_media")
1657 (set_attr "highpart" "ignore")])
1660 [(set (match_operand:SI 0 "arith_reg_dest" "")
1661 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1662 "general_extend_operand"
1664 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1665 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1666 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1670 [(set (match_operand:SI 0 "arith_reg_dest" "")
1671 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1672 "general_extend_operand"
1674 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1675 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1676 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1678 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1679 ;; will sometimes save one instruction. Otherwise we might get
1680 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1683 (define_expand "subsi3"
1684 [(set (match_operand:SI 0 "arith_reg_operand" "")
1685 (minus:SI (match_operand:SI 1 "arith_operand" "")
1686 (match_operand:SI 2 "arith_reg_operand" "")))]
1690 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1692 emit_insn (gen_negsi2 (operands[0], operands[2]));
1693 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1698 if (!can_create_pseudo_p ()
1699 && ! arith_reg_or_0_operand (operands[1], SImode))
1701 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1702 operands[1] = force_reg (SImode, operands[1]);
1706 ;; -------------------------------------------------------------------------
1707 ;; Division instructions
1708 ;; -------------------------------------------------------------------------
1710 ;; We take advantage of the library routines which don't clobber as many
1711 ;; registers as a normal function call would.
1713 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1714 ;; also has an effect on the register that holds the address of the sfunc.
1715 ;; To make this work, we have an extra dummy insn that shows the use
1716 ;; of this register for reorg.
1718 (define_insn "use_sfunc_addr"
1719 [(set (reg:SI PR_REG)
1720 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1721 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1723 [(set_attr "length" "0")])
1725 (define_insn "udivsi3_sh2a"
1726 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1727 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1728 (match_operand:SI 2 "arith_reg_operand" "z")))]
1731 [(set_attr "type" "arith")
1732 (set_attr "in_delay_slot" "no")])
1734 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1735 ;; hard register 0. If we used hard register 0, then the next instruction
1736 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1737 ;; gets allocated to a stack slot that needs its address reloaded, then
1738 ;; there is nothing to prevent reload from using r0 to reload the address.
1739 ;; This reload would clobber the value in r0 we are trying to store.
1740 ;; If we let reload allocate r0, then this problem can never happen.
1742 (define_insn "udivsi3_i1"
1743 [(set (match_operand:SI 0 "register_operand" "=z")
1744 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1745 (clobber (reg:SI T_REG))
1746 (clobber (reg:SI PR_REG))
1747 (clobber (reg:SI R4_REG))
1748 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1749 "TARGET_SH1 && ! TARGET_SH4"
1751 [(set_attr "type" "sfunc")
1752 (set_attr "needs_delay_slot" "yes")])
1754 ; Since shmedia-nofpu code could be linked against shcompact code, and
1755 ; the udivsi3 libcall has the same name, we must consider all registers
1756 ; clobbered that are in the union of the registers clobbered by the
1757 ; shmedia and the shcompact implementation. Note, if the shcompact
1758 ; implementation actually used shcompact code, we'd need to clobber
1759 ; also r23 and fr23.
1760 (define_insn "udivsi3_i1_media"
1761 [(set (match_operand:SI 0 "register_operand" "=z")
1762 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1763 (clobber (reg:SI T_MEDIA_REG))
1764 (clobber (reg:SI PR_MEDIA_REG))
1765 (clobber (reg:SI R20_REG))
1766 (clobber (reg:SI R21_REG))
1767 (clobber (reg:SI R22_REG))
1768 (clobber (reg:DI TR0_REG))
1769 (clobber (reg:DI TR1_REG))
1770 (clobber (reg:DI TR2_REG))
1771 (use (match_operand 1 "target_reg_operand" "b"))]
1772 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1774 [(set_attr "type" "sfunc")
1775 (set_attr "needs_delay_slot" "yes")])
1777 (define_expand "udivsi3_i4_media"
1779 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1781 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1782 (set (match_dup 5) (float:DF (match_dup 3)))
1783 (set (match_dup 6) (float:DF (match_dup 4)))
1784 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1785 (set (match_dup 8) (fix:DI (match_dup 7)))
1786 (set (match_operand:SI 0 "register_operand" "")
1787 (truncate:SI (match_dup 8)))]
1788 "TARGET_SHMEDIA_FPU"
1791 operands[3] = gen_reg_rtx (DImode);
1792 operands[4] = gen_reg_rtx (DImode);
1793 operands[5] = gen_reg_rtx (DFmode);
1794 operands[6] = gen_reg_rtx (DFmode);
1795 operands[7] = gen_reg_rtx (DFmode);
1796 operands[8] = gen_reg_rtx (DImode);
1799 (define_insn "udivsi3_i4"
1800 [(set (match_operand:SI 0 "register_operand" "=y")
1801 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1802 (clobber (reg:SI T_REG))
1803 (clobber (reg:SI PR_REG))
1804 (clobber (reg:DF DR0_REG))
1805 (clobber (reg:DF DR2_REG))
1806 (clobber (reg:DF DR4_REG))
1807 (clobber (reg:SI R0_REG))
1808 (clobber (reg:SI R1_REG))
1809 (clobber (reg:SI R4_REG))
1810 (clobber (reg:SI R5_REG))
1811 (use (reg:PSI FPSCR_REG))
1812 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1813 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1815 [(set_attr "type" "sfunc")
1816 (set_attr "fp_mode" "double")
1817 (set_attr "needs_delay_slot" "yes")])
1819 (define_insn "udivsi3_i4_single"
1820 [(set (match_operand:SI 0 "register_operand" "=y")
1821 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822 (clobber (reg:SI T_REG))
1823 (clobber (reg:SI PR_REG))
1824 (clobber (reg:DF DR0_REG))
1825 (clobber (reg:DF DR2_REG))
1826 (clobber (reg:DF DR4_REG))
1827 (clobber (reg:SI R0_REG))
1828 (clobber (reg:SI R1_REG))
1829 (clobber (reg:SI R4_REG))
1830 (clobber (reg:SI R5_REG))
1831 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1832 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1834 [(set_attr "type" "sfunc")
1835 (set_attr "needs_delay_slot" "yes")])
1837 (define_insn "udivsi3_i4_int"
1838 [(set (match_operand:SI 0 "register_operand" "=z")
1839 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1840 (clobber (reg:SI T_REG))
1841 (clobber (reg:SI R1_REG))
1842 (clobber (reg:SI PR_REG))
1843 (clobber (reg:SI MACH_REG))
1844 (clobber (reg:SI MACL_REG))
1845 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1848 [(set_attr "type" "sfunc")
1849 (set_attr "needs_delay_slot" "yes")])
1852 (define_expand "udivsi3"
1853 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1854 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1855 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1856 (parallel [(set (match_operand:SI 0 "register_operand" "")
1857 (udiv:SI (reg:SI R4_REG)
1859 (clobber (reg:SI T_REG))
1860 (clobber (reg:SI PR_REG))
1861 (clobber (reg:SI R4_REG))
1862 (use (match_dup 3))])]
1868 operands[3] = gen_reg_rtx (Pmode);
1869 /* Emit the move of the address to a pseudo outside of the libcall. */
1870 if (TARGET_DIVIDE_CALL_TABLE)
1872 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1873 that causes problems when the divide code is supposed to come from a
1874 separate library. Division by zero is undefined, so dividing 1 can be
1875 implemented by comparing with the divisor. */
1876 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1878 emit_insn (gen_cmpsi (operands[1], operands[2]));
1879 emit_insn (gen_sgeu (operands[0]));
1882 else if (operands[2] == const0_rtx)
1884 emit_move_insn (operands[0], operands[2]);
1887 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1888 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1890 else if (TARGET_DIVIDE_CALL_FP)
1892 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1893 if (TARGET_FPU_SINGLE)
1894 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1896 last = gen_udivsi3_i4 (operands[0], operands[3]);
1898 else if (TARGET_SHMEDIA_FPU)
1900 operands[1] = force_reg (SImode, operands[1]);
1901 operands[2] = force_reg (SImode, operands[2]);
1902 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1905 else if (TARGET_SH2A)
1907 operands[1] = force_reg (SImode, operands[1]);
1908 operands[2] = force_reg (SImode, operands[2]);
1909 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1912 else if (TARGET_SH5)
1914 function_symbol (operands[3],
1915 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1919 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1920 else if (TARGET_FPU_ANY)
1921 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1923 last = gen_udivsi3_i1 (operands[0], operands[3]);
1927 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1928 last = gen_udivsi3_i1 (operands[0], operands[3]);
1930 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1931 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1936 (define_insn "divsi3_sh2a"
1937 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1938 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1939 (match_operand:SI 2 "arith_reg_operand" "z")))]
1942 [(set_attr "type" "arith")
1943 (set_attr "in_delay_slot" "no")])
1945 (define_insn "divsi3_i1"
1946 [(set (match_operand:SI 0 "register_operand" "=z")
1947 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1948 (clobber (reg:SI T_REG))
1949 (clobber (reg:SI PR_REG))
1950 (clobber (reg:SI R1_REG))
1951 (clobber (reg:SI R2_REG))
1952 (clobber (reg:SI R3_REG))
1953 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1954 "TARGET_SH1 && ! TARGET_SH4"
1956 [(set_attr "type" "sfunc")
1957 (set_attr "needs_delay_slot" "yes")])
1959 (define_insn "divsi3_i1_media"
1960 [(set (match_operand:SI 0 "register_operand" "=z")
1961 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1962 (clobber (reg:SI T_MEDIA_REG))
1963 (clobber (reg:SI PR_MEDIA_REG))
1964 (clobber (reg:SI R1_REG))
1965 (clobber (reg:SI R20_REG))
1966 (clobber (reg:SI R21_REG))
1967 (clobber (reg:SI TR0_REG))
1968 (use (match_operand 1 "target_reg_operand" "b"))]
1969 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1971 [(set_attr "type" "sfunc")])
1973 (define_insn "divsi3_media_2"
1974 [(set (match_operand:SI 0 "register_operand" "=z")
1975 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1976 (clobber (reg:SI T_MEDIA_REG))
1977 (clobber (reg:SI PR_MEDIA_REG))
1978 (clobber (reg:SI R1_REG))
1979 (clobber (reg:SI R21_REG))
1980 (clobber (reg:SI TR0_REG))
1981 (use (reg:SI R20_REG))
1982 (use (match_operand 1 "target_reg_operand" "b"))]
1983 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1985 [(set_attr "type" "sfunc")])
1987 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1988 ;; hard reg clobbers and data dependencies that we need when we want
1989 ;; to rematerialize the division into a call.
1990 (define_insn_and_split "divsi_inv_call"
1991 [(set (match_operand:SI 0 "register_operand" "=r")
1992 (div:SI (match_operand:SI 1 "register_operand" "r")
1993 (match_operand:SI 2 "register_operand" "r")))
1994 (clobber (reg:SI R4_REG))
1995 (clobber (reg:SI R5_REG))
1996 (clobber (reg:SI T_MEDIA_REG))
1997 (clobber (reg:SI PR_MEDIA_REG))
1998 (clobber (reg:SI R1_REG))
1999 (clobber (reg:SI R21_REG))
2000 (clobber (reg:SI TR0_REG))
2001 (clobber (reg:SI R20_REG))
2002 (use (match_operand:SI 3 "register_operand" "r"))]
2005 "&& (high_life_started || reload_completed)"
2006 [(set (match_dup 0) (match_dup 3))]
2008 [(set_attr "highpart" "must_split")])
2010 ;; This is the combiner pattern for -mdiv=inv:call .
2011 (define_insn_and_split "*divsi_inv_call_combine"
2012 [(set (match_operand:SI 0 "register_operand" "=z")
2013 (div:SI (match_operand:SI 1 "register_operand" "r")
2014 (match_operand:SI 2 "register_operand" "r")))
2015 (clobber (reg:SI R4_REG))
2016 (clobber (reg:SI R5_REG))
2017 (clobber (reg:SI T_MEDIA_REG))
2018 (clobber (reg:SI PR_MEDIA_REG))
2019 (clobber (reg:SI R1_REG))
2020 (clobber (reg:SI R21_REG))
2021 (clobber (reg:SI TR0_REG))
2022 (clobber (reg:SI R20_REG))
2023 (use (unspec:SI [(match_dup 1)
2024 (match_operand:SI 3 "" "")
2025 (unspec:SI [(match_operand:SI 4 "" "")
2027 (match_operand:DI 5 "" "")]
2029 (match_operand:DI 6 "" "")
2032 UNSPEC_DIV_INV_M3))]
2035 "&& (high_life_started || reload_completed)"
2039 const char *name = sh_divsi3_libfunc;
2040 enum sh_function_kind kind = SFUNC_GOT;
2043 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2044 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2045 while (TARGET_DIVIDE_INV_CALL2)
2047 rtx x = operands[3];
2049 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2051 x = XVECEXP (x, 0, 0);
2052 name = \"__sdivsi3_2\";
2053 kind = SFUNC_STATIC;
2054 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2057 sym = function_symbol (NULL, name, kind);
2058 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2061 [(set_attr "highpart" "must_split")])
2063 (define_expand "divsi3_i4_media"
2064 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2065 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2066 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2067 (set (match_operand:SI 0 "register_operand" "=r")
2068 (fix:SI (match_dup 5)))]
2069 "TARGET_SHMEDIA_FPU"
2072 operands[3] = gen_reg_rtx (DFmode);
2073 operands[4] = gen_reg_rtx (DFmode);
2074 operands[5] = gen_reg_rtx (DFmode);
2077 (define_insn "divsi3_i4"
2078 [(set (match_operand:SI 0 "register_operand" "=y")
2079 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2080 (clobber (reg:SI PR_REG))
2081 (clobber (reg:DF DR0_REG))
2082 (clobber (reg:DF DR2_REG))
2083 (use (reg:PSI FPSCR_REG))
2084 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2085 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2087 [(set_attr "type" "sfunc")
2088 (set_attr "fp_mode" "double")
2089 (set_attr "needs_delay_slot" "yes")])
2091 (define_insn "divsi3_i4_single"
2092 [(set (match_operand:SI 0 "register_operand" "=y")
2093 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2094 (clobber (reg:SI PR_REG))
2095 (clobber (reg:DF DR0_REG))
2096 (clobber (reg:DF DR2_REG))
2097 (clobber (reg:SI R2_REG))
2098 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2099 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2101 [(set_attr "type" "sfunc")
2102 (set_attr "needs_delay_slot" "yes")])
2104 (define_insn "divsi3_i4_int"
2105 [(set (match_operand:SI 0 "register_operand" "=z")
2106 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2107 (clobber (reg:SI T_REG))
2108 (clobber (reg:SI PR_REG))
2109 (clobber (reg:SI R1_REG))
2110 (clobber (reg:SI MACH_REG))
2111 (clobber (reg:SI MACL_REG))
2112 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2115 [(set_attr "type" "sfunc")
2116 (set_attr "needs_delay_slot" "yes")])
2118 (define_expand "divsi3"
2119 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2120 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2121 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2122 (parallel [(set (match_operand:SI 0 "register_operand" "")
2123 (div:SI (reg:SI R4_REG)
2125 (clobber (reg:SI T_REG))
2126 (clobber (reg:SI PR_REG))
2127 (clobber (reg:SI R1_REG))
2128 (clobber (reg:SI R2_REG))
2129 (clobber (reg:SI R3_REG))
2130 (use (match_dup 3))])]
2136 operands[3] = gen_reg_rtx (Pmode);
2137 /* Emit the move of the address to a pseudo outside of the libcall. */
2138 if (TARGET_DIVIDE_CALL_TABLE)
2140 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2141 last = gen_divsi3_i4_int (operands[0], operands[3]);
2143 else if (TARGET_DIVIDE_CALL_FP)
2145 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2146 if (TARGET_FPU_SINGLE)
2147 last = gen_divsi3_i4_single (operands[0], operands[3]);
2149 last = gen_divsi3_i4 (operands[0], operands[3]);
2151 else if (TARGET_SH2A)
2153 operands[1] = force_reg (SImode, operands[1]);
2154 operands[2] = force_reg (SImode, operands[2]);
2155 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2158 else if (TARGET_DIVIDE_INV)
2160 rtx dividend = operands[1];
2161 rtx divisor = operands[2];
2163 rtx nsb_res = gen_reg_rtx (DImode);
2164 rtx norm64 = gen_reg_rtx (DImode);
2165 rtx tab_ix = gen_reg_rtx (DImode);
2166 rtx norm32 = gen_reg_rtx (SImode);
2167 rtx i92 = force_reg (DImode, GEN_INT (92));
2168 rtx scratch0a = gen_reg_rtx (DImode);
2169 rtx scratch0b = gen_reg_rtx (DImode);
2170 rtx inv0 = gen_reg_rtx (SImode);
2171 rtx scratch1a = gen_reg_rtx (DImode);
2172 rtx scratch1b = gen_reg_rtx (DImode);
2173 rtx shift = gen_reg_rtx (DImode);
2175 rtx inv1 = gen_reg_rtx (SImode);
2176 rtx scratch2a = gen_reg_rtx (DImode);
2177 rtx scratch2b = gen_reg_rtx (SImode);
2178 rtx inv2 = gen_reg_rtx (SImode);
2179 rtx scratch3a = gen_reg_rtx (DImode);
2180 rtx scratch3b = gen_reg_rtx (DImode);
2181 rtx scratch3c = gen_reg_rtx (DImode);
2182 rtx scratch3d = gen_reg_rtx (SImode);
2183 rtx scratch3e = gen_reg_rtx (DImode);
2184 rtx result = gen_reg_rtx (SImode);
2186 if (! arith_reg_or_0_operand (dividend, SImode))
2187 dividend = force_reg (SImode, dividend);
2188 if (! arith_reg_operand (divisor, SImode))
2189 divisor = force_reg (SImode, divisor);
2190 if (flag_pic && Pmode != DImode)
2192 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2193 tab_base = gen_datalabel_ref (tab_base);
2194 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2198 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2199 tab_base = gen_datalabel_ref (tab_base);
2200 tab_base = force_reg (DImode, tab_base);
2202 if (TARGET_DIVIDE_INV20U)
2203 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2205 i2p27 = GEN_INT (0);
2206 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2207 i43 = force_reg (DImode, GEN_INT (43));
2210 emit_insn (gen_nsbdi (nsb_res,
2211 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2212 emit_insn (gen_ashldi3_media (norm64,
2213 gen_rtx_SUBREG (DImode, divisor, 0),
2215 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2216 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2217 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2218 inv0, scratch0a, scratch0b,
2219 scratch1a, scratch1b));
2220 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2221 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2223 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2225 scratch3a, scratch3b, scratch3c,
2226 scratch2a, scratch2b, scratch3d, scratch3e));
2227 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2228 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2229 else if (TARGET_DIVIDE_INV_FP)
2230 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2231 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2232 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2233 gen_reg_rtx (DFmode)));
2235 emit_move_insn (operands[0], result);
2238 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2240 operands[1] = force_reg (SImode, operands[1]);
2241 operands[2] = force_reg (SImode, operands[2]);
2242 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2245 else if (TARGET_SH5)
2247 if (TARGET_DIVIDE_CALL2)
2249 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2250 tab_base = gen_datalabel_ref (tab_base);
2251 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2253 if (TARGET_FPU_ANY && TARGET_SH1)
2254 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2255 else if (TARGET_DIVIDE_CALL2)
2256 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2258 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2261 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2262 (operands[0], operands[3]));
2263 else if (TARGET_FPU_ANY)
2264 last = gen_divsi3_i4_single (operands[0], operands[3]);
2266 last = gen_divsi3_i1 (operands[0], operands[3]);
2270 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2271 last = gen_divsi3_i1 (operands[0], operands[3]);
2273 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2274 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2279 ;; operands: scratch, tab_base, tab_ix
2280 ;; These are unspecs because we could generate an indexed addressing mode
2281 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2282 ;; confuse reload. See PR27117.
2284 (define_insn "divsi_inv_qitable"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2287 (match_operand:DI 2 "register_operand" "r")]
2288 UNSPEC_DIV_INV_TABLE)))]
2292 [(set_attr "type" "load_media")
2293 (set_attr "highpart" "user")])
2295 ;; operands: scratch, tab_base, tab_ix
2296 (define_insn "divsi_inv_hitable"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2299 (match_operand:DI 2 "register_operand" "r")]
2300 UNSPEC_DIV_INV_TABLE)))]
2304 [(set_attr "type" "load_media")
2305 (set_attr "highpart" "user")])
2307 ;; operands: inv0, tab_base, tab_ix, norm32
2308 ;; scratch equiv in sdivsi3_2: r19, r21
2309 (define_expand "divsi_inv_m0"
2310 [(set (match_operand:SI 0 "register_operand" "=r")
2311 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2312 (match_operand:DI 2 "register_operand" "r")
2313 (match_operand:SI 3 "register_operand" "r")]
2315 (clobber (match_operand:DI 4 "register_operand" "=r"))
2316 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2324 ldx.ub r20, r21, r19 // u0.8
2326 muls.l r25, r19, r19 // s2.38
2327 ldx.w r20, r21, r21 // s2.14
2328 shari r19, 24, r19 // truncate to s2.14
2329 sub r21, r19, r19 // some 11 bit inverse in s1.14
2332 rtx inv0 = operands[0];
2333 rtx tab_base = operands[1];
2334 rtx tab_ix = operands[2];
2335 rtx norm32 = operands[3];
2336 rtx scratch0 = operands[4];
2337 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2338 rtx scratch1 = operands[5];
2340 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2341 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2342 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2343 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2344 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2345 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2349 ;; operands: inv1, tab_base, tab_ix, norm32
2350 (define_insn_and_split "divsi_inv_m1"
2351 [(set (match_operand:SI 0 "register_operand" "=r")
2352 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2353 (match_operand:DI 2 "register_operand" "r")
2354 (match_operand:SI 3 "register_operand" "r")]
2356 (clobber (match_operand:SI 4 "register_operand" "=r"))
2357 (clobber (match_operand:DI 5 "register_operand" "=r"))
2358 (clobber (match_operand:DI 6 "register_operand" "=r"))
2359 (clobber (match_operand:DI 7 "register_operand" "=r"))
2360 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2363 "&& !can_create_pseudo_p ()"
2368 muls.l r19, r19, r18 // u0.28
2369 muls.l r25, r18, r18 // s2.58
2370 shlli r19, 45, r0 // multiply by two and convert to s2.58
2372 shari r18, 28, r18 // some 18 bit inverse in s1.30
2375 rtx inv1 = operands[0];
2376 rtx tab_base = operands[1];
2377 rtx tab_ix = operands[2];
2378 rtx norm32 = operands[3];
2379 rtx inv0 = operands[4];
2380 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2381 rtx scratch0a = operands[5];
2382 rtx scratch0b = operands[6];
2383 rtx scratch0 = operands[7];
2384 rtx scratch1 = operands[8];
2385 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2387 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2388 scratch0a, scratch0b));
2389 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2390 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2391 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2392 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2393 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2397 ;; operands: inv2, norm32, inv1, i92
2398 (define_insn_and_split "divsi_inv_m2"
2399 [(set (match_operand:SI 0 "register_operand" "=r")
2400 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2401 (match_operand:SI 2 "register_operand" "r")
2402 (match_operand:DI 3 "register_operand" "r")]
2404 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2407 "&& !can_create_pseudo_p ()"
2412 muls.l r18, r25, r0 // s2.60
2413 shari r0, 16, r0 // s-16.44
2415 muls.l r0, r18, r19 // s-16.74
2416 shari r19, 30, r19 // s-16.44
2418 rtx inv2 = operands[0];
2419 rtx norm32 = operands[1];
2420 rtx inv1 = operands[2];
2421 rtx i92 = operands[3];
2422 rtx scratch0 = operands[4];
2423 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2425 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2426 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2427 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2428 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2429 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2433 (define_insn_and_split "divsi_inv_m3"
2434 [(set (match_operand:SI 0 "register_operand" "=r")
2435 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2436 (match_operand:SI 2 "register_operand" "r")
2437 (match_operand:SI 3 "register_operand" "r")
2438 (match_operand:DI 4 "register_operand" "r")
2439 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2440 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2442 (clobber (match_operand:DI 7 "register_operand" "=r"))
2443 (clobber (match_operand:DI 8 "register_operand" "=r"))
2444 (clobber (match_operand:DI 9 "register_operand" "=r"))
2445 (clobber (match_operand:DI 10 "register_operand" "=r"))
2446 (clobber (match_operand:SI 11 "register_operand" "=r"))
2447 (clobber (match_operand:SI 12 "register_operand" "=r"))
2448 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2451 "&& !can_create_pseudo_p ()"
2456 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2457 r0: scratch0 r19: scratch1 r21: scratch2
2459 muls.l r18, r4, r25 // s32.30
2460 muls.l r19, r4, r19 // s15.30
2462 shari r19, 14, r19 // s18.-14
2468 rtx result = operands[0];
2469 rtx dividend = operands[1];
2470 rtx inv1 = operands[2];
2471 rtx inv2 = operands[3];
2472 rtx shift = operands[4];
2473 rtx scratch0 = operands[7];
2474 rtx scratch1 = operands[8];
2475 rtx scratch2 = operands[9];
2477 if (satisfies_constraint_N (dividend))
2479 emit_move_insn (result, dividend);
2483 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2484 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2485 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2486 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2487 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2488 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2489 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2493 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2494 ;; inv1: tab_base, tab_ix, norm32
2495 ;; inv2: norm32, inv1, i92
2496 (define_insn_and_split "divsi_inv_m1_3"
2497 [(set (match_operand:SI 0 "register_operand" "=r")
2498 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2499 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2500 (match_operand:DI 3 "register_operand" "r")
2501 (match_operand:SI 4 "register_operand" "r")]
2503 (unspec:SI [(match_dup 4)
2504 (unspec:SI [(match_dup 2)
2506 (match_dup 4)] UNSPEC_DIV_INV_M1)
2507 (match_operand:SI 5 "" "")]
2509 (match_operand:DI 6 "register_operand" "r")
2510 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2511 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2513 (clobber (match_operand:DI 9 "register_operand" "=r"))
2514 (clobber (match_operand:DI 10 "register_operand" "=r"))
2515 (clobber (match_operand:DI 11 "register_operand" "=r"))
2516 (clobber (match_operand:DI 12 "register_operand" "=r"))
2517 (clobber (match_operand:SI 13 "register_operand" "=r"))
2518 (clobber (match_operand:SI 14 "register_operand" "=r"))
2519 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2521 && (TARGET_DIVIDE_INV_MINLAT
2522 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2524 "&& !can_create_pseudo_p ()"
2528 rtx result = operands[0];
2529 rtx dividend = operands[1];
2530 rtx tab_base = operands[2];
2531 rtx tab_ix = operands[3];
2532 rtx norm32 = operands[4];
2533 /* rtx i92 = operands[5]; */
2534 rtx shift = operands[6];
2535 rtx i2p27 = operands[7];
2536 rtx i43 = operands[8];
2537 rtx scratch0 = operands[9];
2538 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2539 rtx scratch1 = operands[10];
2540 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2541 rtx scratch2 = operands[11];
2542 rtx scratch3 = operands[12];
2543 rtx scratch4 = operands[13];
2544 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2545 rtx scratch5 = operands[14];
2546 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2547 rtx scratch6 = operands[15];
2549 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2550 scratch0, scratch1));
2551 /* inv0 == scratch4 */
2552 if (! TARGET_DIVIDE_INV20U)
2554 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2556 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2560 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2561 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2563 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2564 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2565 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2566 /* inv1 == scratch4 */
2568 if (TARGET_DIVIDE_INV_MINLAT)
2570 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2571 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2572 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2573 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2574 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2575 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2576 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2577 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2578 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2579 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2580 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2584 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2585 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2586 emit_insn (gen_nsbdi (scratch6,
2587 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2588 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2589 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2590 emit_insn (gen_divsi_inv20 (scratch2,
2591 norm32, scratch4, dividend,
2592 scratch6, scratch3, i43,
2593 /* scratch0 may be shared with i2p27. */
2594 scratch0, scratch1, scratch5,
2595 label, label, i2p27));
2597 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2598 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2602 (define_insn "divsi_inv20"
2603 [(set (match_operand:DI 0 "register_operand" "=&r")
2604 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2605 (match_operand:SI 2 "register_operand" "r")
2606 (match_operand:SI 3 "register_operand" "r")
2607 (match_operand:DI 4 "register_operand" "r")
2608 (match_operand:DI 5 "register_operand" "r")
2609 (match_operand:DI 6 "register_operand" "r")
2610 (match_operand:DI 12 "register_operand" "r")
2611 (match_operand 10 "target_operand" "b")
2612 (match_operand 11 "immediate_operand" "i")]
2614 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2615 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2616 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2618 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2621 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2622 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2623 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2624 %10 label (tr), %11 label (imm)
2626 muls.l inv1, norm32, scratch0 // s2.60
2627 muls.l inv1, dividend, result // s32.30
2628 xor i2p27, result_sign, round_scratch
2629 bge/u dividend_nsb, i43, tr.. (label)
2630 shari scratch0, 16, scratch0 // s-16.44
2631 muls.l sratch0_si, inv1, scratch0 // s-16.74
2632 sub result, round_scratch, result
2633 shari dividend, 14, scratch1 // s19.-14
2634 shari scratch0, 30, scratch0 // s-16.44
2635 muls.l scratch0, scratch1, round_scratch // s15.30
2637 sub result, round_scratch, result */
2639 int likely = TARGET_DIVIDE_INV20L;
2641 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2642 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2643 output_asm_insn (likely
2644 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2645 : \"bge/u\t%4, %6, %10\", operands);
2646 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2647 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2648 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2650 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2651 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2654 (define_insn_and_split "divsi_inv_fp"
2655 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2656 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2657 (match_operand:SI 2 "register_operand" "rf")))
2658 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2659 (clobber (match_operand:SI 4 "register_operand" "=r"))
2660 (clobber (match_operand:SI 5 "register_operand" "=r"))
2661 (clobber (match_operand:DF 6 "register_operand" "=r"))
2662 (clobber (match_operand:DF 7 "register_operand" "=r"))
2663 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2664 "TARGET_SHMEDIA_FPU"
2666 "&& (high_life_started || reload_completed)"
2667 [(set (match_dup 0) (match_dup 3))]
2669 [(set_attr "highpart" "must_split")])
2671 ;; If a matching group of divide-by-inverse instructions is in the same
2672 ;; basic block after gcse & loop optimizations, we want to transform them
2673 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2674 (define_insn_and_split "*divsi_inv_fp_combine"
2675 [(set (match_operand:SI 0 "register_operand" "=f")
2676 (div:SI (match_operand:SI 1 "register_operand" "f")
2677 (match_operand:SI 2 "register_operand" "f")))
2678 (use (unspec:SI [(match_dup 1)
2679 (match_operand:SI 3 "" "")
2680 (unspec:SI [(match_operand:SI 4 "" "")
2682 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2683 (match_operand:DI 6 "" "")
2685 (const_int 0)] UNSPEC_DIV_INV_M3))
2686 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2687 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2688 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2689 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2690 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2691 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2694 [(set (match_dup 9) (float:DF (match_dup 1)))
2695 (set (match_dup 10) (float:DF (match_dup 2)))
2696 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2698 (fix:SI (match_dup 11)))
2699 (set (match_dup 0) (match_dup 8))]
2702 if (! fp_arith_reg_operand (operands[1], SImode))
2704 emit_move_insn (operands[7], operands[1]);
2705 operands[1] = operands[7];
2707 if (! fp_arith_reg_operand (operands[2], SImode))
2709 emit_move_insn (operands[8], operands[2]);
2710 operands[2] = operands[8];
2713 [(set_attr "highpart" "must_split")])
2715 ;; -------------------------------------------------------------------------
2716 ;; Multiplication instructions
2717 ;; -------------------------------------------------------------------------
2719 (define_insn "umulhisi3_i"
2720 [(set (reg:SI MACL_REG)
2721 (mult:SI (zero_extend:SI
2722 (match_operand:HI 0 "arith_reg_operand" "r"))
2724 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2727 [(set_attr "type" "smpy")])
2729 (define_insn "mulhisi3_i"
2730 [(set (reg:SI MACL_REG)
2731 (mult:SI (sign_extend:SI
2732 (match_operand:HI 0 "arith_reg_operand" "r"))
2734 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2737 [(set_attr "type" "smpy")])
2739 (define_expand "mulhisi3"
2740 [(set (reg:SI MACL_REG)
2741 (mult:SI (sign_extend:SI
2742 (match_operand:HI 1 "arith_reg_operand" ""))
2744 (match_operand:HI 2 "arith_reg_operand" ""))))
2745 (set (match_operand:SI 0 "arith_reg_operand" "")
2752 macl = gen_rtx_REG (SImode, MACL_REG);
2754 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2755 insn = get_insns ();
2757 /* expand_binop can't find a suitable code in umul_widen_optab to
2758 make a REG_EQUAL note from, so make one here.
2759 See also smulsi3_highpart.
2760 ??? Alternatively, we could put this at the calling site of expand_binop,
2761 i.e. expand_expr. */
2762 /* Use emit_libcall_block for loop invariant code motion and to make
2763 a REG_EQUAL note. */
2764 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2769 (define_expand "umulhisi3"
2770 [(set (reg:SI MACL_REG)
2771 (mult:SI (zero_extend:SI
2772 (match_operand:HI 1 "arith_reg_operand" ""))
2774 (match_operand:HI 2 "arith_reg_operand" ""))))
2775 (set (match_operand:SI 0 "arith_reg_operand" "")
2782 macl = gen_rtx_REG (SImode, MACL_REG);
2784 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2785 insn = get_insns ();
2787 /* expand_binop can't find a suitable code in umul_widen_optab to
2788 make a REG_EQUAL note from, so make one here.
2789 See also smulsi3_highpart.
2790 ??? Alternatively, we could put this at the calling site of expand_binop,
2791 i.e. expand_expr. */
2792 /* Use emit_libcall_block for loop invariant code motion and to make
2793 a REG_EQUAL note. */
2794 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2799 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2800 ;; a call to a routine which clobbers known registers.
2803 [(set (match_operand:SI 1 "register_operand" "=z")
2804 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2805 (clobber (reg:SI MACL_REG))
2806 (clobber (reg:SI T_REG))
2807 (clobber (reg:SI PR_REG))
2808 (clobber (reg:SI R3_REG))
2809 (clobber (reg:SI R2_REG))
2810 (clobber (reg:SI R1_REG))
2811 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2814 [(set_attr "type" "sfunc")
2815 (set_attr "needs_delay_slot" "yes")])
2817 (define_expand "mulsi3_call"
2818 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2819 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2820 (parallel[(set (match_operand:SI 0 "register_operand" "")
2821 (mult:SI (reg:SI R4_REG)
2823 (clobber (reg:SI MACL_REG))
2824 (clobber (reg:SI T_REG))
2825 (clobber (reg:SI PR_REG))
2826 (clobber (reg:SI R3_REG))
2827 (clobber (reg:SI R2_REG))
2828 (clobber (reg:SI R1_REG))
2829 (use (match_operand:SI 3 "register_operand" ""))])]
2833 (define_insn "mul_r"
2834 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2835 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2836 (match_operand:SI 2 "arith_reg_operand" "z")))]
2839 [(set_attr "type" "dmpy")])
2841 (define_insn "mul_l"
2842 [(set (reg:SI MACL_REG)
2843 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2844 (match_operand:SI 1 "arith_reg_operand" "r")))]
2847 [(set_attr "type" "dmpy")])
2849 (define_expand "mulsi3"
2850 [(set (reg:SI MACL_REG)
2851 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2852 (match_operand:SI 2 "arith_reg_operand" "")))
2853 (set (match_operand:SI 0 "arith_reg_operand" "")
2860 /* The address must be set outside the libcall,
2861 since it goes into a pseudo. */
2862 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2863 rtx addr = force_reg (SImode, sym);
2864 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2870 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2872 emit_insn (gen_mul_l (operands[1], operands[2]));
2873 /* consec_sets_giv can only recognize the first insn that sets a
2874 giv as the giv insn. So we must tag this also with a REG_EQUAL
2876 emit_insn (gen_movsi_i ((operands[0]), macl));
2881 (define_insn "mulsidi3_i"
2882 [(set (reg:SI MACH_REG)
2886 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2887 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2889 (set (reg:SI MACL_REG)
2890 (mult:SI (match_dup 0)
2894 [(set_attr "type" "dmpy")])
2896 (define_expand "mulsidi3"
2897 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2898 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2899 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2900 "TARGET_SH2 || TARGET_SHMEDIA"
2905 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2911 (define_insn "mulsidi3_media"
2912 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2914 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2917 [(set_attr "type" "dmpy_media")
2918 (set_attr "highpart" "ignore")])
2920 (define_insn "mulsidi3_compact"
2921 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2923 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2924 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2925 (clobber (reg:SI MACH_REG))
2926 (clobber (reg:SI MACL_REG))]
2931 [(set (match_operand:DI 0 "arith_reg_dest" "")
2933 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2934 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2935 (clobber (reg:SI MACH_REG))
2936 (clobber (reg:SI MACL_REG))]
2941 rtx low_dst = gen_lowpart (SImode, operands[0]);
2942 rtx high_dst = gen_highpart (SImode, operands[0]);
2944 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2946 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2947 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2948 /* We need something to tag the possible REG_EQUAL notes on to. */
2949 emit_move_insn (operands[0], operands[0]);
2953 (define_insn "umulsidi3_i"
2954 [(set (reg:SI MACH_REG)
2958 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2959 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2961 (set (reg:SI MACL_REG)
2962 (mult:SI (match_dup 0)
2966 [(set_attr "type" "dmpy")])
2968 (define_expand "umulsidi3"
2969 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2970 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2971 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2972 "TARGET_SH2 || TARGET_SHMEDIA"
2977 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2983 (define_insn "umulsidi3_media"
2984 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2986 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2989 [(set_attr "type" "dmpy_media")
2990 (set_attr "highpart" "ignore")])
2992 (define_insn "umulsidi3_compact"
2993 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2995 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2996 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2997 (clobber (reg:SI MACH_REG))
2998 (clobber (reg:SI MACL_REG))]
3003 [(set (match_operand:DI 0 "arith_reg_dest" "")
3004 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3005 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3006 (clobber (reg:SI MACH_REG))
3007 (clobber (reg:SI MACL_REG))]
3012 rtx low_dst = gen_lowpart (SImode, operands[0]);
3013 rtx high_dst = gen_highpart (SImode, operands[0]);
3015 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3017 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3018 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3019 /* We need something to tag the possible REG_EQUAL notes on to. */
3020 emit_move_insn (operands[0], operands[0]);
3024 (define_insn "smulsi3_highpart_i"
3025 [(set (reg:SI MACH_REG)
3029 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3030 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3032 (clobber (reg:SI MACL_REG))]
3035 [(set_attr "type" "dmpy")])
3037 (define_expand "smulsi3_highpart"
3039 [(set (reg:SI MACH_REG)
3043 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3044 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3046 (clobber (reg:SI MACL_REG))])
3047 (set (match_operand:SI 0 "arith_reg_operand" "")
3054 mach = gen_rtx_REG (SImode, MACH_REG);
3056 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3057 insn = get_insns ();
3059 /* expand_binop can't find a suitable code in mul_highpart_optab to
3060 make a REG_EQUAL note from, so make one here.
3061 See also {,u}mulhisi.
3062 ??? Alternatively, we could put this at the calling site of expand_binop,
3063 i.e. expand_mult_highpart. */
3064 /* Use emit_libcall_block for loop invariant code motion and to make
3065 a REG_EQUAL note. */
3066 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3071 (define_insn "umulsi3_highpart_i"
3072 [(set (reg:SI MACH_REG)
3076 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3077 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3079 (clobber (reg:SI MACL_REG))]
3082 [(set_attr "type" "dmpy")])
3084 (define_expand "umulsi3_highpart"
3086 [(set (reg:SI MACH_REG)
3090 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3091 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3093 (clobber (reg:SI MACL_REG))])
3094 (set (match_operand:SI 0 "arith_reg_operand" "")
3101 mach = gen_rtx_REG (SImode, MACH_REG);
3103 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3104 insn = get_insns ();
3106 /* Use emit_libcall_block for loop invariant code motion and to make
3107 a REG_EQUAL note. */
3108 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3113 (define_insn_and_split "muldi3"
3114 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3115 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3116 (match_operand:DI 2 "arith_reg_operand" "r")))
3117 (clobber (match_scratch:DI 3 "=&r"))
3118 (clobber (match_scratch:DI 4 "=r"))]
3125 rtx op3_v2si, op2_v2si;
3127 op3_v2si = operands[3];
3128 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3130 op3_v2si = XEXP (op3_v2si, 0);
3131 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3133 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3134 op2_v2si = operands[2];
3135 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3137 op2_v2si = XEXP (op2_v2si, 0);
3138 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3140 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3141 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3142 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3143 emit_insn (gen_umulsidi3_media (operands[4],
3144 sh_gen_truncate (SImode, operands[1], 0),
3145 sh_gen_truncate (SImode, operands[2], 0)));
3146 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3147 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3148 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3149 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3154 ;; -------------------------------------------------------------------------
3155 ;; Logical operations
3156 ;; -------------------------------------------------------------------------
3158 (define_insn "*andsi3_compact"
3159 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3160 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3161 (match_operand:SI 2 "logical_operand" "r,K08")))]
3164 [(set_attr "type" "arith")])
3166 (define_insn "*andsi3_media"
3167 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3168 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3169 (match_operand:SI 2 "logical_operand" "r,I10")))]
3174 [(set_attr "type" "arith_media")])
3176 (define_insn "*andsi3_bclr"
3177 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3178 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3179 (match_operand:SI 2 "const_int_operand" "Psz")))]
3180 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3182 [(set_attr "type" "arith")])
3184 ;; If the constant is 255, then emit an extu.b instruction instead of an
3185 ;; and, since that will give better code.
3187 (define_expand "andsi3"
3188 [(set (match_operand:SI 0 "arith_reg_operand" "")
3189 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3190 (match_operand:SI 2 "logical_operand" "")))]
3195 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3197 emit_insn (gen_zero_extendqisi2 (operands[0],
3198 gen_lowpart (QImode, operands[1])));
3203 (define_insn_and_split "anddi3"
3204 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3205 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3206 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3213 && ! logical_operand (operands[2], DImode)"
3217 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3218 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3220 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3223 [(set_attr "type" "arith_media")])
3225 (define_insn "andcsi3"
3226 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3227 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3228 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3231 [(set_attr "type" "arith_media")])
3233 (define_insn "andcdi3"
3234 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3239 [(set_attr "type" "arith_media")])
3241 (define_expand "iorsi3"
3242 [(set (match_operand:SI 0 "arith_reg_operand" "")
3243 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3244 (match_operand:SI 2 "logical_operand" "")))]
3248 (define_insn "*iorsi3_compact"
3249 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3250 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3251 (match_operand:SI 2 "logical_operand" "r,K08")))]
3253 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3255 [(set_attr "type" "arith")])
3257 (define_insn "*iorsi3_media"
3258 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3259 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3260 (match_operand:SI 2 "logical_operand" "r,I10")))]
3265 [(set_attr "type" "arith_media")])
3267 (define_insn "*iorsi3_bset"
3268 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3269 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3270 (match_operand:SI 2 "const_int_operand" "Pso")))]
3271 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3273 [(set_attr "type" "arith")])
3275 (define_insn "iordi3"
3276 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3277 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3278 (match_operand:DI 2 "logical_operand" "r,I10")))]
3283 [(set_attr "type" "arith_media")])
3285 (define_insn_and_split "*logical_sidi3"
3286 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3287 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3288 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3289 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3292 "&& reload_completed"
3293 [(set (match_dup 0) (match_dup 3))]
3297 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3298 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3299 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3302 (define_insn_and_split "*logical_sidisi3"
3303 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3304 (truncate:SI (sign_extend:DI
3305 (match_operator:SI 3 "logical_operator"
3306 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3307 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3311 [(set (match_dup 0) (match_dup 3))])
3313 (define_insn_and_split "*logical_sidi3_2"
3314 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3315 (sign_extend:DI (truncate:SI (sign_extend:DI
3316 (match_operator:SI 3 "logical_operator"
3317 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3318 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3322 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3324 (define_expand "xorsi3"
3325 [(set (match_operand:SI 0 "arith_reg_operand" "")
3326 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3327 (match_operand:SI 2 "xor_operand" "")))]
3331 (define_insn "*xorsi3_compact"
3332 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3333 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3334 (match_operand:SI 2 "logical_operand" "K08,r")))]
3337 [(set_attr "type" "arith")])
3339 (define_insn "*xorsi3_media"
3340 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3341 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3342 (match_operand:SI 2 "xor_operand" "r,I06")))]
3347 [(set_attr "type" "arith_media")])
3349 ;; Store the complements of the T bit in a register.
3350 (define_insn "xorsi3_movrt"
3351 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3352 (xor:SI (reg:SI T_REG)
3356 [(set_attr "type" "arith")])
3358 (define_insn "xordi3"
3359 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3360 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3361 (match_operand:DI 2 "xor_operand" "r,I06")))]
3366 [(set_attr "type" "arith_media")])
3368 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3369 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3371 [(set (match_operand:DI 0 "arith_reg_dest" "")
3372 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3373 [(match_operand 1 "any_register_operand" "")
3374 (match_operand 2 "any_register_operand" "")])))]
3376 [(set (match_dup 5) (match_dup 4))
3377 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3380 enum machine_mode inmode = GET_MODE (operands[1]);
3383 if (GET_CODE (operands[0]) == SUBREG)
3385 offset = SUBREG_BYTE (operands[0]);
3386 operands[0] = SUBREG_REG (operands[0]);
3388 gcc_assert (GET_CODE (operands[0]) == REG);
3389 if (! TARGET_LITTLE_ENDIAN)
3390 offset += 8 - GET_MODE_SIZE (inmode);
3391 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3394 ;; -------------------------------------------------------------------------
3395 ;; Shifts and rotates
3396 ;; -------------------------------------------------------------------------
3398 (define_expand "rotldi3"
3399 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3400 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3401 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3403 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3405 (define_insn "rotldi3_mextr"
3406 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3407 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3408 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3412 static char templ[16];
3414 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3415 8 - (int) (INTVAL (operands[2]) >> 3));
3418 [(set_attr "type" "arith_media")])
3420 (define_expand "rotrdi3"
3421 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3422 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3423 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3425 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3427 (define_insn "rotrdi3_mextr"
3428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3429 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3430 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3434 static char templ[16];
3436 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3439 [(set_attr "type" "arith_media")])
3442 [(set (match_operand:DI 0 "arith_reg_dest" "")
3443 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3444 "ua_address_operand" "")))
3445 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3447 (clobber (match_operand:DI 3 "register_operand" ""))]
3449 [(match_dup 4) (match_dup 5)]
3452 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3453 (operands[3], operands[1]));
3454 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3455 GEN_INT (56), GEN_INT (8));
3458 (define_insn "rotlsi3_1"
3459 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3460 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3463 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3466 [(set_attr "type" "arith")])
3468 (define_insn "rotlsi3_31"
3469 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3472 (clobber (reg:SI T_REG))]
3475 [(set_attr "type" "arith")])
3477 (define_insn "rotlsi3_16"
3478 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3479 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3483 [(set_attr "type" "arith")])
3485 (define_expand "rotlsi3"
3486 [(set (match_operand:SI 0 "arith_reg_dest" "")
3487 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3488 (match_operand:SI 2 "immediate_operand" "")))]
3492 static const char rot_tab[] = {
3493 000, 000, 000, 000, 000, 000, 010, 001,
3494 001, 001, 011, 013, 003, 003, 003, 003,
3495 003, 003, 003, 003, 003, 013, 012, 002,
3496 002, 002, 010, 000, 000, 000, 000, 000,
3501 if (GET_CODE (operands[2]) != CONST_INT)
3503 count = INTVAL (operands[2]);
3504 choice = rot_tab[count];
3505 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3511 emit_move_insn (operands[0], operands[1]);
3512 count -= (count & 16) * 2;
3515 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3522 parts[0] = gen_reg_rtx (SImode);
3523 parts[1] = gen_reg_rtx (SImode);
3524 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3525 emit_move_insn (parts[choice-1], operands[1]);
3526 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3527 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3528 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3529 count = (count & ~16) - 8;
3533 for (; count > 0; count--)
3534 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3535 for (; count < 0; count++)
3536 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3541 (define_insn "*rotlhi3_8"
3542 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3543 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3547 [(set_attr "type" "arith")])
3549 (define_expand "rotlhi3"
3550 [(set (match_operand:HI 0 "arith_reg_operand" "")
3551 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3552 (match_operand:HI 2 "immediate_operand" "")))]
3556 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3563 (define_insn "ashlsi3_sh2a"
3564 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3565 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3566 (match_operand:SI 2 "arith_reg_operand" "r")))]
3569 [(set_attr "type" "arith")
3570 (set_attr "length" "4")])
3572 ;; This pattern is used by init_expmed for computing the costs of shift
3575 (define_insn_and_split "ashlsi3_std"
3576 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3577 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3578 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3579 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3581 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3589 && GET_CODE (operands[2]) == CONST_INT
3590 && ! satisfies_constraint_P27 (operands[2])"
3591 [(set (match_dup 3) (match_dup 2))
3593 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3594 (clobber (match_dup 4))])]
3595 "operands[4] = gen_rtx_SCRATCH (SImode);"
3596 [(set_attr "length" "*,*,*,4")
3597 (set_attr "type" "dyn_shift,arith,arith,arith")])
3599 (define_insn "ashlhi3_k"
3600 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3601 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3602 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3603 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3607 [(set_attr "type" "arith")])
3609 (define_insn "ashlsi3_n"
3610 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3611 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3612 (match_operand:SI 2 "const_int_operand" "n")))
3613 (clobber (reg:SI T_REG))]
3614 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3616 [(set (attr "length")
3617 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3619 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3621 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3623 (const_string "8")))
3624 (set_attr "type" "arith")])
3627 [(set (match_operand:SI 0 "arith_reg_dest" "")
3628 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3629 (match_operand:SI 2 "const_int_operand" "")))
3630 (clobber (reg:SI T_REG))]
3631 "TARGET_SH1 && reload_completed"
3632 [(use (reg:SI R0_REG))]
3635 gen_shifty_op (ASHIFT, operands);
3639 (define_insn "ashlsi3_media"
3640 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3641 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3642 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3647 [(set_attr "type" "arith_media")
3648 (set_attr "highpart" "ignore")])
3650 (define_expand "ashlsi3"
3651 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3652 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3653 (match_operand:SI 2 "nonmemory_operand" "")))
3654 (clobber (reg:SI T_REG))])]
3660 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3663 if (GET_CODE (operands[2]) == CONST_INT
3664 && sh_dynamicalize_shift_p (operands[2]))
3665 operands[2] = force_reg (SImode, operands[2]);
3668 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3671 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3675 (define_insn "*ashlhi3_n"
3676 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3677 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3678 (match_operand:HI 2 "const_int_operand" "n")))
3679 (clobber (reg:SI T_REG))]
3682 [(set (attr "length")
3683 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3685 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3687 (const_string "6")))
3688 (set_attr "type" "arith")])
3690 (define_expand "ashlhi3"
3691 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3692 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3693 (match_operand:SI 2 "nonmemory_operand" "")))
3694 (clobber (reg:SI T_REG))])]
3698 if (GET_CODE (operands[2]) != CONST_INT)
3700 /* It may be possible to call gen_ashlhi3 directly with more generic
3701 operands. Make sure operands[1] is a HImode register here. */
3702 if (!arith_reg_operand (operands[1], HImode))
3703 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3707 [(set (match_operand:HI 0 "arith_reg_dest" "")
3708 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3709 (match_operand:HI 2 "const_int_operand" "")))
3710 (clobber (reg:SI T_REG))]
3711 "TARGET_SH1 && reload_completed"
3712 [(use (reg:SI R0_REG))]
3715 gen_shifty_hi_op (ASHIFT, operands);
3720 ; arithmetic shift right
3723 (define_insn "ashrsi3_sh2a"
3724 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3725 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3726 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3729 [(set_attr "type" "dyn_shift")
3730 (set_attr "length" "4")])
3732 (define_insn "ashrsi3_k"
3733 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3734 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3735 (match_operand:SI 2 "const_int_operand" "M")))
3736 (clobber (reg:SI T_REG))]
3737 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3739 [(set_attr "type" "arith")])
3741 ;; We can't do HImode right shifts correctly unless we start out with an
3742 ;; explicit zero / sign extension; doing that would result in worse overall
3743 ;; code, so just let the machine independent code widen the mode.
3744 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3747 ;; ??? This should be a define expand.
3749 (define_insn "ashrsi2_16"
3750 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3751 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3755 [(set_attr "length" "4")])
3758 [(set (match_operand:SI 0 "arith_reg_dest" "")
3759 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3762 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3763 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3764 "operands[2] = gen_lowpart (HImode, operands[0]);")
3766 ;; ??? This should be a define expand.
3768 (define_insn "ashrsi2_31"
3769 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3770 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3772 (clobber (reg:SI T_REG))]
3775 [(set_attr "length" "4")])
3778 [(set (match_operand:SI 0 "arith_reg_dest" "")
3779 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3781 (clobber (reg:SI T_REG))]
3786 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3787 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3792 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3794 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3796 && peep2_reg_dead_p (2, operands[0])
3797 && peep2_reg_dead_p (2, operands[1])"
3801 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3805 (define_insn "ashlsi_c"
3806 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3807 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3809 (lt:SI (match_dup 1) (const_int 0)))]
3812 [(set_attr "type" "arith")])
3814 (define_insn "*ashlsi_c_void"
3815 [(set (reg:SI T_REG)
3816 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3817 (clobber (match_scratch:SI 1 "=0"))]
3818 "TARGET_SH1 && cse_not_expected"
3820 [(set_attr "type" "arith")])
3822 (define_insn "ashrsi3_d"
3823 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3824 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3825 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3828 [(set_attr "type" "dyn_shift")])
3830 (define_insn "ashrsi3_n"
3831 [(set (reg:SI R4_REG)
3832 (ashiftrt:SI (reg:SI R4_REG)
3833 (match_operand:SI 0 "const_int_operand" "i")))
3834 (clobber (reg:SI T_REG))
3835 (clobber (reg:SI PR_REG))
3836 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3839 [(set_attr "type" "sfunc")
3840 (set_attr "needs_delay_slot" "yes")])
3842 (define_insn "ashrsi3_media"
3843 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3844 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3845 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3850 [(set_attr "type" "arith_media")
3851 (set_attr "highpart" "ignore")])
3853 (define_expand "ashrsi3"
3854 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3855 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3856 (match_operand:SI 2 "nonmemory_operand" "")))
3857 (clobber (reg:SI T_REG))])]
3863 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3866 if (expand_ashiftrt (operands))
3872 ;; logical shift right
3874 (define_insn "lshrsi3_sh2a"
3875 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3876 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3877 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3880 [(set_attr "type" "dyn_shift")
3881 (set_attr "length" "4")])
3883 (define_insn "lshrsi3_d"
3884 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3885 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3886 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3889 [(set_attr "type" "dyn_shift")])
3891 ;; Only the single bit shift clobbers the T bit.
3893 (define_insn "lshrsi3_m"
3894 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3895 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3896 (match_operand:SI 2 "const_int_operand" "M")))
3897 (clobber (reg:SI T_REG))]
3898 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3900 [(set_attr "type" "arith")])
3902 (define_insn "lshrsi3_k"
3903 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3904 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3905 (match_operand:SI 2 "const_int_operand" "P27")))]
3906 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3907 && ! satisfies_constraint_M (operands[2])"
3909 [(set_attr "type" "arith")])
3911 (define_insn "lshrsi3_n"
3912 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3913 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3914 (match_operand:SI 2 "const_int_operand" "n")))
3915 (clobber (reg:SI T_REG))]
3916 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3918 [(set (attr "length")
3919 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3921 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3923 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3925 (const_string "8")))
3926 (set_attr "type" "arith")])
3929 [(set (match_operand:SI 0 "arith_reg_dest" "")
3930 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3931 (match_operand:SI 2 "const_int_operand" "")))
3932 (clobber (reg:SI T_REG))]
3933 "TARGET_SH1 && reload_completed"
3934 [(use (reg:SI R0_REG))]
3937 gen_shifty_op (LSHIFTRT, operands);
3941 (define_insn "lshrsi3_media"
3942 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3943 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3944 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3949 [(set_attr "type" "arith_media")
3950 (set_attr "highpart" "ignore")])
3952 (define_expand "lshrsi3"
3953 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3954 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3955 (match_operand:SI 2 "nonmemory_operand" "")))
3956 (clobber (reg:SI T_REG))])]
3962 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3965 if (GET_CODE (operands[2]) == CONST_INT
3966 && sh_dynamicalize_shift_p (operands[2]))
3967 operands[2] = force_reg (SImode, operands[2]);
3968 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3970 rtx count = copy_to_mode_reg (SImode, operands[2]);
3971 emit_insn (gen_negsi2 (count, count));
3972 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3975 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3979 ;; ??? This should be a define expand.
3981 (define_insn "ashldi3_k"
3982 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3983 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3985 (clobber (reg:SI T_REG))]
3987 "shll %R0\;rotcl %S0"
3988 [(set_attr "length" "4")
3989 (set_attr "type" "arith")])
3991 (define_insn "ashldi3_media"
3992 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3993 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3994 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3999 [(set_attr "type" "arith_media")])
4001 (define_insn "*ashldisi3_media"
4002 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4003 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004 (match_operand:DI 2 "const_int_operand" "n")))]
4005 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4006 "shlli.l %1, %2, %0"
4007 [(set_attr "type" "arith_media")
4008 (set_attr "highpart" "ignore")])
4010 (define_expand "ashldi3"
4011 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4012 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4013 (match_operand:DI 2 "immediate_operand" "")))
4014 (clobber (reg:SI T_REG))])]
4020 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4023 if (GET_CODE (operands[2]) != CONST_INT
4024 || INTVAL (operands[2]) != 1)
4028 ;; ??? This should be a define expand.
4030 (define_insn "lshrdi3_k"
4031 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4032 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4034 (clobber (reg:SI T_REG))]
4036 "shlr %S0\;rotcr %R0"
4037 [(set_attr "length" "4")
4038 (set_attr "type" "arith")])
4040 (define_insn "lshrdi3_media"
4041 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4042 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4043 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4045 && (arith_reg_dest (operands[0], DImode)
4046 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4050 [(set_attr "type" "arith_media")])
4052 (define_insn "*lshrdisi3_media"
4053 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4054 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4055 (match_operand:DI 2 "const_int_operand" "n")))]
4056 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4057 "shlri.l %1, %2, %0"
4058 [(set_attr "type" "arith_media")
4059 (set_attr "highpart" "ignore")])
4061 (define_expand "lshrdi3"
4062 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4063 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4064 (match_operand:DI 2 "immediate_operand" "")))
4065 (clobber (reg:SI T_REG))])]
4071 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4074 if (GET_CODE (operands[2]) != CONST_INT
4075 || INTVAL (operands[2]) != 1)
4079 ;; ??? This should be a define expand.
4081 (define_insn "ashrdi3_k"
4082 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4083 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4085 (clobber (reg:SI T_REG))]
4087 "shar %S0\;rotcr %R0"
4088 [(set_attr "length" "4")
4089 (set_attr "type" "arith")])
4091 (define_insn "ashrdi3_media"
4092 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4093 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4094 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4096 && (arith_reg_dest (operands[0], DImode)
4097 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4101 [(set_attr "type" "arith_media")])
4103 (define_insn "*ashrdisi3_media"
4104 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4105 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4106 (match_operand:DI 2 "const_int_operand" "n")))]
4107 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4108 "shari.l %1, %2, %0"
4109 [(set_attr "type" "arith_media")
4110 (set_attr "highpart" "ignore")])
4112 (define_insn "ashrdisi3_media_high"
4113 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4115 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4116 (match_operand:DI 2 "const_int_operand" "n"))))]
4117 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4119 [(set_attr "type" "arith_media")])
4121 (define_insn "ashrdisi3_media_opaque"
4122 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4123 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4124 (match_operand:DI 2 "const_int_operand" "n")]
4128 [(set_attr "type" "arith_media")])
4130 (define_expand "ashrdi3"
4131 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4132 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4133 (match_operand:DI 2 "immediate_operand" "")))
4134 (clobber (reg:SI T_REG))])]
4140 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4143 if (GET_CODE (operands[2]) != CONST_INT
4144 || INTVAL (operands[2]) != 1)
4148 ;; combined left/right shift
4151 [(set (match_operand:SI 0 "register_operand" "")
4152 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4153 (match_operand:SI 2 "const_int_operand" ""))
4154 (match_operand:SI 3 "const_int_operand" "")))]
4155 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4156 [(use (reg:SI R0_REG))]
4157 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4161 [(set (match_operand:SI 0 "register_operand" "")
4162 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4163 (match_operand:SI 2 "const_int_operand" ""))
4164 (match_operand:SI 3 "const_int_operand" "")))
4165 (clobber (reg:SI T_REG))]
4166 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4167 [(use (reg:SI R0_REG))]
4168 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4172 [(set (match_operand:SI 0 "register_operand" "=r")
4173 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4174 (match_operand:SI 2 "const_int_operand" "n"))
4175 (match_operand:SI 3 "const_int_operand" "n")))
4176 (clobber (reg:SI T_REG))]
4177 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4179 [(set (attr "length")
4180 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4182 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4184 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4186 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4188 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4190 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4192 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4193 (const_string "16")]
4194 (const_string "18")))
4195 (set_attr "type" "arith")])
4198 [(set (match_operand:SI 0 "register_operand" "=z")
4199 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4200 (match_operand:SI 2 "const_int_operand" "n"))
4201 (match_operand:SI 3 "const_int_operand" "n")))
4202 (clobber (reg:SI T_REG))]
4203 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4205 [(set (attr "length")
4206 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4208 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4210 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4212 (const_string "10")))
4213 (set_attr "type" "arith")])
4215 ;; shift left / and combination with a scratch register: The combine pass
4216 ;; does not accept the individual instructions, even though they are
4217 ;; cheap. But it needs a precise description so that it is usable after
4219 (define_insn "and_shl_scratch"
4220 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4224 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4225 (match_operand:SI 2 "const_int_operand" "N,n"))
4226 (match_operand:SI 3 "" "0,r"))
4227 (match_operand:SI 4 "const_int_operand" "n,n"))
4228 (match_operand:SI 5 "const_int_operand" "n,n")))
4229 (clobber (reg:SI T_REG))]
4232 [(set (attr "length")
4233 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4235 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4237 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4239 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4240 (const_string "10")]
4241 (const_string "12")))
4242 (set_attr "type" "arith")])
4245 [(set (match_operand:SI 0 "register_operand" "")
4249 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4250 (match_operand:SI 2 "const_int_operand" ""))
4251 (match_operand:SI 3 "register_operand" ""))
4252 (match_operand:SI 4 "const_int_operand" ""))
4253 (match_operand:SI 5 "const_int_operand" "")))
4254 (clobber (reg:SI T_REG))]
4256 [(use (reg:SI R0_REG))]
4259 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4261 if (INTVAL (operands[2]))
4263 gen_shifty_op (LSHIFTRT, operands);
4265 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4266 operands[2] = operands[4];
4267 gen_shifty_op (ASHIFT, operands);
4268 if (INTVAL (operands[5]))
4270 operands[2] = operands[5];
4271 gen_shifty_op (LSHIFTRT, operands);
4276 ;; signed left/right shift combination.
4278 [(set (match_operand:SI 0 "register_operand" "")
4280 (ashift:SI (match_operand:SI 1 "register_operand" "")
4281 (match_operand:SI 2 "const_int_operand" ""))
4282 (match_operand:SI 3 "const_int_operand" "")
4284 (clobber (reg:SI T_REG))]
4286 [(use (reg:SI R0_REG))]
4287 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4290 (define_insn "shl_sext_ext"
4291 [(set (match_operand:SI 0 "register_operand" "=r")
4293 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4294 (match_operand:SI 2 "const_int_operand" "n"))
4295 (match_operand:SI 3 "const_int_operand" "n")
4297 (clobber (reg:SI T_REG))]
4298 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4300 [(set (attr "length")
4301 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4303 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4305 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4307 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4309 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4311 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4313 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4315 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4316 (const_string "16")]
4317 (const_string "18")))
4318 (set_attr "type" "arith")])
4320 (define_insn "shl_sext_sub"
4321 [(set (match_operand:SI 0 "register_operand" "=z")
4323 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4324 (match_operand:SI 2 "const_int_operand" "n"))
4325 (match_operand:SI 3 "const_int_operand" "n")
4327 (clobber (reg:SI T_REG))]
4328 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4330 [(set (attr "length")
4331 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4333 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4335 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4337 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4338 (const_string "12")]
4339 (const_string "14")))
4340 (set_attr "type" "arith")])
4342 ;; These patterns are found in expansions of DImode shifts by 16, and
4343 ;; allow the xtrct instruction to be generated from C source.
4345 (define_insn "xtrct_left"
4346 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4347 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4349 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4353 [(set_attr "type" "arith")])
4355 (define_insn "xtrct_right"
4356 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4357 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4359 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4363 [(set_attr "type" "arith")])
4365 ;; -------------------------------------------------------------------------
4367 ;; -------------------------------------------------------------------------
4370 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4371 (neg:SI (plus:SI (reg:SI T_REG)
4372 (match_operand:SI 1 "arith_reg_operand" "r"))))
4374 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4378 [(set_attr "type" "arith")])
4380 (define_insn "*negdi_media"
4381 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4382 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4385 [(set_attr "type" "arith_media")])
4387 (define_expand "negdi2"
4388 [(set (match_operand:DI 0 "arith_reg_operand" "")
4389 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4395 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4396 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4398 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4399 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4401 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4402 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4404 emit_insn (gen_clrt ());
4405 emit_insn (gen_negc (low_dst, low_src));
4406 emit_insn (gen_negc (high_dst, high_src));
4411 (define_insn "negsi2"
4412 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4413 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4416 [(set_attr "type" "arith")])
4418 (define_insn "one_cmplsi2"
4419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4420 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4423 [(set_attr "type" "arith")])
4425 (define_expand "one_cmpldi2"
4426 [(set (match_operand:DI 0 "arith_reg_dest" "")
4427 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4429 "TARGET_SHMEDIA" "")
4431 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4432 This can be used as some kind of conditional execution, which is useful
4435 [(set (match_operand:SI 0 "arith_reg_dest" "")
4436 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4437 (match_operand:SI 1 "arith_reg_operand" ""))
4441 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4442 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4446 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4447 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4448 (match_operand:SI 1 "arith_reg_operand" "0")
4449 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4451 "bf 0f\;neg %2,%0\\n0:"
4452 [(set_attr "type" "arith") ;; poor approximation
4453 (set_attr "length" "4")])
4456 ;; -------------------------------------------------------------------------
4457 ;; Zero extension instructions
4458 ;; -------------------------------------------------------------------------
4460 (define_insn "zero_extendsidi2"
4461 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4462 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4464 "addz.l %1, r63, %0"
4465 [(set_attr "type" "arith_media")
4466 (set_attr "highpart" "extend")])
4468 (define_insn "zero_extendhidi2"
4469 [(set (match_operand:DI 0 "register_operand" "=r,r")
4470 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4475 [(set_attr "type" "*,load_media")
4476 (set (attr "highpart")
4477 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4478 (const_string "user")]
4479 (const_string "ignore")))])
4482 [(set (match_operand:DI 0 "register_operand" "")
4483 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4484 "TARGET_SHMEDIA && reload_completed"
4485 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4486 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4489 if (GET_CODE (operands[1]) == TRUNCATE)
4490 operands[1] = XEXP (operands[1], 0);
4493 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4494 ;; reload the entire truncate expression.
4495 (define_insn_and_split "*loaddi_trunc"
4496 [(set (match_operand 0 "any_register_operand" "=r")
4497 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4498 "TARGET_SHMEDIA && reload_completed"
4500 "TARGET_SHMEDIA && reload_completed"
4501 [(set (match_dup 0) (match_dup 1))]
4502 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4504 (define_insn "zero_extendqidi2"
4505 [(set (match_operand:DI 0 "register_operand" "=r,r")
4506 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4511 [(set_attr "type" "arith_media,load_media")
4512 (set (attr "highpart")
4513 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4514 (const_string "user")]
4515 (const_string "ignore")))])
4517 (define_expand "zero_extendhisi2"
4518 [(set (match_operand:SI 0 "arith_reg_operand" "")
4519 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4523 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4524 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4527 (define_insn "*zero_extendhisi2_compact"
4528 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4529 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4532 [(set_attr "type" "arith")])
4534 (define_insn "*zero_extendhisi2_media"
4535 [(set (match_operand:SI 0 "register_operand" "=r,r")
4536 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4541 [(set_attr "type" "arith_media,load_media")
4542 (set (attr "highpart")
4543 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4544 (const_string "user")]
4545 (const_string "ignore")))])
4548 [(set (match_operand:SI 0 "register_operand" "")
4549 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4550 "TARGET_SHMEDIA && reload_completed"
4551 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4552 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4555 rtx op1 = operands[1];
4557 if (GET_CODE (op1) == TRUNCATE)
4558 op1 = XEXP (op1, 0);
4560 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4561 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4564 (define_expand "zero_extendqisi2"
4565 [(set (match_operand:SI 0 "arith_reg_operand" "")
4566 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4570 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4571 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4574 (define_insn "*zero_extendqisi2_compact"
4575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4576 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4579 [(set_attr "type" "arith")])
4581 (define_insn "*zero_extendqisi2_media"
4582 [(set (match_operand:SI 0 "register_operand" "=r,r")
4583 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4588 [(set_attr "type" "arith_media,load_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 "ignore")))])
4594 (define_insn "zero_extendqihi2"
4595 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4596 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4599 [(set_attr "type" "arith")])
4601 ;; -------------------------------------------------------------------------
4602 ;; Sign extension instructions
4603 ;; -------------------------------------------------------------------------
4605 ;; ??? This should be a define expand.
4606 ;; ??? Or perhaps it should be dropped?
4608 ;; convert_move generates good code for SH[1-4].
4609 (define_insn "extendsidi2"
4610 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4611 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4617 [(set_attr "type" "arith_media,load_media,fpconv_media")
4618 (set (attr "highpart")
4619 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4620 (const_string "user")]
4621 (const_string "extend")))])
4623 (define_insn "extendhidi2"
4624 [(set (match_operand:DI 0 "register_operand" "=r,r")
4625 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4630 [(set_attr "type" "*,load_media")
4631 (set (attr "highpart")
4632 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4633 (const_string "user")]
4634 (const_string "ignore")))])
4637 [(set (match_operand:DI 0 "register_operand" "")
4638 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4639 "TARGET_SHMEDIA && reload_completed"
4640 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4641 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4644 if (GET_CODE (operands[1]) == TRUNCATE)
4645 operands[1] = XEXP (operands[1], 0);
4648 (define_insn "extendqidi2"
4649 [(set (match_operand:DI 0 "register_operand" "=r,r")
4650 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4655 [(set_attr "type" "*,load_media")
4656 (set (attr "highpart")
4657 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4658 (const_string "user")]
4659 (const_string "ignore")))])
4662 [(set (match_operand:DI 0 "register_operand" "")
4663 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4664 "TARGET_SHMEDIA && reload_completed"
4665 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4666 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4669 if (GET_CODE (operands[1]) == TRUNCATE)
4670 operands[1] = XEXP (operands[1], 0);
4673 (define_expand "extendhisi2"
4674 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4675 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4679 (define_insn "*extendhisi2_compact"
4680 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4681 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4686 [(set_attr "type" "arith,load")])
4688 (define_insn "*extendhisi2_media"
4689 [(set (match_operand:SI 0 "register_operand" "=r,r")
4690 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4695 [(set_attr "type" "arith_media,load_media")
4696 (set (attr "highpart")
4697 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4698 (const_string "user")]
4699 (const_string "ignore")))])
4702 [(set (match_operand:SI 0 "register_operand" "")
4703 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4704 "TARGET_SHMEDIA && reload_completed"
4705 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4706 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4709 rtx op1 = operands[1];
4710 if (GET_CODE (op1) == TRUNCATE)
4711 op1 = XEXP (op1, 0);
4713 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4714 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4717 (define_expand "extendqisi2"
4718 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4719 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4723 (define_insn "*extendqisi2_compact"
4724 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4725 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4730 [(set_attr "type" "arith,load")
4731 (set_attr_alternative "length"
4734 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4735 (const_int 4) (const_int 2))])])
4737 (define_insn "*extendqisi2_media"
4738 [(set (match_operand:SI 0 "register_operand" "=r,r")
4739 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4744 [(set_attr "type" "arith_media,load_media")
4745 (set (attr "highpart")
4746 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4747 (const_string "user")]
4748 (const_string "ignore")))])
4751 [(set (match_operand:SI 0 "register_operand" "")
4752 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4753 "TARGET_SHMEDIA && reload_completed"
4754 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4755 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4758 rtx op1 = operands[1];
4759 if (GET_CODE (op1) == TRUNCATE)
4760 op1 = XEXP (op1, 0);
4762 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4763 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4766 (define_insn "extendqihi2"
4767 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4768 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4773 [(set_attr "type" "arith,load")
4774 (set_attr_alternative "length"
4777 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4778 (const_int 4) (const_int 2))])])
4780 /* It would seem useful to combine the truncXi patterns into the movXi
4781 patterns, but unary operators are ignored when matching constraints,
4782 so we need separate patterns. */
4783 (define_insn "truncdisi2"
4784 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4785 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4794 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4795 (set (attr "highpart")
4796 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4797 (const_string "user")]
4798 (const_string "extend")))])
4800 (define_insn "truncdihi2"
4801 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4802 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4805 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4807 [(set_attr "type" "arith_media,store_media")
4808 (set_attr "length" "8,4")
4809 (set (attr "highpart")
4810 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4811 (const_string "user")]
4812 (const_string "extend")))])
4814 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4815 ; Because we use zero extension, we can't provide signed QImode compares
4816 ; using a simple compare or conditional branch insn.
4817 (define_insn "truncdiqi2"
4818 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4819 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4824 [(set_attr "type" "arith_media,store")
4825 (set (attr "highpart")
4826 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4827 (const_string "user")]
4828 (const_string "extend")))])
4829 ;; -------------------------------------------------------------------------
4830 ;; Move instructions
4831 ;; -------------------------------------------------------------------------
4833 ;; define push and pop so it is easy for sh.c
4834 ;; We can't use push and pop on SHcompact because the stack must always
4835 ;; be 8-byte aligned.
4837 (define_expand "push"
4838 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4839 (match_operand:SI 0 "register_operand" "r,l,x"))]
4840 "TARGET_SH1 && ! TARGET_SH5"
4843 (define_expand "pop"
4844 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4845 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4846 "TARGET_SH1 && ! TARGET_SH5"
4849 (define_expand "push_e"
4850 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4851 (match_operand:SF 0 "" ""))
4852 (use (reg:PSI FPSCR_REG))
4853 (clobber (scratch:SI))])]
4854 "TARGET_SH1 && ! TARGET_SH5"
4857 (define_insn "push_fpul"
4858 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4859 "TARGET_SH2E && ! TARGET_SH5"
4861 [(set_attr "type" "fstore")
4862 (set_attr "late_fp_use" "yes")
4863 (set_attr "hit_stack" "yes")])
4865 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4867 (define_expand "push_4"
4868 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4869 (match_operand:DF 0 "" ""))
4870 (use (reg:PSI FPSCR_REG))
4871 (clobber (scratch:SI))])]
4872 "TARGET_SH1 && ! TARGET_SH5"
4875 (define_expand "pop_e"
4876 [(parallel [(set (match_operand:SF 0 "" "")
4877 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4878 (use (reg:PSI FPSCR_REG))
4879 (clobber (scratch:SI))])]
4880 "TARGET_SH1 && ! TARGET_SH5"
4883 (define_insn "pop_fpul"
4884 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4885 "TARGET_SH2E && ! TARGET_SH5"
4887 [(set_attr "type" "load")
4888 (set_attr "hit_stack" "yes")])
4890 (define_expand "pop_4"
4891 [(parallel [(set (match_operand:DF 0 "" "")
4892 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4893 (use (reg:PSI FPSCR_REG))
4894 (clobber (scratch:SI))])]
4895 "TARGET_SH1 && ! TARGET_SH5"
4898 (define_expand "push_fpscr"
4903 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4904 gen_rtx_PRE_DEC (Pmode,
4905 stack_pointer_rtx)),
4907 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4911 (define_expand "pop_fpscr"
4916 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4917 gen_frame_mem (PSImode,
4918 gen_rtx_POST_INC (Pmode,
4919 stack_pointer_rtx))));
4920 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4924 ;; These two patterns can happen as the result of optimization, when
4925 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4926 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4929 [(set (reg:SI T_REG) (const_int 0))]
4934 [(set (reg:SI T_REG) (const_int 1))]
4938 ;; t/r must come after r/r, lest reload will try to reload stuff like
4939 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4940 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4941 (define_insn "movsi_i"
4942 [(set (match_operand:SI 0 "general_movdst_operand"
4943 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4944 (match_operand:SI 1 "general_movsrc_operand"
4945 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4949 && (register_operand (operands[0], SImode)
4950 || register_operand (operands[1], SImode))"
4968 [(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")
4969 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4971 ;; t/r must come after r/r, lest reload will try to reload stuff like
4972 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4973 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4974 ;; will require a reload.
4975 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4976 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4977 (define_insn "movsi_ie"
4978 [(set (match_operand:SI 0 "general_movdst_operand"
4979 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4980 (match_operand:SI 1 "general_movsrc_operand"
4981 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4982 "(TARGET_SH2E || TARGET_SH2A)
4983 && (register_operand (operands[0], SImode)
4984 || register_operand (operands[1], SImode))"
5011 ! move optimized away"
5012 [(set_attr "type" "pcload_si,move,movi8,move,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")
5013 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5014 (set_attr_alternative "length"
5022 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5023 (const_int 4) (const_int 2))
5028 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5029 (const_int 4) (const_int 2))
5046 (define_insn "movsi_i_lowpart"
5047 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5048 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5050 && (register_operand (operands[0], SImode)
5051 || register_operand (operands[1], SImode))"
5062 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5064 (define_insn_and_split "load_ra"
5065 [(set (match_operand:SI 0 "general_movdst_operand" "")
5066 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5069 "&& ! currently_expanding_to_rtl"
5070 [(set (match_dup 0) (match_dup 1))]
5073 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5074 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5077 ;; The '?'s in the following constraints may not reflect the time taken
5078 ;; to perform the move. They are there to discourage the use of floating-
5079 ;; point registers for storing integer values.
5080 (define_insn "*movsi_media"
5081 [(set (match_operand:SI 0 "general_movdst_operand"
5082 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5083 (match_operand:SI 1 "general_movsrc_operand"
5084 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5086 && (register_operand (operands[0], SImode)
5087 || sh_register_operand (operands[1], SImode)
5088 || GET_CODE (operands[1]) == TRUNCATE)"
5103 [(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")
5104 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5105 (set (attr "highpart")
5106 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5107 (const_string "user")]
5108 (const_string "ignore")))])
5110 (define_insn "*movsi_media_nofpu"
5111 [(set (match_operand:SI 0 "general_movdst_operand"
5112 "=r,r,r,r,m,*b,r,*b")
5113 (match_operand:SI 1 "general_movsrc_operand"
5114 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5116 && (register_operand (operands[0], SImode)
5117 || sh_register_operand (operands[1], SImode)
5118 || GET_CODE (operands[1]) == TRUNCATE)"
5128 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5129 (set_attr "length" "4,4,8,4,4,4,4,12")
5130 (set (attr "highpart")
5131 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5132 (const_string "user")]
5133 (const_string "ignore")))])
5135 (define_expand "movsi_const"
5136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5137 (const:SI (sign_extend:SI
5140 (match_operand:DI 1 "immediate_operand" "s")
5143 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5146 (truncate:HI (match_dup 1))))))]
5147 "TARGET_SHMEDIA && reload_completed
5148 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5151 if (GET_CODE (operands[1]) == LABEL_REF
5152 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5153 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5154 else if (GOTOFF_P (operands[1]))
5156 rtx unspec = XEXP (operands[1], 0);
5158 if (! UNSPEC_GOTOFF_P (unspec))
5160 unspec = XEXP (unspec, 0);
5161 if (! UNSPEC_GOTOFF_P (unspec))
5164 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5165 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5166 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5170 (define_expand "movsi_const_16bit"
5171 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5172 (const:SI (sign_extend:SI
5174 (match_operand:DI 1 "immediate_operand" "s")))))]
5175 "TARGET_SHMEDIA && flag_pic && reload_completed
5176 && GET_CODE (operands[1]) == SYMBOL_REF"
5180 [(set (match_operand:SI 0 "arith_reg_dest" "")
5181 (match_operand:SI 1 "immediate_operand" ""))]
5182 "TARGET_SHMEDIA && reload_completed
5183 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5187 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5189 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5195 [(set (match_operand:SI 0 "register_operand" "")
5196 (match_operand:SI 1 "immediate_operand" ""))]
5197 "TARGET_SHMEDIA && reload_completed
5198 && ((GET_CODE (operands[1]) == CONST_INT
5199 && ! satisfies_constraint_I16 (operands[1]))
5200 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5201 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5203 (define_expand "movsi"
5204 [(set (match_operand:SI 0 "general_movdst_operand" "")
5205 (match_operand:SI 1 "general_movsrc_operand" ""))]
5207 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5209 (define_expand "ic_invalidate_line"
5210 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5211 (match_dup 1)] UNSPEC_ICACHE)
5212 (clobber (scratch:SI))])]
5213 "TARGET_HARD_SH4 || TARGET_SH5"
5218 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5221 else if (TARGET_SHCOMPACT)
5223 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5224 operands[1] = force_reg (Pmode, operands[1]);
5225 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5228 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5230 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5233 operands[0] = force_reg (Pmode, operands[0]);
5234 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5238 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5239 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5240 ;; the requirement *1*00 for associative address writes. The alignment of
5241 ;; %0 implies that its least significant bit is cleared,
5242 ;; thus we clear the V bit of a matching entry if there is one.
5243 (define_insn "ic_invalidate_line_i"
5244 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5245 (match_operand:SI 1 "register_operand" "r")]
5247 (clobber (match_scratch:SI 2 "=&r"))]
5249 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5250 [(set_attr "length" "8")
5251 (set_attr "type" "cwb")])
5253 (define_insn "ic_invalidate_line_sh4a"
5254 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5256 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5257 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5258 [(set_attr "length" "16")
5259 (set_attr "type" "cwb")])
5261 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5262 ;; an add in the code that calculates the address.
5263 (define_insn "ic_invalidate_line_media"
5264 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5267 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5268 [(set_attr "length" "16")
5269 (set_attr "type" "invalidate_line_media")])
5271 (define_insn "ic_invalidate_line_compact"
5272 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5273 (match_operand:SI 1 "register_operand" "r")]
5275 (clobber (reg:SI PR_REG))]
5278 [(set_attr "type" "sfunc")
5279 (set_attr "needs_delay_slot" "yes")])
5281 (define_expand "initialize_trampoline"
5282 [(match_operand:SI 0 "" "")
5283 (match_operand:SI 1 "" "")
5284 (match_operand:SI 2 "" "")]
5290 tramp = force_reg (Pmode, operands[0]);
5291 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5293 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5294 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5296 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5300 (define_insn "initialize_trampoline_compact"
5301 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5302 (match_operand:SI 1 "register_operand" "r")
5303 (reg:SI R2_REG) (reg:SI R3_REG)]
5306 (clobber (reg:SI PR_REG))]
5309 [(set_attr "type" "sfunc")
5310 (set_attr "needs_delay_slot" "yes")])
5312 (define_insn "movqi_i"
5313 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5314 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5316 && (arith_reg_operand (operands[0], QImode)
5317 || arith_reg_operand (operands[1], QImode))"
5326 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5327 (set_attr_alternative "length"
5331 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5332 (const_int 4) (const_int 2))
5334 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5335 (const_int 4) (const_int 2))
5340 (define_insn "*movqi_media"
5341 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5342 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5344 && (arith_reg_operand (operands[0], QImode)
5345 || extend_reg_or_0_operand (operands[1], QImode))"
5351 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5352 (set (attr "highpart")
5353 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5354 (const_string "user")]
5355 (const_string "ignore")))])
5357 (define_expand "movqi"
5358 [(set (match_operand:QI 0 "general_operand" "")
5359 (match_operand:QI 1 "general_operand" ""))]
5361 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5363 (define_expand "reload_inqi"
5364 [(set (match_operand:SI 2 "" "=&r")
5365 (match_operand:QI 1 "inqhi_operand" ""))
5366 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5367 (truncate:QI (match_dup 3)))]
5371 rtx inner = XEXP (operands[1], 0);
5372 int regno = REGNO (inner);
5374 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5375 operands[1] = gen_rtx_REG (SImode, regno);
5376 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5379 /* When storing r0, we have to avoid reg+reg addressing. */
5380 (define_insn "movhi_i"
5381 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5382 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5384 && (arith_reg_operand (operands[0], HImode)
5385 || arith_reg_operand (operands[1], HImode))
5386 && (GET_CODE (operands[0]) != MEM
5387 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5388 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5389 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5399 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5401 (define_insn "*movhi_media"
5402 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5403 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5405 && (arith_reg_operand (operands[0], HImode)
5406 || arith_reg_or_0_operand (operands[1], HImode))"
5413 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5414 (set (attr "highpart")
5415 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5416 (const_string "user")]
5417 (const_string "ignore")))])
5420 [(set (match_operand:HI 0 "register_operand" "")
5421 (match_operand:HI 1 "immediate_operand" ""))]
5422 "TARGET_SHMEDIA && reload_completed
5423 && ! satisfies_constraint_I16 (operands[1])"
5424 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5426 (define_expand "movhi"
5427 [(set (match_operand:HI 0 "general_movdst_operand" "")
5428 (match_operand:HI 1 "general_movsrc_operand" ""))]
5430 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5432 (define_expand "reload_inhi"
5433 [(set (match_operand:SI 2 "" "=&r")
5434 (match_operand:HI 1 "inqhi_operand" ""))
5435 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5436 (truncate:HI (match_dup 3)))]
5440 rtx inner = XEXP (operands[1], 0);
5441 int regno = REGNO (inner);
5443 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5444 operands[1] = gen_rtx_REG (SImode, regno);
5445 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5448 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5449 ;; compiled with -m2 -ml -O3 -funroll-loops
5450 (define_insn "*movdi_i"
5451 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5452 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5454 && (arith_reg_operand (operands[0], DImode)
5455 || arith_reg_operand (operands[1], DImode))"
5456 "* return output_movedouble (insn, operands, DImode);"
5457 [(set_attr "length" "4")
5458 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5460 ;; If the output is a register and the input is memory or a register, we have
5461 ;; to be careful and see which word needs to be loaded first.
5464 [(set (match_operand:DI 0 "general_movdst_operand" "")
5465 (match_operand:DI 1 "general_movsrc_operand" ""))]
5466 "TARGET_SH1 && reload_completed"
5467 [(set (match_dup 2) (match_dup 3))
5468 (set (match_dup 4) (match_dup 5))]
5473 if ((GET_CODE (operands[0]) == MEM
5474 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5475 || (GET_CODE (operands[1]) == MEM
5476 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5479 switch (GET_CODE (operands[0]))
5482 regno = REGNO (operands[0]);
5485 regno = subreg_regno (operands[0]);
5495 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5497 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5498 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5499 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5500 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5504 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5505 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5506 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5507 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5510 if (operands[2] == 0 || operands[3] == 0
5511 || operands[4] == 0 || operands[5] == 0)
5515 ;; The '?'s in the following constraints may not reflect the time taken
5516 ;; to perform the move. They are there to discourage the use of floating-
5517 ;; point registers for storing integer values.
5518 (define_insn "*movdi_media"
5519 [(set (match_operand:DI 0 "general_movdst_operand"
5520 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5521 (match_operand:DI 1 "general_movsrc_operand"
5522 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5524 && (register_operand (operands[0], DImode)
5525 || sh_register_operand (operands[1], DImode))"
5540 [(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")
5541 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5543 (define_insn "*movdi_media_nofpu"
5544 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5545 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5547 && (register_operand (operands[0], DImode)
5548 || sh_register_operand (operands[1], DImode))"
5558 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5559 (set_attr "length" "4,4,16,4,4,4,4,*")])
5561 (define_insn "*movdi_media_I16"
5562 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5563 (match_operand:DI 1 "const_int_operand" "I16"))]
5564 "TARGET_SHMEDIA && reload_completed"
5566 [(set_attr "type" "arith_media")
5567 (set_attr "length" "4")])
5570 [(set (match_operand:DI 0 "arith_reg_dest" "")
5571 (match_operand:DI 1 "immediate_operand" ""))]
5572 "TARGET_SHMEDIA && reload_completed
5573 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5574 [(set (match_dup 0) (match_dup 1))]
5579 if (TARGET_SHMEDIA64)
5580 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5582 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5584 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5589 (define_expand "movdi_const"
5590 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5591 (const:DI (sign_extend:DI
5594 (match_operand:DI 1 "immediate_operand" "s")
5597 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5603 (const_int 32)))))))
5605 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5611 (const_int 16)))))))
5613 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5618 "TARGET_SHMEDIA64 && reload_completed
5619 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5622 sh_mark_label (operands[1], 4);
5625 (define_expand "movdi_const_32bit"
5626 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5627 (const:DI (sign_extend:DI
5630 (match_operand:DI 1 "immediate_operand" "s")
5633 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5638 "TARGET_SHMEDIA32 && reload_completed
5639 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5642 sh_mark_label (operands[1], 2);
5645 (define_expand "movdi_const_16bit"
5646 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5647 (const:DI (sign_extend:DI
5649 (match_operand:DI 1 "immediate_operand" "s")))))]
5650 "TARGET_SHMEDIA && flag_pic && reload_completed
5651 && GET_CODE (operands[1]) == SYMBOL_REF"
5655 [(set (match_operand:DI 0 "ext_dest_operand" "")
5656 (match_operand:DI 1 "immediate_operand" ""))]
5657 "TARGET_SHMEDIA && reload_completed
5658 && GET_CODE (operands[1]) == CONST_INT
5659 && ! satisfies_constraint_I16 (operands[1])"
5660 [(set (match_dup 0) (match_dup 2))
5664 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5665 unsigned HOST_WIDE_INT low = val;
5666 unsigned HOST_WIDE_INT high = val;
5667 unsigned HOST_WIDE_INT sign;
5668 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5670 /* Zero-extend the 16 least-significant bits. */
5673 /* Arithmetic shift right the word by 16 bits. */
5675 if (GET_CODE (operands[0]) == SUBREG
5676 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5685 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5691 /* If we can't generate the constant with a two-insn movi / shori
5692 sequence, try some other strategies. */
5693 if (! CONST_OK_FOR_I16 (high))
5695 /* Try constant load / left shift. We know VAL != 0. */
5696 val2 = val ^ (val-1);
5699 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5701 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5702 || (! CONST_OK_FOR_I16 (high >> 16)
5703 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5705 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5706 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5707 GEN_INT (trailing_zeroes));
5711 /* Try constant load / right shift. */
5712 val2 = (val >> 15) + 1;
5713 if (val2 == (val2 & -val2))
5715 int shift = 49 - exact_log2 (val2);
5717 val2 = trunc_int_for_mode (val << shift, DImode);
5718 if (CONST_OK_FOR_I16 (val2))
5720 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5726 val2 = val & 0xffff;
5727 if ((val >> 16 & 0xffff) == val2
5728 && (val >> 32 & 0xffff) == val2
5729 && (val >> 48 & 0xffff) == val2)
5731 val2 = (HOST_WIDE_INT) val >> 48;
5732 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5733 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5736 /* Try movi / mshflo.l */
5737 val2 = (HOST_WIDE_INT) val >> 32;
5738 if (val2 == ((unsigned HOST_WIDE_INT)
5739 trunc_int_for_mode (val, SImode)))
5741 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5745 /* Try movi / mshflo.l w/ r63. */
5746 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5747 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5749 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5755 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5758 operands[2] = GEN_INT (val2);
5762 [(set (match_operand:DI 0 "ext_dest_operand" "")
5763 (match_operand:DI 1 "immediate_operand" ""))]
5764 "TARGET_SHMEDIA && reload_completed
5765 && GET_CODE (operands[1]) == CONST_DOUBLE"
5766 [(set (match_dup 0) (match_dup 2))
5768 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5771 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5772 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5773 unsigned HOST_WIDE_INT val = low;
5774 unsigned HOST_WIDE_INT sign;
5776 /* Zero-extend the 16 least-significant bits. */
5778 operands[1] = GEN_INT (val);
5780 /* Arithmetic shift right the double-word by 16 bits. */
5782 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5785 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5789 /* This will only be true if high is a sign-extension of low, i.e.,
5790 it must be either 0 or (unsigned)-1, and be zero iff the
5791 most-significant bit of low is set. */
5792 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5793 operands[2] = GEN_INT (low);
5795 operands[2] = immed_double_const (low, high, DImode);
5798 (define_insn "shori_media"
5799 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5800 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5802 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5803 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5807 [(set_attr "type" "arith_media,*")])
5809 (define_insn "*shori_media_si"
5810 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5811 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5813 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5817 (define_expand "movdi"
5818 [(set (match_operand:DI 0 "general_movdst_operand" "")
5819 (match_operand:DI 1 "general_movsrc_operand" ""))]
5821 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5823 (define_insn "movdf_media"
5824 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5825 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5827 && (register_operand (operands[0], DFmode)
5828 || sh_register_operand (operands[1], DFmode))"
5839 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5841 (define_insn "movdf_media_nofpu"
5842 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5843 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5845 && (register_operand (operands[0], DFmode)
5846 || sh_register_operand (operands[1], DFmode))"
5852 [(set_attr "type" "arith_media,*,load_media,store_media")])
5855 [(set (match_operand:DF 0 "arith_reg_dest" "")
5856 (match_operand:DF 1 "immediate_operand" ""))]
5857 "TARGET_SHMEDIA && reload_completed"
5858 [(set (match_dup 3) (match_dup 2))]
5861 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5863 REAL_VALUE_TYPE value;
5865 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5866 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5868 if (HOST_BITS_PER_WIDE_INT >= 64)
5869 operands[2] = immed_double_const ((unsigned long) values[endian]
5870 | ((HOST_WIDE_INT) values[1 - endian]
5874 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5875 operands[2] = immed_double_const (values[endian], values[1 - endian],
5879 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5882 ;; ??? This should be a define expand.
5884 (define_insn "movdf_k"
5885 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5886 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5888 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5889 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5890 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5891 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5892 && (arith_reg_operand (operands[0], DFmode)
5893 || arith_reg_operand (operands[1], DFmode))"
5894 "* return output_movedouble (insn, operands, DFmode);"
5895 [(set_attr "length" "4")
5896 (set_attr "type" "move,pcload,load,store")])
5898 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5899 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5900 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5901 ;; the d/m/c/X alternative, which is split later into single-precision
5902 ;; instructions. And when not optimizing, no splits are done before fixing
5903 ;; up pcloads, so we need usable length information for that.
5904 (define_insn "movdf_i4"
5905 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5906 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5907 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5908 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5909 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5910 && (arith_reg_operand (operands[0], DFmode)
5911 || arith_reg_operand (operands[1], DFmode))"
5923 [(set_attr_alternative "length"
5924 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5926 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5927 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5928 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5930 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5931 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5932 ;; increment or decrement r15 explicitly.
5934 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5935 (const_int 10) (const_int 8))
5937 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5938 (const_int 10) (const_int 8))])
5939 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5940 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5941 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5942 (const_string "double")
5943 (const_string "none")))])
5945 ;; Moving DFmode between fp/general registers through memory
5946 ;; (the top of the stack) is faster than moving through fpul even for
5947 ;; little endian. Because the type of an instruction is important for its
5948 ;; scheduling, it is beneficial to split these operations, rather than
5949 ;; emitting them in one single chunk, even if this will expose a stack
5950 ;; use that will prevent scheduling of other stack accesses beyond this
5953 [(set (match_operand:DF 0 "register_operand" "")
5954 (match_operand:DF 1 "register_operand" ""))
5955 (use (match_operand:PSI 2 "fpscr_operand" ""))
5956 (clobber (match_scratch:SI 3 "=X"))]
5957 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5958 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5964 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5966 emit_move_insn (stack_pointer_rtx,
5967 plus_constant (stack_pointer_rtx, -8));
5968 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5971 tos = gen_tmp_stack_mem (DFmode,
5972 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5973 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5974 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5975 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5976 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5977 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5979 tos = gen_tmp_stack_mem (DFmode,
5980 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5981 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5982 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5983 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5985 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5989 ;; local-alloc sometimes allocates scratch registers even when not required,
5990 ;; so we must be prepared to handle these.
5992 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5994 [(set (match_operand:DF 0 "general_movdst_operand" "")
5995 (match_operand:DF 1 "general_movsrc_operand" ""))
5996 (use (match_operand:PSI 2 "fpscr_operand" ""))
5997 (clobber (match_scratch:SI 3 ""))]
5998 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6000 && true_regnum (operands[0]) < 16
6001 && true_regnum (operands[1]) < 16"
6002 [(set (match_dup 0) (match_dup 1))]
6005 /* If this was a reg <-> mem operation with base + index reg addressing,
6006 we have to handle this in a special way. */
6007 rtx mem = operands[0];
6009 if (! memory_operand (mem, DFmode))
6014 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6015 mem = SUBREG_REG (mem);
6016 if (GET_CODE (mem) == MEM)
6018 rtx addr = XEXP (mem, 0);
6019 if (GET_CODE (addr) == PLUS
6020 && GET_CODE (XEXP (addr, 0)) == REG
6021 && GET_CODE (XEXP (addr, 1)) == REG)
6024 rtx reg0 = gen_rtx_REG (Pmode, 0);
6025 rtx regop = operands[store_p], word0 ,word1;
6027 if (GET_CODE (regop) == SUBREG)
6028 alter_subreg (®op);
6029 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6033 mem = copy_rtx (mem);
6034 PUT_MODE (mem, SImode);
6035 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6036 alter_subreg (&word0);
6037 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6038 alter_subreg (&word1);
6039 if (store_p || ! refers_to_regno_p (REGNO (word0),
6040 REGNO (word0) + 1, addr, 0))
6043 ? gen_movsi_ie (mem, word0)
6044 : gen_movsi_ie (word0, mem));
6045 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6046 mem = copy_rtx (mem);
6048 ? gen_movsi_ie (mem, word1)
6049 : gen_movsi_ie (word1, mem));
6050 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6054 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6055 emit_insn (gen_movsi_ie (word1, mem));
6056 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6057 mem = copy_rtx (mem);
6058 emit_insn (gen_movsi_ie (word0, mem));
6065 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6067 [(set (match_operand:DF 0 "register_operand" "")
6068 (match_operand:DF 1 "memory_operand" ""))
6069 (use (match_operand:PSI 2 "fpscr_operand" ""))
6070 (clobber (reg:SI R0_REG))]
6071 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6072 [(parallel [(set (match_dup 0) (match_dup 1))
6074 (clobber (scratch:SI))])]
6077 (define_expand "reload_indf__frn"
6078 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6079 (match_operand:DF 1 "immediate_operand" "FQ"))
6080 (use (reg:PSI FPSCR_REG))
6081 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6085 (define_expand "reload_outdf__RnFRm"
6086 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6087 (match_operand:DF 1 "register_operand" "af,r"))
6088 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6092 ;; Simplify no-op moves.
6094 [(set (match_operand:SF 0 "register_operand" "")
6095 (match_operand:SF 1 "register_operand" ""))
6096 (use (match_operand:PSI 2 "fpscr_operand" ""))
6097 (clobber (match_scratch:SI 3 ""))]
6098 "TARGET_SH2E && reload_completed
6099 && true_regnum (operands[0]) == true_regnum (operands[1])"
6100 [(set (match_dup 0) (match_dup 0))]
6103 ;; fmovd substitute post-reload splits
6105 [(set (match_operand:DF 0 "register_operand" "")
6106 (match_operand:DF 1 "register_operand" ""))
6107 (use (match_operand:PSI 2 "fpscr_operand" ""))
6108 (clobber (match_scratch:SI 3 ""))]
6109 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6110 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6111 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6115 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6116 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6117 gen_rtx_REG (SFmode, src), operands[2]));
6118 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6119 gen_rtx_REG (SFmode, src + 1), operands[2]));
6124 [(set (match_operand:DF 0 "register_operand" "")
6125 (mem:DF (match_operand:SI 1 "register_operand" "")))
6126 (use (match_operand:PSI 2 "fpscr_operand" ""))
6127 (clobber (match_scratch:SI 3 ""))]
6128 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6129 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6130 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6134 int regno = true_regnum (operands[0]);
6136 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6138 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6139 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6140 regno + !! TARGET_LITTLE_ENDIAN),
6141 mem2, operands[2]));
6142 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6143 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6144 regno + ! TARGET_LITTLE_ENDIAN),
6145 change_address (mem, SFmode, NULL_RTX),
6151 [(set (match_operand:DF 0 "register_operand" "")
6152 (match_operand:DF 1 "memory_operand" ""))
6153 (use (match_operand:PSI 2 "fpscr_operand" ""))
6154 (clobber (match_scratch:SI 3 ""))]
6155 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6156 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6160 int regno = true_regnum (operands[0]);
6161 rtx addr, insn, adjust = NULL_RTX;
6162 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6163 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6164 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6166 operands[1] = copy_rtx (mem2);
6167 addr = XEXP (mem2, 0);
6168 if (GET_CODE (addr) != POST_INC)
6170 /* If we have to modify the stack pointer, the value that we have
6171 read with post-increment might be modified by an interrupt,
6172 so write it back. */
6173 if (REGNO (addr) == STACK_POINTER_REGNUM)
6174 adjust = gen_push_e (reg0);
6176 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6177 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6179 addr = XEXP (addr, 0);
6180 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6181 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6182 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6186 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6191 [(set (match_operand:DF 0 "memory_operand" "")
6192 (match_operand:DF 1 "register_operand" ""))
6193 (use (match_operand:PSI 2 "fpscr_operand" ""))
6194 (clobber (match_scratch:SI 3 ""))]
6195 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6196 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6200 int regno = true_regnum (operands[1]);
6201 rtx insn, addr, adjust = NULL_RTX;
6203 operands[0] = copy_rtx (operands[0]);
6204 PUT_MODE (operands[0], SFmode);
6205 insn = emit_insn (gen_movsf_ie (operands[0],
6206 gen_rtx_REG (SFmode,
6207 regno + ! TARGET_LITTLE_ENDIAN),
6209 operands[0] = copy_rtx (operands[0]);
6210 addr = XEXP (operands[0], 0);
6211 if (GET_CODE (addr) != PRE_DEC)
6213 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6214 emit_insn_before (adjust, insn);
6215 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6217 addr = XEXP (addr, 0);
6219 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6220 insn = emit_insn (gen_movsf_ie (operands[0],
6221 gen_rtx_REG (SFmode,
6222 regno + !! TARGET_LITTLE_ENDIAN),
6224 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6228 ;; If the output is a register and the input is memory or a register, we have
6229 ;; to be careful and see which word needs to be loaded first.
6232 [(set (match_operand:DF 0 "general_movdst_operand" "")
6233 (match_operand:DF 1 "general_movsrc_operand" ""))]
6234 "TARGET_SH1 && reload_completed"
6235 [(set (match_dup 2) (match_dup 3))
6236 (set (match_dup 4) (match_dup 5))]
6241 if ((GET_CODE (operands[0]) == MEM
6242 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6243 || (GET_CODE (operands[1]) == MEM
6244 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6247 switch (GET_CODE (operands[0]))
6250 regno = REGNO (operands[0]);
6253 regno = subreg_regno (operands[0]);
6263 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6265 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6266 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6267 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6268 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6272 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6273 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6274 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6275 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6278 if (operands[2] == 0 || operands[3] == 0
6279 || operands[4] == 0 || operands[5] == 0)
6283 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6284 ;; used only once, let combine add in the index again.
6287 [(set (match_operand:SI 0 "register_operand" "")
6288 (match_operand:SI 1 "" ""))
6289 (clobber (match_operand 2 "register_operand" ""))]
6290 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6291 && ALLOW_INDEXED_ADDRESS"
6292 [(use (reg:SI R0_REG))]
6295 rtx addr, reg, const_int;
6297 if (GET_CODE (operands[1]) != MEM)
6299 addr = XEXP (operands[1], 0);
6300 if (GET_CODE (addr) != PLUS)
6302 reg = XEXP (addr, 0);
6303 const_int = XEXP (addr, 1);
6304 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6305 && GET_CODE (const_int) == CONST_INT))
6307 emit_move_insn (operands[2], const_int);
6308 emit_move_insn (operands[0],
6309 change_address (operands[1], VOIDmode,
6310 gen_rtx_PLUS (SImode, reg, operands[2])));
6315 [(set (match_operand:SI 1 "" "")
6316 (match_operand:SI 0 "register_operand" ""))
6317 (clobber (match_operand 2 "register_operand" ""))]
6318 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6319 && ALLOW_INDEXED_ADDRESS"
6320 [(use (reg:SI R0_REG))]
6323 rtx addr, reg, const_int;
6325 if (GET_CODE (operands[1]) != MEM)
6327 addr = XEXP (operands[1], 0);
6328 if (GET_CODE (addr) != PLUS)
6330 reg = XEXP (addr, 0);
6331 const_int = XEXP (addr, 1);
6332 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6333 && GET_CODE (const_int) == CONST_INT))
6335 emit_move_insn (operands[2], const_int);
6336 emit_move_insn (change_address (operands[1], VOIDmode,
6337 gen_rtx_PLUS (SImode, reg, operands[2])),
6342 (define_expand "movdf"
6343 [(set (match_operand:DF 0 "general_movdst_operand" "")
6344 (match_operand:DF 1 "general_movsrc_operand" ""))]
6348 if (prepare_move_operands (operands, DFmode)) DONE;
6351 if (TARGET_SHMEDIA_FPU)
6352 emit_insn (gen_movdf_media (operands[0], operands[1]));
6354 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6357 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6359 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6364 ;;This is incompatible with the way gcc uses subregs.
6365 ;;(define_insn "movv2sf_i"
6366 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6367 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6368 ;; "TARGET_SHMEDIA_FPU
6369 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6370 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6374 ;; fst%M0.p %m0, %1"
6375 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6377 (define_insn_and_split "movv2sf_i"
6378 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6379 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6380 "TARGET_SHMEDIA_FPU"
6382 "TARGET_SHMEDIA_FPU && reload_completed"
6383 [(set (match_dup 0) (match_dup 1))]
6386 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6387 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6390 (define_expand "movv2sf"
6391 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6392 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6393 "TARGET_SHMEDIA_FPU"
6396 if (prepare_move_operands (operands, V2SFmode))
6400 (define_expand "addv2sf3"
6401 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6402 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6403 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6404 "TARGET_SHMEDIA_FPU"
6407 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6411 (define_expand "subv2sf3"
6412 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6413 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6414 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6415 "TARGET_SHMEDIA_FPU"
6418 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6422 (define_expand "mulv2sf3"
6423 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6424 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6425 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6426 "TARGET_SHMEDIA_FPU"
6429 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6433 (define_expand "divv2sf3"
6434 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6435 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6436 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6437 "TARGET_SHMEDIA_FPU"
6440 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6444 (define_insn_and_split "*movv4sf_i"
6445 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6446 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6447 "TARGET_SHMEDIA_FPU"
6449 "&& reload_completed"
6455 for (i = 0; i < 4/2; i++)
6459 if (GET_CODE (operands[0]) == MEM)
6460 x = adjust_address (operands[0], V2SFmode,
6461 i * GET_MODE_SIZE (V2SFmode));
6463 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6465 if (GET_CODE (operands[1]) == MEM)
6466 y = adjust_address (operands[1], V2SFmode,
6467 i * GET_MODE_SIZE (V2SFmode));
6469 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6471 emit_insn (gen_movv2sf_i (x, y));
6476 [(set_attr "length" "8")])
6478 (define_expand "movv4sf"
6479 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6480 (match_operand:V4SF 1 "general_operand" ""))]
6481 "TARGET_SHMEDIA_FPU"
6484 if (prepare_move_operands (operands, V4SFmode))
6488 (define_insn_and_split "*movv16sf_i"
6489 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6490 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6491 "TARGET_SHMEDIA_FPU"
6493 "&& reload_completed"
6499 for (i = 0; i < 16/2; i++)
6503 if (GET_CODE (operands[0]) == MEM)
6504 x = adjust_address (operands[0], V2SFmode,
6505 i * GET_MODE_SIZE (V2SFmode));
6508 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6512 if (GET_CODE (operands[1]) == MEM)
6513 y = adjust_address (operands[1], V2SFmode,
6514 i * GET_MODE_SIZE (V2SFmode));
6517 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6521 emit_insn (gen_movv2sf_i (x, y));
6526 [(set_attr "length" "32")])
6528 (define_expand "movv16sf"
6529 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6530 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6531 "TARGET_SHMEDIA_FPU"
6534 if (prepare_move_operands (operands, V16SFmode))
6538 (define_insn "movsf_media"
6539 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6540 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6542 && (register_operand (operands[0], SFmode)
6543 || sh_register_operand (operands[1], SFmode))"
6554 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6555 (set (attr "highpart")
6556 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6557 (const_string "user")]
6558 (const_string "ignore")))])
6560 (define_insn "movsf_media_nofpu"
6561 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6562 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6564 && (register_operand (operands[0], SFmode)
6565 || sh_register_operand (operands[1], SFmode))"
6571 [(set_attr "type" "arith_media,*,load_media,store_media")
6572 (set (attr "highpart")
6573 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6574 (const_string "user")]
6575 (const_string "ignore")))])
6578 [(set (match_operand:SF 0 "arith_reg_dest" "")
6579 (match_operand:SF 1 "immediate_operand" ""))]
6580 "TARGET_SHMEDIA && reload_completed
6581 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6582 [(set (match_dup 3) (match_dup 2))]
6586 REAL_VALUE_TYPE value;
6588 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6589 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6590 operands[2] = GEN_INT (values);
6592 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6595 (define_insn "movsf_i"
6596 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6597 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6600 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6601 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6602 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6603 && (arith_reg_operand (operands[0], SFmode)
6604 || arith_reg_operand (operands[1], SFmode))"
6613 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6615 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6616 ;; update_flow_info would not know where to put REG_EQUAL notes
6617 ;; when the destination changes mode.
6618 (define_insn "movsf_ie"
6619 [(set (match_operand:SF 0 "general_movdst_operand"
6620 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6621 (match_operand:SF 1 "general_movsrc_operand"
6622 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6623 (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"))
6624 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6627 && (arith_reg_operand (operands[0], SFmode)
6628 || arith_reg_operand (operands[1], SFmode)
6629 || arith_reg_operand (operands[3], SImode)
6630 || (fpul_operand (operands[0], SFmode)
6631 && memory_operand (operands[1], SFmode)
6632 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6633 || (fpul_operand (operands[1], SFmode)
6634 && memory_operand (operands[0], SFmode)
6635 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6655 ! move optimized away"
6656 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6657 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6658 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6659 (set_attr_alternative "length"
6666 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6667 (const_int 4) (const_int 2))
6669 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6670 (const_int 4) (const_int 2))
6683 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6684 (const_string "single")
6685 (const_string "none")))])
6688 [(set (match_operand:SF 0 "register_operand" "")
6689 (match_operand:SF 1 "register_operand" ""))
6690 (use (match_operand:PSI 2 "fpscr_operand" ""))
6691 (clobber (reg:SI FPUL_REG))]
6693 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6695 (clobber (scratch:SI))])
6696 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6698 (clobber (scratch:SI))])]
6701 (define_expand "movsf"
6702 [(set (match_operand:SF 0 "general_movdst_operand" "")
6703 (match_operand:SF 1 "general_movsrc_operand" ""))]
6707 if (prepare_move_operands (operands, SFmode))
6711 if (TARGET_SHMEDIA_FPU)
6712 emit_insn (gen_movsf_media (operands[0], operands[1]));
6714 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6719 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6724 (define_insn "mov_nop"
6725 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6728 [(set_attr "length" "0")
6729 (set_attr "type" "nil")])
6731 (define_expand "reload_insf__frn"
6732 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6733 (match_operand:SF 1 "immediate_operand" "FQ"))
6734 (use (reg:PSI FPSCR_REG))
6735 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6739 (define_expand "reload_insi__i_fpul"
6740 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6741 (match_operand:SI 1 "immediate_operand" "i"))
6742 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6746 (define_expand "ptabs"
6747 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6751 if (!TARGET_PT_FIXED)
6753 rtx eq = operands[1];
6755 /* ??? For canonical RTL we really should remove any CONST from EQ
6756 before wrapping it in the AND, and finally wrap the EQ into a
6757 const if is constant. However, for reload we must expose the
6758 input register or symbolic constant, and we can't have
6759 different insn structures outside of the operands for different
6760 alternatives of the same pattern. */
6761 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6764 = (gen_rtx_IF_THEN_ELSE
6767 gen_rtx_MEM (PDImode, operands[1]),
6768 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6769 PDImode, operands[1])));
6773 ;; expanded by ptabs expander.
6774 (define_insn "*extendsipdi_media"
6775 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6776 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6780 (mem:PDI (match_dup 1))
6781 (sign_extend:PDI (match_dup 1))))]
6782 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6786 [(set_attr "type" "ptabs_media,pt_media")
6787 (set_attr "length" "4,*")])
6789 (define_insn "*truncdipdi_media"
6790 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6791 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6795 (mem:PDI (match_dup 1))
6796 (truncate:PDI (match_dup 1))))]
6797 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6801 [(set_attr "type" "ptabs_media,pt_media")
6802 (set_attr "length" "4,*")])
6804 (define_insn "*movsi_y"
6805 [(set (match_operand:SI 0 "register_operand" "=y,y")
6806 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6807 (clobber (match_scratch:SI 2 "=&z,r"))]
6809 && (reload_in_progress || reload_completed)"
6811 [(set_attr "length" "4")
6812 (set_attr "type" "pcload,move")])
6815 [(set (match_operand:SI 0 "register_operand" "")
6816 (match_operand:SI 1 "immediate_operand" ""))
6817 (clobber (match_operand:SI 2 "register_operand" ""))]
6819 [(set (match_dup 2) (match_dup 1))
6820 (set (match_dup 0) (match_dup 2))]
6824 [(set (match_operand:SI 0 "register_operand" "")
6825 (match_operand:SI 1 "memory_operand" ""))
6826 (clobber (reg:SI R0_REG))]
6828 [(set (match_dup 0) (match_dup 1))]
6831 ;; ------------------------------------------------------------------------
6832 ;; Define the real conditional branch instructions.
6833 ;; ------------------------------------------------------------------------
6835 (define_insn "branch_true"
6836 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6837 (label_ref (match_operand 0 "" ""))
6840 "* return output_branch (1, insn, operands);"
6841 [(set_attr "type" "cbranch")])
6843 (define_insn "branch_false"
6844 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6845 (label_ref (match_operand 0 "" ""))
6848 "* return output_branch (0, insn, operands);"
6849 [(set_attr "type" "cbranch")])
6851 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6852 ;; which destination is too far away.
6853 ;; The const_int_operand is distinct for each branch target; it avoids
6854 ;; unwanted matches with redundant_insn.
6855 (define_insn "block_branch_redirect"
6856 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6859 [(set_attr "length" "0")])
6861 ;; This one has the additional purpose to record a possible scratch register
6862 ;; for the following branch.
6863 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6864 ;; because the insn then might be deemed dead and deleted. And we can't
6865 ;; make the use in the jump insn explicit because that would disable
6866 ;; delay slot scheduling from the target.
6867 (define_insn "indirect_jump_scratch"
6868 [(set (match_operand:SI 0 "register_operand" "=r")
6869 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6870 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6873 [(set_attr "length" "0")])
6875 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6876 ;; being pulled into the delay slot of a condbranch that has been made to
6877 ;; jump around the unconditional jump because it was out of range.
6878 (define_insn "stuff_delay_slot"
6880 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6881 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6884 [(set_attr "length" "0")
6885 (set_attr "cond_delay_slot" "yes")])
6887 ;; Conditional branch insns
6889 (define_expand "beq_media"
6891 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6892 (match_operand:DI 2 "arith_operand" "r,I06"))
6893 (match_operand 0 "" "")
6896 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6898 (define_insn "*beq_media_i"
6900 (if_then_else (match_operator 3 "equality_comparison_operator"
6901 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6902 (match_operand:DI 2 "arith_operand" "r,I06")])
6903 (match_operand 0 "target_operand" "b,b")
6908 b%o3i%' %1, %2, %0%>"
6909 [(set_attr "type" "cbranch_media")])
6911 (define_insn "*beq_media_i32"
6913 (if_then_else (match_operator 3 "equality_comparison_operator"
6914 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6915 (match_operand:SI 2 "arith_operand" "r,I06")])
6916 (match_operand 0 "target_operand" "b,b")
6921 b%o3i%' %1, %2, %0%>"
6922 [(set_attr "type" "cbranch_media")])
6924 (define_expand "bne_media"
6926 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6927 (match_operand:DI 2 "arith_operand" "r,I06"))
6928 (match_operand 0 "" "")
6931 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6933 (define_expand "bgt_media"
6935 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6936 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6937 (match_operand 0 "" "")
6940 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6942 (define_expand "bge_media"
6944 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6945 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6946 (match_operand 0 "" "")
6949 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6951 (define_expand "bgtu_media"
6953 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6954 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6955 (match_operand 0 "" "")
6958 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6960 (define_expand "bgeu_media"
6962 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6963 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6964 (match_operand 0 "" "")
6967 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6969 (define_insn "*bgt_media_i"
6971 (if_then_else (match_operator 3 "greater_comparison_operator"
6972 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6973 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6974 (match_operand 0 "target_operand" "b")
6977 "b%o3%' %N1, %N2, %0%>"
6978 [(set_attr "type" "cbranch_media")])
6980 (define_insn "*bgt_media_i32"
6982 (if_then_else (match_operator 3 "greater_comparison_operator"
6983 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6984 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6985 (match_operand 0 "target_operand" "b")
6988 "b%o3%' %N1, %N2, %0%>"
6989 [(set_attr "type" "cbranch_media")])
6991 ;; These are only needed to make invert_jump() happy - otherwise, jump
6992 ;; optimization will be silently disabled.
6993 (define_insn "*blt_media_i"
6995 (if_then_else (match_operator 3 "less_comparison_operator"
6996 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6997 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6998 (match_operand 0 "target_operand" "b")
7001 "b%o3%' %N2, %N1, %0%>"
7002 [(set_attr "type" "cbranch_media")])
7004 (define_insn "*blt_media_i32"
7006 (if_then_else (match_operator 3 "less_comparison_operator"
7007 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7008 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7009 (match_operand 0 "target_operand" "b")
7012 "b%o3%' %N2, %N1, %0%>"
7013 [(set_attr "type" "cbranch_media")])
7015 (define_expand "beq"
7017 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7018 (label_ref (match_operand 0 "" ""))
7025 enum machine_mode mode = GET_MODE (sh_compare_op0);
7027 if (mode != DImode && mode != SImode)
7029 rtx tmp = gen_reg_rtx (DImode);
7031 emit_insn (gen_seq (tmp));
7032 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7036 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7037 if (CONSTANT_P (sh_compare_op1)
7038 && (! satisfies_constraint_I06 (sh_compare_op1)))
7039 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7040 emit_jump_insn (gen_beq_media (operands[0],
7041 sh_compare_op0, sh_compare_op1));
7045 from_compare (operands, EQ);
7048 (define_expand "bne"
7050 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7051 (label_ref (match_operand 0 "" ""))
7058 enum machine_mode mode = GET_MODE (sh_compare_op0);
7060 if (mode != DImode && mode != SImode)
7062 rtx tmp = gen_reg_rtx (DImode);
7064 emit_insn (gen_seq (tmp));
7065 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7069 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7070 if (CONSTANT_P (sh_compare_op1)
7071 && (! satisfies_constraint_I06 (sh_compare_op1)))
7072 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7073 emit_jump_insn (gen_bne_media (operands[0],
7074 sh_compare_op0, sh_compare_op1));
7078 from_compare (operands, EQ);
7081 (define_expand "bgt"
7083 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7084 (label_ref (match_operand 0 "" ""))
7091 enum machine_mode mode = GET_MODE (sh_compare_op0);
7093 if (mode != DImode && mode != SImode)
7095 rtx tmp = gen_reg_rtx (DImode);
7097 emit_insn (gen_sgt (tmp));
7098 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7102 if (sh_compare_op0 != const0_rtx)
7103 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7104 if (sh_compare_op1 != const0_rtx)
7105 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7106 emit_jump_insn (gen_bgt_media (operands[0],
7107 sh_compare_op0, sh_compare_op1));
7111 from_compare (operands, GT);
7114 (define_expand "blt"
7116 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7117 (label_ref (match_operand 0 "" ""))
7124 enum machine_mode mode = GET_MODE (sh_compare_op0);
7126 if (mode != DImode && mode != SImode)
7128 rtx tmp = gen_reg_rtx (DImode);
7130 emit_insn (gen_slt (tmp));
7131 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7135 if (sh_compare_op0 != const0_rtx)
7136 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7137 if (sh_compare_op1 != const0_rtx)
7138 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7139 emit_jump_insn (gen_bgt_media (operands[0],
7140 sh_compare_op1, sh_compare_op0));
7144 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7146 rtx tmp = sh_compare_op0;
7147 sh_compare_op0 = sh_compare_op1;
7148 sh_compare_op1 = tmp;
7149 emit_insn (gen_bgt (operands[0]));
7152 from_compare (operands, GE);
7155 (define_expand "ble"
7157 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7158 (label_ref (match_operand 0 "" ""))
7165 enum machine_mode mode = GET_MODE (sh_compare_op0);
7167 if (mode != DImode && mode != SImode)
7169 rtx tmp = gen_reg_rtx (DImode);
7171 emit_insn (gen_sle (tmp));
7172 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7176 if (sh_compare_op0 != const0_rtx)
7177 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7178 if (sh_compare_op1 != const0_rtx)
7179 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7180 emit_jump_insn (gen_bge_media (operands[0],
7181 sh_compare_op1, sh_compare_op0));
7187 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7189 rtx tmp = sh_compare_op0;
7190 sh_compare_op0 = sh_compare_op1;
7191 sh_compare_op1 = tmp;
7192 emit_insn (gen_bge (operands[0]));
7195 from_compare (operands, GT);
7198 (define_expand "bge"
7200 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7201 (label_ref (match_operand 0 "" ""))
7208 enum machine_mode mode = GET_MODE (sh_compare_op0);
7210 if (mode != DImode && mode != SImode)
7212 rtx tmp = gen_reg_rtx (DImode);
7214 emit_insn (gen_sge (tmp));
7215 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7219 if (sh_compare_op0 != const0_rtx)
7220 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7221 if (sh_compare_op1 != const0_rtx)
7222 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7223 emit_jump_insn (gen_bge_media (operands[0],
7224 sh_compare_op0, sh_compare_op1));
7230 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7232 rtx tmp = sh_compare_op0;
7233 sh_compare_op0 = sh_compare_op1;
7234 sh_compare_op1 = tmp;
7235 emit_insn (gen_ble (operands[0]));
7238 from_compare (operands, GE);
7241 (define_expand "bgtu"
7243 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7244 (label_ref (match_operand 0 "" ""))
7251 enum machine_mode mode = GET_MODE (sh_compare_op0);
7253 if (sh_compare_op0 != const0_rtx)
7254 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7255 if (sh_compare_op1 != const0_rtx)
7256 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7257 emit_jump_insn (gen_bgtu_media (operands[0],
7258 sh_compare_op0, sh_compare_op1));
7262 from_compare (operands, GTU);
7265 (define_expand "bltu"
7267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7268 (label_ref (match_operand 0 "" ""))
7275 enum machine_mode mode = GET_MODE (sh_compare_op0);
7277 if (sh_compare_op0 != const0_rtx)
7278 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7279 if (sh_compare_op1 != const0_rtx)
7280 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7281 emit_jump_insn (gen_bgtu_media (operands[0],
7282 sh_compare_op1, sh_compare_op0));
7286 from_compare (operands, GEU);
7289 (define_expand "bgeu"
7291 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7292 (label_ref (match_operand 0 "" ""))
7299 enum machine_mode mode = GET_MODE (sh_compare_op0);
7301 if (sh_compare_op0 != const0_rtx)
7302 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7303 if (sh_compare_op1 != const0_rtx)
7304 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7305 emit_jump_insn (gen_bgeu_media (operands[0],
7306 sh_compare_op0, sh_compare_op1));
7310 from_compare (operands, GEU);
7313 (define_expand "bleu"
7315 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7316 (label_ref (match_operand 0 "" ""))
7323 enum machine_mode mode = GET_MODE (sh_compare_op0);
7325 if (sh_compare_op0 != const0_rtx)
7326 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7327 if (sh_compare_op1 != const0_rtx)
7328 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7329 emit_jump_insn (gen_bgeu_media (operands[0],
7330 sh_compare_op1, sh_compare_op0));
7334 from_compare (operands, GTU);
7337 (define_expand "bunordered"
7338 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7340 (if_then_else (ne (match_dup 1) (const_int 0))
7341 (match_operand 0 "" "")
7346 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7347 operands[1] = gen_reg_rtx (SImode);
7348 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7349 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7352 ;; combiner splitter for test-and-branch on single bit in register. This
7353 ;; is endian dependent because the non-paradoxical subreg looks different
7358 (match_operator 3 "equality_comparison_operator"
7359 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7360 "extend_reg_operand" "")
7364 "const_int_operand" "")) 0)
7366 (match_operand 0 "target_operand" "")
7368 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7369 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7370 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7371 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7375 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7376 operands[6] = (GET_CODE (operands[3]) == EQ
7377 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7378 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7381 ; operand 0 is the loop count pseudo register
7382 ; operand 1 is the number of loop iterations or 0 if it is unknown
7383 ; operand 2 is the maximum number of loop iterations
7384 ; operand 3 is the number of levels of enclosed loops
7385 ; operand 4 is the label to jump to at the top of the loop
7387 (define_expand "doloop_end"
7388 [(parallel [(set (pc) (if_then_else
7389 (ne:SI (match_operand:SI 0 "" "")
7391 (label_ref (match_operand 4 "" ""))
7394 (plus:SI (match_dup 0) (const_int -1)))
7395 (clobber (reg:SI T_REG))])]
7399 if (GET_MODE (operands[0]) != SImode)
7404 (define_insn_and_split "doloop_end_split"
7406 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7408 (label_ref (match_operand 1 "" ""))
7411 (plus (match_dup 0) (const_int -1)))
7412 (clobber (reg:SI T_REG))]
7416 [(parallel [(set (reg:SI T_REG)
7417 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7419 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7420 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7421 (label_ref (match_operand 1 "" ""))
7424 [(set_attr "type" "cbranch")])
7427 ;; ------------------------------------------------------------------------
7428 ;; Jump and linkage insns
7429 ;; ------------------------------------------------------------------------
7431 (define_insn "jump_compact"
7433 (label_ref (match_operand 0 "" "")))]
7434 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7437 /* The length is 16 if the delay slot is unfilled. */
7438 if (get_attr_length(insn) > 4)
7439 return output_far_jump(insn, operands[0]);
7441 return \"bra %l0%#\";
7443 [(set_attr "type" "jump")
7444 (set_attr "needs_delay_slot" "yes")])
7446 ;; ??? It would be much saner to explicitly use the scratch register
7447 ;; in the jump insn, and have indirect_jump_scratch only set it,
7448 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7449 ;; from the target then, as it uses simplejump_p.
7450 ;;(define_insn "jump_compact_far"
7452 ;; (label_ref (match_operand 0 "" "")))
7453 ;; (use (match_operand 1 "register_operand" "r")]
7455 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7456 ;; [(set_attr "type" "jump")
7457 ;; (set_attr "needs_delay_slot" "yes")])
7459 (define_insn "jump_media"
7461 (match_operand 0 "target_operand" "b"))]
7464 [(set_attr "type" "jump_media")])
7466 (define_expand "jump"
7468 (label_ref (match_operand 0 "" "")))]
7473 emit_jump_insn (gen_jump_compact (operands[0]));
7474 else if (TARGET_SHMEDIA)
7476 if (reload_in_progress || reload_completed)
7478 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7484 (define_insn "force_mode_for_call"
7485 [(use (reg:PSI FPSCR_REG))]
7488 [(set_attr "length" "0")
7489 (set (attr "fp_mode")
7490 (if_then_else (eq_attr "fpu_single" "yes")
7491 (const_string "single") (const_string "double")))])
7493 (define_insn "calli"
7494 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7495 (match_operand 1 "" ""))
7496 (use (reg:PSI FPSCR_REG))
7497 (clobber (reg:SI PR_REG))]
7501 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7502 return \"jsr/n\\t@%0\";
7504 return \"jsr\\t@%0%#\";
7507 [(set_attr "type" "call")
7508 (set (attr "fp_mode")
7509 (if_then_else (eq_attr "fpu_single" "yes")
7510 (const_string "single") (const_string "double")))
7511 (set_attr "needs_delay_slot" "yes")
7512 (set_attr "fp_set" "unknown")])
7514 ;; This is TBR relative jump instruction for SH2A architecture.
7515 ;; Its use is enabled assigning an attribute "function_vector"
7516 ;; and the vector number to a function during its declaration.
7518 (define_insn "calli_tbr_rel"
7519 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7520 (match_operand 1 "" ""))
7521 (use (reg:PSI FPSCR_REG))
7522 (clobber (reg:SI PR_REG))]
7523 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7526 unsigned HOST_WIDE_INT vect_num;
7527 vect_num = sh2a_get_function_vector_number (operands[0]);
7528 operands[2] = GEN_INT (vect_num * 4);
7530 return \"jsr/n\\t@@(%O2,tbr)\";
7532 [(set_attr "type" "call")
7533 (set (attr "fp_mode")
7534 (if_then_else (eq_attr "fpu_single" "yes")
7535 (const_string "single") (const_string "double")))
7536 (set_attr "needs_delay_slot" "no")
7537 (set_attr "fp_set" "unknown")])
7539 ;; This is a pc-rel call, using bsrf, for use with PIC.
7541 (define_insn "calli_pcrel"
7542 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7543 (match_operand 1 "" ""))
7544 (use (reg:PSI FPSCR_REG))
7545 (use (reg:SI PIC_REG))
7546 (use (match_operand 2 "" ""))
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_and_split "call_pcrel"
7558 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7559 (match_operand 1 "" ""))
7560 (use (reg:PSI FPSCR_REG))
7561 (use (reg:SI PIC_REG))
7562 (clobber (reg:SI PR_REG))
7563 (clobber (match_scratch:SI 2 "=r"))]
7570 rtx lab = PATTERN (gen_call_site ());
7572 if (SYMBOL_REF_LOCAL_P (operands[0]))
7573 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7575 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7576 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7579 [(set_attr "type" "call")
7580 (set (attr "fp_mode")
7581 (if_then_else (eq_attr "fpu_single" "yes")
7582 (const_string "single") (const_string "double")))
7583 (set_attr "needs_delay_slot" "yes")
7584 (set_attr "fp_set" "unknown")])
7586 (define_insn "call_compact"
7587 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7588 (match_operand 1 "" ""))
7589 (match_operand 2 "immediate_operand" "n")
7590 (use (reg:SI R0_REG))
7591 (use (reg:SI R1_REG))
7592 (use (reg:PSI FPSCR_REG))
7593 (clobber (reg:SI PR_REG))]
7594 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7596 [(set_attr "type" "call")
7597 (set (attr "fp_mode")
7598 (if_then_else (eq_attr "fpu_single" "yes")
7599 (const_string "single") (const_string "double")))
7600 (set_attr "needs_delay_slot" "yes")])
7602 (define_insn "call_compact_rettramp"
7603 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7604 (match_operand 1 "" ""))
7605 (match_operand 2 "immediate_operand" "n")
7606 (use (reg:SI R0_REG))
7607 (use (reg:SI R1_REG))
7608 (use (reg:PSI FPSCR_REG))
7609 (clobber (reg:SI R10_REG))
7610 (clobber (reg:SI PR_REG))]
7611 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7613 [(set_attr "type" "call")
7614 (set (attr "fp_mode")
7615 (if_then_else (eq_attr "fpu_single" "yes")
7616 (const_string "single") (const_string "double")))
7617 (set_attr "needs_delay_slot" "yes")])
7619 (define_insn "call_media"
7620 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7621 (match_operand 1 "" ""))
7622 (clobber (reg:DI PR_MEDIA_REG))]
7625 [(set_attr "type" "jump_media")])
7627 (define_insn "call_valuei"
7628 [(set (match_operand 0 "" "=rf")
7629 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7630 (match_operand 2 "" "")))
7631 (use (reg:PSI FPSCR_REG))
7632 (clobber (reg:SI PR_REG))]
7636 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7637 return \"jsr/n\\t@%1\";
7639 return \"jsr\\t@%1%#\";
7641 [(set_attr "type" "call")
7642 (set (attr "fp_mode")
7643 (if_then_else (eq_attr "fpu_single" "yes")
7644 (const_string "single") (const_string "double")))
7645 (set_attr "needs_delay_slot" "yes")
7646 (set_attr "fp_set" "unknown")])
7648 ;; This is TBR relative jump instruction for SH2A architecture.
7649 ;; Its use is enabled assigning an attribute "function_vector"
7650 ;; and the vector number to a function during its declaration.
7652 (define_insn "call_valuei_tbr_rel"
7653 [(set (match_operand 0 "" "=rf")
7654 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7655 (match_operand 2 "" "")))
7656 (use (reg:PSI FPSCR_REG))
7657 (clobber (reg:SI PR_REG))]
7658 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7661 unsigned HOST_WIDE_INT vect_num;
7662 vect_num = sh2a_get_function_vector_number (operands[1]);
7663 operands[3] = GEN_INT (vect_num * 4);
7665 return \"jsr/n\\t@@(%O3,tbr)\";
7667 [(set_attr "type" "call")
7668 (set (attr "fp_mode")
7669 (if_then_else (eq_attr "fpu_single" "yes")
7670 (const_string "single") (const_string "double")))
7671 (set_attr "needs_delay_slot" "no")
7672 (set_attr "fp_set" "unknown")])
7674 (define_insn "call_valuei_pcrel"
7675 [(set (match_operand 0 "" "=rf")
7676 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7677 (match_operand 2 "" "")))
7678 (use (reg:PSI FPSCR_REG))
7679 (use (reg:SI PIC_REG))
7680 (use (match_operand 3 "" ""))
7681 (clobber (reg:SI PR_REG))]
7684 [(set_attr "type" "call")
7685 (set (attr "fp_mode")
7686 (if_then_else (eq_attr "fpu_single" "yes")
7687 (const_string "single") (const_string "double")))
7688 (set_attr "needs_delay_slot" "yes")
7689 (set_attr "fp_set" "unknown")])
7691 (define_insn_and_split "call_value_pcrel"
7692 [(set (match_operand 0 "" "=rf")
7693 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7694 (match_operand 2 "" "")))
7695 (use (reg:PSI FPSCR_REG))
7696 (use (reg:SI PIC_REG))
7697 (clobber (reg:SI PR_REG))
7698 (clobber (match_scratch:SI 3 "=r"))]
7705 rtx lab = PATTERN (gen_call_site ());
7707 if (SYMBOL_REF_LOCAL_P (operands[1]))
7708 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7710 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7711 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7712 operands[2], copy_rtx (lab)));
7715 [(set_attr "type" "call")
7716 (set (attr "fp_mode")
7717 (if_then_else (eq_attr "fpu_single" "yes")
7718 (const_string "single") (const_string "double")))
7719 (set_attr "needs_delay_slot" "yes")
7720 (set_attr "fp_set" "unknown")])
7722 (define_insn "call_value_compact"
7723 [(set (match_operand 0 "" "=rf")
7724 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7725 (match_operand 2 "" "")))
7726 (match_operand 3 "immediate_operand" "n")
7727 (use (reg:SI R0_REG))
7728 (use (reg:SI R1_REG))
7729 (use (reg:PSI FPSCR_REG))
7730 (clobber (reg:SI PR_REG))]
7731 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7733 [(set_attr "type" "call")
7734 (set (attr "fp_mode")
7735 (if_then_else (eq_attr "fpu_single" "yes")
7736 (const_string "single") (const_string "double")))
7737 (set_attr "needs_delay_slot" "yes")])
7739 (define_insn "call_value_compact_rettramp"
7740 [(set (match_operand 0 "" "=rf")
7741 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7742 (match_operand 2 "" "")))
7743 (match_operand 3 "immediate_operand" "n")
7744 (use (reg:SI R0_REG))
7745 (use (reg:SI R1_REG))
7746 (use (reg:PSI FPSCR_REG))
7747 (clobber (reg:SI R10_REG))
7748 (clobber (reg:SI PR_REG))]
7749 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7751 [(set_attr "type" "call")
7752 (set (attr "fp_mode")
7753 (if_then_else (eq_attr "fpu_single" "yes")
7754 (const_string "single") (const_string "double")))
7755 (set_attr "needs_delay_slot" "yes")])
7757 (define_insn "call_value_media"
7758 [(set (match_operand 0 "" "=rf")
7759 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7760 (match_operand 2 "" "")))
7761 (clobber (reg:DI PR_MEDIA_REG))]
7764 [(set_attr "type" "jump_media")])
7766 (define_expand "call"
7767 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7768 (match_operand 1 "" ""))
7769 (match_operand 2 "" "")
7770 (use (reg:PSI FPSCR_REG))
7771 (clobber (reg:SI PR_REG))])]
7777 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7778 emit_call_insn (gen_call_media (operands[0], operands[1]));
7781 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7783 rtx cookie_rtx = operands[2];
7784 long cookie = INTVAL (cookie_rtx);
7785 rtx func = XEXP (operands[0], 0);
7790 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7792 rtx reg = gen_reg_rtx (Pmode);
7794 emit_insn (gen_symGOTPLT2reg (reg, func));
7798 func = legitimize_pic_address (func, Pmode, 0);
7801 r0 = gen_rtx_REG (SImode, R0_REG);
7802 r1 = gen_rtx_REG (SImode, R1_REG);
7804 /* Since such a call function may use all call-clobbered
7805 registers, we force a mode switch earlier, so that we don't
7806 run out of registers when adjusting fpscr for the call. */
7807 emit_insn (gen_force_mode_for_call ());
7810 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7812 operands[0] = force_reg (SImode, operands[0]);
7814 emit_move_insn (r0, func);
7815 emit_move_insn (r1, cookie_rtx);
7817 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7818 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7821 emit_call_insn (gen_call_compact (operands[0], operands[1],
7826 else if (TARGET_SHCOMPACT && flag_pic
7827 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7828 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7830 rtx reg = gen_reg_rtx (Pmode);
7832 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7833 XEXP (operands[0], 0) = reg;
7835 if (!flag_pic && TARGET_SH2A
7836 && GET_CODE (operands[0]) == MEM
7837 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7839 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7841 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7846 if (flag_pic && TARGET_SH2
7847 && GET_CODE (operands[0]) == MEM
7848 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7850 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7855 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7856 operands[1] = operands[2];
7859 emit_call_insn (gen_calli (operands[0], operands[1]));
7863 (define_insn "call_pop_compact"
7864 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7865 (match_operand 1 "" ""))
7866 (match_operand 2 "immediate_operand" "n")
7867 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7868 (match_operand 3 "immediate_operand" "n")))
7869 (use (reg:SI R0_REG))
7870 (use (reg:SI R1_REG))
7871 (use (reg:PSI FPSCR_REG))
7872 (clobber (reg:SI PR_REG))]
7873 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7875 [(set_attr "type" "call")
7876 (set (attr "fp_mode")
7877 (if_then_else (eq_attr "fpu_single" "yes")
7878 (const_string "single") (const_string "double")))
7879 (set_attr "needs_delay_slot" "yes")])
7881 (define_insn "call_pop_compact_rettramp"
7882 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7883 (match_operand 1 "" ""))
7884 (match_operand 2 "immediate_operand" "n")
7885 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7886 (match_operand 3 "immediate_operand" "n")))
7887 (use (reg:SI R0_REG))
7888 (use (reg:SI R1_REG))
7889 (use (reg:PSI FPSCR_REG))
7890 (clobber (reg:SI R10_REG))
7891 (clobber (reg:SI PR_REG))]
7892 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7894 [(set_attr "type" "call")
7895 (set (attr "fp_mode")
7896 (if_then_else (eq_attr "fpu_single" "yes")
7897 (const_string "single") (const_string "double")))
7898 (set_attr "needs_delay_slot" "yes")])
7900 (define_expand "call_pop"
7901 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7902 (match_operand 1 "" ""))
7903 (match_operand 2 "" "")
7904 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7905 (match_operand 3 "" "")))])]
7914 gcc_assert (operands[2] && INTVAL (operands[2]));
7915 cookie_rtx = operands[2];
7916 cookie = INTVAL (cookie_rtx);
7917 func = XEXP (operands[0], 0);
7921 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7923 rtx reg = gen_reg_rtx (Pmode);
7924 emit_insn (gen_symGOTPLT2reg (reg, func));
7928 func = legitimize_pic_address (func, Pmode, 0);
7931 r0 = gen_rtx_REG (SImode, R0_REG);
7932 r1 = gen_rtx_REG (SImode, R1_REG);
7934 /* Since such a call function may use all call-clobbered
7935 registers, we force a mode switch earlier, so that we don't
7936 run out of registers when adjusting fpscr for the call. */
7937 emit_insn (gen_force_mode_for_call ());
7939 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7941 operands[0] = force_reg (SImode, operands[0]);
7943 emit_move_insn (r0, func);
7944 emit_move_insn (r1, cookie_rtx);
7946 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7947 emit_call_insn (gen_call_pop_compact_rettramp
7948 (operands[0], operands[1], operands[2], operands[3]));
7950 emit_call_insn (gen_call_pop_compact
7951 (operands[0], operands[1], operands[2], operands[3]));
7956 (define_expand "call_value"
7957 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7958 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7959 (match_operand 2 "" "")))
7960 (match_operand 3 "" "")
7961 (use (reg:PSI FPSCR_REG))
7962 (clobber (reg:SI PR_REG))])]
7968 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7969 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7973 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7975 rtx cookie_rtx = operands[3];
7976 long cookie = INTVAL (cookie_rtx);
7977 rtx func = XEXP (operands[1], 0);
7982 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7984 rtx reg = gen_reg_rtx (Pmode);
7986 emit_insn (gen_symGOTPLT2reg (reg, func));
7990 func = legitimize_pic_address (func, Pmode, 0);
7993 r0 = gen_rtx_REG (SImode, R0_REG);
7994 r1 = gen_rtx_REG (SImode, R1_REG);
7996 /* Since such a call function may use all call-clobbered
7997 registers, we force a mode switch earlier, so that we don't
7998 run out of registers when adjusting fpscr for the call. */
7999 emit_insn (gen_force_mode_for_call ());
8002 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8004 operands[1] = force_reg (SImode, operands[1]);
8006 emit_move_insn (r0, func);
8007 emit_move_insn (r1, cookie_rtx);
8009 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8010 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
8015 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
8016 operands[2], operands[3]));
8020 else if (TARGET_SHCOMPACT && flag_pic
8021 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8022 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8024 rtx reg = gen_reg_rtx (Pmode);
8026 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
8027 XEXP (operands[1], 0) = reg;
8029 if (!flag_pic && TARGET_SH2A
8030 && GET_CODE (operands[1]) == MEM
8031 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8033 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
8035 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
8036 XEXP (operands[1], 0), operands[2]));
8040 if (flag_pic && TARGET_SH2
8041 && GET_CODE (operands[1]) == MEM
8042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8044 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
8049 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8051 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
8055 (define_insn "sibcalli"
8056 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
8057 (match_operand 1 "" ""))
8058 (use (reg:PSI FPSCR_REG))
8062 [(set_attr "needs_delay_slot" "yes")
8063 (set (attr "fp_mode")
8064 (if_then_else (eq_attr "fpu_single" "yes")
8065 (const_string "single") (const_string "double")))
8066 (set_attr "type" "jump_ind")])
8068 (define_insn "sibcalli_pcrel"
8069 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
8070 (match_operand 1 "" ""))
8071 (use (match_operand 2 "" ""))
8072 (use (reg:PSI FPSCR_REG))
8076 [(set_attr "needs_delay_slot" "yes")
8077 (set (attr "fp_mode")
8078 (if_then_else (eq_attr "fpu_single" "yes")
8079 (const_string "single") (const_string "double")))
8080 (set_attr "type" "jump_ind")])
8082 ;; This uses an unspec to describe that the symbol_ref is very close.
8083 (define_insn "sibcalli_thunk"
8084 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
8086 (match_operand 1 "" ""))
8087 (use (reg:PSI FPSCR_REG))
8091 [(set_attr "needs_delay_slot" "yes")
8092 (set (attr "fp_mode")
8093 (if_then_else (eq_attr "fpu_single" "yes")
8094 (const_string "single") (const_string "double")))
8095 (set_attr "type" "jump")
8096 (set_attr "length" "2")])
8098 (define_insn_and_split "sibcall_pcrel"
8099 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8100 (match_operand 1 "" ""))
8101 (use (reg:PSI FPSCR_REG))
8102 (clobber (match_scratch:SI 2 "=k"))
8110 rtx lab = PATTERN (gen_call_site ());
8113 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8114 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
8116 SIBLING_CALL_P (call_insn) = 1;
8119 [(set_attr "needs_delay_slot" "yes")
8120 (set (attr "fp_mode")
8121 (if_then_else (eq_attr "fpu_single" "yes")
8122 (const_string "single") (const_string "double")))
8123 (set_attr "type" "jump_ind")])
8125 (define_insn "sibcall_compact"
8126 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8127 (match_operand 1 "" ""))
8129 (use (match_operand:SI 2 "register_operand" "z,x"))
8130 (use (reg:SI R1_REG))
8131 (use (reg:PSI FPSCR_REG))
8132 ;; We want to make sure the `x' above will only match MACH_REG
8133 ;; because sibcall_epilogue may clobber MACL_REG.
8134 (clobber (reg:SI MACL_REG))]
8138 jmp @%0\\n sts %2, r0"
8139 [(set_attr "needs_delay_slot" "yes,no")
8140 (set_attr "length" "2,4")
8141 (set (attr "fp_mode") (const_string "single"))
8142 (set_attr "type" "jump_ind")])
8144 (define_insn "sibcall_media"
8145 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8146 (match_operand 1 "" ""))
8147 (use (reg:SI PR_MEDIA_REG))
8151 [(set_attr "type" "jump_media")])
8153 (define_expand "sibcall"
8155 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8156 (match_operand 1 "" ""))
8157 (match_operand 2 "" "")
8158 (use (reg:PSI FPSCR_REG))
8165 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8166 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8169 else if (TARGET_SHCOMPACT && operands[2]
8170 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8172 rtx cookie_rtx = operands[2];
8173 long cookie = INTVAL (cookie_rtx);
8174 rtx func = XEXP (operands[0], 0);
8179 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8181 rtx reg = gen_reg_rtx (Pmode);
8183 emit_insn (gen_symGOT2reg (reg, func));
8187 func = legitimize_pic_address (func, Pmode, 0);
8190 /* FIXME: if we could tell whether all argument registers are
8191 already taken, we could decide whether to force the use of
8192 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8193 simple way to tell. We could use the CALL_COOKIE, but we
8194 can't currently tell a register used for regular argument
8195 passing from one that is unused. If we leave it up to reload
8196 to decide which register to use, it seems to always choose
8197 R0_REG, which leaves no available registers in SIBCALL_REGS
8198 to hold the address of the trampoline. */
8199 mach = gen_rtx_REG (SImode, MACH_REG);
8200 r1 = gen_rtx_REG (SImode, R1_REG);
8202 /* Since such a call function may use all call-clobbered
8203 registers, we force a mode switch earlier, so that we don't
8204 run out of registers when adjusting fpscr for the call. */
8205 emit_insn (gen_force_mode_for_call ());
8208 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8210 operands[0] = force_reg (SImode, operands[0]);
8212 /* We don't need a return trampoline, since the callee will
8213 return directly to the upper caller. */
8214 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8216 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8217 cookie_rtx = GEN_INT (cookie);
8220 emit_move_insn (mach, func);
8221 emit_move_insn (r1, cookie_rtx);
8223 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8226 else if (TARGET_SHCOMPACT && flag_pic
8227 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8228 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8230 rtx reg = gen_reg_rtx (Pmode);
8232 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8233 XEXP (operands[0], 0) = reg;
8235 if (flag_pic && TARGET_SH2
8236 && GET_CODE (operands[0]) == MEM
8237 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8238 /* The PLT needs the PIC register, but the epilogue would have
8239 to restore it, so we can only use PC-relative PIC calls for
8240 static functions. */
8241 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8243 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8247 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8249 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8253 (define_insn "sibcall_valuei"
8254 [(set (match_operand 0 "" "=rf")
8255 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8256 (match_operand 2 "" "")))
8257 (use (reg:PSI FPSCR_REG))
8261 [(set_attr "needs_delay_slot" "yes")
8262 (set (attr "fp_mode")
8263 (if_then_else (eq_attr "fpu_single" "yes")
8264 (const_string "single") (const_string "double")))
8265 (set_attr "type" "jump_ind")])
8267 (define_insn "sibcall_valuei_pcrel"
8268 [(set (match_operand 0 "" "=rf")
8269 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8270 (match_operand 2 "" "")))
8271 (use (match_operand 3 "" ""))
8272 (use (reg:PSI FPSCR_REG))
8276 [(set_attr "needs_delay_slot" "yes")
8277 (set (attr "fp_mode")
8278 (if_then_else (eq_attr "fpu_single" "yes")
8279 (const_string "single") (const_string "double")))
8280 (set_attr "type" "jump_ind")])
8282 (define_insn_and_split "sibcall_value_pcrel"
8283 [(set (match_operand 0 "" "=rf")
8284 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8285 (match_operand 2 "" "")))
8286 (use (reg:PSI FPSCR_REG))
8287 (clobber (match_scratch:SI 3 "=k"))
8295 rtx lab = PATTERN (gen_call_site ());
8298 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8299 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8303 SIBLING_CALL_P (call_insn) = 1;
8306 [(set_attr "needs_delay_slot" "yes")
8307 (set (attr "fp_mode")
8308 (if_then_else (eq_attr "fpu_single" "yes")
8309 (const_string "single") (const_string "double")))
8310 (set_attr "type" "jump_ind")])
8312 (define_insn "sibcall_value_compact"
8313 [(set (match_operand 0 "" "=rf,rf")
8314 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8315 (match_operand 2 "" "")))
8317 (use (match_operand:SI 3 "register_operand" "z,x"))
8318 (use (reg:SI R1_REG))
8319 (use (reg:PSI FPSCR_REG))
8320 ;; We want to make sure the `x' above will only match MACH_REG
8321 ;; because sibcall_epilogue may clobber MACL_REG.
8322 (clobber (reg:SI MACL_REG))]
8326 jmp @%1\\n sts %3, r0"
8327 [(set_attr "needs_delay_slot" "yes,no")
8328 (set_attr "length" "2,4")
8329 (set (attr "fp_mode") (const_string "single"))
8330 (set_attr "type" "jump_ind")])
8332 (define_insn "sibcall_value_media"
8333 [(set (match_operand 0 "" "=rf")
8334 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8335 (match_operand 2 "" "")))
8336 (use (reg:SI PR_MEDIA_REG))
8340 [(set_attr "type" "jump_media")])
8342 (define_expand "sibcall_value"
8344 [(set (match_operand 0 "arith_reg_operand" "")
8345 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8346 (match_operand 2 "" "")))
8347 (match_operand 3 "" "")
8348 (use (reg:PSI FPSCR_REG))
8355 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8356 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8360 else if (TARGET_SHCOMPACT && operands[3]
8361 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8363 rtx cookie_rtx = operands[3];
8364 long cookie = INTVAL (cookie_rtx);
8365 rtx func = XEXP (operands[1], 0);
8370 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8372 rtx reg = gen_reg_rtx (Pmode);
8374 emit_insn (gen_symGOT2reg (reg, func));
8378 func = legitimize_pic_address (func, Pmode, 0);
8381 /* FIXME: if we could tell whether all argument registers are
8382 already taken, we could decide whether to force the use of
8383 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8384 simple way to tell. We could use the CALL_COOKIE, but we
8385 can't currently tell a register used for regular argument
8386 passing from one that is unused. If we leave it up to reload
8387 to decide which register to use, it seems to always choose
8388 R0_REG, which leaves no available registers in SIBCALL_REGS
8389 to hold the address of the trampoline. */
8390 mach = gen_rtx_REG (SImode, MACH_REG);
8391 r1 = gen_rtx_REG (SImode, R1_REG);
8393 /* Since such a call function may use all call-clobbered
8394 registers, we force a mode switch earlier, so that we don't
8395 run out of registers when adjusting fpscr for the call. */
8396 emit_insn (gen_force_mode_for_call ());
8399 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8401 operands[1] = force_reg (SImode, operands[1]);
8403 /* We don't need a return trampoline, since the callee will
8404 return directly to the upper caller. */
8405 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8407 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8408 cookie_rtx = GEN_INT (cookie);
8411 emit_move_insn (mach, func);
8412 emit_move_insn (r1, cookie_rtx);
8414 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8415 operands[2], mach));
8418 else if (TARGET_SHCOMPACT && flag_pic
8419 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8420 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8422 rtx reg = gen_reg_rtx (Pmode);
8424 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8425 XEXP (operands[1], 0) = reg;
8427 if (flag_pic && TARGET_SH2
8428 && GET_CODE (operands[1]) == MEM
8429 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8430 /* The PLT needs the PIC register, but the epilogue would have
8431 to restore it, so we can only use PC-relative PIC calls for
8432 static functions. */
8433 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8435 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8436 XEXP (operands[1], 0),
8441 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8443 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8447 (define_insn "call_value_pop_compact"
8448 [(set (match_operand 0 "" "=rf")
8449 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8450 (match_operand 2 "" "")))
8451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8452 (match_operand 4 "immediate_operand" "n")))
8453 (match_operand 3 "immediate_operand" "n")
8454 (use (reg:SI R0_REG))
8455 (use (reg:SI R1_REG))
8456 (use (reg:PSI FPSCR_REG))
8457 (clobber (reg:SI PR_REG))]
8458 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8460 [(set_attr "type" "call")
8461 (set (attr "fp_mode")
8462 (if_then_else (eq_attr "fpu_single" "yes")
8463 (const_string "single") (const_string "double")))
8464 (set_attr "needs_delay_slot" "yes")])
8466 (define_insn "call_value_pop_compact_rettramp"
8467 [(set (match_operand 0 "" "=rf")
8468 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8469 (match_operand 2 "" "")))
8470 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8471 (match_operand 4 "immediate_operand" "n")))
8472 (match_operand 3 "immediate_operand" "n")
8473 (use (reg:SI R0_REG))
8474 (use (reg:SI R1_REG))
8475 (use (reg:PSI FPSCR_REG))
8476 (clobber (reg:SI R10_REG))
8477 (clobber (reg:SI PR_REG))]
8478 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8480 [(set_attr "type" "call")
8481 (set (attr "fp_mode")
8482 (if_then_else (eq_attr "fpu_single" "yes")
8483 (const_string "single") (const_string "double")))
8484 (set_attr "needs_delay_slot" "yes")])
8486 (define_expand "call_value_pop"
8487 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8488 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8489 (match_operand 2 "" "")))
8490 (match_operand 3 "" "")
8491 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8492 (match_operand 4 "" "")))])]
8501 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8502 cookie_rtx = operands[3];
8503 cookie = INTVAL (cookie_rtx);
8504 func = XEXP (operands[1], 0);
8508 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8510 rtx reg = gen_reg_rtx (Pmode);
8512 emit_insn (gen_symGOTPLT2reg (reg, func));
8516 func = legitimize_pic_address (func, Pmode, 0);
8519 r0 = gen_rtx_REG (SImode, R0_REG);
8520 r1 = gen_rtx_REG (SImode, R1_REG);
8522 /* Since such a call function may use all call-clobbered
8523 registers, we force a mode switch earlier, so that we don't
8524 run out of registers when adjusting fpscr for the call. */
8525 emit_insn (gen_force_mode_for_call ());
8527 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8529 operands[1] = force_reg (SImode, operands[1]);
8531 emit_move_insn (r0, func);
8532 emit_move_insn (r1, cookie_rtx);
8534 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8535 emit_call_insn (gen_call_value_pop_compact_rettramp
8536 (operands[0], operands[1], operands[2],
8537 operands[3], operands[4]));
8539 emit_call_insn (gen_call_value_pop_compact
8540 (operands[0], operands[1], operands[2],
8541 operands[3], operands[4]));
8546 (define_expand "sibcall_epilogue"
8551 sh_expand_epilogue (1);
8552 if (TARGET_SHCOMPACT)
8556 /* If epilogue clobbers r0, preserve it in macl. */
8557 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8558 if ((set = single_set (insn))
8559 && GET_CODE (SET_DEST (set)) == REG
8560 && REGNO (SET_DEST (set)) == R0_REG)
8562 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8563 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8565 /* We can't tell at this point whether the sibcall is a
8566 sibcall_compact and, if it is, whether it uses r0 or
8567 mach as operand 2, so let the instructions that
8568 preserve r0 be optimized away if r0 turns out to be
8570 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8571 emit_move_insn (r0, tmp);
8578 (define_insn "indirect_jump_compact"
8580 (match_operand:SI 0 "arith_reg_operand" "r"))]
8583 [(set_attr "needs_delay_slot" "yes")
8584 (set_attr "type" "jump_ind")])
8586 (define_expand "indirect_jump"
8588 (match_operand 0 "register_operand" ""))]
8592 if (GET_MODE (operands[0]) != Pmode)
8593 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8596 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8597 ;; which can be present in structured code from indirect jumps which can not
8598 ;; be present in structured code. This allows -fprofile-arcs to work.
8600 ;; For SH1 processors.
8601 (define_insn "casesi_jump_1"
8603 (match_operand:SI 0 "register_operand" "r"))
8604 (use (label_ref (match_operand 1 "" "")))]
8607 [(set_attr "needs_delay_slot" "yes")
8608 (set_attr "type" "jump_ind")])
8610 ;; For all later processors.
8611 (define_insn "casesi_jump_2"
8612 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8613 (label_ref (match_operand 1 "" ""))))
8614 (use (label_ref (match_operand 2 "" "")))]
8616 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8618 [(set_attr "needs_delay_slot" "yes")
8619 (set_attr "type" "jump_ind")])
8621 (define_insn "casesi_jump_media"
8622 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8623 (use (label_ref (match_operand 1 "" "")))]
8626 [(set_attr "type" "jump_media")])
8628 ;; Call subroutine returning any type.
8629 ;; ??? This probably doesn't work.
8631 (define_expand "untyped_call"
8632 [(parallel [(call (match_operand 0 "" "")
8634 (match_operand 1 "" "")
8635 (match_operand 2 "" "")])]
8636 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8641 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8643 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8645 rtx set = XVECEXP (operands[2], 0, i);
8646 emit_move_insn (SET_DEST (set), SET_SRC (set));
8649 /* The optimizer does not know that the call sets the function value
8650 registers we stored in the result block. We avoid problems by
8651 claiming that all hard registers are used and clobbered at this
8653 emit_insn (gen_blockage ());
8658 ;; ------------------------------------------------------------------------
8660 ;; ------------------------------------------------------------------------
8663 [(set (reg:SI T_REG)
8664 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8665 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8668 [(set_attr "type" "arith")])
8675 ;; Load address of a label. This is only generated by the casesi expand,
8676 ;; and by machine_dependent_reorg (fixing up fp moves).
8677 ;; This must use unspec, because this only works for labels that are
8681 [(set (reg:SI R0_REG)
8682 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8685 [(set_attr "in_delay_slot" "no")
8686 (set_attr "type" "arith")])
8688 ;; machine_dependent_reorg will make this a `mova'.
8689 (define_insn "mova_const"
8690 [(set (reg:SI R0_REG)
8691 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8694 [(set_attr "in_delay_slot" "no")
8695 (set_attr "type" "arith")])
8697 (define_expand "GOTaddr2picreg"
8698 [(set (reg:SI R0_REG)
8699 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8701 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8702 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8705 if (TARGET_VXWORKS_RTP)
8707 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8708 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8709 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8713 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8714 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8718 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8719 rtx pic = operands[0];
8720 rtx lab = PATTERN (gen_call_site ());
8723 equiv = operands[1];
8724 operands[1] = gen_rtx_MINUS (Pmode,
8728 gen_rtx_MINUS (Pmode,
8729 gen_rtx_CONST (Pmode,
8732 operands[1] = gen_sym2PIC (operands[1]);
8733 PUT_MODE (operands[1], Pmode);
8735 if (Pmode == SImode)
8737 emit_insn (gen_movsi_const (pic, operands[1]));
8738 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8742 emit_insn (gen_movdi_const (pic, operands[1]));
8743 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8746 insn = emit_move_insn (operands[0], tr);
8748 set_unique_reg_note (insn, REG_EQUAL, equiv);
8755 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8758 (define_expand "vxworks_picreg"
8759 [(set (reg:SI PIC_REG)
8760 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8761 (set (reg:SI R0_REG)
8762 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8763 (set (reg:SI PIC_REG)
8764 (mem:SI (reg:SI PIC_REG)))
8765 (set (reg:SI PIC_REG)
8766 (mem:SI (plus:SI (reg:SI PIC_REG)
8768 "TARGET_VXWORKS_RTP")
8771 [(set (match_operand 0 "target_reg_operand" "=b")
8772 (const (unspec [(match_operand 1 "" "Csy")]
8773 UNSPEC_DATALABEL)))]
8774 "TARGET_SHMEDIA && flag_pic
8775 && satisfies_constraint_Csy (operands[1])"
8776 "ptb/u datalabel %1, %0"
8777 [(set_attr "type" "ptabs_media")
8778 (set_attr "length" "*")])
8780 (define_insn "ptrel_si"
8781 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8782 (plus:SI (match_operand:SI 1 "register_operand" "r")
8784 (match_operand:SI 2 "" "")]
8786 "%O2: ptrel/u %1, %0"
8787 [(set_attr "type" "ptabs_media")])
8789 (define_insn "ptrel_di"
8790 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8791 (plus:DI (match_operand:DI 1 "register_operand" "r")
8793 (match_operand:DI 2 "" "")]
8795 "%O2: ptrel/u %1, %0"
8796 [(set_attr "type" "ptabs_media")])
8798 (define_expand "builtin_setjmp_receiver"
8799 [(match_operand 0 "" "")]
8803 emit_insn (gen_GOTaddr2picreg ());
8807 (define_expand "call_site"
8808 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8812 static HOST_WIDE_INT i = 0;
8813 operands[0] = GEN_INT (i);
8817 (define_expand "sym_label2reg"
8818 [(set (match_operand:SI 0 "" "")
8821 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8824 (match_operand:SI 2 "" "")
8828 (define_expand "symGOT_load"
8829 [(set (match_dup 2) (match_operand 1 "" ""))
8830 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8831 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8837 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8838 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8842 rtx reg = operands[2];
8844 if (Pmode == DImode)
8847 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8849 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8854 emit_insn (gen_movsi_const (reg, operands[1]));
8856 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8860 emit_move_insn (operands[2], operands[1]);
8862 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8864 gen_rtx_REG (Pmode, PIC_REG)));
8866 /* When stack protector inserts codes after the result is set to
8867 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8868 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8869 when rX is a GOT address for the guard symbol. Ugly but doesn't
8870 matter because this is a rare situation. */
8872 && flag_stack_protect
8873 && GET_CODE (operands[1]) == CONST
8874 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8875 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8876 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8877 \"__stack_chk_guard\") == 0)
8878 emit_insn (gen_blockage ());
8880 /* N.B. This is not constant for a GOTPLT relocation. */
8881 mem = gen_rtx_MEM (Pmode, operands[3]);
8882 MEM_NOTRAP_P (mem) = 1;
8883 /* ??? Should we have a special alias set for the GOT? */
8884 insn = emit_move_insn (operands[0], mem);
8886 set_unique_reg_note (insn, REG_EQUAL,
8887 XVECEXP (XEXP (operands[1], 0), 0, 0));
8892 (define_expand "sym2GOT"
8893 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8897 (define_expand "symGOT2reg"
8898 [(match_operand 0 "" "") (match_operand 1 "" "")]
8904 gotsym = gen_sym2GOT (operands[1]);
8905 PUT_MODE (gotsym, Pmode);
8906 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8908 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8913 (define_expand "symGOTPLT2reg"
8914 [(match_operand 0 "" "") (match_operand 1 "" "")]
8918 rtx pltsym = gen_rtx_CONST (Pmode,
8919 gen_rtx_UNSPEC (Pmode,
8920 gen_rtvec (1, operands[1]),
8922 emit_insn (gen_symGOT_load (operands[0], pltsym));
8926 (define_expand "sym2GOTOFF"
8927 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8931 (define_expand "symGOTOFF2reg"
8932 [(match_operand 0 "" "") (match_operand 1 "" "")]
8936 rtx gotoffsym, insn;
8937 rtx t = (!can_create_pseudo_p ()
8939 : gen_reg_rtx (GET_MODE (operands[0])));
8941 gotoffsym = gen_sym2GOTOFF (operands[1]);
8942 PUT_MODE (gotoffsym, Pmode);
8943 emit_move_insn (t, gotoffsym);
8944 insn = emit_move_insn (operands[0],
8945 gen_rtx_PLUS (Pmode, t,
8946 gen_rtx_REG (Pmode, PIC_REG)));
8948 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8953 (define_expand "symPLT_label2reg"
8954 [(set (match_operand:SI 0 "" "")
8957 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8961 (match_operand:SI 2 "" "")
8963 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8964 ;; Even though the PIC register is not really used by the call
8965 ;; sequence in which this is expanded, the PLT code assumes the PIC
8966 ;; register is set, so we must not skip its initialization. Since
8967 ;; we only use this expand as part of calling sequences, and never
8968 ;; to take the address of a function, this is the best point to
8969 ;; insert the (use). Using the PLT to take the address of a
8970 ;; function would be wrong, not only because the PLT entry could
8971 ;; then be called from a function that doesn't initialize the PIC
8972 ;; register to the proper GOT, but also because pointers to the
8973 ;; same function might not compare equal, should they be set by
8974 ;; different shared libraries.
8975 (use (reg:SI PIC_REG))]
8979 (define_expand "sym2PIC"
8980 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8984 ;; TLS code generation.
8985 ;; ??? this should be a define_insn_and_split
8986 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8987 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8990 (define_insn "tls_global_dynamic"
8991 [(set (match_operand:SI 0 "register_operand" "=&z")
8992 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8995 (use (reg:PSI FPSCR_REG))
8996 (use (reg:SI PIC_REG))
8997 (clobber (reg:SI PR_REG))
8998 (clobber (scratch:SI))]
9004 \\tmova\\t2f,r0\\n\\
9005 \\tmov.l\\t2f,r1\\n\\
9008 \\tadd\\tr12,r4\\n\\
9012 1:\\t.long\\t%a1@TLSGD\\n\\
9013 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9016 [(set_attr "type" "tls_load")
9017 (set_attr "length" "26")])
9019 (define_insn "tls_local_dynamic"
9020 [(set (match_operand:SI 0 "register_operand" "=&z")
9021 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
9024 (use (reg:PSI FPSCR_REG))
9025 (use (reg:SI PIC_REG))
9026 (clobber (reg:SI PR_REG))
9027 (clobber (scratch:SI))]
9033 \\tmova\\t2f,r0\\n\\
9034 \\tmov.l\\t2f,r1\\n\\
9037 \\tadd\\tr12,r4\\n\\
9041 1:\\t.long\\t%a1@TLSLDM\\n\\
9042 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9045 [(set_attr "type" "tls_load")
9046 (set_attr "length" "26")])
9048 (define_expand "sym2DTPOFF"
9049 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
9053 (define_expand "symDTPOFF2reg"
9054 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
9058 rtx dtpoffsym, insn;
9059 rtx t = (!can_create_pseudo_p ()
9061 : gen_reg_rtx (GET_MODE (operands[0])));
9063 dtpoffsym = gen_sym2DTPOFF (operands[1]);
9064 PUT_MODE (dtpoffsym, Pmode);
9065 emit_move_insn (t, dtpoffsym);
9066 insn = emit_move_insn (operands[0],
9067 gen_rtx_PLUS (Pmode, t, operands[2]));
9071 (define_expand "sym2GOTTPOFF"
9072 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
9076 (define_insn "tls_initial_exec"
9077 [(set (match_operand:SI 0 "register_operand" "=&r")
9078 (unspec:SI [(match_operand:SI 1 "" "")]
9080 (use (reg:SI GBR_REG))
9081 (use (reg:SI PIC_REG))
9082 (clobber (reg:SI R0_REG))]
9088 \\tstc\\tgbr,%0\\n\\
9089 \\tmov.l\\t@(r0,r12),r0\\n\\
9093 1:\\t.long\\t%a1\\n\\
9096 [(set_attr "type" "tls_load")
9097 (set_attr "length" "16")])
9099 (define_expand "sym2TPOFF"
9100 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
9104 (define_expand "symTPOFF2reg"
9105 [(match_operand 0 "" "") (match_operand 1 "" "")]
9111 tpoffsym = gen_sym2TPOFF (operands[1]);
9112 PUT_MODE (tpoffsym, Pmode);
9113 insn = emit_move_insn (operands[0], tpoffsym);
9117 (define_insn "load_gbr"
9118 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
9119 (use (reg:SI GBR_REG))]
9122 [(set_attr "type" "tls_load")])
9124 ;; case instruction for switch statements.
9126 ;; Operand 0 is index
9127 ;; operand 1 is the minimum bound
9128 ;; operand 2 is the maximum bound - minimum bound + 1
9129 ;; operand 3 is CODE_LABEL for the table;
9130 ;; operand 4 is the CODE_LABEL to go to if index out of range.
9132 (define_expand "casesi"
9133 [(match_operand:SI 0 "arith_reg_operand" "")
9134 (match_operand:SI 1 "arith_reg_operand" "")
9135 (match_operand:SI 2 "arith_reg_operand" "")
9136 (match_operand 3 "" "") (match_operand 4 "" "")]
9140 rtx reg = gen_reg_rtx (SImode);
9141 rtx reg2 = gen_reg_rtx (SImode);
9144 rtx reg = gen_reg_rtx (DImode);
9145 rtx reg2 = gen_reg_rtx (DImode);
9146 rtx reg3 = gen_reg_rtx (Pmode);
9147 rtx reg4 = gen_reg_rtx (Pmode);
9148 rtx reg5 = gen_reg_rtx (Pmode);
9151 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9152 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9153 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9155 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9156 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9157 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9158 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9159 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9160 (Pmode, operands[3])));
9161 /* Messy: can we subreg to clean this up? */
9162 if (Pmode == DImode)
9163 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9165 load = gen_casesi_load_media (reg4,
9166 gen_rtx_SUBREG (DImode, reg3, 0),
9168 PUT_MODE (SET_SRC (load), Pmode);
9170 /* ??? The following add could be eliminated if we used ptrel. */
9171 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9172 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9176 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9177 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9178 /* If optimizing, casesi_worker depends on the mode of the instruction
9179 before label it 'uses' - operands[3]. */
9180 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9182 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9184 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9186 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9187 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9188 operands[3], but to lab. We will fix this up in
9189 machine_dependent_reorg. */
9194 (define_expand "casesi_0"
9195 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9196 (set (match_dup 4) (minus:SI (match_dup 4)
9197 (match_operand:SI 1 "arith_operand" "")))
9199 (gtu:SI (match_dup 4)
9200 (match_operand:SI 2 "arith_reg_operand" "")))
9202 (if_then_else (ne (reg:SI T_REG)
9204 (label_ref (match_operand 3 "" ""))
9209 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9210 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9211 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9213 (define_insn "casesi_worker_0"
9214 [(set (match_operand:SI 0 "register_operand" "=r,r")
9215 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9216 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9217 (clobber (match_scratch:SI 3 "=X,1"))
9218 (clobber (match_scratch:SI 4 "=&z,z"))]
9223 [(set (match_operand:SI 0 "register_operand" "")
9224 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9225 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9226 (clobber (match_scratch:SI 3 ""))
9227 (clobber (match_scratch:SI 4 ""))]
9228 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9229 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9230 (parallel [(set (match_dup 0)
9231 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9232 (label_ref (match_dup 2))] UNSPEC_CASESI))
9233 (clobber (match_dup 3))])
9234 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9235 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9238 [(set (match_operand:SI 0 "register_operand" "")
9239 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9240 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9241 (clobber (match_scratch:SI 3 ""))
9242 (clobber (match_scratch:SI 4 ""))]
9243 "TARGET_SH2 && reload_completed"
9244 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9245 (parallel [(set (match_dup 0)
9246 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9247 (label_ref (match_dup 2))] UNSPEC_CASESI))
9248 (clobber (match_dup 3))])]
9249 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9251 (define_insn "casesi_worker_1"
9252 [(set (match_operand:SI 0 "register_operand" "=r,r")
9253 (unspec:SI [(reg:SI R0_REG)
9254 (match_operand:SI 1 "register_operand" "0,r")
9255 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9256 (clobber (match_scratch:SI 3 "=X,1"))]
9260 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9262 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9264 switch (GET_MODE (diff_vec))
9267 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9269 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9271 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9272 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9273 return \"mov.b @(r0,%1),%0\";
9278 [(set_attr "length" "4")])
9280 (define_insn "casesi_worker_2"
9281 [(set (match_operand:SI 0 "register_operand" "=r,r")
9282 (unspec:SI [(reg:SI R0_REG)
9283 (match_operand:SI 1 "register_operand" "0,r")
9284 (label_ref (match_operand 2 "" ""))
9285 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9286 (clobber (match_operand:SI 4 "" "=X,1"))]
9287 "TARGET_SH2 && reload_completed && flag_pic"
9290 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9293 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9295 switch (GET_MODE (diff_vec))
9298 output_asm_insn (\"shll2 %1\", operands);
9299 load = \"mov.l @(r0,%1),%0\"; break;
9301 output_asm_insn (\"add %1,%1\", operands);
9302 load = \"mov.w @(r0,%1),%0\"; break;
9304 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9305 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9307 load = \"mov.b @(r0,%1),%0\";
9312 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9315 [(set_attr "length" "8")])
9317 (define_insn "casesi_shift_media"
9318 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9319 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9320 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9325 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9327 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9329 switch (GET_MODE (diff_vec))
9332 return \"shlli %1, 2, %0\";
9334 return \"shlli %1, 1, %0\";
9336 if (rtx_equal_p (operands[0], operands[1]))
9338 return \"add %1, r63, %0\";
9343 [(set_attr "type" "arith_media")])
9345 (define_insn "casesi_load_media"
9346 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9347 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9348 (match_operand:DI 2 "arith_reg_operand" "r")
9349 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9353 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9355 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9357 switch (GET_MODE (diff_vec))
9360 return \"ldx.l %1, %2, %0\";
9363 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9364 return \"ldx.uw %1, %2, %0\";
9366 return \"ldx.w %1, %2, %0\";
9368 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9369 return \"ldx.ub %1, %2, %0\";
9370 return \"ldx.b %1, %2, %0\";
9375 [(set_attr "type" "load_media")])
9377 (define_expand "return"
9379 "reload_completed && ! sh_need_epilogue ()"
9384 emit_jump_insn (gen_return_media ());
9388 if (TARGET_SHCOMPACT
9389 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9391 emit_jump_insn (gen_shcompact_return_tramp ());
9396 (define_insn "*return_i"
9398 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9399 && (crtl->args.info.call_cookie
9400 & CALL_COOKIE_RET_TRAMP (1)))
9402 && lookup_attribute (\"trap_exit\",
9403 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9406 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9407 && !current_function_interrupt)
9412 [(set_attr "type" "return")
9413 (set_attr "needs_delay_slot" "yes")])
9415 ;; trapa has no delay slot.
9416 (define_insn "*return_trapa"
9418 "TARGET_SH1 && !TARGET_SHCOMPACT
9419 && reload_completed"
9421 [(set_attr "type" "return")])
9423 (define_expand "shcompact_return_tramp"
9426 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9429 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9431 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9432 emit_jump_insn (gen_shcompact_return_tramp_i ());
9436 (define_insn "shcompact_return_tramp_i"
9437 [(parallel [(return) (use (reg:SI R0_REG))])]
9439 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9441 [(set_attr "type" "jump_ind")
9442 (set_attr "needs_delay_slot" "yes")])
9444 (define_insn "return_media_i"
9445 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9446 "TARGET_SHMEDIA && reload_completed"
9448 [(set_attr "type" "jump_media")])
9450 (define_insn "return_media_rte"
9452 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9454 [(set_attr "type" "jump_media")])
9456 (define_expand "return_media"
9458 "TARGET_SHMEDIA && reload_completed"
9461 int tr_regno = sh_media_register_for_return ();
9464 if (current_function_interrupt)
9466 emit_jump_insn (gen_return_media_rte ());
9471 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9473 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9475 tr = gen_rtx_REG (Pmode, tr_regno);
9476 emit_move_insn (tr, r18);
9479 tr = gen_rtx_REG (Pmode, tr_regno);
9481 emit_jump_insn (gen_return_media_i (tr));
9485 (define_insn "shcompact_preserve_incoming_args"
9486 [(set (match_operand:SI 0 "register_operand" "+r")
9487 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9490 [(set_attr "length" "0")])
9492 (define_insn "shcompact_incoming_args"
9493 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9494 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9495 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9496 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9497 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9498 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9499 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9500 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9501 (set (mem:BLK (reg:SI MACL_REG))
9502 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9503 (use (reg:SI R0_REG))
9504 (clobber (reg:SI R0_REG))
9505 (clobber (reg:SI MACL_REG))
9506 (clobber (reg:SI MACH_REG))
9507 (clobber (reg:SI PR_REG))]
9510 [(set_attr "needs_delay_slot" "yes")])
9512 (define_insn "shmedia_save_restore_regs_compact"
9513 [(set (reg:SI SP_REG)
9514 (plus:SI (reg:SI SP_REG)
9515 (match_operand:SI 0 "immediate_operand" "i")))
9516 (use (reg:SI R0_REG))
9517 (clobber (reg:SI PR_REG))]
9519 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9520 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9522 [(set_attr "needs_delay_slot" "yes")])
9524 (define_expand "prologue"
9527 "sh_expand_prologue (); DONE;")
9529 (define_expand "epilogue"
9534 sh_expand_epilogue (0);
9535 emit_jump_insn (gen_return ());
9539 (define_expand "eh_return"
9540 [(use (match_operand 0 "register_operand" ""))]
9543 rtx ra = operands[0];
9545 if (TARGET_SHMEDIA64)
9546 emit_insn (gen_eh_set_ra_di (ra));
9548 emit_insn (gen_eh_set_ra_si (ra));
9553 ;; Clobber the return address on the stack. We can't expand this
9554 ;; until we know where it will be put in the stack frame.
9556 (define_insn "eh_set_ra_si"
9557 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9559 (clobber (match_scratch:SI 1 "=&r"))]
9560 "! TARGET_SHMEDIA64"
9563 (define_insn "eh_set_ra_di"
9564 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9566 (clobber (match_scratch:DI 1 "=&r"))]
9571 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9573 (clobber (match_scratch 1 ""))]
9578 sh_set_return_address (operands[0], operands[1]);
9582 (define_insn "blockage"
9583 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9586 [(set_attr "length" "0")])
9588 ;; ------------------------------------------------------------------------
9590 ;; ------------------------------------------------------------------------
9593 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9594 (eq:SI (reg:SI T_REG) (const_int 1)))]
9597 [(set_attr "type" "arith")])
9599 ;; complements the T bit and stores the result in a register
9600 (define_insn "movrt"
9601 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9602 (if_then_else (eq:SI (reg:SI T_REG) (const_int 0))
9607 [(set_attr "type" "arith")])
9609 (define_expand "seq"
9610 [(set (match_operand:SI 0 "arith_reg_dest" "")
9619 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9620 if (sh_compare_op1 != const0_rtx)
9621 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9622 ? GET_MODE (sh_compare_op0)
9623 : GET_MODE (sh_compare_op1),
9625 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9627 if (GET_MODE (operands[0]) != SImode)
9628 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9630 switch (GET_MODE (sh_compare_op0))
9633 emit_insn (gen_cmpeqsi_media (operands[0],
9634 sh_compare_op0, sh_compare_op1));
9638 emit_insn (gen_cmpeqdi_media (operands[0],
9639 sh_compare_op0, sh_compare_op1));
9643 if (! TARGET_SHMEDIA_FPU)
9645 emit_insn (gen_cmpeqsf_media (operands[0],
9646 sh_compare_op0, sh_compare_op1));
9650 if (! TARGET_SHMEDIA_FPU)
9652 emit_insn (gen_cmpeqdf_media (operands[0],
9653 sh_compare_op0, sh_compare_op1));
9663 if (GET_MODE (operands[0]) != SImode)
9664 reg = (!can_create_pseudo_p ()
9665 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9666 : gen_reg_rtx (SImode));
9668 switch (GET_MODE (sh_compare_op0))
9671 emit_insn (gen_cmpeqsi_media (reg,
9672 sh_compare_op0, sh_compare_op1));
9676 emit_insn (gen_cmpeqdi_media (reg,
9677 sh_compare_op0, sh_compare_op1));
9681 if (! TARGET_SHMEDIA_FPU)
9683 emit_insn (gen_cmpeqsf_media (reg,
9684 sh_compare_op0, sh_compare_op1));
9688 if (! TARGET_SHMEDIA_FPU)
9690 emit_insn (gen_cmpeqdf_media (reg,
9691 sh_compare_op0, sh_compare_op1));
9698 if (GET_MODE (operands[0]) == DImode)
9699 emit_insn (gen_extendsidi2 (operands[0], reg));
9703 if (sh_expand_t_scc (EQ, operands[0]))
9705 if (! currently_expanding_to_rtl)
9707 operands[1] = prepare_scc_operands (EQ);
9710 (define_expand "slt"
9711 [(set (match_operand:SI 0 "arith_reg_operand" "")
9720 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9721 if (sh_compare_op1 != const0_rtx)
9722 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9723 ? GET_MODE (sh_compare_op0)
9724 : GET_MODE (sh_compare_op1),
9728 if (GET_MODE (operands[0]) != SImode)
9729 reg = (!can_create_pseudo_p ()
9730 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9731 : gen_reg_rtx (SImode));
9733 switch (GET_MODE (sh_compare_op0))
9736 emit_insn (gen_cmpgtsi_media (reg,
9737 sh_compare_op1, sh_compare_op0));
9741 emit_insn (gen_cmpgtdi_media (reg,
9742 sh_compare_op1, sh_compare_op0));
9746 if (! TARGET_SHMEDIA_FPU)
9748 emit_insn (gen_cmpgtsf_media (reg,
9749 sh_compare_op1, sh_compare_op0));
9753 if (! TARGET_SHMEDIA_FPU)
9755 emit_insn (gen_cmpgtdf_media (reg,
9756 sh_compare_op1, sh_compare_op0));
9763 if (GET_MODE (operands[0]) == DImode)
9764 emit_insn (gen_extendsidi2 (operands[0], reg));
9768 if (! currently_expanding_to_rtl)
9770 operands[1] = prepare_scc_operands (LT);
9773 (define_expand "sle"
9774 [(match_operand:SI 0 "arith_reg_operand" "")]
9778 rtx tmp = sh_compare_op0;
9784 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9785 if (sh_compare_op1 != const0_rtx)
9786 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9787 ? GET_MODE (sh_compare_op0)
9788 : GET_MODE (sh_compare_op1),
9792 if (GET_MODE (operands[0]) != SImode)
9793 reg = (!can_create_pseudo_p ()
9794 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9795 : gen_reg_rtx (SImode));
9797 switch (GET_MODE (sh_compare_op0))
9801 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9803 emit_insn (gen_cmpgtsi_media (tmp,
9804 sh_compare_op0, sh_compare_op1));
9805 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9811 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9813 emit_insn (gen_cmpgtdi_media (tmp,
9814 sh_compare_op0, sh_compare_op1));
9815 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9820 if (! TARGET_SHMEDIA_FPU)
9822 emit_insn (gen_cmpgesf_media (reg,
9823 sh_compare_op1, sh_compare_op0));
9827 if (! TARGET_SHMEDIA_FPU)
9829 emit_insn (gen_cmpgedf_media (reg,
9830 sh_compare_op1, sh_compare_op0));
9837 if (GET_MODE (operands[0]) == DImode)
9838 emit_insn (gen_extendsidi2 (operands[0], reg));
9843 sh_compare_op0 = sh_compare_op1;
9844 sh_compare_op1 = tmp;
9845 emit_insn (gen_sge (operands[0]));
9849 (define_expand "sgt"
9850 [(set (match_operand:SI 0 "arith_reg_operand" "")
9860 if (GET_MODE (operands[0]) != SImode)
9861 reg = (!can_create_pseudo_p () ?
9862 gen_rtx_SUBREG (SImode, operands[0], 0)
9863 : gen_reg_rtx (SImode));
9864 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9865 if (sh_compare_op1 != const0_rtx)
9866 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9867 ? GET_MODE (sh_compare_op0)
9868 : GET_MODE (sh_compare_op1),
9871 switch (GET_MODE (sh_compare_op0))
9874 emit_insn (gen_cmpgtsi_media (reg,
9875 sh_compare_op0, sh_compare_op1));
9879 emit_insn (gen_cmpgtdi_media (reg,
9880 sh_compare_op0, sh_compare_op1));
9884 if (! TARGET_SHMEDIA_FPU)
9886 emit_insn (gen_cmpgtsf_media (reg,
9887 sh_compare_op0, sh_compare_op1));
9891 if (! TARGET_SHMEDIA_FPU)
9893 emit_insn (gen_cmpgtdf_media (reg,
9894 sh_compare_op0, sh_compare_op1));
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 (GT);
9911 (define_expand "sge"
9912 [(set (match_operand:SI 0 "arith_reg_operand" "")
9920 enum machine_mode mode = GET_MODE (sh_compare_op0);
9922 if ((mode) == VOIDmode)
9923 mode = GET_MODE (sh_compare_op1);
9925 if (GET_MODE (operands[0]) != SImode)
9926 reg = (!can_create_pseudo_p ()
9927 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9928 : gen_reg_rtx (SImode));
9929 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9930 if (sh_compare_op1 != const0_rtx)
9931 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9937 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9939 emit_insn (gen_cmpgtsi_media (tmp,
9940 sh_compare_op1, sh_compare_op0));
9941 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9947 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9949 emit_insn (gen_cmpgtdi_media (tmp,
9950 sh_compare_op1, sh_compare_op0));
9951 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9956 if (! TARGET_SHMEDIA_FPU)
9958 emit_insn (gen_cmpgesf_media (reg,
9959 sh_compare_op0, sh_compare_op1));
9963 if (! TARGET_SHMEDIA_FPU)
9965 emit_insn (gen_cmpgedf_media (reg,
9966 sh_compare_op0, sh_compare_op1));
9973 if (GET_MODE (operands[0]) == DImode)
9974 emit_insn (gen_extendsidi2 (operands[0], reg));
9979 if (! currently_expanding_to_rtl)
9981 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9985 rtx lab = gen_label_rtx ();
9986 prepare_scc_operands (EQ);
9987 emit_jump_insn (gen_branch_true (lab));
9988 prepare_scc_operands (GT);
9990 emit_insn (gen_movt (operands[0]));
9993 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9996 operands[1] = prepare_scc_operands (GE);
9999 (define_expand "sgtu"
10000 [(set (match_operand:SI 0 "arith_reg_operand" "")
10005 if (TARGET_SHMEDIA)
10010 if (GET_MODE (operands[0]) == DImode)
10011 reg = (!can_create_pseudo_p ()
10012 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10013 : gen_reg_rtx (SImode));
10014 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10015 if (sh_compare_op1 != const0_rtx)
10016 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10017 ? GET_MODE (sh_compare_op0)
10018 : GET_MODE (sh_compare_op1),
10021 emit_insn (gen_cmpgtudi_media (reg,
10022 sh_compare_op0, sh_compare_op1));
10023 if (GET_MODE (operands[0]) == DImode)
10024 emit_insn (gen_extendsidi2 (operands[0], reg));
10028 if (! currently_expanding_to_rtl)
10030 operands[1] = prepare_scc_operands (GTU);
10033 (define_expand "sltu"
10034 [(set (match_operand:SI 0 "arith_reg_operand" "")
10039 if (TARGET_SHMEDIA)
10044 if (GET_MODE (operands[0]) == DImode)
10045 reg = (!can_create_pseudo_p ()
10046 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10047 : gen_reg_rtx (SImode));
10048 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10049 if (sh_compare_op1 != const0_rtx)
10050 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10051 ? GET_MODE (sh_compare_op0)
10052 : GET_MODE (sh_compare_op1),
10055 emit_insn (gen_cmpgtudi_media (reg,
10056 sh_compare_op1, sh_compare_op0));
10057 if (GET_MODE (operands[0]) == DImode)
10058 emit_insn (gen_extendsidi2 (operands[0], reg));
10062 if (! currently_expanding_to_rtl)
10064 operands[1] = prepare_scc_operands (LTU);
10067 (define_expand "sleu"
10068 [(set (match_operand:SI 0 "arith_reg_operand" "")
10073 if (TARGET_SHMEDIA)
10078 if (GET_MODE (operands[0]) != SImode)
10079 reg = (!can_create_pseudo_p ()
10080 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10081 : gen_reg_rtx (SImode));
10082 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10083 if (sh_compare_op1 != const0_rtx)
10084 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10085 ? GET_MODE (sh_compare_op0)
10086 : GET_MODE (sh_compare_op1),
10089 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10091 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
10092 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10093 if (GET_MODE (operands[0]) == DImode)
10094 emit_insn (gen_extendsidi2 (operands[0], reg));
10098 if (! currently_expanding_to_rtl)
10100 operands[1] = prepare_scc_operands (LEU);
10103 (define_expand "sgeu"
10104 [(set (match_operand:SI 0 "arith_reg_operand" "")
10109 if (TARGET_SHMEDIA)
10114 if (GET_MODE (operands[0]) != SImode)
10115 reg = (!can_create_pseudo_p ()
10116 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10117 : gen_reg_rtx (SImode));
10118 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10119 if (sh_compare_op1 != const0_rtx)
10120 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10121 ? GET_MODE (sh_compare_op0)
10122 : GET_MODE (sh_compare_op1),
10125 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
10127 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
10128 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10129 if (GET_MODE (operands[0]) == DImode)
10130 emit_insn (gen_extendsidi2 (operands[0], reg));
10135 if (! currently_expanding_to_rtl)
10137 operands[1] = prepare_scc_operands (GEU);
10140 ;; sne moves the complement of the T reg to DEST like this:
10144 ;; This is better than xoring compare result with 1 because it does
10145 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
10148 (define_expand "sne"
10149 [(set (match_dup 2) (const_int -1))
10150 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
10151 (neg:SI (plus:SI (match_dup 1)
10153 (set (reg:SI T_REG)
10154 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10159 if (TARGET_SHMEDIA)
10164 if (GET_MODE (operands[0]) != SImode)
10165 reg = (!can_create_pseudo_p ()
10166 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10167 : gen_reg_rtx (SImode));
10168 if (! TARGET_SHMEDIA_FPU
10169 && GET_MODE (sh_compare_op0) != DImode
10170 && GET_MODE (sh_compare_op0) != SImode)
10173 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10174 if (sh_compare_op1 != const0_rtx)
10175 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10176 ? GET_MODE (sh_compare_op0)
10177 : GET_MODE (sh_compare_op1),
10180 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10182 emit_insn (gen_seq (tmp));
10183 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10184 if (GET_MODE (operands[0]) == DImode)
10185 emit_insn (gen_extendsidi2 (operands[0], reg));
10190 if (sh_expand_t_scc (NE, operands[0]))
10192 if (! currently_expanding_to_rtl)
10194 operands[1] = prepare_scc_operands (EQ);
10195 operands[2] = gen_reg_rtx (SImode);
10198 (define_expand "sunordered"
10199 [(set (match_operand:SI 0 "arith_reg_operand" "")
10200 (unordered:SI (match_dup 1) (match_dup 2)))]
10201 "TARGET_SHMEDIA_FPU"
10204 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10205 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10208 ;; Use the same trick for FP sle / sge
10210 ;; Apart from the constant use and the T setting, this is like movt,
10211 ;; except that it uses the logically negated value of T, i.e.
10212 ;; operand[0] := T ? 0 : 1.
10213 (define_expand "movnegt"
10214 [(set (match_dup 2) (const_int -1))
10215 (parallel [(set (match_operand 0 "" "")
10216 (neg:SI (plus:SI (match_dup 1)
10218 (set (reg:SI T_REG)
10219 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10222 "operands[2] = gen_reg_rtx (SImode);")
10224 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10225 ;; This prevents a regression that occurred when we switched from xor to
10226 ;; mov/neg for sne.
10229 [(set (match_operand:SI 0 "arith_reg_dest" "")
10230 (plus:SI (reg:SI T_REG)
10233 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10234 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10237 ;; -------------------------------------------------------------------------
10238 ;; Instructions to cope with inline literal tables
10239 ;; -------------------------------------------------------------------------
10241 ; 2 byte integer in line
10243 (define_insn "consttable_2"
10244 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10245 (match_operand 1 "" "")]
10250 if (operands[1] != const0_rtx)
10251 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10254 [(set_attr "length" "2")
10255 (set_attr "in_delay_slot" "no")])
10257 ; 4 byte integer in line
10259 (define_insn "consttable_4"
10260 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10261 (match_operand 1 "" "")]
10266 if (operands[1] != const0_rtx)
10267 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10270 [(set_attr "length" "4")
10271 (set_attr "in_delay_slot" "no")])
10273 ; 8 byte integer in line
10275 (define_insn "consttable_8"
10276 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10277 (match_operand 1 "" "")]
10282 if (operands[1] != const0_rtx)
10283 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10286 [(set_attr "length" "8")
10287 (set_attr "in_delay_slot" "no")])
10289 ; 4 byte floating point
10291 (define_insn "consttable_sf"
10292 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10293 (match_operand 1 "" "")]
10298 if (operands[1] != const0_rtx)
10301 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10302 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10306 [(set_attr "length" "4")
10307 (set_attr "in_delay_slot" "no")])
10309 ; 8 byte floating point
10311 (define_insn "consttable_df"
10312 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10313 (match_operand 1 "" "")]
10318 if (operands[1] != const0_rtx)
10321 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10322 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10326 [(set_attr "length" "8")
10327 (set_attr "in_delay_slot" "no")])
10329 ;; Alignment is needed for some constant tables; it may also be added for
10330 ;; Instructions at the start of loops, or after unconditional branches.
10331 ;; ??? We would get more accurate lengths if we did instruction
10332 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10333 ;; here is too conservative.
10335 ; align to a two byte boundary
10337 (define_expand "align_2"
10338 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10342 ; align to a four byte boundary
10343 ;; align_4 and align_log are instructions for the starts of loops, or
10344 ;; after unconditional branches, which may take up extra room.
10346 (define_expand "align_4"
10347 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10351 ; align to a cache line boundary
10353 (define_insn "align_log"
10354 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10357 [(set_attr "length" "0")
10358 (set_attr "in_delay_slot" "no")])
10360 ; emitted at the end of the literal table, used to emit the
10361 ; 32bit branch labels if needed.
10363 (define_insn "consttable_end"
10364 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10366 "* return output_jump_label_table ();"
10367 [(set_attr "in_delay_slot" "no")])
10369 ; emitted at the end of the window in the literal table.
10371 (define_insn "consttable_window_end"
10372 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10375 [(set_attr "length" "0")
10376 (set_attr "in_delay_slot" "no")])
10378 ;; -------------------------------------------------------------------------
10380 ;; -------------------------------------------------------------------------
10382 ;; String/block move insn.
10384 (define_expand "movmemsi"
10385 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10386 (mem:BLK (match_operand:BLK 1 "" "")))
10387 (use (match_operand:SI 2 "nonmemory_operand" ""))
10388 (use (match_operand:SI 3 "immediate_operand" ""))
10389 (clobber (reg:SI PR_REG))
10390 (clobber (reg:SI R4_REG))
10391 (clobber (reg:SI R5_REG))
10392 (clobber (reg:SI R0_REG))])]
10393 "TARGET_SH1 && ! TARGET_SH5"
10396 if(expand_block_move (operands))
10401 (define_insn "block_move_real"
10402 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10403 (mem:BLK (reg:SI R5_REG)))
10404 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10405 (clobber (reg:SI PR_REG))
10406 (clobber (reg:SI R0_REG))])]
10407 "TARGET_SH1 && ! TARGET_HARD_SH4"
10409 [(set_attr "type" "sfunc")
10410 (set_attr "needs_delay_slot" "yes")])
10412 (define_insn "block_lump_real"
10413 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10414 (mem:BLK (reg:SI R5_REG)))
10415 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10416 (use (reg:SI R6_REG))
10417 (clobber (reg:SI PR_REG))
10418 (clobber (reg:SI T_REG))
10419 (clobber (reg:SI R4_REG))
10420 (clobber (reg:SI R5_REG))
10421 (clobber (reg:SI R6_REG))
10422 (clobber (reg:SI R0_REG))])]
10423 "TARGET_SH1 && ! TARGET_HARD_SH4"
10425 [(set_attr "type" "sfunc")
10426 (set_attr "needs_delay_slot" "yes")])
10428 (define_insn "block_move_real_i4"
10429 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10430 (mem:BLK (reg:SI R5_REG)))
10431 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10432 (clobber (reg:SI PR_REG))
10433 (clobber (reg:SI R0_REG))
10434 (clobber (reg:SI R1_REG))
10435 (clobber (reg:SI R2_REG))])]
10438 [(set_attr "type" "sfunc")
10439 (set_attr "needs_delay_slot" "yes")])
10441 (define_insn "block_lump_real_i4"
10442 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10443 (mem:BLK (reg:SI R5_REG)))
10444 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10445 (use (reg:SI R6_REG))
10446 (clobber (reg:SI PR_REG))
10447 (clobber (reg:SI T_REG))
10448 (clobber (reg:SI R4_REG))
10449 (clobber (reg:SI R5_REG))
10450 (clobber (reg:SI R6_REG))
10451 (clobber (reg:SI R0_REG))
10452 (clobber (reg:SI R1_REG))
10453 (clobber (reg:SI R2_REG))
10454 (clobber (reg:SI R3_REG))])]
10457 [(set_attr "type" "sfunc")
10458 (set_attr "needs_delay_slot" "yes")])
10460 ;; -------------------------------------------------------------------------
10461 ;; Floating point instructions.
10462 ;; -------------------------------------------------------------------------
10464 ;; ??? All patterns should have a type attribute.
10466 (define_expand "movpsi"
10467 [(set (match_operand:PSI 0 "register_operand" "")
10468 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10469 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10472 ;; The c / m alternative is a fake to guide reload to load directly into
10473 ;; fpscr, since reload doesn't know how to use post-increment.
10474 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10475 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10476 ;; predicate after reload.
10477 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10478 ;; like a mac -> gpr move.
10479 (define_insn "fpu_switch"
10480 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10481 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10483 && (! reload_completed
10484 || true_regnum (operands[0]) != FPSCR_REG
10485 || GET_CODE (operands[1]) != MEM
10486 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10488 ! precision stays the same
10497 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10498 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10501 [(set (reg:PSI FPSCR_REG)
10502 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10503 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10506 rtx fpscr, mem, new_insn;
10508 fpscr = SET_DEST (PATTERN (curr_insn));
10509 mem = SET_SRC (PATTERN (curr_insn));
10510 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10512 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10513 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10518 [(set (reg:PSI FPSCR_REG)
10519 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10520 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10521 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10524 rtx fpscr, mem, new_insn;
10526 fpscr = SET_DEST (PATTERN (curr_insn));
10527 mem = SET_SRC (PATTERN (curr_insn));
10528 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10530 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10531 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10533 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10534 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10538 ;; ??? This uses the fp unit, but has no type indicating that.
10539 ;; If we did that, this would either give a bogus latency or introduce
10540 ;; a bogus FIFO constraint.
10541 ;; Since this insn is currently only used for prologues/epilogues,
10542 ;; it is probably best to claim no function unit, which matches the
10543 ;; current setting.
10544 (define_insn "toggle_sz"
10545 [(set (reg:PSI FPSCR_REG)
10546 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10547 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10549 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10551 ;; There's no way we can use it today, since optimize mode switching
10552 ;; doesn't enable us to know from which mode we're switching to the
10553 ;; mode it requests, to tell whether we can use a relative mode switch
10554 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10556 (define_insn "toggle_pr"
10557 [(set (reg:PSI FPSCR_REG)
10558 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10559 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10561 [(set_attr "type" "fpscr_toggle")])
10563 (define_expand "addsf3"
10564 [(set (match_operand:SF 0 "arith_reg_operand" "")
10565 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10566 (match_operand:SF 2 "arith_reg_operand" "")))]
10567 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10572 expand_sf_binop (&gen_addsf3_i, operands);
10577 (define_insn "*addsf3_media"
10578 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10580 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10581 "TARGET_SHMEDIA_FPU"
10582 "fadd.s %1, %2, %0"
10583 [(set_attr "type" "fparith_media")])
10585 (define_insn_and_split "unary_sf_op"
10586 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10591 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10592 (match_operator:SF 2 "unary_float_operator"
10593 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10594 (parallel [(match_operand 4
10595 "const_int_operand" "n")]))]))
10596 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10597 "TARGET_SHMEDIA_FPU"
10599 "TARGET_SHMEDIA_FPU && reload_completed"
10600 [(set (match_dup 5) (match_dup 6))]
10603 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10604 rtx op1 = gen_rtx_REG (SFmode,
10605 (true_regnum (operands[1])
10606 + (INTVAL (operands[4]) ^ endian)));
10608 operands[7] = gen_rtx_REG (SFmode,
10609 (true_regnum (operands[0])
10610 + (INTVAL (operands[3]) ^ endian)));
10611 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10613 [(set_attr "type" "fparith_media")])
10615 (define_insn_and_split "binary_sf_op0"
10616 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10618 (match_operator:SF 3 "binary_float_operator"
10619 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10620 (parallel [(const_int 0)]))
10621 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10622 (parallel [(const_int 0)]))])
10625 (parallel [(const_int 1)]))))]
10626 "TARGET_SHMEDIA_FPU"
10628 "&& reload_completed"
10629 [(set (match_dup 4) (match_dup 5))]
10632 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10633 rtx op1 = gen_rtx_REG (SFmode,
10634 true_regnum (operands[1]) + endian);
10635 rtx op2 = gen_rtx_REG (SFmode,
10636 true_regnum (operands[2]) + endian);
10638 operands[4] = gen_rtx_REG (SFmode,
10639 true_regnum (operands[0]) + endian);
10640 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10642 [(set_attr "type" "fparith_media")])
10644 (define_insn_and_split "binary_sf_op1"
10645 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10649 (parallel [(const_int 0)]))
10650 (match_operator:SF 3 "binary_float_operator"
10651 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10652 (parallel [(const_int 1)]))
10653 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10654 (parallel [(const_int 1)]))])))]
10655 "TARGET_SHMEDIA_FPU"
10657 "&& reload_completed"
10658 [(set (match_dup 4) (match_dup 5))]
10661 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10662 rtx op1 = gen_rtx_REG (SFmode,
10663 true_regnum (operands[1]) + (1 ^ endian));
10664 rtx op2 = gen_rtx_REG (SFmode,
10665 true_regnum (operands[2]) + (1 ^ endian));
10667 operands[4] = gen_rtx_REG (SFmode,
10668 true_regnum (operands[0]) + (1 ^ endian));
10669 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10671 [(set_attr "type" "fparith_media")])
10673 (define_insn "addsf3_i"
10674 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10676 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10677 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10680 [(set_attr "type" "fp")
10681 (set_attr "fp_mode" "single")])
10683 (define_expand "subsf3"
10684 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10685 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10686 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10687 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10692 expand_sf_binop (&gen_subsf3_i, operands);
10697 (define_insn "*subsf3_media"
10698 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10699 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10700 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10701 "TARGET_SHMEDIA_FPU"
10702 "fsub.s %1, %2, %0"
10703 [(set_attr "type" "fparith_media")])
10705 (define_insn "subsf3_i"
10706 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10707 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10708 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10709 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10712 [(set_attr "type" "fp")
10713 (set_attr "fp_mode" "single")])
10715 (define_expand "mulsf3"
10716 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10717 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10718 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10719 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10722 (define_insn "*mulsf3_media"
10723 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10724 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10725 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10726 "TARGET_SHMEDIA_FPU"
10727 "fmul.s %1, %2, %0"
10728 [(set_attr "type" "fparith_media")])
10730 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10731 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10732 ;; we start out with a mulsf pattern that does not depend on fpscr.
10733 ;; This is split after combine to introduce the dependency, in order to
10734 ;; get mode switching and scheduling right.
10735 (define_insn_and_split "mulsf3_ie"
10736 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10737 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10738 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10741 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10745 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10746 get_fpscr_rtx ()));
10749 [(set_attr "type" "fp")])
10751 (define_insn "mulsf3_i4"
10752 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10753 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10754 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10755 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10758 [(set_attr "type" "fp")
10759 (set_attr "fp_mode" "single")])
10761 (define_insn "mac_media"
10762 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10763 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10764 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10765 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10766 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10767 "fmac.s %1, %2, %0"
10768 [(set_attr "type" "fparith_media")])
10770 (define_insn "*macsf3"
10771 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10772 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10773 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10774 (match_operand:SF 3 "arith_reg_operand" "0")))
10775 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10776 "TARGET_SH2E && TARGET_FMAC"
10778 [(set_attr "type" "fp")
10779 (set_attr "fp_mode" "single")])
10781 (define_expand "divsf3"
10782 [(set (match_operand:SF 0 "arith_reg_operand" "")
10783 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10784 (match_operand:SF 2 "arith_reg_operand" "")))]
10785 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10790 expand_sf_binop (&gen_divsf3_i, operands);
10795 (define_insn "*divsf3_media"
10796 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10797 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10798 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10799 "TARGET_SHMEDIA_FPU"
10800 "fdiv.s %1, %2, %0"
10801 [(set_attr "type" "fdiv_media")])
10803 (define_insn "divsf3_i"
10804 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10805 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10806 (match_operand:SF 2 "arith_reg_operand" "f")))
10807 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10810 [(set_attr "type" "fdiv")
10811 (set_attr "fp_mode" "single")])
10813 (define_insn "floatdisf2"
10814 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10815 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10816 "TARGET_SHMEDIA_FPU"
10818 [(set_attr "type" "fpconv_media")])
10820 (define_expand "floatsisf2"
10821 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10822 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10823 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10826 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10828 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10833 (define_insn "*floatsisf2_media"
10834 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10835 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10836 "TARGET_SHMEDIA_FPU"
10838 [(set_attr "type" "fpconv_media")])
10840 (define_insn "floatsisf2_i4"
10841 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10842 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10843 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10844 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10846 [(set_attr "type" "fp")
10847 (set_attr "fp_mode" "single")])
10849 (define_insn "*floatsisf2_ie"
10850 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10851 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10852 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10854 [(set_attr "type" "fp")])
10856 (define_insn "fix_truncsfdi2"
10857 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10858 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10859 "TARGET_SHMEDIA_FPU"
10861 [(set_attr "type" "fpconv_media")])
10863 (define_expand "fix_truncsfsi2"
10864 [(set (match_operand:SI 0 "fpul_operand" "=y")
10865 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10866 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10869 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10871 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10876 (define_insn "*fix_truncsfsi2_media"
10877 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10878 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10879 "TARGET_SHMEDIA_FPU"
10881 [(set_attr "type" "fpconv_media")])
10883 (define_insn "fix_truncsfsi2_i4"
10884 [(set (match_operand:SI 0 "fpul_operand" "=y")
10885 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10886 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10887 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10889 [(set_attr "type" "ftrc_s")
10890 (set_attr "fp_mode" "single")])
10892 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10893 ;; fix_truncsfsi2_i4.
10894 ;; (define_insn "fix_truncsfsi2_i4_2"
10895 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10896 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10897 ;; (use (reg:PSI FPSCR_REG))
10898 ;; (clobber (reg:SI FPUL_REG))]
10901 ;; [(set_attr "length" "4")
10902 ;; (set_attr "fp_mode" "single")])
10905 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10906 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10907 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10908 ;; (clobber (reg:SI FPUL_REG))]
10910 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10911 ;; (use (match_dup 2))])
10912 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10914 (define_insn "*fixsfsi"
10915 [(set (match_operand:SI 0 "fpul_operand" "=y")
10916 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10917 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10919 [(set_attr "type" "fp")])
10921 (define_insn "cmpgtsf_t"
10922 [(set (reg:SI T_REG)
10923 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10924 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10925 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10927 [(set_attr "type" "fp_cmp")
10928 (set_attr "fp_mode" "single")])
10930 (define_insn "cmpeqsf_t"
10931 [(set (reg:SI T_REG)
10932 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10933 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10934 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10936 [(set_attr "type" "fp_cmp")
10937 (set_attr "fp_mode" "single")])
10939 (define_insn "ieee_ccmpeqsf_t"
10940 [(set (reg:SI T_REG)
10941 (ior:SI (reg:SI T_REG)
10942 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10943 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10944 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10945 "* return output_ieee_ccmpeq (insn, operands);"
10946 [(set_attr "length" "4")])
10949 (define_insn "cmpgtsf_t_i4"
10950 [(set (reg:SI T_REG)
10951 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10952 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10953 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10954 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10956 [(set_attr "type" "fp_cmp")
10957 (set_attr "fp_mode" "single")])
10959 (define_insn "cmpeqsf_t_i4"
10960 [(set (reg:SI T_REG)
10961 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10962 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10963 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10964 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10966 [(set_attr "type" "fp_cmp")
10967 (set_attr "fp_mode" "single")])
10969 (define_insn "*ieee_ccmpeqsf_t_4"
10970 [(set (reg:SI T_REG)
10971 (ior:SI (reg:SI T_REG)
10972 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10973 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10974 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10975 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10976 "* return output_ieee_ccmpeq (insn, operands);"
10977 [(set_attr "length" "4")
10978 (set_attr "fp_mode" "single")])
10980 (define_insn "cmpeqsf_media"
10981 [(set (match_operand:SI 0 "register_operand" "=r")
10982 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10983 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10984 "TARGET_SHMEDIA_FPU"
10985 "fcmpeq.s %1, %2, %0"
10986 [(set_attr "type" "fcmp_media")])
10988 (define_insn "cmpgtsf_media"
10989 [(set (match_operand:SI 0 "register_operand" "=r")
10990 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10991 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10992 "TARGET_SHMEDIA_FPU"
10993 "fcmpgt.s %1, %2, %0"
10994 [(set_attr "type" "fcmp_media")])
10996 (define_insn "cmpgesf_media"
10997 [(set (match_operand:SI 0 "register_operand" "=r")
10998 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10999 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11000 "TARGET_SHMEDIA_FPU"
11001 "fcmpge.s %1, %2, %0"
11002 [(set_attr "type" "fcmp_media")])
11004 (define_insn "cmpunsf_media"
11005 [(set (match_operand:SI 0 "register_operand" "=r")
11006 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
11007 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11008 "TARGET_SHMEDIA_FPU"
11009 "fcmpun.s %1, %2, %0"
11010 [(set_attr "type" "fcmp_media")])
11012 (define_expand "cmpsf"
11013 [(set (reg:SI T_REG)
11014 (compare (match_operand:SF 0 "arith_operand" "")
11015 (match_operand:SF 1 "arith_operand" "")))]
11016 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11019 sh_compare_op0 = operands[0];
11020 sh_compare_op1 = operands[1];
11024 (define_expand "negsf2"
11025 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11026 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11027 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11032 expand_sf_unop (&gen_negsf2_i, operands);
11037 (define_insn "*negsf2_media"
11038 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11039 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11040 "TARGET_SHMEDIA_FPU"
11042 [(set_attr "type" "fmove_media")])
11044 (define_insn "negsf2_i"
11045 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11046 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11047 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11050 [(set_attr "type" "fmove")
11051 (set_attr "fp_mode" "single")])
11053 (define_expand "sqrtsf2"
11054 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11055 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11056 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
11061 expand_sf_unop (&gen_sqrtsf2_i, operands);
11066 (define_insn "*sqrtsf2_media"
11067 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11068 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11069 "TARGET_SHMEDIA_FPU"
11071 [(set_attr "type" "fdiv_media")])
11073 (define_insn "sqrtsf2_i"
11074 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11075 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11076 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11079 [(set_attr "type" "fdiv")
11080 (set_attr "fp_mode" "single")])
11082 (define_insn "rsqrtsf2"
11083 [(set (match_operand:SF 0 "register_operand" "=f")
11084 (div:SF (match_operand:SF 1 "immediate_operand" "i")
11085 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
11086 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11087 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11088 && operands[1] == CONST1_RTX (SFmode)"
11090 [(set_attr "type" "fsrra")
11091 (set_attr "fp_mode" "single")])
11093 (define_insn "fsca"
11094 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11096 (unspec:SF [(mult:SF
11097 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
11098 (match_operand:SF 2 "immediate_operand" "i"))
11100 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
11102 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11103 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11104 && operands[2] == sh_fsca_int2sf ()"
11106 [(set_attr "type" "fsca")
11107 (set_attr "fp_mode" "single")])
11109 (define_expand "sinsf2"
11110 [(set (match_operand:SF 0 "nonimmediate_operand" "")
11111 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11113 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11116 rtx scaled = gen_reg_rtx (SFmode);
11117 rtx truncated = gen_reg_rtx (SImode);
11118 rtx fsca = gen_reg_rtx (V2SFmode);
11119 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11121 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11122 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11123 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11124 get_fpscr_rtx ()));
11125 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
11129 (define_expand "cossf2"
11130 [(set (match_operand:SF 0 "nonimmediate_operand" "")
11131 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11133 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11136 rtx scaled = gen_reg_rtx (SFmode);
11137 rtx truncated = gen_reg_rtx (SImode);
11138 rtx fsca = gen_reg_rtx (V2SFmode);
11139 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11141 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11142 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11143 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11144 get_fpscr_rtx ()));
11145 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
11149 (define_expand "sindf2"
11150 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11151 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11153 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11156 rtx scaled = gen_reg_rtx (DFmode);
11157 rtx truncated = gen_reg_rtx (SImode);
11158 rtx fsca = gen_reg_rtx (V2SFmode);
11159 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11160 rtx sfresult = gen_reg_rtx (SFmode);
11162 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11163 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11164 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11165 get_fpscr_rtx ()));
11166 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11167 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11171 (define_expand "cosdf2"
11172 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11173 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11175 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11178 rtx scaled = gen_reg_rtx (DFmode);
11179 rtx truncated = gen_reg_rtx (SImode);
11180 rtx fsca = gen_reg_rtx (V2SFmode);
11181 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11182 rtx sfresult = gen_reg_rtx (SFmode);
11184 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11185 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11186 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11187 get_fpscr_rtx ()));
11188 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11189 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11193 (define_expand "abssf2"
11194 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11195 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11196 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11201 expand_sf_unop (&gen_abssf2_i, operands);
11206 (define_insn "*abssf2_media"
11207 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11208 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11209 "TARGET_SHMEDIA_FPU"
11211 [(set_attr "type" "fmove_media")])
11213 (define_insn "abssf2_i"
11214 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11215 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11216 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11219 [(set_attr "type" "fmove")
11220 (set_attr "fp_mode" "single")])
11222 (define_expand "adddf3"
11223 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11224 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11225 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11226 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11229 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11231 expand_df_binop (&gen_adddf3_i, operands);
11236 (define_insn "*adddf3_media"
11237 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11238 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11239 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11240 "TARGET_SHMEDIA_FPU"
11241 "fadd.d %1, %2, %0"
11242 [(set_attr "type" "dfparith_media")])
11244 (define_insn "adddf3_i"
11245 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11246 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11247 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11248 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11249 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11251 [(set_attr "type" "dfp_arith")
11252 (set_attr "fp_mode" "double")])
11254 (define_expand "subdf3"
11255 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11256 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11257 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11258 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11261 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11263 expand_df_binop (&gen_subdf3_i, operands);
11268 (define_insn "*subdf3_media"
11269 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11270 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11271 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11272 "TARGET_SHMEDIA_FPU"
11273 "fsub.d %1, %2, %0"
11274 [(set_attr "type" "dfparith_media")])
11276 (define_insn "subdf3_i"
11277 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11278 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11279 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11280 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11281 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11283 [(set_attr "type" "dfp_arith")
11284 (set_attr "fp_mode" "double")])
11286 (define_expand "muldf3"
11287 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11288 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11289 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11290 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11293 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11295 expand_df_binop (&gen_muldf3_i, operands);
11300 (define_insn "*muldf3_media"
11301 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11302 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11303 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11304 "TARGET_SHMEDIA_FPU"
11305 "fmul.d %1, %2, %0"
11306 [(set_attr "type" "dfmul_media")])
11308 (define_insn "muldf3_i"
11309 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11310 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11311 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11312 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11313 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11315 [(set_attr "type" "dfp_mul")
11316 (set_attr "fp_mode" "double")])
11318 (define_expand "divdf3"
11319 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11320 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11321 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11322 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11325 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11327 expand_df_binop (&gen_divdf3_i, operands);
11332 (define_insn "*divdf3_media"
11333 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11334 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11335 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11336 "TARGET_SHMEDIA_FPU"
11337 "fdiv.d %1, %2, %0"
11338 [(set_attr "type" "dfdiv_media")])
11340 (define_insn "divdf3_i"
11341 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11342 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11343 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11344 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11345 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11347 [(set_attr "type" "dfdiv")
11348 (set_attr "fp_mode" "double")])
11350 (define_insn "floatdidf2"
11351 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11352 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11353 "TARGET_SHMEDIA_FPU"
11355 [(set_attr "type" "dfpconv_media")])
11357 (define_expand "floatsidf2"
11358 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11359 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11360 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11363 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11365 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11366 get_fpscr_rtx ()));
11371 (define_insn "*floatsidf2_media"
11372 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11373 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11374 "TARGET_SHMEDIA_FPU"
11376 [(set_attr "type" "dfpconv_media")])
11378 (define_insn "floatsidf2_i"
11379 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11380 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11381 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11382 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11384 [(set_attr "type" "dfp_conv")
11385 (set_attr "fp_mode" "double")])
11387 (define_insn "fix_truncdfdi2"
11388 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11389 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11390 "TARGET_SHMEDIA_FPU"
11392 [(set_attr "type" "dfpconv_media")])
11394 (define_expand "fix_truncdfsi2"
11395 [(set (match_operand:SI 0 "fpul_operand" "")
11396 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11397 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11400 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11402 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11403 get_fpscr_rtx ()));
11408 (define_insn "*fix_truncdfsi2_media"
11409 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11410 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11411 "TARGET_SHMEDIA_FPU"
11413 [(set_attr "type" "dfpconv_media")])
11415 (define_insn "fix_truncdfsi2_i"
11416 [(set (match_operand:SI 0 "fpul_operand" "=y")
11417 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11418 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11419 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11421 [(set_attr "type" "dfp_conv")
11422 (set_attr "dfp_comp" "no")
11423 (set_attr "fp_mode" "double")])
11425 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11426 ;; fix_truncdfsi2_i.
11427 ;; (define_insn "fix_truncdfsi2_i4"
11428 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11429 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11430 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11431 ;; (clobber (reg:SI FPUL_REG))]
11434 ;; [(set_attr "length" "4")
11435 ;; (set_attr "fp_mode" "double")])
11438 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11439 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11440 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11441 ;; (clobber (reg:SI FPUL_REG))]
11443 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11444 ;; (use (match_dup 2))])
11445 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11447 (define_insn "cmpgtdf_t"
11448 [(set (reg:SI T_REG)
11449 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11450 (match_operand:DF 1 "arith_reg_operand" "f")))
11451 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11452 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11454 [(set_attr "type" "dfp_cmp")
11455 (set_attr "fp_mode" "double")])
11457 (define_insn "cmpeqdf_t"
11458 [(set (reg:SI T_REG)
11459 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11460 (match_operand:DF 1 "arith_reg_operand" "f")))
11461 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11462 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11464 [(set_attr "type" "dfp_cmp")
11465 (set_attr "fp_mode" "double")])
11467 (define_insn "*ieee_ccmpeqdf_t"
11468 [(set (reg:SI T_REG)
11469 (ior:SI (reg:SI T_REG)
11470 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11471 (match_operand:DF 1 "arith_reg_operand" "f"))))
11472 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11473 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11474 "* return output_ieee_ccmpeq (insn, operands);"
11475 [(set_attr "length" "4")
11476 (set_attr "fp_mode" "double")])
11478 (define_insn "cmpeqdf_media"
11479 [(set (match_operand:SI 0 "register_operand" "=r")
11480 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11481 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11482 "TARGET_SHMEDIA_FPU"
11483 "fcmpeq.d %1,%2,%0"
11484 [(set_attr "type" "fcmp_media")])
11486 (define_insn "cmpgtdf_media"
11487 [(set (match_operand:SI 0 "register_operand" "=r")
11488 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11489 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11490 "TARGET_SHMEDIA_FPU"
11491 "fcmpgt.d %1,%2,%0"
11492 [(set_attr "type" "fcmp_media")])
11494 (define_insn "cmpgedf_media"
11495 [(set (match_operand:SI 0 "register_operand" "=r")
11496 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11497 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11498 "TARGET_SHMEDIA_FPU"
11499 "fcmpge.d %1,%2,%0"
11500 [(set_attr "type" "fcmp_media")])
11502 (define_insn "cmpundf_media"
11503 [(set (match_operand:SI 0 "register_operand" "=r")
11504 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11505 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11506 "TARGET_SHMEDIA_FPU"
11507 "fcmpun.d %1,%2,%0"
11508 [(set_attr "type" "fcmp_media")])
11510 (define_expand "cmpdf"
11511 [(set (reg:SI T_REG)
11512 (compare (match_operand:DF 0 "arith_operand" "")
11513 (match_operand:DF 1 "arith_operand" "")))]
11514 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11517 sh_compare_op0 = operands[0];
11518 sh_compare_op1 = operands[1];
11522 (define_expand "negdf2"
11523 [(set (match_operand:DF 0 "arith_reg_operand" "")
11524 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11525 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11528 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11530 expand_df_unop (&gen_negdf2_i, operands);
11535 (define_insn "*negdf2_media"
11536 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11537 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11538 "TARGET_SHMEDIA_FPU"
11540 [(set_attr "type" "fmove_media")])
11542 (define_insn "negdf2_i"
11543 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11544 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11545 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11546 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11548 [(set_attr "type" "fmove")
11549 (set_attr "fp_mode" "double")])
11551 (define_expand "sqrtdf2"
11552 [(set (match_operand:DF 0 "arith_reg_operand" "")
11553 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11554 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11557 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11559 expand_df_unop (&gen_sqrtdf2_i, operands);
11564 (define_insn "*sqrtdf2_media"
11565 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11566 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11567 "TARGET_SHMEDIA_FPU"
11569 [(set_attr "type" "dfdiv_media")])
11571 (define_insn "sqrtdf2_i"
11572 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11573 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11574 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11575 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11577 [(set_attr "type" "dfdiv")
11578 (set_attr "fp_mode" "double")])
11580 (define_expand "absdf2"
11581 [(set (match_operand:DF 0 "arith_reg_operand" "")
11582 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11583 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11586 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11588 expand_df_unop (&gen_absdf2_i, operands);
11593 (define_insn "*absdf2_media"
11594 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11595 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11596 "TARGET_SHMEDIA_FPU"
11598 [(set_attr "type" "fmove_media")])
11600 (define_insn "absdf2_i"
11601 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11602 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11603 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11604 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11606 [(set_attr "type" "fmove")
11607 (set_attr "fp_mode" "double")])
11609 (define_expand "extendsfdf2"
11610 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11611 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11612 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11615 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11617 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11618 get_fpscr_rtx ()));
11623 (define_insn "*extendsfdf2_media"
11624 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11625 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11626 "TARGET_SHMEDIA_FPU"
11628 [(set_attr "type" "dfpconv_media")])
11630 (define_insn "extendsfdf2_i4"
11631 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11632 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11633 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11634 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11636 [(set_attr "type" "fp")
11637 (set_attr "fp_mode" "double")])
11639 (define_expand "truncdfsf2"
11640 [(set (match_operand:SF 0 "fpul_operand" "")
11641 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11642 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11645 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11647 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11648 get_fpscr_rtx ()));
11653 (define_insn "*truncdfsf2_media"
11654 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11655 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11656 "TARGET_SHMEDIA_FPU"
11658 [(set_attr "type" "dfpconv_media")])
11660 (define_insn "truncdfsf2_i4"
11661 [(set (match_operand:SF 0 "fpul_operand" "=y")
11662 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11663 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11664 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11666 [(set_attr "type" "fp")
11667 (set_attr "fp_mode" "double")])
11669 ;; Bit field extract patterns. These give better code for packed bitfields,
11670 ;; because they allow auto-increment addresses to be generated.
11672 (define_expand "insv"
11673 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11674 (match_operand:SI 1 "immediate_operand" "")
11675 (match_operand:SI 2 "immediate_operand" ""))
11676 (match_operand:SI 3 "general_operand" ""))]
11677 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11680 rtx addr_target, orig_address, shift_reg, qi_val;
11681 HOST_WIDE_INT bitsize, size, v = 0;
11682 rtx x = operands[3];
11684 if (TARGET_SH2A && TARGET_BITOPS
11685 && (satisfies_constraint_Sbw (operands[0])
11686 || satisfies_constraint_Sbv (operands[0]))
11687 && satisfies_constraint_M (operands[1])
11688 && satisfies_constraint_K03 (operands[2]))
11690 if (satisfies_constraint_N (operands[3]))
11692 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11695 else if (satisfies_constraint_M (operands[3]))
11697 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11700 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11701 && satisfies_constraint_M (operands[1]))
11703 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11706 else if (REG_P (operands[3])
11707 && satisfies_constraint_M (operands[1]))
11709 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11710 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11714 /* ??? expmed doesn't care for non-register predicates. */
11715 if (! memory_operand (operands[0], VOIDmode)
11716 || ! immediate_operand (operands[1], VOIDmode)
11717 || ! immediate_operand (operands[2], VOIDmode)
11718 || ! general_operand (x, VOIDmode))
11720 /* If this isn't a 16 / 24 / 32 bit field, or if
11721 it doesn't start on a byte boundary, then fail. */
11722 bitsize = INTVAL (operands[1]);
11723 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11724 || (INTVAL (operands[2]) % 8) != 0)
11727 size = bitsize / 8;
11728 orig_address = XEXP (operands[0], 0);
11729 shift_reg = gen_reg_rtx (SImode);
11730 if (GET_CODE (x) == CONST_INT)
11733 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11737 emit_insn (gen_movsi (shift_reg, operands[3]));
11738 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11740 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11742 operands[0] = replace_equiv_address (operands[0], addr_target);
11743 emit_insn (gen_movqi (operands[0], qi_val));
11747 if (GET_CODE (x) == CONST_INT)
11749 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11752 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11753 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11755 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11756 emit_insn (gen_movqi (operands[0], qi_val));
11762 (define_insn "movua"
11763 [(set (match_operand:SI 0 "register_operand" "=z")
11764 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11768 [(set_attr "type" "movua")])
11770 ;; We shouldn't need this, but cse replaces increments with references
11771 ;; to other regs before flow has a chance to create post_inc
11772 ;; addressing modes, and only postreload's cse_move2add brings the
11773 ;; increments back to a usable form.
11775 [(set (match_operand:SI 0 "register_operand" "")
11776 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11777 (const_int 32) (const_int 0)))
11778 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11779 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11780 [(set (match_operand:SI 0 "register_operand" "")
11781 (sign_extract:SI (mem:SI (post_inc:SI
11782 (match_operand:SI 1 "register_operand" "")))
11783 (const_int 32) (const_int 0)))]
11786 (define_expand "extv"
11787 [(set (match_operand:SI 0 "register_operand" "")
11788 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11789 (match_operand 2 "const_int_operand" "")
11790 (match_operand 3 "const_int_operand" "")))]
11791 "TARGET_SH4A_ARCH || TARGET_SH2A"
11793 if (TARGET_SH2A && TARGET_BITOPS
11794 && (satisfies_constraint_Sbw (operands[1])
11795 || satisfies_constraint_Sbv (operands[1]))
11796 && satisfies_constraint_M (operands[2])
11797 && satisfies_constraint_K03 (operands[3]))
11799 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11800 if (REGNO (operands[0]) != T_REG)
11801 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11804 if (TARGET_SH4A_ARCH
11805 && INTVAL (operands[2]) == 32
11806 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11807 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11809 rtx src = adjust_address (operands[1], BLKmode, 0);
11810 set_mem_size (src, GEN_INT (4));
11811 emit_insn (gen_movua (operands[0], src));
11818 (define_expand "extzv"
11819 [(set (match_operand:SI 0 "register_operand" "")
11820 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11821 (match_operand 2 "const_int_operand" "")
11822 (match_operand 3 "const_int_operand" "")))]
11823 "TARGET_SH4A_ARCH || TARGET_SH2A"
11825 if (TARGET_SH2A && TARGET_BITOPS
11826 && (satisfies_constraint_Sbw (operands[1])
11827 || satisfies_constraint_Sbv (operands[1]))
11828 && satisfies_constraint_M (operands[2])
11829 && satisfies_constraint_K03 (operands[3]))
11831 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11832 if (REGNO (operands[0]) != T_REG)
11833 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11836 if (TARGET_SH4A_ARCH
11837 && INTVAL (operands[2]) == 32
11838 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11839 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11841 rtx src = adjust_address (operands[1], BLKmode, 0);
11842 set_mem_size (src, GEN_INT (4));
11843 emit_insn (gen_movua (operands[0], src));
11850 ;; SH2A instructions for bitwise operations.
11852 ;; Clear a bit in a memory location.
11853 (define_insn "bclr_m2a"
11854 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11856 (not:QI (ashift:QI (const_int 1)
11857 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11859 "TARGET_SH2A && TARGET_BITOPS"
11862 bclr.b\\t%1,@(0,%t0)"
11863 [(set_attr "length" "4,4")])
11865 (define_insn "bclrmem_m2a"
11866 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11867 (and:QI (match_dup 0)
11868 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11869 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11872 bclr.b\\t%W1,@(0,%t0)"
11873 [(set_attr "length" "4,4")])
11875 ;; Set a bit in a memory location.
11876 (define_insn "bset_m2a"
11877 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11879 (ashift:QI (const_int 1)
11880 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11882 "TARGET_SH2A && TARGET_BITOPS"
11885 bset.b\\t%1,@(0,%t0)"
11886 [(set_attr "length" "4,4")])
11888 (define_insn "bsetmem_m2a"
11889 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11890 (ior:QI (match_dup 0)
11891 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11892 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11895 bset.b\\t%V1,@(0,%t0)"
11896 [(set_attr "length" "4,4")])
11898 ;;; Transfer the contents of the T bit to a specified bit of memory.
11899 (define_insn "bst_m2a"
11900 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11901 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11903 (not:QI (ashift:QI (const_int 1)
11904 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11907 (ashift:QI (const_int 1) (match_dup 1))
11909 "TARGET_SH2A && TARGET_BITOPS"
11912 bst.b\\t%1,@(0,%t0)"
11913 [(set_attr "length" "4")])
11915 ;; Store a specified bit of memory in the T bit.
11916 (define_insn "bld_m2a"
11917 [(set (reg:SI T_REG)
11919 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11921 (match_operand 1 "const_int_operand" "K03,K03")))]
11922 "TARGET_SH2A && TARGET_BITOPS"
11925 bld.b\\t%1,@(0,%t0)"
11926 [(set_attr "length" "4,4")])
11928 ;; Store a specified bit of memory in the T bit.
11929 (define_insn "bldsign_m2a"
11930 [(set (reg:SI T_REG)
11932 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11934 (match_operand 1 "const_int_operand" "K03,K03")))]
11935 "TARGET_SH2A && TARGET_BITOPS"
11938 bld.b\\t%1,@(0,%t0)"
11939 [(set_attr "length" "4,4")])
11941 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11942 (define_insn "bld_reg"
11943 [(set (reg:SI T_REG)
11944 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11946 (match_operand 1 "const_int_operand" "K03")))]
11950 (define_insn "*bld_regqi"
11951 [(set (reg:SI T_REG)
11952 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11954 (match_operand 1 "const_int_operand" "K03")))]
11958 ;; Take logical and of a specified bit of memory with the T bit and
11959 ;; store its result in the T bit.
11960 (define_insn "band_m2a"
11961 [(set (reg:SI T_REG)
11962 (and:SI (reg:SI T_REG)
11964 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11966 (match_operand 1 "const_int_operand" "K03,K03"))))]
11967 "TARGET_SH2A && TARGET_BITOPS"
11970 band.b\\t%1,@(0,%t0)"
11971 [(set_attr "length" "4,4")])
11973 (define_insn "bandreg_m2a"
11974 [(set (match_operand:SI 0 "register_operand" "=r,r")
11975 (and:SI (zero_extract:SI
11976 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11978 (match_operand 2 "const_int_operand" "K03,K03"))
11979 (match_operand:SI 3 "register_operand" "r,r")))]
11980 "TARGET_SH2A && TARGET_BITOPS"
11982 band.b\\t%2,%1\;movt\\t%0
11983 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11984 [(set_attr "length" "6,6")])
11986 ;; Take logical or of a specified bit of memory with the T bit and
11987 ;; store its result in the T bit.
11988 (define_insn "bor_m2a"
11989 [(set (reg:SI T_REG)
11990 (ior:SI (reg:SI T_REG)
11992 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11994 (match_operand 1 "const_int_operand" "K03,K03"))))]
11995 "TARGET_SH2A && TARGET_BITOPS"
11998 bor.b\\t%1,@(0,%t0)"
11999 [(set_attr "length" "4,4")])
12001 (define_insn "borreg_m2a"
12002 [(set (match_operand:SI 0 "register_operand" "=r,r")
12003 (ior:SI (zero_extract:SI
12004 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12006 (match_operand 2 "const_int_operand" "K03,K03"))
12007 (match_operand:SI 3 "register_operand" "=r,r")))]
12008 "TARGET_SH2A && TARGET_BITOPS"
12010 bor.b\\t%2,%1\;movt\\t%0
12011 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
12012 [(set_attr "length" "6,6")])
12014 ;; Take exclusive or of a specified bit of memory with the T bit and
12015 ;; store its result in the T bit.
12016 (define_insn "bxor_m2a"
12017 [(set (reg:SI T_REG)
12018 (xor:SI (reg:SI T_REG)
12020 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
12022 (match_operand 1 "const_int_operand" "K03,K03"))))]
12023 "TARGET_SH2A && TARGET_BITOPS"
12026 bxor.b\\t%1,@(0,%t0)"
12027 [(set_attr "length" "4,4")])
12029 (define_insn "bxorreg_m2a"
12030 [(set (match_operand:SI 0 "register_operand" "=r,r")
12031 (xor:SI (zero_extract:SI
12032 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12034 (match_operand 2 "const_int_operand" "K03,K03"))
12035 (match_operand:SI 3 "register_operand" "=r,r")))]
12036 "TARGET_SH2A && TARGET_BITOPS"
12038 bxor.b\\t%2,%1\;movt\\t%0
12039 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
12040 [(set_attr "length" "6,6")])
12043 ;; -------------------------------------------------------------------------
12045 ;; -------------------------------------------------------------------------
12046 ;; This matches cases where the bit in a memory location is set.
12048 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12049 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12051 (ior:SI (match_dup 0)
12052 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
12054 (match_operand 3 "arith_reg_operand" "r,r"))]
12055 "TARGET_SH2A && TARGET_BITOPS
12056 && satisfies_constraint_Pso (operands[2])
12057 && REGNO (operands[0]) == REGNO (operands[3])"
12058 [(set (match_dup 1)
12059 (ior:QI (match_dup 1)
12063 ;; This matches cases where the bit in a memory location is cleared.
12065 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12066 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12068 (and:SI (match_dup 0)
12069 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
12071 (match_operand 3 "arith_reg_operand" "r,r"))]
12072 "TARGET_SH2A && TARGET_BITOPS
12073 && satisfies_constraint_Psz (operands[2])
12074 && REGNO (operands[0]) == REGNO (operands[3])"
12075 [(set (match_dup 1)
12076 (and:QI (match_dup 1)
12080 ;; This matches cases where a stack pointer increment at the start of the
12081 ;; epilogue combines with a stack slot read loading the return value.
12084 [(set (match_operand:SI 0 "arith_reg_operand" "")
12085 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
12086 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
12087 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
12090 ;; See the comment on the dt combiner pattern above.
12093 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12094 (plus:SI (match_dup 0)
12096 (set (reg:SI T_REG)
12097 (eq:SI (match_dup 0)
12102 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
12103 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
12104 ;; reload when the constant is too large for a reg+offset address.
12106 ;; ??? We would get much better code if this was done in reload. This would
12107 ;; require modifying find_reloads_address to recognize that if the constant
12108 ;; is out-of-range for an immediate add, then we get better code by reloading
12109 ;; the constant into a register than by reloading the sum into a register,
12110 ;; since the former is one instruction shorter if the address does not need
12111 ;; to be offsettable. Unfortunately this does not work, because there is
12112 ;; only one register, r0, that can be used as an index register. This register
12113 ;; is also the function return value register. So, if we try to force reload
12114 ;; to use double-reg addresses, then we end up with some instructions that
12115 ;; need to use r0 twice. The only way to fix this is to change the calling
12116 ;; convention so that r0 is not used to return values.
12119 [(set (match_operand:SI 0 "register_operand" "=r")
12120 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12121 (set (mem:SI (match_dup 0))
12122 (match_operand:SI 2 "general_movsrc_operand" ""))]
12123 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12124 "mov.l %2,@(%0,%1)")
12127 [(set (match_operand:SI 0 "register_operand" "=r")
12128 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12129 (set (match_operand:SI 2 "general_movdst_operand" "")
12130 (mem:SI (match_dup 0)))]
12131 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12132 "mov.l @(%0,%1),%2")
12135 [(set (match_operand:SI 0 "register_operand" "=r")
12136 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12137 (set (mem:HI (match_dup 0))
12138 (match_operand:HI 2 "general_movsrc_operand" ""))]
12139 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12140 "mov.w %2,@(%0,%1)")
12143 [(set (match_operand:SI 0 "register_operand" "=r")
12144 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12145 (set (match_operand:HI 2 "general_movdst_operand" "")
12146 (mem:HI (match_dup 0)))]
12147 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12148 "mov.w @(%0,%1),%2")
12151 [(set (match_operand:SI 0 "register_operand" "=r")
12152 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12153 (set (mem:QI (match_dup 0))
12154 (match_operand:QI 2 "general_movsrc_operand" ""))]
12155 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12156 "mov.b %2,@(%0,%1)")
12159 [(set (match_operand:SI 0 "register_operand" "=r")
12160 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12161 (set (match_operand:QI 2 "general_movdst_operand" "")
12162 (mem:QI (match_dup 0)))]
12163 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12164 "mov.b @(%0,%1),%2")
12167 [(set (match_operand:SI 0 "register_operand" "=r")
12168 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12169 (set (mem:SF (match_dup 0))
12170 (match_operand:SF 2 "general_movsrc_operand" ""))]
12171 "TARGET_SH1 && REGNO (operands[0]) == 0
12172 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12173 || (GET_CODE (operands[2]) == SUBREG
12174 && REGNO (SUBREG_REG (operands[2])) < 16))
12175 && reg_unused_after (operands[0], insn)"
12176 "mov.l %2,@(%0,%1)")
12179 [(set (match_operand:SI 0 "register_operand" "=r")
12180 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12181 (set (match_operand:SF 2 "general_movdst_operand" "")
12183 (mem:SF (match_dup 0)))]
12184 "TARGET_SH1 && REGNO (operands[0]) == 0
12185 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12186 || (GET_CODE (operands[2]) == SUBREG
12187 && REGNO (SUBREG_REG (operands[2])) < 16))
12188 && reg_unused_after (operands[0], insn)"
12189 "mov.l @(%0,%1),%2")
12192 [(set (match_operand:SI 0 "register_operand" "=r")
12193 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12194 (set (mem:SF (match_dup 0))
12195 (match_operand:SF 2 "general_movsrc_operand" ""))]
12196 "TARGET_SH2E && REGNO (operands[0]) == 0
12197 && ((GET_CODE (operands[2]) == REG
12198 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12199 || (GET_CODE (operands[2]) == SUBREG
12200 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12201 && reg_unused_after (operands[0], insn)"
12202 "fmov{.s|} %2,@(%0,%1)")
12205 [(set (match_operand:SI 0 "register_operand" "=r")
12206 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12207 (set (match_operand:SF 2 "general_movdst_operand" "")
12209 (mem:SF (match_dup 0)))]
12210 "TARGET_SH2E && REGNO (operands[0]) == 0
12211 && ((GET_CODE (operands[2]) == REG
12212 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12213 || (GET_CODE (operands[2]) == SUBREG
12214 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12215 && reg_unused_after (operands[0], insn)"
12216 "fmov{.s|} @(%0,%1),%2")
12218 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
12219 (define_insn "sp_switch_1"
12220 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
12224 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
12225 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
12226 return \"mov r0,r15\";
12228 [(set_attr "length" "10")])
12230 ;; Switch back to the original stack for interrupt functions with the
12231 ;; sp_switch attribute. */
12232 (define_insn "sp_switch_2"
12235 "mov.l @r15+,r15\;mov.l @r15+,r0"
12236 [(set_attr "length" "4")])
12238 ;; Integer vector moves
12240 (define_expand "movv8qi"
12241 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
12242 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
12244 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
12246 (define_insn "movv8qi_i"
12247 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
12248 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12250 && (register_operand (operands[0], V8QImode)
12251 || sh_register_operand (operands[1], V8QImode))"
12258 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12259 (set_attr "length" "4,4,16,4,4")])
12262 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
12263 (subreg:V8QI (const_int 0) 0))]
12265 [(set (match_dup 0)
12266 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
12267 (const_int 0) (const_int 0) (const_int 0)
12268 (const_int 0) (const_int 0)]))])
12271 [(set (match_operand 0 "arith_reg_dest" "")
12272 (match_operand 1 "sh_rep_vec" ""))]
12273 "TARGET_SHMEDIA && reload_completed
12274 && GET_MODE (operands[0]) == GET_MODE (operands[1])
12275 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
12276 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
12277 && (XVECEXP (operands[1], 0, 0) != const0_rtx
12278 || XVECEXP (operands[1], 0, 1) != const0_rtx)
12279 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
12280 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
12281 [(set (match_dup 0) (match_dup 1))
12285 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
12286 rtx elt1 = XVECEXP (operands[1], 0, 1);
12289 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
12293 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
12294 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
12296 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
12297 operands[1] = XVECEXP (operands[1], 0, 0);
12300 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
12302 = GEN_INT (TARGET_LITTLE_ENDIAN
12303 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
12304 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
12307 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
12309 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
12315 [(set (match_operand 0 "arith_reg_dest" "")
12316 (match_operand 1 "sh_const_vec" ""))]
12317 "TARGET_SHMEDIA && reload_completed
12318 && GET_MODE (operands[0]) == GET_MODE (operands[1])
12319 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
12320 [(set (match_dup 0) (match_dup 1))]
12323 rtx v = operands[1];
12324 enum machine_mode new_mode
12325 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
12327 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
12329 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
12332 (define_expand "movv2hi"
12333 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
12334 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
12336 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
12338 (define_insn "movv2hi_i"
12339 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12340 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12342 && (register_operand (operands[0], V2HImode)
12343 || sh_register_operand (operands[1], V2HImode))"
12350 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12351 (set_attr "length" "4,4,16,4,4")
12352 (set (attr "highpart")
12353 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
12354 (const_string "user")]
12355 (const_string "ignore")))])
12357 (define_expand "movv4hi"
12358 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
12359 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
12361 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
12363 (define_insn "movv4hi_i"
12364 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12365 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12367 && (register_operand (operands[0], V4HImode)
12368 || sh_register_operand (operands[1], V4HImode))"
12375 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12376 (set_attr "length" "4,4,16,4,4")
12377 (set_attr "highpart" "depend")])
12379 (define_expand "movv2si"
12380 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
12381 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
12383 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
12385 (define_insn "movv2si_i"
12386 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
12387 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12389 && (register_operand (operands[0], V2SImode)
12390 || sh_register_operand (operands[1], V2SImode))"
12397 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12398 (set_attr "length" "4,4,16,4,4")
12399 (set_attr "highpart" "depend")])
12401 ;; Multimedia Intrinsics
12403 (define_insn "absv2si2"
12404 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12405 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
12408 [(set_attr "type" "mcmp_media")
12409 (set_attr "highpart" "depend")])
12411 (define_insn "absv4hi2"
12412 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12413 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
12416 [(set_attr "type" "mcmp_media")
12417 (set_attr "highpart" "depend")])
12419 (define_insn "addv2si3"
12420 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12421 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12422 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12424 "madd.l %1, %2, %0"
12425 [(set_attr "type" "arith_media")
12426 (set_attr "highpart" "depend")])
12428 (define_insn "addv4hi3"
12429 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12430 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12431 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12433 "madd.w %1, %2, %0"
12434 [(set_attr "type" "arith_media")
12435 (set_attr "highpart" "depend")])
12437 (define_insn_and_split "addv2hi3"
12438 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12439 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12440 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12447 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12448 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12449 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12450 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12451 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12453 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12454 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12457 [(set_attr "highpart" "must_split")])
12459 (define_insn "ssaddv2si3"
12460 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12461 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12462 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12464 "madds.l %1, %2, %0"
12465 [(set_attr "type" "mcmp_media")
12466 (set_attr "highpart" "depend")])
12468 (define_insn "usaddv8qi3"
12469 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12470 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12471 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12473 "madds.ub %1, %2, %0"
12474 [(set_attr "type" "mcmp_media")
12475 (set_attr "highpart" "depend")])
12477 (define_insn "ssaddv4hi3"
12478 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12479 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12480 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12482 "madds.w %1, %2, %0"
12483 [(set_attr "type" "mcmp_media")
12484 (set_attr "highpart" "depend")])
12486 (define_insn "negcmpeqv8qi"
12487 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12488 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12489 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12491 "mcmpeq.b %N1, %N2, %0"
12492 [(set_attr "type" "mcmp_media")
12493 (set_attr "highpart" "depend")])
12495 (define_insn "negcmpeqv2si"
12496 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12497 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12498 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12500 "mcmpeq.l %N1, %N2, %0"
12501 [(set_attr "type" "mcmp_media")
12502 (set_attr "highpart" "depend")])
12504 (define_insn "negcmpeqv4hi"
12505 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12506 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12507 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12509 "mcmpeq.w %N1, %N2, %0"
12510 [(set_attr "type" "mcmp_media")
12511 (set_attr "highpart" "depend")])
12513 (define_insn "negcmpgtuv8qi"
12514 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12515 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12516 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12518 "mcmpgt.ub %N1, %N2, %0"
12519 [(set_attr "type" "mcmp_media")
12520 (set_attr "highpart" "depend")])
12522 (define_insn "negcmpgtv2si"
12523 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12524 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12525 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12527 "mcmpgt.l %N1, %N2, %0"
12528 [(set_attr "type" "mcmp_media")
12529 (set_attr "highpart" "depend")])
12531 (define_insn "negcmpgtv4hi"
12532 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12533 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12534 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12536 "mcmpgt.w %N1, %N2, %0"
12537 [(set_attr "type" "mcmp_media")
12538 (set_attr "highpart" "depend")])
12540 (define_insn "mcmv"
12541 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12542 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12543 (match_operand:DI 2 "arith_reg_operand" "r"))
12544 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12545 (not:DI (match_dup 2)))))]
12548 [(set_attr "type" "arith_media")
12549 (set_attr "highpart" "depend")])
12551 (define_insn "mcnvs_lw"
12552 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12554 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12555 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12557 "mcnvs.lw %N1, %N2, %0"
12558 [(set_attr "type" "mcmp_media")])
12560 (define_insn "mcnvs_wb"
12561 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12563 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12564 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12566 "mcnvs.wb %N1, %N2, %0"
12567 [(set_attr "type" "mcmp_media")])
12569 (define_insn "mcnvs_wub"
12570 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12572 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12573 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12575 "mcnvs.wub %N1, %N2, %0"
12576 [(set_attr "type" "mcmp_media")])
12578 (define_insn "mextr_rl"
12579 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12580 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12581 (match_operand:HI 3 "mextr_bit_offset" "i"))
12582 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12583 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12584 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12587 static char templ[21];
12589 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12590 (int) INTVAL (operands[3]) >> 3);
12593 [(set_attr "type" "arith_media")])
12595 (define_insn "*mextr_lr"
12596 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12597 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12598 (match_operand:HI 3 "mextr_bit_offset" "i"))
12599 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12600 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12601 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12604 static char templ[21];
12606 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12607 (int) INTVAL (operands[4]) >> 3);
12610 [(set_attr "type" "arith_media")])
12612 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12613 ; vector then varies depending on endianness.
12614 (define_expand "mextr1"
12615 [(match_operand:DI 0 "arith_reg_dest" "")
12616 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12617 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12621 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12622 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12626 (define_expand "mextr2"
12627 [(match_operand:DI 0 "arith_reg_dest" "")
12628 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12629 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12633 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12634 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12638 (define_expand "mextr3"
12639 [(match_operand:DI 0 "arith_reg_dest" "")
12640 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12641 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12645 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12646 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12650 (define_expand "mextr4"
12651 [(match_operand:DI 0 "arith_reg_dest" "")
12652 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12653 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12657 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12658 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12662 (define_expand "mextr5"
12663 [(match_operand:DI 0 "arith_reg_dest" "")
12664 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12665 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12669 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12670 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12674 (define_expand "mextr6"
12675 [(match_operand:DI 0 "arith_reg_dest" "")
12676 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12677 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12681 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12682 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12686 (define_expand "mextr7"
12687 [(match_operand:DI 0 "arith_reg_dest" "")
12688 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12689 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12693 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12694 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12698 (define_expand "mmacfx_wl"
12699 [(match_operand:V2SI 0 "arith_reg_dest" "")
12700 (match_operand:V2HI 1 "extend_reg_operand" "")
12701 (match_operand:V2HI 2 "extend_reg_operand" "")
12702 (match_operand:V2SI 3 "arith_reg_operand" "")]
12706 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12707 operands[1], operands[2]));
12711 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12713 (define_insn "mmacfx_wl_i"
12714 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12716 (match_operand:V2SI 1 "arith_reg_operand" "0")
12721 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12722 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12725 "mmacfx.wl %2, %3, %0"
12726 [(set_attr "type" "mac_media")
12727 (set_attr "highpart" "depend")])
12729 (define_expand "mmacnfx_wl"
12730 [(match_operand:V2SI 0 "arith_reg_dest" "")
12731 (match_operand:V2HI 1 "extend_reg_operand" "")
12732 (match_operand:V2HI 2 "extend_reg_operand" "")
12733 (match_operand:V2SI 3 "arith_reg_operand" "")]
12737 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12738 operands[1], operands[2]));
12742 (define_insn "mmacnfx_wl_i"
12743 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12745 (match_operand:V2SI 1 "arith_reg_operand" "0")
12750 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12751 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12754 "mmacnfx.wl %2, %3, %0"
12755 [(set_attr "type" "mac_media")
12756 (set_attr "highpart" "depend")])
12758 (define_insn "mulv2si3"
12759 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12760 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12761 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12763 "mmul.l %1, %2, %0"
12764 [(set_attr "type" "d2mpy_media")
12765 (set_attr "highpart" "depend")])
12767 (define_insn "mulv4hi3"
12768 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12769 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12770 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12772 "mmul.w %1, %2, %0"
12773 [(set_attr "type" "dmpy_media")
12774 (set_attr "highpart" "depend")])
12776 (define_insn "mmulfx_l"
12777 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12781 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12782 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12785 "mmulfx.l %1, %2, %0"
12786 [(set_attr "type" "d2mpy_media")
12787 (set_attr "highpart" "depend")])
12789 (define_insn "mmulfx_w"
12790 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12794 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12795 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12798 "mmulfx.w %1, %2, %0"
12799 [(set_attr "type" "dmpy_media")
12800 (set_attr "highpart" "depend")])
12802 (define_insn "mmulfxrp_w"
12803 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12808 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12809 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12813 "mmulfxrp.w %1, %2, %0"
12814 [(set_attr "type" "dmpy_media")
12815 (set_attr "highpart" "depend")])
12818 (define_expand "mmulhi_wl"
12819 [(match_operand:V2SI 0 "arith_reg_dest" "")
12820 (match_operand:V4HI 1 "arith_reg_operand" "")
12821 (match_operand:V4HI 2 "arith_reg_operand" "")]
12825 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12826 (operands[0], operands[1], operands[2]));
12830 (define_expand "mmullo_wl"
12831 [(match_operand:V2SI 0 "arith_reg_dest" "")
12832 (match_operand:V4HI 1 "arith_reg_operand" "")
12833 (match_operand:V4HI 2 "arith_reg_operand" "")]
12837 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12838 (operands[0], operands[1], operands[2]));
12842 (define_insn "mmul23_wl"
12843 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12846 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12847 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12848 (parallel [(const_int 2) (const_int 3)])))]
12850 "* return (TARGET_LITTLE_ENDIAN
12851 ? \"mmulhi.wl %1, %2, %0\"
12852 : \"mmullo.wl %1, %2, %0\");"
12853 [(set_attr "type" "dmpy_media")
12854 (set (attr "highpart")
12855 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12856 (const_string "user")))])
12858 (define_insn "mmul01_wl"
12859 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12862 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12863 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12864 (parallel [(const_int 0) (const_int 1)])))]
12866 "* return (TARGET_LITTLE_ENDIAN
12867 ? \"mmullo.wl %1, %2, %0\"
12868 : \"mmulhi.wl %1, %2, %0\");"
12869 [(set_attr "type" "dmpy_media")
12870 (set (attr "highpart")
12871 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12872 (const_string "user")))])
12875 (define_expand "mmulsum_wq"
12876 [(match_operand:DI 0 "arith_reg_dest" "")
12877 (match_operand:V4HI 1 "arith_reg_operand" "")
12878 (match_operand:V4HI 2 "arith_reg_operand" "")
12879 (match_operand:DI 3 "arith_reg_operand" "")]
12883 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12884 operands[1], operands[2]));
12888 (define_insn "mmulsum_wq_i"
12889 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12890 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12895 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12896 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12897 (parallel [(const_int 0)]))
12898 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12899 (sign_extend:V4DI (match_dup 3)))
12900 (parallel [(const_int 1)])))
12902 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12903 (sign_extend:V4DI (match_dup 3)))
12904 (parallel [(const_int 2)]))
12905 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12906 (sign_extend:V4DI (match_dup 3)))
12907 (parallel [(const_int 3)]))))))]
12909 "mmulsum.wq %2, %3, %0"
12910 [(set_attr "type" "mac_media")])
12912 (define_expand "mperm_w"
12913 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12914 (match_operand:V4HI 1 "arith_reg_operand" "r")
12915 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12919 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12920 (operands[0], operands[1], operands[2]));
12924 ; This use of vec_select isn't exactly correct according to rtl.texi
12925 ; (because not constant), but it seems a straightforward extension.
12926 (define_insn "mperm_w_little"
12927 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12929 (match_operand:V4HI 1 "arith_reg_operand" "r")
12931 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12932 (const_int 2) (const_int 0))
12933 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12934 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12935 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12936 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12937 "mperm.w %1, %N2, %0"
12938 [(set_attr "type" "arith_media")])
12940 (define_insn "mperm_w_big"
12941 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12943 (match_operand:V4HI 1 "arith_reg_operand" "r")
12945 [(zero_extract:QI (not:QI (match_operand:QI 2
12946 "extend_reg_or_0_operand" "rZ"))
12947 (const_int 2) (const_int 0))
12948 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12949 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12950 (zero_extract:QI (not:QI (match_dup 2))
12951 (const_int 2) (const_int 6))])))]
12952 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12953 "mperm.w %1, %N2, %0"
12954 [(set_attr "type" "arith_media")])
12956 (define_insn "mperm_w0"
12957 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12958 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12959 "trunc_hi_operand" "r"))))]
12961 "mperm.w %1, r63, %0"
12962 [(set_attr "type" "arith_media")
12963 (set_attr "highpart" "ignore")])
12965 (define_expand "msad_ubq"
12966 [(match_operand:DI 0 "arith_reg_dest" "")
12967 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12968 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12969 (match_operand:DI 3 "arith_reg_operand" "")]
12973 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12974 operands[1], operands[2]));
12978 (define_insn "msad_ubq_i"
12979 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12984 (match_operand:DI 1 "arith_reg_operand" "0")
12985 (abs:DI (vec_select:DI
12988 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12990 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12991 (parallel [(const_int 0)]))))
12992 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12993 (zero_extend:V8DI (match_dup 3)))
12994 (parallel [(const_int 1)]))))
12996 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12997 (zero_extend:V8DI (match_dup 3)))
12998 (parallel [(const_int 2)])))
12999 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13000 (zero_extend:V8DI (match_dup 3)))
13001 (parallel [(const_int 3)])))))
13004 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13005 (zero_extend:V8DI (match_dup 3)))
13006 (parallel [(const_int 4)])))
13007 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13008 (zero_extend:V8DI (match_dup 3)))
13009 (parallel [(const_int 5)]))))
13011 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13012 (zero_extend:V8DI (match_dup 3)))
13013 (parallel [(const_int 6)])))
13014 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13015 (zero_extend:V8DI (match_dup 3)))
13016 (parallel [(const_int 7)])))))))]
13018 "msad.ubq %N2, %N3, %0"
13019 [(set_attr "type" "mac_media")])
13021 (define_insn "mshalds_l"
13022 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13025 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
13026 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13027 (const_int 31)))))]
13029 "mshalds.l %1, %2, %0"
13030 [(set_attr "type" "mcmp_media")
13031 (set_attr "highpart" "depend")])
13033 (define_insn "mshalds_w"
13034 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13037 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13038 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13039 (const_int 15)))))]
13041 "mshalds.w %1, %2, %0"
13042 [(set_attr "type" "mcmp_media")
13043 (set_attr "highpart" "depend")])
13045 (define_insn "ashrv2si3"
13046 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13047 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13048 (match_operand:DI 2 "arith_reg_operand" "r")))]
13050 "mshard.l %1, %2, %0"
13051 [(set_attr "type" "arith_media")
13052 (set_attr "highpart" "depend")])
13054 (define_insn "ashrv4hi3"
13055 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13056 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13057 (match_operand:DI 2 "arith_reg_operand" "r")))]
13059 "mshard.w %1, %2, %0"
13060 [(set_attr "type" "arith_media")
13061 (set_attr "highpart" "depend")])
13063 (define_insn "mshards_q"
13064 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
13066 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
13067 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
13069 "mshards.q %1, %N2, %0"
13070 [(set_attr "type" "mcmp_media")])
13072 (define_expand "mshfhi_b"
13073 [(match_operand:V8QI 0 "arith_reg_dest" "")
13074 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13075 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13079 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
13080 (operands[0], operands[1], operands[2]));
13084 (define_expand "mshflo_b"
13085 [(match_operand:V8QI 0 "arith_reg_dest" "")
13086 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13087 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13091 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
13092 (operands[0], operands[1], operands[2]));
13096 (define_insn "mshf4_b"
13098 (match_operand:V8QI 0 "arith_reg_dest" "=r")
13100 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13101 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13102 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
13103 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
13105 "* return (TARGET_LITTLE_ENDIAN
13106 ? \"mshfhi.b %N1, %N2, %0\"
13107 : \"mshflo.b %N1, %N2, %0\");"
13108 [(set_attr "type" "arith_media")
13109 (set (attr "highpart")
13110 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13111 (const_string "user")))])
13113 (define_insn "mshf0_b"
13115 (match_operand:V8QI 0 "arith_reg_dest" "=r")
13117 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13118 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13119 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
13120 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
13122 "* return (TARGET_LITTLE_ENDIAN
13123 ? \"mshflo.b %N1, %N2, %0\"
13124 : \"mshfhi.b %N1, %N2, %0\");"
13125 [(set_attr "type" "arith_media")
13126 (set (attr "highpart")
13127 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13128 (const_string "user")))])
13130 (define_expand "mshfhi_l"
13131 [(match_operand:V2SI 0 "arith_reg_dest" "")
13132 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13133 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13137 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
13138 (operands[0], operands[1], operands[2]));
13142 (define_expand "mshflo_l"
13143 [(match_operand:V2SI 0 "arith_reg_dest" "")
13144 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13145 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13149 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
13150 (operands[0], operands[1], operands[2]));
13154 (define_insn "mshf4_l"
13155 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13157 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13158 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13159 (parallel [(const_int 1) (const_int 3)])))]
13161 "* return (TARGET_LITTLE_ENDIAN
13162 ? \"mshfhi.l %N1, %N2, %0\"
13163 : \"mshflo.l %N1, %N2, %0\");"
13164 [(set_attr "type" "arith_media")
13165 (set (attr "highpart")
13166 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13167 (const_string "user")))])
13169 (define_insn "mshf0_l"
13170 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13172 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13173 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13174 (parallel [(const_int 0) (const_int 2)])))]
13176 "* return (TARGET_LITTLE_ENDIAN
13177 ? \"mshflo.l %N1, %N2, %0\"
13178 : \"mshfhi.l %N1, %N2, %0\");"
13179 [(set_attr "type" "arith_media")
13180 (set (attr "highpart")
13181 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13182 (const_string "user")))])
13184 (define_expand "mshfhi_w"
13185 [(match_operand:V4HI 0 "arith_reg_dest" "")
13186 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13187 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13191 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
13192 (operands[0], operands[1], operands[2]));
13196 (define_expand "mshflo_w"
13197 [(match_operand:V4HI 0 "arith_reg_dest" "")
13198 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13199 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13203 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
13204 (operands[0], operands[1], operands[2]));
13208 (define_insn "mshf4_w"
13209 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13211 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13212 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13213 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
13215 "* return (TARGET_LITTLE_ENDIAN
13216 ? \"mshfhi.w %N1, %N2, %0\"
13217 : \"mshflo.w %N1, %N2, %0\");"
13218 [(set_attr "type" "arith_media")
13219 (set (attr "highpart")
13220 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13221 (const_string "user")))])
13223 (define_insn "mshf0_w"
13224 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13226 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13227 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13228 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
13230 "* return (TARGET_LITTLE_ENDIAN
13231 ? \"mshflo.w %N1, %N2, %0\"
13232 : \"mshfhi.w %N1, %N2, %0\");"
13233 [(set_attr "type" "arith_media")
13234 (set (attr "highpart")
13235 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13236 (const_string "user")))])
13238 (define_insn "mshflo_w_x"
13239 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13241 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
13242 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
13243 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
13245 "mshflo.w %N1, %N2, %0"
13246 [(set_attr "type" "arith_media")
13247 (set_attr "highpart" "ignore")])
13249 /* These are useful to expand ANDs and as combiner patterns. */
13250 (define_insn_and_split "mshfhi_l_di"
13251 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
13252 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
13254 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
13255 (const_int -4294967296))))]
13258 mshfhi.l %N1, %N2, %0
13260 "TARGET_SHMEDIA && reload_completed
13261 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13262 [(set (match_dup 3) (match_dup 4))
13263 (set (match_dup 5) (match_dup 6))]
13266 operands[3] = gen_lowpart (SImode, operands[0]);
13267 operands[4] = gen_highpart (SImode, operands[1]);
13268 operands[5] = gen_highpart (SImode, operands[0]);
13269 operands[6] = gen_highpart (SImode, operands[2]);
13271 [(set_attr "type" "arith_media")])
13273 (define_insn "*mshfhi_l_di_rev"
13274 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13275 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13276 (const_int -4294967296))
13277 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13280 "mshfhi.l %N2, %N1, %0"
13281 [(set_attr "type" "arith_media")])
13284 [(set (match_operand:DI 0 "arith_reg_dest" "")
13285 (ior:DI (zero_extend:DI (match_operand:SI 1
13286 "extend_reg_or_0_operand" ""))
13287 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
13288 (const_int -4294967296))))
13289 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
13294 emit_insn (gen_ashldi3_media (operands[3],
13295 simplify_gen_subreg (DImode, operands[1],
13298 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
13302 (define_insn "mshflo_l_di"
13303 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13304 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13305 (const_int 4294967295))
13306 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13310 "mshflo.l %N1, %N2, %0"
13311 [(set_attr "type" "arith_media")
13312 (set_attr "highpart" "ignore")])
13314 (define_insn "*mshflo_l_di_rev"
13315 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13316 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13318 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13319 (const_int 4294967295))))]
13322 "mshflo.l %N2, %N1, %0"
13323 [(set_attr "type" "arith_media")
13324 (set_attr "highpart" "ignore")])
13326 ;; Combiner pattern for trampoline initialization.
13327 (define_insn_and_split "*double_shori"
13328 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13329 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
13331 (match_operand:DI 2 "const_int_operand" "n")))]
13333 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
13335 "rtx_equal_p (operands[0], operands[1])"
13339 HOST_WIDE_INT v = INTVAL (operands[2]);
13341 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
13342 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
13345 [(set_attr "highpart" "ignore")])
13348 (define_insn "*mshflo_l_di_x"
13349 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13350 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
13352 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13356 "mshflo.l %N1, %N2, %0"
13357 [(set_attr "type" "arith_media")
13358 (set_attr "highpart" "ignore")])
13360 (define_insn_and_split "concat_v2sf"
13361 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
13362 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
13363 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
13364 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
13368 mshflo.l %N1, %N2, %0
13371 "TARGET_SHMEDIA && reload_completed
13372 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13373 [(set (match_dup 3) (match_dup 1))
13374 (set (match_dup 4) (match_dup 2))]
13377 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
13378 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
13380 [(set_attr "type" "arith_media")
13381 (set_attr "highpart" "ignore")])
13383 (define_insn "*mshflo_l_di_x_rev"
13384 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13385 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13387 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
13390 "mshflo.l %N2, %N1, %0"
13391 [(set_attr "type" "arith_media")
13392 (set_attr "highpart" "ignore")])
13394 (define_insn "ashlv2si3"
13395 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13396 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13397 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13399 "mshlld.l %1, %2, %0"
13400 [(set_attr "type" "arith_media")
13401 (set_attr "highpart" "depend")])
13404 [(set (match_operand 0 "any_register_operand" "")
13405 (match_operator 3 "shift_operator"
13406 [(match_operand 1 "any_register_operand" "")
13407 (match_operand 2 "shift_count_reg_operand" "")]))]
13408 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
13409 [(set (match_dup 0) (match_dup 3))]
13412 rtx count = operands[2];
13413 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
13415 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
13416 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
13417 || GET_CODE (count) == TRUNCATE)
13418 count = XEXP (count, 0);
13419 inner_mode = GET_MODE (count);
13420 count = simplify_gen_subreg (outer_mode, count, inner_mode,
13421 subreg_lowpart_offset (outer_mode, inner_mode));
13422 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
13423 operands[1], count);
13426 (define_insn "ashlv4hi3"
13427 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13428 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13429 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13431 "mshlld.w %1, %2, %0"
13432 [(set_attr "type" "arith_media")
13433 (set_attr "highpart" "depend")])
13435 (define_insn "lshrv2si3"
13436 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13437 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13438 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13440 "mshlrd.l %1, %2, %0"
13441 [(set_attr "type" "arith_media")
13442 (set_attr "highpart" "depend")])
13444 (define_insn "lshrv4hi3"
13445 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13446 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13447 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13449 "mshlrd.w %1, %2, %0"
13450 [(set_attr "type" "arith_media")
13451 (set_attr "highpart" "depend")])
13453 (define_insn "subv2si3"
13454 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13455 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13456 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13458 "msub.l %N1, %2, %0"
13459 [(set_attr "type" "arith_media")
13460 (set_attr "highpart" "depend")])
13462 (define_insn "subv4hi3"
13463 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13464 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13465 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13467 "msub.w %N1, %2, %0"
13468 [(set_attr "type" "arith_media")
13469 (set_attr "highpart" "depend")])
13471 (define_insn_and_split "subv2hi3"
13472 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13473 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13474 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13481 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13482 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13483 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13484 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13485 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13487 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13488 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13491 [(set_attr "highpart" "must_split")])
13493 (define_insn "sssubv2si3"
13494 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13495 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13496 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13498 "msubs.l %N1, %2, %0"
13499 [(set_attr "type" "mcmp_media")
13500 (set_attr "highpart" "depend")])
13502 (define_insn "ussubv8qi3"
13503 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13504 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13505 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13507 "msubs.ub %N1, %2, %0"
13508 [(set_attr "type" "mcmp_media")
13509 (set_attr "highpart" "depend")])
13511 (define_insn "sssubv4hi3"
13512 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13513 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13514 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13516 "msubs.w %N1, %2, %0"
13517 [(set_attr "type" "mcmp_media")
13518 (set_attr "highpart" "depend")])
13520 ;; Floating Point Intrinsics
13522 (define_insn "fcosa_s"
13523 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13524 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13528 [(set_attr "type" "atrans_media")])
13530 (define_insn "fsina_s"
13531 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13532 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13536 [(set_attr "type" "atrans_media")])
13538 (define_insn "fipr"
13539 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13540 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13541 "fp_arith_reg_operand" "f")
13542 (match_operand:V4SF 2
13543 "fp_arith_reg_operand" "f"))
13544 (parallel [(const_int 0)]))
13545 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13546 (parallel [(const_int 1)])))
13547 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13548 (parallel [(const_int 2)]))
13549 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13550 (parallel [(const_int 3)])))))]
13552 "fipr.s %1, %2, %0"
13553 [(set_attr "type" "fparith_media")])
13555 (define_insn "fsrra_s"
13556 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13557 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13561 [(set_attr "type" "atrans_media")])
13563 (define_insn "ftrv"
13564 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13568 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13569 (parallel [(const_int 0) (const_int 5)
13570 (const_int 10) (const_int 15)]))
13571 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13573 (vec_select:V4SF (match_dup 1)
13574 (parallel [(const_int 4) (const_int 9)
13575 (const_int 14) (const_int 3)]))
13576 (vec_select:V4SF (match_dup 2)
13577 (parallel [(const_int 1) (const_int 2)
13578 (const_int 3) (const_int 0)]))))
13581 (vec_select:V4SF (match_dup 1)
13582 (parallel [(const_int 8) (const_int 13)
13583 (const_int 2) (const_int 7)]))
13584 (vec_select:V4SF (match_dup 2)
13585 (parallel [(const_int 2) (const_int 3)
13586 (const_int 0) (const_int 1)])))
13588 (vec_select:V4SF (match_dup 1)
13589 (parallel [(const_int 12) (const_int 1)
13590 (const_int 6) (const_int 11)]))
13591 (vec_select:V4SF (match_dup 2)
13592 (parallel [(const_int 3) (const_int 0)
13593 (const_int 1) (const_int 2)]))))))]
13595 "ftrv.s %1, %2, %0"
13596 [(set_attr "type" "fparith_media")])
13598 (define_insn "ldhi_l"
13599 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13601 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13604 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13608 [(set_attr "type" "load_media")])
13610 (define_insn "ldhi_q"
13611 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13613 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13616 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13620 [(set_attr "type" "load_media")])
13622 (define_insn_and_split "*ldhi_q_comb0"
13623 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13625 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13626 "register_operand" "r")
13627 (match_operand:SI 2
13628 "ua_offset" "I06"))
13631 (plus:SI (and:SI (match_dup 1) (const_int 7))
13634 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13638 "emit_insn (gen_ldhi_q (operands[0],
13639 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13643 (define_insn_and_split "*ldhi_q_comb1"
13644 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13646 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13647 "register_operand" "r")
13648 (match_operand:SI 2
13649 "ua_offset" "I06"))
13652 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13653 "ua_offset" "I06"))
13657 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13658 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13662 "emit_insn (gen_ldhi_q (operands[0],
13663 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13667 (define_insn "ldlo_l"
13668 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13670 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13672 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13673 (and:SI (match_dup 1) (const_int 3))))]
13676 [(set_attr "type" "load_media")])
13678 (define_insn "ldlo_q"
13679 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13681 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13683 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13684 (and:SI (match_dup 1) (const_int 7))))]
13687 [(set_attr "type" "load_media")])
13689 (define_insn_and_split "*ldlo_q_comb0"
13690 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13692 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13693 (match_operand:SI 2 "ua_offset" "I06"))
13695 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13696 (and:SI (match_dup 1) (const_int 7))))]
13697 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13701 "emit_insn (gen_ldlo_q (operands[0],
13702 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13705 (define_insn_and_split "*ldlo_q_comb1"
13706 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13708 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13709 (match_operand:SI 2 "ua_offset" "I06"))
13711 (minus:SI (const_int 8)
13712 (and:SI (plus:SI (match_dup 1)
13713 (match_operand:SI 3 "ua_offset" "I06"))
13715 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13716 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13717 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13721 "emit_insn (gen_ldlo_q (operands[0],
13722 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13725 (define_insn "sthi_l"
13726 [(set (zero_extract:SI
13727 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13730 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13732 (match_operand:SI 1 "arith_reg_operand" "r"))]
13735 [(set_attr "type" "ustore_media")])
13737 ;; All unaligned stores are considered to be 'narrow' because they typically
13738 ;; operate on less that a quadword, and when they operate on a full quadword,
13739 ;; the vanilla store high / store low sequence will cause a stall if not
13740 ;; scheduled apart.
13741 (define_insn "sthi_q"
13742 [(set (zero_extract:DI
13743 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13746 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13748 (match_operand:DI 1 "arith_reg_operand" "r"))]
13751 [(set_attr "type" "ustore_media")])
13753 (define_insn_and_split "*sthi_q_comb0"
13754 [(set (zero_extract:DI
13755 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13756 "register_operand" "r")
13757 (match_operand:SI 1 "ua_offset"
13761 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13763 (match_operand:DI 2 "arith_reg_operand" "r"))]
13764 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13768 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13772 (define_insn_and_split "*sthi_q_comb1"
13773 [(set (zero_extract:DI
13774 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13775 "register_operand" "r")
13776 (match_operand:SI 1 "ua_offset"
13780 (plus:SI (and:SI (plus:SI (match_dup 0)
13781 (match_operand:SI 2 "ua_offset" "I06"))
13785 (match_operand:DI 3 "arith_reg_operand" "r"))]
13786 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13787 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13791 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13795 ;; This is highpart user because the address is used as full 64 bit.
13796 (define_insn "stlo_l"
13797 [(set (zero_extract:SI
13798 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13800 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13801 (and:SI (match_dup 0) (const_int 3)))
13802 (match_operand:SI 1 "arith_reg_operand" "r"))]
13805 [(set_attr "type" "ustore_media")])
13807 (define_insn "stlo_q"
13808 [(set (zero_extract:DI
13809 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13811 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13812 (and:SI (match_dup 0) (const_int 7)))
13813 (match_operand:DI 1 "arith_reg_operand" "r"))]
13816 [(set_attr "type" "ustore_media")])
13818 (define_insn_and_split "*stlo_q_comb0"
13819 [(set (zero_extract:DI
13820 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13821 (match_operand:SI 1 "ua_offset" "I06"))
13823 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13824 (and:SI (match_dup 0) (const_int 7)))
13825 (match_operand:DI 2 "arith_reg_operand" "r"))]
13826 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13830 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13834 (define_insn_and_split "*stlo_q_comb1"
13835 [(set (zero_extract:DI
13836 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13837 (match_operand:SI 1 "ua_offset" "I06"))
13839 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13840 (match_operand:SI 2
13841 "ua_offset" "I06"))
13843 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13844 (match_operand:DI 3 "arith_reg_operand" "r"))]
13845 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13849 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13853 (define_insn "ldhi_l64"
13854 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13856 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13859 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13863 [(set_attr "type" "load_media")])
13865 (define_insn "ldhi_q64"
13866 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13868 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13871 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13875 [(set_attr "type" "load_media")])
13877 (define_insn "ldlo_l64"
13878 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13880 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13882 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13883 (and:DI (match_dup 1) (const_int 3))))]
13886 [(set_attr "type" "load_media")])
13888 (define_insn "ldlo_q64"
13889 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13891 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13893 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13894 (and:DI (match_dup 1) (const_int 7))))]
13897 [(set_attr "type" "load_media")])
13899 (define_insn "sthi_l64"
13900 [(set (zero_extract:SI
13901 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13904 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13906 (match_operand:SI 1 "arith_reg_operand" "r"))]
13909 [(set_attr "type" "ustore_media")])
13911 (define_insn "sthi_q64"
13912 [(set (zero_extract:DI
13913 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13916 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13918 (match_operand:DI 1 "arith_reg_operand" "r"))]
13921 [(set_attr "type" "ustore_media")])
13923 (define_insn "stlo_l64"
13924 [(set (zero_extract:SI
13925 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13927 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13928 (and:DI (match_dup 0) (const_int 3)))
13929 (match_operand:SI 1 "arith_reg_operand" "r"))]
13932 [(set_attr "type" "ustore_media")])
13934 (define_insn "stlo_q64"
13935 [(set (zero_extract:DI
13936 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13938 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13939 (and:DI (match_dup 0) (const_int 7)))
13940 (match_operand:DI 1 "arith_reg_operand" "r"))]
13943 [(set_attr "type" "ustore_media")])
13946 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13947 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13951 [(set_attr "type" "arith_media")])
13953 (define_insn "nsbsi"
13954 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13956 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13960 [(set_attr "type" "arith_media")])
13962 (define_insn "nsbdi"
13963 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13965 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13969 [(set_attr "type" "arith_media")])
13971 (define_expand "ffsdi2"
13972 [(set (match_operand:DI 0 "arith_reg_dest" "")
13973 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13977 rtx scratch = gen_reg_rtx (DImode);
13980 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13981 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13982 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13983 emit_insn (gen_nsbdi (scratch, scratch));
13984 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13985 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13986 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13987 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13992 (define_expand "ffssi2"
13993 [(set (match_operand:SI 0 "arith_reg_dest" "")
13994 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13998 rtx scratch = gen_reg_rtx (SImode);
13999 rtx discratch = gen_reg_rtx (DImode);
14002 emit_insn (gen_adddi3 (discratch,
14003 simplify_gen_subreg (DImode, operands[1], SImode, 0),
14005 emit_insn (gen_andcdi3 (discratch,
14006 simplify_gen_subreg (DImode, operands[1], SImode, 0),
14008 emit_insn (gen_nsbsi (scratch, discratch));
14009 last = emit_insn (gen_subsi3 (operands[0],
14010 force_reg (SImode, GEN_INT (63)), scratch));
14011 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
14016 (define_insn "byterev"
14017 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14018 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
14019 (parallel [(const_int 7) (const_int 6) (const_int 5)
14020 (const_int 4) (const_int 3) (const_int 2)
14021 (const_int 1) (const_int 0)])))]
14024 [(set_attr "type" "arith_media")])
14026 (define_insn "*prefetch_media"
14027 [(prefetch (match_operand:QI 0 "address_operand" "p")
14028 (match_operand:SI 1 "const_int_operand" "n")
14029 (match_operand:SI 2 "const_int_operand" "n"))]
14033 operands[0] = gen_rtx_MEM (QImode, operands[0]);
14034 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
14037 [(set_attr "type" "other")])
14039 (define_insn "*prefetch_i4"
14040 [(prefetch (match_operand:SI 0 "register_operand" "r")
14041 (match_operand:SI 1 "const_int_operand" "n")
14042 (match_operand:SI 2 "const_int_operand" "n"))]
14043 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
14046 return \"pref @%0\";
14048 [(set_attr "type" "other")])
14050 ;; In user mode, the "pref" instruction will raise a RADDERR exception
14051 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
14052 ;; implementation of __builtin_prefetch for VxWorks RTPs.
14053 (define_expand "prefetch"
14054 [(prefetch (match_operand 0 "address_operand" "p")
14055 (match_operand:SI 1 "const_int_operand" "n")
14056 (match_operand:SI 2 "const_int_operand" "n"))]
14057 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
14058 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
14061 if (GET_MODE (operands[0]) != Pmode
14062 || GET_CODE (operands[1]) != CONST_INT
14063 || GET_CODE (operands[2]) != CONST_INT)
14065 if (! TARGET_SHMEDIA)
14066 operands[0] = force_reg (Pmode, operands[0]);
14069 (define_insn "prefetch_m2a"
14070 [(prefetch (match_operand:SI 0 "register_operand" "r")
14071 (match_operand:SI 1 "const_int_operand" "n")
14072 (match_operand:SI 2 "const_int_operand" "n"))]
14075 [(set_attr "type" "other")])
14077 (define_insn "alloco_i"
14078 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
14079 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
14085 if (GET_CODE (operands[0]) == PLUS)
14087 xops[0] = XEXP (operands[0], 0);
14088 xops[1] = XEXP (operands[0], 1);
14092 xops[0] = operands[0];
14093 xops[1] = const0_rtx;
14095 output_asm_insn (\"alloco %0, %1\", xops);
14098 [(set_attr "type" "other")])
14101 [(set (match_operand 0 "any_register_operand" "")
14102 (match_operand 1 "" ""))]
14103 "TARGET_SHMEDIA && reload_completed"
14104 [(set (match_dup 0) (match_dup 1))]
14109 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
14114 ; Stack Protector Patterns
14116 (define_expand "stack_protect_set"
14117 [(set (match_operand 0 "memory_operand" "")
14118 (match_operand 1 "memory_operand" ""))]
14121 if (TARGET_SHMEDIA)
14123 if (TARGET_SHMEDIA64)
14124 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
14126 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
14129 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
14134 (define_insn "stack_protect_set_si"
14135 [(set (match_operand:SI 0 "memory_operand" "=m")
14136 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14137 (set (match_scratch:SI 2 "=&r") (const_int 0))]
14139 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
14140 [(set_attr "type" "other")
14141 (set_attr "length" "6")])
14143 (define_insn "stack_protect_set_si_media"
14144 [(set (match_operand:SI 0 "memory_operand" "=m")
14145 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14146 (set (match_scratch:SI 2 "=&r") (const_int 0))]
14148 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
14149 [(set_attr "type" "other")
14150 (set_attr "length" "12")])
14152 (define_insn "stack_protect_set_di_media"
14153 [(set (match_operand:DI 0 "memory_operand" "=m")
14154 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14155 (set (match_scratch:DI 2 "=&r") (const_int 0))]
14157 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
14158 [(set_attr "type" "other")
14159 (set_attr "length" "12")])
14161 (define_expand "stack_protect_test"
14162 [(match_operand 0 "memory_operand" "")
14163 (match_operand 1 "memory_operand" "")
14164 (match_operand 2 "" "")]
14167 if (TARGET_SHMEDIA)
14169 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
14171 if (TARGET_SHMEDIA64)
14172 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
14175 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
14178 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
14182 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
14183 emit_jump_insn (gen_branch_true (operands[2]));
14189 (define_insn "stack_protect_test_si"
14190 [(set (reg:SI T_REG)
14191 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
14192 (match_operand:SI 1 "memory_operand" "m")]
14194 (set (match_scratch:SI 2 "=&r") (const_int 0))
14195 (set (match_scratch:SI 3 "=&r") (const_int 0))]
14197 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
14198 [(set_attr "type" "other")
14199 (set_attr "length" "10")])
14201 (define_insn "stack_protect_test_si_media"
14202 [(set (match_operand:SI 0 "register_operand" "=&r")
14203 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
14204 (match_operand:SI 2 "memory_operand" "m")]
14206 (set (match_scratch:SI 3 "=&r") (const_int 0))]
14208 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14209 [(set_attr "type" "other")
14210 (set_attr "length" "16")])
14212 (define_insn "stack_protect_test_di_media"
14213 [(set (match_operand:DI 0 "register_operand" "=&r")
14214 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
14215 (match_operand:DI 2 "memory_operand" "m")]
14217 (set (match_scratch:DI 3 "=&r") (const_int 0))]
14219 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14220 [(set_attr "type" "other")
14221 (set_attr "length" "16")])