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, 2008, 2009 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 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158 (UNSPEC_EXTRACT_S16 43)
159 (UNSPEC_EXTRACT_U16 44)
161 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165 (UNSPEC_PCREL_SYMOFF 46)
167 ;; These are used with unspec_volatile.
173 (UNSPECV_WINDOW_END 10)
174 (UNSPECV_CONST_END 11)
175 (UNSPECV_EH_RETURN 12)
178 ;; -------------------------------------------------------------------------
180 ;; -------------------------------------------------------------------------
185 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
186 (const (symbol_ref "sh_cpu_attr")))
188 (define_attr "endian" "big,little"
189 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
190 (const_string "little") (const_string "big"))))
192 ;; Indicate if the default fpu mode is single precision.
193 (define_attr "fpu_single" "yes,no"
194 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
195 (const_string "yes") (const_string "no"))))
197 (define_attr "fmovd" "yes,no"
198 (const (if_then_else (symbol_ref "TARGET_FMOVD")
199 (const_string "yes") (const_string "no"))))
201 (define_attr "pipe_model" "sh1,sh4,sh5media"
203 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
204 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
205 (const_string "sh1"))))
207 ;; cbranch conditional branch instructions
208 ;; jump unconditional jumps
209 ;; arith ordinary arithmetic
210 ;; arith3 a compound insn that behaves similarly to a sequence of
211 ;; three insns of type arith
212 ;; arith3b like above, but might end with a redirected branch
214 ;; load_si Likewise, SImode variant for general register.
215 ;; fload Likewise, but load to fp register.
217 ;; fstore floating point register to memory
218 ;; move general purpose register to register
219 ;; movi8 8-bit immediate to general purpose register
220 ;; mt_group other sh4 mt instructions
221 ;; fmove register to register, floating point
222 ;; smpy word precision integer multiply
223 ;; dmpy longword or doublelongword precision integer multiply
225 ;; pload load of pr reg, which can't be put into delay slot of rts
226 ;; prset copy register to pr reg, ditto
227 ;; pstore store of pr reg, which can't be put into delay slot of jsr
228 ;; prget copy pr to register, ditto
229 ;; pcload pc relative load of constant value
230 ;; pcfload Likewise, but load to fp register.
231 ;; pcload_si Likewise, SImode variant for general register.
232 ;; rte return from exception
233 ;; sfunc special function call with known used registers
234 ;; call function call
236 ;; fpscr_toggle toggle a bit in the fpscr
237 ;; fdiv floating point divide (or square root)
238 ;; gp_fpul move from general purpose register to fpul
239 ;; fpul_gp move from fpul to general purpose register
240 ;; mac_gp move from mac[lh] to general purpose register
241 ;; gp_mac move from general purpose register to mac[lh]
242 ;; mac_mem move from mac[lh] to memory
243 ;; mem_mac move from memory to mac[lh]
244 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
245 ;; ftrc_s fix_truncsfsi2_i4
246 ;; dfdiv double precision floating point divide (or square root)
247 ;; cwb ic_invalidate_line_i
248 ;; movua SH4a unaligned load
249 ;; fsrra square root reciprocal approximate
250 ;; fsca sine and cosine approximate
251 ;; tls_load load TLS related address
252 ;; arith_media SHmedia arithmetic, logical, and shift instructions
253 ;; cbranch_media SHmedia conditional branch instructions
254 ;; cmp_media SHmedia compare instructions
255 ;; dfdiv_media SHmedia double precision divide and square root
256 ;; dfmul_media SHmedia double precision multiply instruction
257 ;; dfparith_media SHmedia double precision floating point arithmetic
258 ;; dfpconv_media SHmedia double precision floating point conversions
259 ;; dmpy_media SHmedia longword multiply
260 ;; fcmp_media SHmedia floating point compare instructions
261 ;; fdiv_media SHmedia single precision divide and square root
262 ;; fload_media SHmedia floating point register load instructions
263 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
264 ;; fparith_media SHmedia single precision floating point arithmetic
265 ;; fpconv_media SHmedia single precision floating point conversions
266 ;; fstore_media SHmedia floating point register store instructions
267 ;; gettr_media SHmedia gettr instruction
268 ;; invalidate_line_media SHmedia invalidate_line sequence
269 ;; jump_media SHmedia unconditional branch instructions
270 ;; load_media SHmedia general register load instructions
271 ;; pt_media SHmedia pt instruction (expanded by assembler)
272 ;; ptabs_media SHmedia ptabs instruction
273 ;; store_media SHmedia general register store instructions
274 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
275 ;; mac_media SHmedia mac-style fixed point operations
276 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
277 ;; atrans_media SHmedia approximate transcendental functions
278 ;; ustore_media SHmedia unaligned stores
279 ;; nil no-op move, will be deleted.
282 "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"
283 (const_string "other"))
285 ;; We define a new attribute namely "insn_class".We use
286 ;; this for the DFA based pipeline description.
288 ;; mt_group SH4 "mt" group instructions.
290 ;; ex_group SH4 "ex" group instructions.
292 ;; ls_group SH4 "ls" group instructions.
295 (define_attr "insn_class"
296 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
297 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
298 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
299 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
300 (eq_attr "type" "cbranch,jump") (const_string "br_group")
301 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
302 (const_string "fe_group")
303 (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")]
304 (const_string "none")))
305 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
306 ;; so these do not belong in an insn group, although they are modeled
307 ;; with their own define_insn_reservations.
309 ;; Indicate what precision must be selected in fpscr for this insn, if any.
311 (define_attr "fp_mode" "single,double,none" (const_string "none"))
313 ;; Indicate if the fpu mode is set by this instruction
314 ;; "unknown" must have the value as "none" in fp_mode, and means
315 ;; that the instruction/abi has left the processor in an unknown
317 ;; "none" means that nothing has changed and no mode is set.
318 ;; This attribute is only used for the Renesas ABI.
319 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
321 ; If a conditional branch destination is within -252..258 bytes away
322 ; from the instruction it can be 2 bytes long. Something in the
323 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
324 ; branches are initially assumed to be 16 bytes long.
325 ; In machine_dependent_reorg, we split all branches that are longer than
328 ;; The maximum range used for SImode constant pool entries is 1018. A final
329 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
330 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
331 ;; instruction around the pool table, 2 bytes of alignment before the table,
332 ;; and 30 bytes of alignment after the table. That gives a maximum total
333 ;; pool size of 1058 bytes.
334 ;; Worst case code/pool content size ratio is 1:2 (using asms).
335 ;; Thus, in the worst case, there is one instruction in front of a maximum
336 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
337 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
338 ;; If we have a forward branch, the initial table will be put after the
339 ;; unconditional branch.
341 ;; ??? We could do much better by keeping track of the actual pcloads within
342 ;; the branch range and in the pcload range in front of the branch range.
344 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
346 (define_attr "short_cbranch_p" "no,yes"
347 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
351 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
355 ] (const_string "no")))
357 (define_attr "med_branch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366 ] (const_string "no")))
368 (define_attr "med_cbranch_p" "no,yes"
369 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
374 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377 ] (const_string "no")))
379 (define_attr "braf_branch_p" "no,yes"
380 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
387 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390 ] (const_string "no")))
392 (define_attr "braf_cbranch_p" "no,yes"
393 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
395 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
400 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403 ] (const_string "no")))
405 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
406 ; For wider ranges, we need a combination of a code and a data part.
407 ; If we can get a scratch register for a long range jump, the code
408 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
409 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
410 ; long; otherwise, it must be 6 bytes long.
412 ; All other instructions are two bytes long by default.
414 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
415 ;; but getattrtab doesn't understand this.
416 (define_attr "length" ""
417 (cond [(eq_attr "type" "cbranch")
418 (cond [(eq_attr "short_cbranch_p" "yes")
420 (eq_attr "med_cbranch_p" "yes")
422 (eq_attr "braf_cbranch_p" "yes")
424 ;; ??? using pc is not computed transitively.
425 (ne (match_dup 0) (match_dup 0))
427 (ne (symbol_ref ("flag_pic")) (const_int 0))
430 (eq_attr "type" "jump")
431 (cond [(eq_attr "med_branch_p" "yes")
433 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
435 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
437 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
438 (symbol_ref "code_for_indirect_jump_scratch"))))
439 (cond [(eq_attr "braf_branch_p" "yes")
441 (eq (symbol_ref "flag_pic") (const_int 0))
443 (ne (symbol_ref "TARGET_SH2") (const_int 0))
444 (const_int 10)] (const_int 18))
445 (eq_attr "braf_branch_p" "yes")
447 ;; ??? using pc is not computed transitively.
448 (ne (match_dup 0) (match_dup 0))
450 (ne (symbol_ref ("flag_pic")) (const_int 0))
453 (eq_attr "type" "pt_media")
454 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
455 (const_int 20) (const_int 12))
456 (and (eq_attr "type" "jump_media")
457 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
459 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
463 ;; DFA descriptions for the pipelines
466 (include "shmedia.md")
469 (include "predicates.md")
470 (include "constraints.md")
472 ;; Definitions for filling delay slots
474 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
476 (define_attr "banked" "yes,no"
477 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
479 (const_string "yes")]
480 (const_string "no")))
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
487 (const_string "yes")))
489 (define_attr "interrupt_function" "no,yes"
490 (const (symbol_ref "current_function_interrupt")))
492 (define_attr "in_delay_slot" "yes,no"
493 (cond [(eq_attr "type" "cbranch") (const_string "no")
494 (eq_attr "type" "pcload,pcload_si") (const_string "no")
495 (eq_attr "needs_delay_slot" "yes") (const_string "no")
496 (eq_attr "length" "2") (const_string "yes")
497 ] (const_string "no")))
499 (define_attr "cond_delay_slot" "yes,no"
500 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
501 ] (const_string "no")))
503 (define_attr "is_sfunc" ""
504 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
506 (define_attr "is_mac_media" ""
507 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
509 (define_attr "branch_zero" "yes,no"
510 (cond [(eq_attr "type" "!cbranch") (const_string "no")
511 (ne (symbol_ref "(next_active_insn (insn)\
512 == (prev_active_insn\
513 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
514 && get_attr_length (next_active_insn (insn)) == 2")
516 (const_string "yes")]
517 (const_string "no")))
519 ;; SH4 Double-precision computation with double-precision result -
520 ;; the two halves are ready at different times.
521 (define_attr "dfp_comp" "yes,no"
522 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
523 (const_string "no")))
525 ;; Insns for which the latency of a preceding fp insn is decreased by one.
526 (define_attr "late_fp_use" "yes,no" (const_string "no"))
527 ;; And feeding insns for which this relevant.
528 (define_attr "any_fp_comp" "yes,no"
529 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
530 (const_string "yes")]
531 (const_string "no")))
533 (define_attr "any_int_load" "yes,no"
534 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
535 (const_string "yes")]
536 (const_string "no")))
538 (define_attr "highpart" "user, ignore, extend, depend, must_split"
539 (const_string "user"))
542 (eq_attr "needs_delay_slot" "yes")
543 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
545 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
546 ;; and thus we can't put a pop instruction in its delay slot.
547 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
548 ;; instruction can go in the delay slot.
550 ;; Since a normal return (rts) implicitly uses the PR register,
551 ;; we can't allow PR register loads in an rts delay slot.
554 (eq_attr "type" "return")
555 [(and (eq_attr "in_delay_slot" "yes")
556 (ior (and (eq_attr "interrupt_function" "no")
557 (eq_attr "type" "!pload,prset"))
558 (and (eq_attr "interrupt_function" "yes")
560 (eq (symbol_ref "TARGET_SH3") (const_int 0))
561 (eq_attr "hit_stack" "no")
562 (eq_attr "banked" "no"))))) (nil) (nil)])
564 ;; Since a call implicitly uses the PR register, we can't allow
565 ;; a PR register store in a jsr delay slot.
568 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
569 [(and (eq_attr "in_delay_slot" "yes")
570 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
572 ;; Say that we have annulled true branches, since this gives smaller and
573 ;; faster code when branches are predicted as not taken.
575 ;; ??? The non-annulled condition should really be "in_delay_slot",
576 ;; but insns that can be filled in non-annulled get priority over insns
577 ;; that can only be filled in anulled.
580 (and (eq_attr "type" "cbranch")
581 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
582 ;; SH2e has a hardware bug that pretty much prohibits the use of
583 ;; annuled delay slots.
584 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
585 (not (eq_attr "cpu" "sh2e"))) (nil)])
587 ;; -------------------------------------------------------------------------
588 ;; SImode signed integer comparisons
589 ;; -------------------------------------------------------------------------
593 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
594 (match_operand:SI 1 "arith_operand" "K08,r"))
598 [(set_attr "type" "mt_group")])
600 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
601 ;; That would still allow reload to create cmpi instructions, but would
602 ;; perhaps allow forcing the constant into a register when that is better.
603 ;; Probably should use r0 for mem/imm compares, but force constant into a
604 ;; register for pseudo/imm compares.
606 (define_insn "cmpeqsi_t"
608 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
609 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
615 [(set_attr "type" "mt_group")])
617 (define_insn "cmpgtsi_t"
619 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
625 [(set_attr "type" "mt_group")])
627 (define_insn "cmpgesi_t"
629 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
630 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
635 [(set_attr "type" "mt_group")])
637 ;; -------------------------------------------------------------------------
638 ;; SImode compare and branch
639 ;; -------------------------------------------------------------------------
641 (define_expand "cbranchsi4"
643 (if_then_else (match_operator 0 "comparison_operator"
644 [(match_operand:SI 1 "arith_operand" "")
645 (match_operand:SI 2 "arith_operand" "")])
646 (label_ref (match_operand 3 "" ""))
648 (clobber (reg:SI T_REG))]
651 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
652 operands[2], operands[3]));
653 else if (TARGET_CBRANCHDI4)
654 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
656 sh_emit_compare_and_branch (operands, SImode);
659 ;; -------------------------------------------------------------------------
660 ;; SImode unsigned integer comparisons
661 ;; -------------------------------------------------------------------------
663 (define_insn_and_split "cmpgeusi_t"
665 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
669 "&& operands[1] == CONST0_RTX (SImode)"
673 emit_insn (gen_sett ());
676 [(set_attr "type" "mt_group")])
678 (define_insn "cmpgtusi_t"
680 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681 (match_operand:SI 1 "arith_reg_operand" "r")))]
684 [(set_attr "type" "mt_group")])
687 ;; -------------------------------------------------------------------------
688 ;; DImode compare and branch
689 ;; -------------------------------------------------------------------------
692 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693 ;; Therefore, we aim to have a set of three branches that go straight to the
694 ;; destination, i.e. only one of them is taken at any one time.
695 ;; This mechanism should also be slightly better for the sh4-200.
697 (define_expand "cbranchdi4"
699 (if_then_else (match_operator 0 "comparison_operator"
700 [(match_operand:DI 1 "arith_operand" "")
701 (match_operand:DI 2 "arith_operand" "")])
702 (label_ref (match_operand 3 "" ""))
704 (clobber (match_dup 4))
705 (clobber (reg:SI T_REG))]
706 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
709 enum rtx_code comparison;
713 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
714 operands[2], operands[3]));
718 else if (!TARGET_CBRANCHDI4)
720 sh_emit_compare_and_branch (operands, DImode);
726 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
729 comparison = prepare_cbranch_operands (operands, DImode,
730 LAST_AND_UNUSED_RTX_CODE);
731 if (comparison != GET_CODE (operands[0]))
733 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
734 operands[4] = gen_rtx_SCRATCH (SImode);
738 (define_insn_and_split "cbranchdi4_i"
740 (if_then_else (match_operator 0 "comparison_operator"
741 [(match_operand:DI 1 "arith_operand" "r,r")
742 (match_operand:DI 2 "arith_operand" "rN,I08")])
743 (label_ref (match_operand 3 "" ""))
745 (clobber (match_scratch:SI 4 "=X,&r"))
746 (clobber (reg:SI T_REG))]
749 "&& reload_completed"
753 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
758 ;; -------------------------------------------------------------------------
759 ;; DImode signed integer comparisons
760 ;; -------------------------------------------------------------------------
764 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
765 (match_operand:DI 1 "arith_operand" "r"))
768 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
770 [(set_attr "length" "6")
771 (set_attr "type" "arith3b")])
773 (define_insn "cmpeqdi_t"
775 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
776 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
779 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
780 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
781 [(set_attr "length" "6")
782 (set_attr "type" "arith3b")])
786 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
787 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
788 ;; If we applied this split when not optimizing, it would only be
789 ;; applied during the machine-dependent reorg, when no new basic blocks
791 "TARGET_SH1 && reload_completed && optimize"
792 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
793 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
794 (label_ref (match_dup 6))
796 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
801 = gen_rtx_REG (SImode,
802 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
804 = (operands[1] == const0_rtx
806 : gen_rtx_REG (SImode,
807 true_regnum (operands[1])
808 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
809 operands[4] = gen_lowpart (SImode, operands[0]);
810 operands[5] = gen_lowpart (SImode, operands[1]);
811 operands[6] = gen_label_rtx ();
814 (define_insn "cmpgtdi_t"
816 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
817 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
820 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
821 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
822 [(set_attr "length" "8")
823 (set_attr "type" "arith3")])
825 (define_insn "cmpgedi_t"
827 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
828 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
831 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
833 [(set_attr "length" "8,2")
834 (set_attr "type" "arith3,mt_group")])
836 ;; -------------------------------------------------------------------------
837 ;; DImode unsigned integer comparisons
838 ;; -------------------------------------------------------------------------
840 (define_insn "cmpgeudi_t"
842 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
843 (match_operand:DI 1 "arith_reg_operand" "r")))]
845 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
846 [(set_attr "length" "8")
847 (set_attr "type" "arith3")])
849 (define_insn "cmpgtudi_t"
851 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
852 (match_operand:DI 1 "arith_reg_operand" "r")))]
854 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
855 [(set_attr "length" "8")
856 (set_attr "type" "arith3")])
858 (define_insn "cmpeqsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
861 (match_operand:SI 2 "cmp_operand" "Nr")))]
864 [(set_attr "type" "cmp_media")])
866 (define_insn "cmpeqdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (eq:SI (match_operand:DI 1 "register_operand" "%r")
869 (match_operand:DI 2 "cmp_operand" "Nr")))]
872 [(set_attr "type" "cmp_media")])
874 (define_insn "cmpgtsi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
880 [(set_attr "type" "cmp_media")])
882 (define_insn "cmpgtdi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
888 [(set_attr "type" "cmp_media")])
890 (define_insn "cmpgtusi_media"
891 [(set (match_operand:SI 0 "register_operand" "=r")
892 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
893 (match_operand:SI 2 "cmp_operand" "rN")))]
895 "cmpgtu %N1, %N2, %0"
896 [(set_attr "type" "cmp_media")])
898 (define_insn "cmpgtudi_media"
899 [(set (match_operand:SI 0 "register_operand" "=r")
900 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
901 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
903 "cmpgtu %N1, %N2, %0"
904 [(set_attr "type" "cmp_media")])
906 ; These two patterns are for combine.
907 (define_insn "*cmpne0sisi_media"
908 [(set (match_operand:SI 0 "register_operand" "=r")
909 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
912 [(set_attr "type" "cmp_media")])
914 ;; -------------------------------------------------------------------------
915 ;; Conditional move instructions
916 ;; -------------------------------------------------------------------------
918 ;; The insn names may seem reversed, but note that cmveq performs the move
919 ;; if op1 == 0, and cmvne does it if op1 != 0.
921 (define_insn "movdicc_false"
922 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
923 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
925 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
926 (match_operand:DI 3 "arith_reg_operand" "0")))]
929 [(set_attr "type" "arith_media")])
931 (define_insn "movdicc_true"
932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
933 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
935 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
936 (match_operand:DI 3 "arith_reg_operand" "0")))]
939 [(set_attr "type" "arith_media")])
942 [(set (match_operand:DI 0 "arith_reg_dest" "")
943 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
944 [(match_operand:DI 1 "arith_reg_operand" "")
946 (match_operand:DI 2 "arith_reg_dest" "")
948 (set (match_dup 2) (match_dup 0))]
949 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
951 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
954 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
955 VOIDmode, operands[1], CONST0_RTX (DImode));
959 [(set (match_operand:DI 0 "general_movdst_operand" "")
960 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
961 (set (match_operand:DI 2 "arith_reg_dest" "")
962 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
963 [(match_operand:DI 3 "arith_reg_operand" "")
967 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
969 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
972 (define_expand "movdicc"
973 [(set (match_operand:DI 0 "register_operand" "")
974 (if_then_else:DI (match_operand 1 "comparison_operator" "")
975 (match_operand:DI 2 "register_operand" "")
976 (match_operand:DI 3 "register_operand" "")))]
980 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
981 && GET_MODE (XEXP (operands[1], 0)) == DImode
982 && XEXP (operands[1], 1) == const0_rtx)
986 if (!can_create_pseudo_p ())
989 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
990 GET_CODE (operands[1]),
991 XEXP (operands[1], 0),
992 XEXP (operands[1], 1));
998 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1000 (define_insn "movsicc_false"
1001 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1002 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1004 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1005 (match_operand:SI 3 "arith_reg_operand" "0")))]
1008 [(set_attr "type" "arith_media")])
1010 (define_insn "movsicc_true"
1011 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1012 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1014 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1015 (match_operand:SI 3 "arith_reg_operand" "0")))]
1018 [(set_attr "type" "arith_media")])
1021 [(set (match_operand:SI 0 "arith_reg_dest" "")
1022 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1023 [(match_operand:SI 1 "arith_reg_operand" "")
1025 (match_operand:SI 2 "arith_reg_dest" "")
1027 (set (match_dup 2) (match_dup 0))]
1028 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1030 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1033 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1034 VOIDmode, operands[1], CONST0_RTX (SImode));
1038 [(set (match_operand:SI 0 "general_movdst_operand" "")
1039 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1040 (set (match_operand:SI 2 "arith_reg_dest" "")
1041 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1042 [(match_operand:SI 3 "arith_reg_operand" "")
1046 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1047 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1049 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1052 replace_rtx (operands[4], operands[0], operands[1]);
1056 [(set (match_operand 0 "any_register_operand" "")
1057 (match_operand 1 "any_register_operand" ""))
1058 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1059 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1060 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1061 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1062 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1063 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1064 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1065 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1066 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1067 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1068 && (REGNO_REG_CLASS (REGNO (operands[0]))
1069 == REGNO_REG_CLASS (REGNO (operands[2])))
1070 && (REGNO_REG_CLASS (REGNO (operands[1]))
1071 == REGNO_REG_CLASS (REGNO (operands[0])))"
1072 [(set (match_dup 0) (match_dup 3))
1073 (set (match_dup 4) (match_dup 5))]
1076 rtx set1, set2, insn2;
1077 rtx replacements[4];
1079 /* We want to replace occurrences of operands[0] with operands[1] and
1080 operands[2] with operands[0] in operands[4]/operands[5].
1081 Doing just two replace_rtx calls naively would result in the second
1082 replacement undoing all that the first did if operands[1] and operands[2]
1083 are identical, so we must do this simultaneously. */
1084 replacements[0] = operands[0];
1085 replacements[1] = operands[1];
1086 replacements[2] = operands[2];
1087 replacements[3] = operands[0];
1088 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1089 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1090 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1093 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1094 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1095 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1096 /* The operands array is aliased to recog_data.operand, which gets
1097 clobbered by extract_insn, so finish with it now. */
1098 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1099 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1100 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1101 always uses emit_insn. */
1102 /* Check that we don't violate matching constraints or earlyclobbers. */
1103 extract_insn (emit_insn (set1));
1104 if (! constrain_operands (1))
1106 insn2 = emit (set2);
1107 if (GET_CODE (insn2) == BARRIER)
1109 extract_insn (insn2);
1110 if (! constrain_operands (1))
1114 tmp = replacements[0];
1115 replacements[0] = replacements[1];
1116 replacements[1] = tmp;
1117 tmp = replacements[2];
1118 replacements[2] = replacements[3];
1119 replacements[3] = tmp;
1120 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1121 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1122 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1128 ;; The register allocator is rather clumsy in handling multi-way conditional
1129 ;; moves, so allow the combiner to make them, and we split them up after
1131 (define_insn_and_split "*movsicc_umin"
1132 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1133 (umin:SI (if_then_else:SI
1134 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1136 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1137 (match_operand:SI 3 "register_operand" "0"))
1138 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1139 (clobber (match_scratch:SI 5 "=&r"))]
1140 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1142 "TARGET_SHMEDIA && reload_completed"
1146 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1148 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1149 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1154 (define_insn "*movsicc_t_false"
1155 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1156 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1157 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1158 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1159 "TARGET_PRETEND_CMOVE
1160 && (arith_reg_operand (operands[1], SImode)
1161 || (immediate_operand (operands[1], SImode)
1162 && satisfies_constraint_I08 (operands[1])))"
1163 "bt 0f\;mov %1,%0\\n0:"
1164 [(set_attr "type" "mt_group,arith") ;; poor approximation
1165 (set_attr "length" "4")])
1167 (define_insn "*movsicc_t_true"
1168 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1169 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1170 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1171 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1172 "TARGET_PRETEND_CMOVE
1173 && (arith_reg_operand (operands[1], SImode)
1174 || (immediate_operand (operands[1], SImode)
1175 && satisfies_constraint_I08 (operands[1])))"
1176 "bf 0f\;mov %1,%0\\n0:"
1177 [(set_attr "type" "mt_group,arith") ;; poor approximation
1178 (set_attr "length" "4")])
1180 (define_expand "movsicc"
1181 [(set (match_operand:SI 0 "arith_reg_dest" "")
1182 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1183 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1184 (match_operand:SI 3 "arith_reg_operand" "")))]
1185 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1188 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1189 && GET_MODE (XEXP (operands[1], 0)) == SImode
1191 || (REG_P (XEXP (operands[1], 0))
1192 && REGNO (XEXP (operands[1], 0)) == T_REG))
1193 && XEXP (operands[1], 1) == const0_rtx)
1196 else if (TARGET_PRETEND_CMOVE)
1198 enum rtx_code code = GET_CODE (operands[1]);
1199 enum rtx_code new_code = code;
1200 rtx op0 = XEXP (operands[1], 0);
1201 rtx op1 = XEXP (operands[1], 1);
1203 if (! currently_expanding_to_rtl)
1207 case LT: case LE: case LEU: case LTU:
1208 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1211 new_code = reverse_condition (code);
1213 case EQ: case GT: case GE: case GEU: case GTU:
1218 sh_emit_scc_to_t (new_code, op0, op1);
1219 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1220 gen_rtx_REG (SImode, T_REG), const0_rtx);
1224 if (!can_create_pseudo_p ())
1227 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1228 GET_CODE (operands[1]),
1229 XEXP (operands[1], 0),
1230 XEXP (operands[1], 1));
1236 (define_expand "movqicc"
1237 [(set (match_operand:QI 0 "register_operand" "")
1238 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1239 (match_operand:QI 2 "register_operand" "")
1240 (match_operand:QI 3 "register_operand" "")))]
1244 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1245 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1246 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1247 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1251 ;; -------------------------------------------------------------------------
1252 ;; Addition instructions
1253 ;; -------------------------------------------------------------------------
1255 (define_expand "adddi3"
1256 [(set (match_operand:DI 0 "arith_reg_operand" "")
1257 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258 (match_operand:DI 2 "arith_operand" "")))]
1264 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1266 operands[2] = force_reg (DImode, operands[2]);
1267 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1272 (define_insn "*adddi3_media"
1273 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1274 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1275 (match_operand:DI 2 "arith_operand" "r,I10")))]
1280 [(set_attr "type" "arith_media")])
1282 (define_insn "*adddisi3_media"
1283 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1284 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1285 (match_operand:DI 2 "arith_operand" "r,I10")))]
1290 [(set_attr "type" "arith_media")
1291 (set_attr "highpart" "ignore")])
1293 (define_insn "adddi3z_media"
1294 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1296 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1297 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1299 "addz.l %1, %N2, %0"
1300 [(set_attr "type" "arith_media")
1301 (set_attr "highpart" "ignore")])
1303 (define_insn "adddi3_compact"
1304 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1305 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1306 (match_operand:DI 2 "arith_reg_operand" "r")))
1307 (clobber (reg:SI T_REG))]
1310 [(set_attr "length" "6")])
1313 [(set (match_operand:DI 0 "arith_reg_dest" "")
1314 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1315 (match_operand:DI 2 "arith_reg_operand" "")))
1316 (clobber (reg:SI T_REG))]
1317 "TARGET_SH1 && reload_completed"
1321 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1322 high0 = gen_rtx_REG (SImode,
1323 true_regnum (operands[0])
1324 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325 high2 = gen_rtx_REG (SImode,
1326 true_regnum (operands[2])
1327 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1328 emit_insn (gen_clrt ());
1329 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1330 emit_insn (gen_addc1 (high0, high0, high2));
1335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1336 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1337 (match_operand:SI 2 "arith_reg_operand" "r"))
1340 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1343 [(set_attr "type" "arith")])
1345 (define_insn "addc1"
1346 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1347 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348 (match_operand:SI 2 "arith_reg_operand" "r"))
1350 (clobber (reg:SI T_REG))]
1353 [(set_attr "type" "arith")])
1355 (define_expand "addsi3"
1356 [(set (match_operand:SI 0 "arith_reg_operand" "")
1357 (plus:SI (match_operand:SI 1 "arith_operand" "")
1358 (match_operand:SI 2 "arith_operand" "")))]
1363 operands[1] = force_reg (SImode, operands[1]);
1366 (define_insn "addsi3_media"
1367 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1368 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1369 (match_operand:SI 2 "arith_operand" "r,I10")))]
1374 [(set_attr "type" "arith_media")
1375 (set_attr "highpart" "ignore")])
1377 (define_insn "addsidi3_media"
1378 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1379 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1381 (match_operand:SI 2 "arith_operand"
1387 [(set_attr "type" "arith_media")
1388 (set_attr "highpart" "ignore")])
1390 (define_insn "*addsi3_compact"
1391 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1393 (match_operand:SI 2 "arith_operand" "rI08")))]
1396 [(set_attr "type" "arith")])
1398 ;; -------------------------------------------------------------------------
1399 ;; Subtraction instructions
1400 ;; -------------------------------------------------------------------------
1402 (define_expand "subdi3"
1403 [(set (match_operand:DI 0 "arith_reg_operand" "")
1404 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1405 (match_operand:DI 2 "arith_reg_operand" "")))]
1411 operands[1] = force_reg (DImode, operands[1]);
1412 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1417 (define_insn "*subdi3_media"
1418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1419 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1420 (match_operand:DI 2 "arith_reg_operand" "r")))]
1423 [(set_attr "type" "arith_media")])
1425 (define_insn "subdisi3_media"
1426 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1427 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1428 (match_operand:DI 2 "arith_reg_operand" "r")))]
1431 [(set_attr "type" "arith_media")
1432 (set_attr "highpart" "ignore")])
1434 (define_insn "subdi3_compact"
1435 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1436 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1437 (match_operand:DI 2 "arith_reg_operand" "r")))
1438 (clobber (reg:SI T_REG))]
1441 [(set_attr "length" "6")])
1444 [(set (match_operand:DI 0 "arith_reg_dest" "")
1445 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1446 (match_operand:DI 2 "arith_reg_operand" "")))
1447 (clobber (reg:SI T_REG))]
1448 "TARGET_SH1 && reload_completed"
1452 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1453 high0 = gen_rtx_REG (SImode,
1454 true_regnum (operands[0])
1455 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456 high2 = gen_rtx_REG (SImode,
1457 true_regnum (operands[2])
1458 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1459 emit_insn (gen_clrt ());
1460 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1461 emit_insn (gen_subc1 (high0, high0, high2));
1466 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1467 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1468 (match_operand:SI 2 "arith_reg_operand" "r"))
1471 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1476 [(set_attr "type" "arith")])
1478 (define_insn "subc1"
1479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481 (match_operand:SI 2 "arith_reg_operand" "r"))
1483 (clobber (reg:SI T_REG))]
1486 [(set_attr "type" "arith")])
1488 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1489 ;; pattern for this case. This helps multimedia applications that compute
1490 ;; the sum of absolute differences.
1491 (define_insn "mov_neg_si_t"
1492 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1495 [(set_attr "type" "arith")])
1497 (define_insn "*subsi3_internal"
1498 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1499 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1500 (match_operand:SI 2 "arith_reg_operand" "r")))]
1503 [(set_attr "type" "arith")])
1505 (define_insn_and_split "*subsi3_media"
1506 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1507 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1508 (match_operand:SI 2 "extend_reg_operand" "r")))]
1510 && (operands[1] != constm1_rtx
1511 || (GET_CODE (operands[2]) != TRUNCATE
1512 && GET_CODE (operands[2]) != SUBREG))"
1514 "operands[1] == constm1_rtx"
1515 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1517 [(set_attr "type" "arith_media")
1518 (set_attr "highpart" "ignore")])
1521 [(set (match_operand:SI 0 "arith_reg_dest" "")
1522 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1523 "general_extend_operand"
1525 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1526 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1527 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1531 [(set (match_operand:SI 0 "arith_reg_dest" "")
1532 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1533 "general_extend_operand"
1535 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1536 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1537 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1539 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1540 ;; will sometimes save one instruction. Otherwise we might get
1541 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1544 (define_expand "subsi3"
1545 [(set (match_operand:SI 0 "arith_reg_operand" "")
1546 (minus:SI (match_operand:SI 1 "arith_operand" "")
1547 (match_operand:SI 2 "arith_reg_operand" "")))]
1551 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1553 emit_insn (gen_negsi2 (operands[0], operands[2]));
1554 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1559 if (!can_create_pseudo_p ()
1560 && ! arith_reg_or_0_operand (operands[1], SImode))
1562 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1563 operands[1] = force_reg (SImode, operands[1]);
1567 ;; -------------------------------------------------------------------------
1568 ;; Division instructions
1569 ;; -------------------------------------------------------------------------
1571 ;; We take advantage of the library routines which don't clobber as many
1572 ;; registers as a normal function call would.
1574 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1575 ;; also has an effect on the register that holds the address of the sfunc.
1576 ;; To make this work, we have an extra dummy insn that shows the use
1577 ;; of this register for reorg.
1579 (define_insn "use_sfunc_addr"
1580 [(set (reg:SI PR_REG)
1581 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1582 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1584 [(set_attr "length" "0")])
1586 (define_insn "udivsi3_sh2a"
1587 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1588 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1589 (match_operand:SI 2 "arith_reg_operand" "z")))]
1592 [(set_attr "type" "arith")
1593 (set_attr "in_delay_slot" "no")])
1595 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1596 ;; hard register 0. If we used hard register 0, then the next instruction
1597 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1598 ;; gets allocated to a stack slot that needs its address reloaded, then
1599 ;; there is nothing to prevent reload from using r0 to reload the address.
1600 ;; This reload would clobber the value in r0 we are trying to store.
1601 ;; If we let reload allocate r0, then this problem can never happen.
1603 (define_insn "udivsi3_i1"
1604 [(set (match_operand:SI 0 "register_operand" "=z")
1605 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1606 (clobber (reg:SI T_REG))
1607 (clobber (reg:SI PR_REG))
1608 (clobber (reg:SI R4_REG))
1609 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1610 "TARGET_SH1 && ! TARGET_SH4"
1612 [(set_attr "type" "sfunc")
1613 (set_attr "needs_delay_slot" "yes")])
1615 ; Since shmedia-nofpu code could be linked against shcompact code, and
1616 ; the udivsi3 libcall has the same name, we must consider all registers
1617 ; clobbered that are in the union of the registers clobbered by the
1618 ; shmedia and the shcompact implementation. Note, if the shcompact
1619 ; implementation actually used shcompact code, we'd need to clobber
1620 ; also r23 and fr23.
1621 (define_insn "udivsi3_i1_media"
1622 [(set (match_operand:SI 0 "register_operand" "=z")
1623 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1624 (clobber (reg:SI T_MEDIA_REG))
1625 (clobber (reg:SI PR_MEDIA_REG))
1626 (clobber (reg:SI R20_REG))
1627 (clobber (reg:SI R21_REG))
1628 (clobber (reg:SI R22_REG))
1629 (clobber (reg:DI TR0_REG))
1630 (clobber (reg:DI TR1_REG))
1631 (clobber (reg:DI TR2_REG))
1632 (use (match_operand 1 "target_reg_operand" "b"))]
1633 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1635 [(set_attr "type" "sfunc")
1636 (set_attr "needs_delay_slot" "yes")])
1638 (define_expand "udivsi3_i4_media"
1640 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1642 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1643 (set (match_dup 5) (float:DF (match_dup 3)))
1644 (set (match_dup 6) (float:DF (match_dup 4)))
1645 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1646 (set (match_dup 8) (fix:DI (match_dup 7)))
1647 (set (match_operand:SI 0 "register_operand" "")
1648 (truncate:SI (match_dup 8)))]
1649 "TARGET_SHMEDIA_FPU"
1652 operands[3] = gen_reg_rtx (DImode);
1653 operands[4] = gen_reg_rtx (DImode);
1654 operands[5] = gen_reg_rtx (DFmode);
1655 operands[6] = gen_reg_rtx (DFmode);
1656 operands[7] = gen_reg_rtx (DFmode);
1657 operands[8] = gen_reg_rtx (DImode);
1660 (define_insn "udivsi3_i4"
1661 [(set (match_operand:SI 0 "register_operand" "=y")
1662 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663 (clobber (reg:SI T_REG))
1664 (clobber (reg:SI PR_REG))
1665 (clobber (reg:DF DR0_REG))
1666 (clobber (reg:DF DR2_REG))
1667 (clobber (reg:DF DR4_REG))
1668 (clobber (reg:SI R0_REG))
1669 (clobber (reg:SI R1_REG))
1670 (clobber (reg:SI R4_REG))
1671 (clobber (reg:SI R5_REG))
1672 (use (reg:PSI FPSCR_REG))
1673 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1674 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1676 [(set_attr "type" "sfunc")
1677 (set_attr "fp_mode" "double")
1678 (set_attr "needs_delay_slot" "yes")])
1680 (define_insn "udivsi3_i4_single"
1681 [(set (match_operand:SI 0 "register_operand" "=y")
1682 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1683 (clobber (reg:SI T_REG))
1684 (clobber (reg:SI PR_REG))
1685 (clobber (reg:DF DR0_REG))
1686 (clobber (reg:DF DR2_REG))
1687 (clobber (reg:DF DR4_REG))
1688 (clobber (reg:SI R0_REG))
1689 (clobber (reg:SI R1_REG))
1690 (clobber (reg:SI R4_REG))
1691 (clobber (reg:SI R5_REG))
1692 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1693 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1695 [(set_attr "type" "sfunc")
1696 (set_attr "needs_delay_slot" "yes")])
1698 (define_insn "udivsi3_i4_int"
1699 [(set (match_operand:SI 0 "register_operand" "=z")
1700 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1701 (clobber (reg:SI T_REG))
1702 (clobber (reg:SI R1_REG))
1703 (clobber (reg:SI PR_REG))
1704 (clobber (reg:SI MACH_REG))
1705 (clobber (reg:SI MACL_REG))
1706 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1709 [(set_attr "type" "sfunc")
1710 (set_attr "needs_delay_slot" "yes")])
1713 (define_expand "udivsi3"
1714 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1715 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1716 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1717 (parallel [(set (match_operand:SI 0 "register_operand" "")
1718 (udiv:SI (reg:SI R4_REG)
1720 (clobber (reg:SI T_REG))
1721 (clobber (reg:SI PR_REG))
1722 (clobber (reg:SI R4_REG))
1723 (use (match_dup 3))])]
1729 operands[3] = gen_reg_rtx (Pmode);
1730 /* Emit the move of the address to a pseudo outside of the libcall. */
1731 if (TARGET_DIVIDE_CALL_TABLE)
1733 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1734 that causes problems when the divide code is supposed to come from a
1735 separate library. Division by zero is undefined, so dividing 1 can be
1736 implemented by comparing with the divisor. */
1737 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1739 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1740 emit_insn (gen_cstoresi4 (operands[0], test,
1741 operands[1], operands[2]));
1744 else if (operands[2] == const0_rtx)
1746 emit_move_insn (operands[0], operands[2]);
1749 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1750 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1752 else if (TARGET_DIVIDE_CALL_FP)
1754 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1755 if (TARGET_FPU_SINGLE)
1756 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1758 last = gen_udivsi3_i4 (operands[0], operands[3]);
1760 else if (TARGET_SHMEDIA_FPU)
1762 operands[1] = force_reg (SImode, operands[1]);
1763 operands[2] = force_reg (SImode, operands[2]);
1764 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1767 else if (TARGET_SH2A)
1769 operands[1] = force_reg (SImode, operands[1]);
1770 operands[2] = force_reg (SImode, operands[2]);
1771 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1774 else if (TARGET_SH5)
1776 function_symbol (operands[3],
1777 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1781 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1782 else if (TARGET_FPU_ANY)
1783 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1785 last = gen_udivsi3_i1 (operands[0], operands[3]);
1789 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1790 last = gen_udivsi3_i1 (operands[0], operands[3]);
1792 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1793 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1798 (define_insn "divsi3_sh2a"
1799 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1800 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1801 (match_operand:SI 2 "arith_reg_operand" "z")))]
1804 [(set_attr "type" "arith")
1805 (set_attr "in_delay_slot" "no")])
1807 (define_insn "divsi3_i1"
1808 [(set (match_operand:SI 0 "register_operand" "=z")
1809 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1810 (clobber (reg:SI T_REG))
1811 (clobber (reg:SI PR_REG))
1812 (clobber (reg:SI R1_REG))
1813 (clobber (reg:SI R2_REG))
1814 (clobber (reg:SI R3_REG))
1815 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1816 "TARGET_SH1 && ! TARGET_SH4"
1818 [(set_attr "type" "sfunc")
1819 (set_attr "needs_delay_slot" "yes")])
1821 (define_insn "divsi3_i1_media"
1822 [(set (match_operand:SI 0 "register_operand" "=z")
1823 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1824 (clobber (reg:SI T_MEDIA_REG))
1825 (clobber (reg:SI PR_MEDIA_REG))
1826 (clobber (reg:SI R1_REG))
1827 (clobber (reg:SI R20_REG))
1828 (clobber (reg:SI R21_REG))
1829 (clobber (reg:SI TR0_REG))
1830 (use (match_operand 1 "target_reg_operand" "b"))]
1831 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1833 [(set_attr "type" "sfunc")])
1835 (define_insn "divsi3_media_2"
1836 [(set (match_operand:SI 0 "register_operand" "=z")
1837 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1838 (clobber (reg:SI T_MEDIA_REG))
1839 (clobber (reg:SI PR_MEDIA_REG))
1840 (clobber (reg:SI R1_REG))
1841 (clobber (reg:SI R21_REG))
1842 (clobber (reg:SI TR0_REG))
1843 (use (reg:SI R20_REG))
1844 (use (match_operand 1 "target_reg_operand" "b"))]
1845 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1847 [(set_attr "type" "sfunc")])
1849 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1850 ;; hard reg clobbers and data dependencies that we need when we want
1851 ;; to rematerialize the division into a call.
1852 (define_insn_and_split "divsi_inv_call"
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1854 (div:SI (match_operand:SI 1 "register_operand" "r")
1855 (match_operand:SI 2 "register_operand" "r")))
1856 (clobber (reg:SI R4_REG))
1857 (clobber (reg:SI R5_REG))
1858 (clobber (reg:SI T_MEDIA_REG))
1859 (clobber (reg:SI PR_MEDIA_REG))
1860 (clobber (reg:SI R1_REG))
1861 (clobber (reg:SI R21_REG))
1862 (clobber (reg:SI TR0_REG))
1863 (clobber (reg:SI R20_REG))
1864 (use (match_operand:SI 3 "register_operand" "r"))]
1867 "&& (high_life_started || reload_completed)"
1868 [(set (match_dup 0) (match_dup 3))]
1870 [(set_attr "highpart" "must_split")])
1872 ;; This is the combiner pattern for -mdiv=inv:call .
1873 (define_insn_and_split "*divsi_inv_call_combine"
1874 [(set (match_operand:SI 0 "register_operand" "=z")
1875 (div:SI (match_operand:SI 1 "register_operand" "r")
1876 (match_operand:SI 2 "register_operand" "r")))
1877 (clobber (reg:SI R4_REG))
1878 (clobber (reg:SI R5_REG))
1879 (clobber (reg:SI T_MEDIA_REG))
1880 (clobber (reg:SI PR_MEDIA_REG))
1881 (clobber (reg:SI R1_REG))
1882 (clobber (reg:SI R21_REG))
1883 (clobber (reg:SI TR0_REG))
1884 (clobber (reg:SI R20_REG))
1885 (use (unspec:SI [(match_dup 1)
1886 (match_operand:SI 3 "" "")
1887 (unspec:SI [(match_operand:SI 4 "" "")
1889 (match_operand:DI 5 "" "")]
1891 (match_operand:DI 6 "" "")
1894 UNSPEC_DIV_INV_M3))]
1897 "&& (high_life_started || reload_completed)"
1901 const char *name = sh_divsi3_libfunc;
1902 enum sh_function_kind kind = SFUNC_GOT;
1905 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1906 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1907 while (TARGET_DIVIDE_INV_CALL2)
1909 rtx x = operands[3];
1911 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1913 x = XVECEXP (x, 0, 0);
1914 name = \"__sdivsi3_2\";
1915 kind = SFUNC_STATIC;
1916 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1919 sym = function_symbol (NULL, name, kind);
1920 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1923 [(set_attr "highpart" "must_split")])
1925 (define_expand "divsi3_i4_media"
1926 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1927 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1928 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1929 (set (match_operand:SI 0 "register_operand" "=r")
1930 (fix:SI (match_dup 5)))]
1931 "TARGET_SHMEDIA_FPU"
1934 operands[3] = gen_reg_rtx (DFmode);
1935 operands[4] = gen_reg_rtx (DFmode);
1936 operands[5] = gen_reg_rtx (DFmode);
1939 (define_insn "divsi3_i4"
1940 [(set (match_operand:SI 0 "register_operand" "=y")
1941 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942 (clobber (reg:SI PR_REG))
1943 (clobber (reg:DF DR0_REG))
1944 (clobber (reg:DF DR2_REG))
1945 (use (reg:PSI FPSCR_REG))
1946 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1947 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1949 [(set_attr "type" "sfunc")
1950 (set_attr "fp_mode" "double")
1951 (set_attr "needs_delay_slot" "yes")])
1953 (define_insn "divsi3_i4_single"
1954 [(set (match_operand:SI 0 "register_operand" "=y")
1955 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956 (clobber (reg:SI PR_REG))
1957 (clobber (reg:DF DR0_REG))
1958 (clobber (reg:DF DR2_REG))
1959 (clobber (reg:SI R2_REG))
1960 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1961 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1963 [(set_attr "type" "sfunc")
1964 (set_attr "needs_delay_slot" "yes")])
1966 (define_insn "divsi3_i4_int"
1967 [(set (match_operand:SI 0 "register_operand" "=z")
1968 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1969 (clobber (reg:SI T_REG))
1970 (clobber (reg:SI PR_REG))
1971 (clobber (reg:SI R1_REG))
1972 (clobber (reg:SI MACH_REG))
1973 (clobber (reg:SI MACL_REG))
1974 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1977 [(set_attr "type" "sfunc")
1978 (set_attr "needs_delay_slot" "yes")])
1980 (define_expand "divsi3"
1981 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1982 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1983 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1984 (parallel [(set (match_operand:SI 0 "register_operand" "")
1985 (div:SI (reg:SI R4_REG)
1987 (clobber (reg:SI T_REG))
1988 (clobber (reg:SI PR_REG))
1989 (clobber (reg:SI R1_REG))
1990 (clobber (reg:SI R2_REG))
1991 (clobber (reg:SI R3_REG))
1992 (use (match_dup 3))])]
1998 operands[3] = gen_reg_rtx (Pmode);
1999 /* Emit the move of the address to a pseudo outside of the libcall. */
2000 if (TARGET_DIVIDE_CALL_TABLE)
2002 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2003 last = gen_divsi3_i4_int (operands[0], operands[3]);
2005 else if (TARGET_DIVIDE_CALL_FP)
2007 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2008 if (TARGET_FPU_SINGLE)
2009 last = gen_divsi3_i4_single (operands[0], operands[3]);
2011 last = gen_divsi3_i4 (operands[0], operands[3]);
2013 else if (TARGET_SH2A)
2015 operands[1] = force_reg (SImode, operands[1]);
2016 operands[2] = force_reg (SImode, operands[2]);
2017 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2020 else if (TARGET_DIVIDE_INV)
2022 rtx dividend = operands[1];
2023 rtx divisor = operands[2];
2025 rtx nsb_res = gen_reg_rtx (DImode);
2026 rtx norm64 = gen_reg_rtx (DImode);
2027 rtx tab_ix = gen_reg_rtx (DImode);
2028 rtx norm32 = gen_reg_rtx (SImode);
2029 rtx i92 = force_reg (DImode, GEN_INT (92));
2030 rtx scratch0a = gen_reg_rtx (DImode);
2031 rtx scratch0b = gen_reg_rtx (DImode);
2032 rtx inv0 = gen_reg_rtx (SImode);
2033 rtx scratch1a = gen_reg_rtx (DImode);
2034 rtx scratch1b = gen_reg_rtx (DImode);
2035 rtx shift = gen_reg_rtx (DImode);
2037 rtx inv1 = gen_reg_rtx (SImode);
2038 rtx scratch2a = gen_reg_rtx (DImode);
2039 rtx scratch2b = gen_reg_rtx (SImode);
2040 rtx inv2 = gen_reg_rtx (SImode);
2041 rtx scratch3a = gen_reg_rtx (DImode);
2042 rtx scratch3b = gen_reg_rtx (DImode);
2043 rtx scratch3c = gen_reg_rtx (DImode);
2044 rtx scratch3d = gen_reg_rtx (SImode);
2045 rtx scratch3e = gen_reg_rtx (DImode);
2046 rtx result = gen_reg_rtx (SImode);
2048 if (! arith_reg_or_0_operand (dividend, SImode))
2049 dividend = force_reg (SImode, dividend);
2050 if (! arith_reg_operand (divisor, SImode))
2051 divisor = force_reg (SImode, divisor);
2052 if (flag_pic && Pmode != DImode)
2054 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2055 tab_base = gen_datalabel_ref (tab_base);
2056 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2060 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2061 tab_base = gen_datalabel_ref (tab_base);
2062 tab_base = force_reg (DImode, tab_base);
2064 if (TARGET_DIVIDE_INV20U)
2065 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2067 i2p27 = GEN_INT (0);
2068 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2069 i43 = force_reg (DImode, GEN_INT (43));
2072 emit_insn (gen_nsbdi (nsb_res,
2073 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2074 emit_insn (gen_ashldi3_media (norm64,
2075 gen_rtx_SUBREG (DImode, divisor, 0),
2077 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2078 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2079 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2080 inv0, scratch0a, scratch0b,
2081 scratch1a, scratch1b));
2082 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2083 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2085 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2087 scratch3a, scratch3b, scratch3c,
2088 scratch2a, scratch2b, scratch3d, scratch3e));
2089 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2090 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2091 else if (TARGET_DIVIDE_INV_FP)
2092 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2093 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2094 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2095 gen_reg_rtx (DFmode)));
2097 emit_move_insn (operands[0], result);
2100 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2102 operands[1] = force_reg (SImode, operands[1]);
2103 operands[2] = force_reg (SImode, operands[2]);
2104 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2107 else if (TARGET_SH5)
2109 if (TARGET_DIVIDE_CALL2)
2111 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2112 tab_base = gen_datalabel_ref (tab_base);
2113 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2115 if (TARGET_FPU_ANY && TARGET_SH1)
2116 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2117 else if (TARGET_DIVIDE_CALL2)
2118 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2120 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2123 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2124 (operands[0], operands[3]));
2125 else if (TARGET_FPU_ANY)
2126 last = gen_divsi3_i4_single (operands[0], operands[3]);
2128 last = gen_divsi3_i1 (operands[0], operands[3]);
2132 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2133 last = gen_divsi3_i1 (operands[0], operands[3]);
2135 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2136 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2141 ;; operands: scratch, tab_base, tab_ix
2142 ;; These are unspecs because we could generate an indexed addressing mode
2143 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2144 ;; confuse reload. See PR27117.
2146 (define_insn "divsi_inv_qitable"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2148 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2149 (match_operand:DI 2 "register_operand" "r")]
2150 UNSPEC_DIV_INV_TABLE)))]
2154 [(set_attr "type" "load_media")
2155 (set_attr "highpart" "user")])
2157 ;; operands: scratch, tab_base, tab_ix
2158 (define_insn "divsi_inv_hitable"
2159 [(set (match_operand:DI 0 "register_operand" "=r")
2160 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2161 (match_operand:DI 2 "register_operand" "r")]
2162 UNSPEC_DIV_INV_TABLE)))]
2166 [(set_attr "type" "load_media")
2167 (set_attr "highpart" "user")])
2169 ;; operands: inv0, tab_base, tab_ix, norm32
2170 ;; scratch equiv in sdivsi3_2: r19, r21
2171 (define_expand "divsi_inv_m0"
2172 [(set (match_operand:SI 0 "register_operand" "=r")
2173 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2174 (match_operand:DI 2 "register_operand" "r")
2175 (match_operand:SI 3 "register_operand" "r")]
2177 (clobber (match_operand:DI 4 "register_operand" "=r"))
2178 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2186 ldx.ub r20, r21, r19 // u0.8
2188 muls.l r25, r19, r19 // s2.38
2189 ldx.w r20, r21, r21 // s2.14
2190 shari r19, 24, r19 // truncate to s2.14
2191 sub r21, r19, r19 // some 11 bit inverse in s1.14
2194 rtx inv0 = operands[0];
2195 rtx tab_base = operands[1];
2196 rtx tab_ix = operands[2];
2197 rtx norm32 = operands[3];
2198 rtx scratch0 = operands[4];
2199 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2200 rtx scratch1 = operands[5];
2202 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2203 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2204 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2205 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2206 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2207 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2211 ;; operands: inv1, tab_base, tab_ix, norm32
2212 (define_insn_and_split "divsi_inv_m1"
2213 [(set (match_operand:SI 0 "register_operand" "=r")
2214 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2215 (match_operand:DI 2 "register_operand" "r")
2216 (match_operand:SI 3 "register_operand" "r")]
2218 (clobber (match_operand:SI 4 "register_operand" "=r"))
2219 (clobber (match_operand:DI 5 "register_operand" "=r"))
2220 (clobber (match_operand:DI 6 "register_operand" "=r"))
2221 (clobber (match_operand:DI 7 "register_operand" "=r"))
2222 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2225 "&& !can_create_pseudo_p ()"
2230 muls.l r19, r19, r18 // u0.28
2231 muls.l r25, r18, r18 // s2.58
2232 shlli r19, 45, r0 // multiply by two and convert to s2.58
2234 shari r18, 28, r18 // some 18 bit inverse in s1.30
2237 rtx inv1 = operands[0];
2238 rtx tab_base = operands[1];
2239 rtx tab_ix = operands[2];
2240 rtx norm32 = operands[3];
2241 rtx inv0 = operands[4];
2242 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2243 rtx scratch0a = operands[5];
2244 rtx scratch0b = operands[6];
2245 rtx scratch0 = operands[7];
2246 rtx scratch1 = operands[8];
2247 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2249 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2250 scratch0a, scratch0b));
2251 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2252 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2253 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2254 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2255 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2259 ;; operands: inv2, norm32, inv1, i92
2260 (define_insn_and_split "divsi_inv_m2"
2261 [(set (match_operand:SI 0 "register_operand" "=r")
2262 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2263 (match_operand:SI 2 "register_operand" "r")
2264 (match_operand:DI 3 "register_operand" "r")]
2266 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2269 "&& !can_create_pseudo_p ()"
2274 muls.l r18, r25, r0 // s2.60
2275 shari r0, 16, r0 // s-16.44
2277 muls.l r0, r18, r19 // s-16.74
2278 shari r19, 30, r19 // s-16.44
2280 rtx inv2 = operands[0];
2281 rtx norm32 = operands[1];
2282 rtx inv1 = operands[2];
2283 rtx i92 = operands[3];
2284 rtx scratch0 = operands[4];
2285 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2287 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2288 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2289 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2290 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2291 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2295 (define_insn_and_split "divsi_inv_m3"
2296 [(set (match_operand:SI 0 "register_operand" "=r")
2297 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2298 (match_operand:SI 2 "register_operand" "r")
2299 (match_operand:SI 3 "register_operand" "r")
2300 (match_operand:DI 4 "register_operand" "r")
2301 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2302 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2304 (clobber (match_operand:DI 7 "register_operand" "=r"))
2305 (clobber (match_operand:DI 8 "register_operand" "=r"))
2306 (clobber (match_operand:DI 9 "register_operand" "=r"))
2307 (clobber (match_operand:DI 10 "register_operand" "=r"))
2308 (clobber (match_operand:SI 11 "register_operand" "=r"))
2309 (clobber (match_operand:SI 12 "register_operand" "=r"))
2310 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2313 "&& !can_create_pseudo_p ()"
2318 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2319 r0: scratch0 r19: scratch1 r21: scratch2
2321 muls.l r18, r4, r25 // s32.30
2322 muls.l r19, r4, r19 // s15.30
2324 shari r19, 14, r19 // s18.-14
2330 rtx result = operands[0];
2331 rtx dividend = operands[1];
2332 rtx inv1 = operands[2];
2333 rtx inv2 = operands[3];
2334 rtx shift = operands[4];
2335 rtx scratch0 = operands[7];
2336 rtx scratch1 = operands[8];
2337 rtx scratch2 = operands[9];
2339 if (satisfies_constraint_N (dividend))
2341 emit_move_insn (result, dividend);
2345 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2346 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2347 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2348 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2349 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2350 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2351 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2355 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2356 ;; inv1: tab_base, tab_ix, norm32
2357 ;; inv2: norm32, inv1, i92
2358 (define_insn_and_split "divsi_inv_m1_3"
2359 [(set (match_operand:SI 0 "register_operand" "=r")
2360 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2361 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2362 (match_operand:DI 3 "register_operand" "r")
2363 (match_operand:SI 4 "register_operand" "r")]
2365 (unspec:SI [(match_dup 4)
2366 (unspec:SI [(match_dup 2)
2368 (match_dup 4)] UNSPEC_DIV_INV_M1)
2369 (match_operand:SI 5 "" "")]
2371 (match_operand:DI 6 "register_operand" "r")
2372 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2373 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2375 (clobber (match_operand:DI 9 "register_operand" "=r"))
2376 (clobber (match_operand:DI 10 "register_operand" "=r"))
2377 (clobber (match_operand:DI 11 "register_operand" "=r"))
2378 (clobber (match_operand:DI 12 "register_operand" "=r"))
2379 (clobber (match_operand:SI 13 "register_operand" "=r"))
2380 (clobber (match_operand:SI 14 "register_operand" "=r"))
2381 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2383 && (TARGET_DIVIDE_INV_MINLAT
2384 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2386 "&& !can_create_pseudo_p ()"
2390 rtx result = operands[0];
2391 rtx dividend = operands[1];
2392 rtx tab_base = operands[2];
2393 rtx tab_ix = operands[3];
2394 rtx norm32 = operands[4];
2395 /* rtx i92 = operands[5]; */
2396 rtx shift = operands[6];
2397 rtx i2p27 = operands[7];
2398 rtx i43 = operands[8];
2399 rtx scratch0 = operands[9];
2400 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2401 rtx scratch1 = operands[10];
2402 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2403 rtx scratch2 = operands[11];
2404 rtx scratch3 = operands[12];
2405 rtx scratch4 = operands[13];
2406 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2407 rtx scratch5 = operands[14];
2408 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2409 rtx scratch6 = operands[15];
2411 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2412 scratch0, scratch1));
2413 /* inv0 == scratch4 */
2414 if (! TARGET_DIVIDE_INV20U)
2416 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2418 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2422 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2423 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2425 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2426 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2427 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2428 /* inv1 == scratch4 */
2430 if (TARGET_DIVIDE_INV_MINLAT)
2432 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2433 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2434 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2435 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2436 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2437 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2438 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2439 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2440 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2441 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2442 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2446 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2447 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2448 emit_insn (gen_nsbdi (scratch6,
2449 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2450 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2451 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2452 emit_insn (gen_divsi_inv20 (scratch2,
2453 norm32, scratch4, dividend,
2454 scratch6, scratch3, i43,
2455 /* scratch0 may be shared with i2p27. */
2456 scratch0, scratch1, scratch5,
2457 label, label, i2p27));
2459 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2460 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2464 (define_insn "divsi_inv20"
2465 [(set (match_operand:DI 0 "register_operand" "=&r")
2466 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2467 (match_operand:SI 2 "register_operand" "r")
2468 (match_operand:SI 3 "register_operand" "r")
2469 (match_operand:DI 4 "register_operand" "r")
2470 (match_operand:DI 5 "register_operand" "r")
2471 (match_operand:DI 6 "register_operand" "r")
2472 (match_operand:DI 12 "register_operand" "r")
2473 (match_operand 10 "target_operand" "b")
2474 (match_operand 11 "immediate_operand" "i")]
2476 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2477 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2478 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2480 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2483 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2484 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2485 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2486 %10 label (tr), %11 label (imm)
2488 muls.l inv1, norm32, scratch0 // s2.60
2489 muls.l inv1, dividend, result // s32.30
2490 xor i2p27, result_sign, round_scratch
2491 bge/u dividend_nsb, i43, tr.. (label)
2492 shari scratch0, 16, scratch0 // s-16.44
2493 muls.l sratch0_si, inv1, scratch0 // s-16.74
2494 sub result, round_scratch, result
2495 shari dividend, 14, scratch1 // s19.-14
2496 shari scratch0, 30, scratch0 // s-16.44
2497 muls.l scratch0, scratch1, round_scratch // s15.30
2499 sub result, round_scratch, result */
2501 int likely = TARGET_DIVIDE_INV20L;
2503 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2504 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2505 output_asm_insn (likely
2506 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2507 : \"bge/u\t%4, %6, %10\", operands);
2508 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2509 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2510 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2512 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2513 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2516 (define_insn_and_split "divsi_inv_fp"
2517 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2518 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2519 (match_operand:SI 2 "register_operand" "rf")))
2520 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2521 (clobber (match_operand:SI 4 "register_operand" "=r"))
2522 (clobber (match_operand:SI 5 "register_operand" "=r"))
2523 (clobber (match_operand:DF 6 "register_operand" "=r"))
2524 (clobber (match_operand:DF 7 "register_operand" "=r"))
2525 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2526 "TARGET_SHMEDIA_FPU"
2528 "&& (high_life_started || reload_completed)"
2529 [(set (match_dup 0) (match_dup 3))]
2531 [(set_attr "highpart" "must_split")])
2533 ;; If a matching group of divide-by-inverse instructions is in the same
2534 ;; basic block after gcse & loop optimizations, we want to transform them
2535 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2536 (define_insn_and_split "*divsi_inv_fp_combine"
2537 [(set (match_operand:SI 0 "register_operand" "=f")
2538 (div:SI (match_operand:SI 1 "register_operand" "f")
2539 (match_operand:SI 2 "register_operand" "f")))
2540 (use (unspec:SI [(match_dup 1)
2541 (match_operand:SI 3 "" "")
2542 (unspec:SI [(match_operand:SI 4 "" "")
2544 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2545 (match_operand:DI 6 "" "")
2547 (const_int 0)] UNSPEC_DIV_INV_M3))
2548 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2549 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2550 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2551 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2552 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2553 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2556 [(set (match_dup 9) (float:DF (match_dup 1)))
2557 (set (match_dup 10) (float:DF (match_dup 2)))
2558 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2560 (fix:SI (match_dup 11)))
2561 (set (match_dup 0) (match_dup 8))]
2564 if (! fp_arith_reg_operand (operands[1], SImode))
2566 emit_move_insn (operands[7], operands[1]);
2567 operands[1] = operands[7];
2569 if (! fp_arith_reg_operand (operands[2], SImode))
2571 emit_move_insn (operands[8], operands[2]);
2572 operands[2] = operands[8];
2575 [(set_attr "highpart" "must_split")])
2577 ;; -------------------------------------------------------------------------
2578 ;; Multiplication instructions
2579 ;; -------------------------------------------------------------------------
2581 (define_insn "umulhisi3_i"
2582 [(set (reg:SI MACL_REG)
2583 (mult:SI (zero_extend:SI
2584 (match_operand:HI 0 "arith_reg_operand" "r"))
2586 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2589 [(set_attr "type" "smpy")])
2591 (define_insn "mulhisi3_i"
2592 [(set (reg:SI MACL_REG)
2593 (mult:SI (sign_extend:SI
2594 (match_operand:HI 0 "arith_reg_operand" "r"))
2596 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2599 [(set_attr "type" "smpy")])
2601 (define_expand "mulhisi3"
2602 [(set (reg:SI MACL_REG)
2603 (mult:SI (sign_extend:SI
2604 (match_operand:HI 1 "arith_reg_operand" ""))
2606 (match_operand:HI 2 "arith_reg_operand" ""))))
2607 (set (match_operand:SI 0 "arith_reg_operand" "")
2614 macl = gen_rtx_REG (SImode, MACL_REG);
2616 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2617 insn = get_insns ();
2619 /* expand_binop can't find a suitable code in umul_widen_optab to
2620 make a REG_EQUAL note from, so make one here.
2621 See also smulsi3_highpart.
2622 ??? Alternatively, we could put this at the calling site of expand_binop,
2623 i.e. expand_expr. */
2624 /* Use emit_libcall_block for loop invariant code motion and to make
2625 a REG_EQUAL note. */
2626 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2631 (define_expand "umulhisi3"
2632 [(set (reg:SI MACL_REG)
2633 (mult:SI (zero_extend:SI
2634 (match_operand:HI 1 "arith_reg_operand" ""))
2636 (match_operand:HI 2 "arith_reg_operand" ""))))
2637 (set (match_operand:SI 0 "arith_reg_operand" "")
2644 macl = gen_rtx_REG (SImode, MACL_REG);
2646 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2647 insn = get_insns ();
2649 /* expand_binop can't find a suitable code in umul_widen_optab to
2650 make a REG_EQUAL note from, so make one here.
2651 See also smulsi3_highpart.
2652 ??? Alternatively, we could put this at the calling site of expand_binop,
2653 i.e. expand_expr. */
2654 /* Use emit_libcall_block for loop invariant code motion and to make
2655 a REG_EQUAL note. */
2656 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2661 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2662 ;; a call to a routine which clobbers known registers.
2665 [(set (match_operand:SI 1 "register_operand" "=z")
2666 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2667 (clobber (reg:SI MACL_REG))
2668 (clobber (reg:SI T_REG))
2669 (clobber (reg:SI PR_REG))
2670 (clobber (reg:SI R3_REG))
2671 (clobber (reg:SI R2_REG))
2672 (clobber (reg:SI R1_REG))
2673 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2676 [(set_attr "type" "sfunc")
2677 (set_attr "needs_delay_slot" "yes")])
2679 (define_expand "mulsi3_call"
2680 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2681 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2682 (parallel[(set (match_operand:SI 0 "register_operand" "")
2683 (mult:SI (reg:SI R4_REG)
2685 (clobber (reg:SI MACL_REG))
2686 (clobber (reg:SI T_REG))
2687 (clobber (reg:SI PR_REG))
2688 (clobber (reg:SI R3_REG))
2689 (clobber (reg:SI R2_REG))
2690 (clobber (reg:SI R1_REG))
2691 (use (match_operand:SI 3 "register_operand" ""))])]
2695 (define_insn "mul_r"
2696 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2697 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2698 (match_operand:SI 2 "arith_reg_operand" "z")))]
2701 [(set_attr "type" "dmpy")])
2703 (define_insn "mul_l"
2704 [(set (reg:SI MACL_REG)
2705 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2706 (match_operand:SI 1 "arith_reg_operand" "r")))]
2709 [(set_attr "type" "dmpy")])
2711 (define_expand "mulsi3"
2712 [(set (reg:SI MACL_REG)
2713 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2714 (match_operand:SI 2 "arith_reg_operand" "")))
2715 (set (match_operand:SI 0 "arith_reg_operand" "")
2722 /* The address must be set outside the libcall,
2723 since it goes into a pseudo. */
2724 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2725 rtx addr = force_reg (SImode, sym);
2726 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2732 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2734 emit_insn (gen_mul_l (operands[1], operands[2]));
2735 /* consec_sets_giv can only recognize the first insn that sets a
2736 giv as the giv insn. So we must tag this also with a REG_EQUAL
2738 emit_insn (gen_movsi_i ((operands[0]), macl));
2743 (define_insn "mulsidi3_i"
2744 [(set (reg:SI MACH_REG)
2748 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2749 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2751 (set (reg:SI MACL_REG)
2752 (mult:SI (match_dup 0)
2756 [(set_attr "type" "dmpy")])
2758 (define_expand "mulsidi3"
2759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2760 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2761 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2762 "TARGET_SH2 || TARGET_SHMEDIA"
2767 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2773 (define_insn "mulsidi3_media"
2774 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2775 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2776 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2779 [(set_attr "type" "dmpy_media")
2780 (set_attr "highpart" "ignore")])
2782 (define_insn "mulsidi3_compact"
2783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2785 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2786 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2787 (clobber (reg:SI MACH_REG))
2788 (clobber (reg:SI MACL_REG))]
2793 [(set (match_operand:DI 0 "arith_reg_dest" "")
2795 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2796 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2797 (clobber (reg:SI MACH_REG))
2798 (clobber (reg:SI MACL_REG))]
2803 rtx low_dst = gen_lowpart (SImode, operands[0]);
2804 rtx high_dst = gen_highpart (SImode, operands[0]);
2806 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2808 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2809 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2810 /* We need something to tag the possible REG_EQUAL notes on to. */
2811 emit_move_insn (operands[0], operands[0]);
2815 (define_insn "umulsidi3_i"
2816 [(set (reg:SI MACH_REG)
2820 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2821 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2823 (set (reg:SI MACL_REG)
2824 (mult:SI (match_dup 0)
2828 [(set_attr "type" "dmpy")])
2830 (define_expand "umulsidi3"
2831 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2832 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2833 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2834 "TARGET_SH2 || TARGET_SHMEDIA"
2839 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2845 (define_insn "umulsidi3_media"
2846 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2847 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2848 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2851 [(set_attr "type" "dmpy_media")
2852 (set_attr "highpart" "ignore")])
2854 (define_insn "umulsidi3_compact"
2855 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2857 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2858 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2859 (clobber (reg:SI MACH_REG))
2860 (clobber (reg:SI MACL_REG))]
2865 [(set (match_operand:DI 0 "arith_reg_dest" "")
2866 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2867 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2868 (clobber (reg:SI MACH_REG))
2869 (clobber (reg:SI MACL_REG))]
2874 rtx low_dst = gen_lowpart (SImode, operands[0]);
2875 rtx high_dst = gen_highpart (SImode, operands[0]);
2877 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2879 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2880 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2881 /* We need something to tag the possible REG_EQUAL notes on to. */
2882 emit_move_insn (operands[0], operands[0]);
2886 (define_insn "smulsi3_highpart_i"
2887 [(set (reg:SI MACH_REG)
2891 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2892 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2894 (clobber (reg:SI MACL_REG))]
2897 [(set_attr "type" "dmpy")])
2899 (define_expand "smulsi3_highpart"
2901 [(set (reg:SI MACH_REG)
2905 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2906 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2908 (clobber (reg:SI MACL_REG))])
2909 (set (match_operand:SI 0 "arith_reg_operand" "")
2916 mach = gen_rtx_REG (SImode, MACH_REG);
2918 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2919 insn = get_insns ();
2921 /* expand_binop can't find a suitable code in mul_highpart_optab to
2922 make a REG_EQUAL note from, so make one here.
2923 See also {,u}mulhisi.
2924 ??? Alternatively, we could put this at the calling site of expand_binop,
2925 i.e. expand_mult_highpart. */
2926 /* Use emit_libcall_block for loop invariant code motion and to make
2927 a REG_EQUAL note. */
2928 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2933 (define_insn "umulsi3_highpart_i"
2934 [(set (reg:SI MACH_REG)
2938 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2939 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2941 (clobber (reg:SI MACL_REG))]
2944 [(set_attr "type" "dmpy")])
2946 (define_expand "umulsi3_highpart"
2948 [(set (reg:SI MACH_REG)
2952 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2953 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2955 (clobber (reg:SI MACL_REG))])
2956 (set (match_operand:SI 0 "arith_reg_operand" "")
2963 mach = gen_rtx_REG (SImode, MACH_REG);
2965 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2966 insn = get_insns ();
2968 /* Use emit_libcall_block for loop invariant code motion and to make
2969 a REG_EQUAL note. */
2970 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2975 (define_insn_and_split "muldi3"
2976 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2977 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2978 (match_operand:DI 2 "arith_reg_operand" "r")))
2979 (clobber (match_scratch:DI 3 "=&r"))
2980 (clobber (match_scratch:DI 4 "=r"))]
2987 rtx op3_v2si, op2_v2si;
2989 op3_v2si = operands[3];
2990 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2992 op3_v2si = XEXP (op3_v2si, 0);
2993 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2995 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2996 op2_v2si = operands[2];
2997 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2999 op2_v2si = XEXP (op2_v2si, 0);
3000 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3002 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3003 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3004 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3005 emit_insn (gen_umulsidi3_media (operands[4],
3006 sh_gen_truncate (SImode, operands[1], 0),
3007 sh_gen_truncate (SImode, operands[2], 0)));
3008 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3009 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3010 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3011 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3016 ;; -------------------------------------------------------------------------
3017 ;; Logical operations
3018 ;; -------------------------------------------------------------------------
3020 (define_insn "*andsi3_compact"
3021 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3022 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3023 (match_operand:SI 2 "logical_operand" "r,K08")))]
3026 [(set_attr "type" "arith")])
3028 (define_insn "*andsi3_media"
3029 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3030 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3031 (match_operand:SI 2 "logical_operand" "r,I10")))]
3036 [(set_attr "type" "arith_media")])
3038 (define_insn "*andsi3_bclr"
3039 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3040 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3041 (match_operand:SI 2 "const_int_operand" "Psz")))]
3042 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3044 [(set_attr "type" "arith")])
3046 ;; If the constant is 255, then emit an extu.b instruction instead of an
3047 ;; and, since that will give better code.
3049 (define_expand "andsi3"
3050 [(set (match_operand:SI 0 "arith_reg_operand" "")
3051 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3052 (match_operand:SI 2 "logical_operand" "")))]
3057 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3059 emit_insn (gen_zero_extendqisi2 (operands[0],
3060 gen_lowpart (QImode, operands[1])));
3065 (define_insn_and_split "anddi3"
3066 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3067 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3068 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3075 && ! logical_operand (operands[2], DImode)"
3079 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3080 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3082 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3085 [(set_attr "type" "arith_media")])
3087 (define_insn "andcsi3"
3088 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3089 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3090 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3093 [(set_attr "type" "arith_media")])
3095 (define_insn "andcdi3"
3096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3097 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3098 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3101 [(set_attr "type" "arith_media")])
3103 (define_expand "iorsi3"
3104 [(set (match_operand:SI 0 "arith_reg_operand" "")
3105 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3106 (match_operand:SI 2 "logical_operand" "")))]
3110 (define_insn "*iorsi3_compact"
3111 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3112 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3113 (match_operand:SI 2 "logical_operand" "r,K08")))]
3115 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3117 [(set_attr "type" "arith")])
3119 (define_insn "*iorsi3_media"
3120 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3121 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3122 (match_operand:SI 2 "logical_operand" "r,I10")))]
3127 [(set_attr "type" "arith_media")])
3129 (define_insn "*iorsi3_bset"
3130 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3131 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3132 (match_operand:SI 2 "const_int_operand" "Pso")))]
3133 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3135 [(set_attr "type" "arith")])
3137 (define_insn "iordi3"
3138 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3139 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3140 (match_operand:DI 2 "logical_operand" "r,I10")))]
3145 [(set_attr "type" "arith_media")])
3147 (define_insn_and_split "*logical_sidi3"
3148 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3149 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3150 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3151 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3154 "&& reload_completed"
3155 [(set (match_dup 0) (match_dup 3))]
3159 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3160 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3161 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3164 (define_insn_and_split "*logical_sidisi3"
3165 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3166 (truncate:SI (sign_extend:DI
3167 (match_operator:SI 3 "logical_operator"
3168 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3169 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3173 [(set (match_dup 0) (match_dup 3))])
3175 (define_insn_and_split "*logical_sidi3_2"
3176 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3177 (sign_extend:DI (truncate:SI (sign_extend:DI
3178 (match_operator:SI 3 "logical_operator"
3179 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3180 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3184 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3186 (define_expand "xorsi3"
3187 [(set (match_operand:SI 0 "arith_reg_operand" "")
3188 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3189 (match_operand:SI 2 "xor_operand" "")))]
3193 (define_insn "*xorsi3_compact"
3194 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3195 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3196 (match_operand:SI 2 "logical_operand" "K08,r")))]
3199 [(set_attr "type" "arith")])
3201 (define_insn "*xorsi3_media"
3202 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3203 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3204 (match_operand:SI 2 "xor_operand" "r,I06")))]
3209 [(set_attr "type" "arith_media")])
3211 ;; Store the complements of the T bit in a register.
3212 (define_insn "xorsi3_movrt"
3213 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3214 (xor:SI (reg:SI T_REG)
3218 [(set_attr "type" "arith")])
3220 (define_insn "xordi3"
3221 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3223 (match_operand:DI 2 "xor_operand" "r,I06")))]
3228 [(set_attr "type" "arith_media")])
3230 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3231 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3233 [(set (match_operand:DI 0 "arith_reg_dest" "")
3234 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3235 [(match_operand 1 "any_register_operand" "")
3236 (match_operand 2 "any_register_operand" "")])))]
3238 [(set (match_dup 5) (match_dup 4))
3239 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3242 enum machine_mode inmode = GET_MODE (operands[1]);
3245 if (GET_CODE (operands[0]) == SUBREG)
3247 offset = SUBREG_BYTE (operands[0]);
3248 operands[0] = SUBREG_REG (operands[0]);
3250 gcc_assert (REG_P (operands[0]));
3251 if (! TARGET_LITTLE_ENDIAN)
3252 offset += 8 - GET_MODE_SIZE (inmode);
3253 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3256 ;; -------------------------------------------------------------------------
3257 ;; Shifts and rotates
3258 ;; -------------------------------------------------------------------------
3260 (define_expand "rotldi3"
3261 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3262 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3263 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3265 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3267 (define_insn "rotldi3_mextr"
3268 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3269 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3270 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3274 static char templ[16];
3276 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3277 8 - (int) (INTVAL (operands[2]) >> 3));
3280 [(set_attr "type" "arith_media")])
3282 (define_expand "rotrdi3"
3283 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3284 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3285 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3287 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3289 (define_insn "rotrdi3_mextr"
3290 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3291 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3292 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3296 static char templ[16];
3298 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3301 [(set_attr "type" "arith_media")])
3304 [(set (match_operand:DI 0 "arith_reg_dest" "")
3305 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3306 "ua_address_operand" "")))
3307 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3309 (clobber (match_operand:DI 3 "register_operand" ""))]
3311 [(match_dup 4) (match_dup 5)]
3314 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3315 (operands[3], operands[1]));
3316 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3317 GEN_INT (56), GEN_INT (8));
3320 (define_insn "rotlsi3_1"
3321 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3322 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3325 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3328 [(set_attr "type" "arith")])
3330 (define_insn "rotlsi3_31"
3331 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3332 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3334 (clobber (reg:SI T_REG))]
3337 [(set_attr "type" "arith")])
3339 (define_insn "rotlsi3_16"
3340 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3341 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3345 [(set_attr "type" "arith")])
3347 (define_expand "rotlsi3"
3348 [(set (match_operand:SI 0 "arith_reg_dest" "")
3349 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3350 (match_operand:SI 2 "immediate_operand" "")))]
3354 static const char rot_tab[] = {
3355 000, 000, 000, 000, 000, 000, 010, 001,
3356 001, 001, 011, 013, 003, 003, 003, 003,
3357 003, 003, 003, 003, 003, 013, 012, 002,
3358 002, 002, 010, 000, 000, 000, 000, 000,
3363 if (!CONST_INT_P (operands[2]))
3365 count = INTVAL (operands[2]);
3366 choice = rot_tab[count];
3367 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3373 emit_move_insn (operands[0], operands[1]);
3374 count -= (count & 16) * 2;
3377 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3384 parts[0] = gen_reg_rtx (SImode);
3385 parts[1] = gen_reg_rtx (SImode);
3386 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3387 emit_move_insn (parts[choice-1], operands[1]);
3388 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3389 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3390 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3391 count = (count & ~16) - 8;
3395 for (; count > 0; count--)
3396 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3397 for (; count < 0; count++)
3398 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3403 (define_insn "*rotlhi3_8"
3404 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3405 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3409 [(set_attr "type" "arith")])
3411 (define_expand "rotlhi3"
3412 [(set (match_operand:HI 0 "arith_reg_operand" "")
3413 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3414 (match_operand:HI 2 "immediate_operand" "")))]
3418 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3425 (define_insn "ashlsi3_sh2a"
3426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428 (match_operand:SI 2 "arith_reg_operand" "r")))]
3431 [(set_attr "type" "arith")
3432 (set_attr "length" "4")])
3434 ;; This pattern is used by init_expmed for computing the costs of shift
3437 (define_insn_and_split "ashlsi3_std"
3438 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3439 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3440 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3441 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3443 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3451 && CONST_INT_P (operands[2])
3452 && ! satisfies_constraint_P27 (operands[2])"
3453 [(set (match_dup 3) (match_dup 2))
3455 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3456 (clobber (match_dup 4))])]
3457 "operands[4] = gen_rtx_SCRATCH (SImode);"
3458 [(set_attr "length" "*,*,*,4")
3459 (set_attr "type" "dyn_shift,arith,arith,arith")])
3461 (define_insn "ashlhi3_k"
3462 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3463 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3464 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3465 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3469 [(set_attr "type" "arith")])
3471 (define_insn "ashlsi3_n"
3472 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3473 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3474 (match_operand:SI 2 "const_int_operand" "n")))
3475 (clobber (reg:SI T_REG))]
3476 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3478 [(set (attr "length")
3479 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3481 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3483 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3485 (const_string "8")))
3486 (set_attr "type" "arith")])
3489 [(set (match_operand:SI 0 "arith_reg_dest" "")
3490 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3491 (match_operand:SI 2 "const_int_operand" "")))
3492 (clobber (reg:SI T_REG))]
3493 "TARGET_SH1 && reload_completed"
3494 [(use (reg:SI R0_REG))]
3497 gen_shifty_op (ASHIFT, operands);
3501 (define_insn "ashlsi3_media"
3502 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3503 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3504 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3509 [(set_attr "type" "arith_media")
3510 (set_attr "highpart" "ignore")])
3512 (define_expand "ashlsi3"
3513 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3514 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3515 (match_operand:SI 2 "nonmemory_operand" "")))
3516 (clobber (reg:SI T_REG))])]
3522 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3525 if (CONST_INT_P (operands[2])
3526 && sh_dynamicalize_shift_p (operands[2]))
3527 operands[2] = force_reg (SImode, operands[2]);
3530 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3533 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3537 (define_insn "*ashlhi3_n"
3538 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3539 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3540 (match_operand:HI 2 "const_int_operand" "n")))
3541 (clobber (reg:SI T_REG))]
3544 [(set (attr "length")
3545 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3547 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3549 (const_string "6")))
3550 (set_attr "type" "arith")])
3552 (define_expand "ashlhi3"
3553 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3554 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3555 (match_operand:SI 2 "nonmemory_operand" "")))
3556 (clobber (reg:SI T_REG))])]
3560 if (!CONST_INT_P (operands[2]))
3562 /* It may be possible to call gen_ashlhi3 directly with more generic
3563 operands. Make sure operands[1] is a HImode register here. */
3564 if (!arith_reg_operand (operands[1], HImode))
3565 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3569 [(set (match_operand:HI 0 "arith_reg_dest" "")
3570 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3571 (match_operand:HI 2 "const_int_operand" "")))
3572 (clobber (reg:SI T_REG))]
3573 "TARGET_SH1 && reload_completed"
3574 [(use (reg:SI R0_REG))]
3577 gen_shifty_hi_op (ASHIFT, operands);
3582 ; arithmetic shift right
3585 (define_insn "ashrsi3_sh2a"
3586 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3587 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3588 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3591 [(set_attr "type" "dyn_shift")
3592 (set_attr "length" "4")])
3594 (define_insn "ashrsi3_k"
3595 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3596 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3597 (match_operand:SI 2 "const_int_operand" "M")))
3598 (clobber (reg:SI T_REG))]
3599 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3601 [(set_attr "type" "arith")])
3603 ;; We can't do HImode right shifts correctly unless we start out with an
3604 ;; explicit zero / sign extension; doing that would result in worse overall
3605 ;; code, so just let the machine independent code widen the mode.
3606 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3609 ;; ??? This should be a define expand.
3611 (define_insn "ashrsi2_16"
3612 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3613 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3617 [(set_attr "length" "4")])
3620 [(set (match_operand:SI 0 "arith_reg_dest" "")
3621 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3624 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3625 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3626 "operands[2] = gen_lowpart (HImode, operands[0]);")
3628 ;; ??? This should be a define expand.
3630 (define_insn "ashrsi2_31"
3631 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3632 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3634 (clobber (reg:SI T_REG))]
3637 [(set_attr "length" "4")])
3640 [(set (match_operand:SI 0 "arith_reg_dest" "")
3641 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3643 (clobber (reg:SI T_REG))]
3648 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3649 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3654 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3656 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3658 && peep2_reg_dead_p (2, operands[0])
3659 && peep2_reg_dead_p (2, operands[1])"
3663 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3667 (define_insn "ashlsi_c"
3668 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3671 (lt:SI (match_dup 1) (const_int 0)))]
3674 [(set_attr "type" "arith")])
3676 (define_insn "*ashlsi_c_void"
3677 [(set (reg:SI T_REG)
3678 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3679 (clobber (match_scratch:SI 1 "=0"))]
3680 "TARGET_SH1 && cse_not_expected"
3682 [(set_attr "type" "arith")])
3684 (define_insn "ashrsi3_d"
3685 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3686 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3687 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3690 [(set_attr "type" "dyn_shift")])
3692 (define_insn "ashrsi3_n"
3693 [(set (reg:SI R4_REG)
3694 (ashiftrt:SI (reg:SI R4_REG)
3695 (match_operand:SI 0 "const_int_operand" "i")))
3696 (clobber (reg:SI T_REG))
3697 (clobber (reg:SI PR_REG))
3698 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3701 [(set_attr "type" "sfunc")
3702 (set_attr "needs_delay_slot" "yes")])
3704 (define_insn "ashrsi3_media"
3705 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3706 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3707 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3712 [(set_attr "type" "arith_media")
3713 (set_attr "highpart" "ignore")])
3715 (define_expand "ashrsi3"
3716 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3717 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3718 (match_operand:SI 2 "nonmemory_operand" "")))
3719 (clobber (reg:SI T_REG))])]
3725 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3728 if (expand_ashiftrt (operands))
3734 ;; logical shift right
3736 (define_insn "lshrsi3_sh2a"
3737 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3739 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3742 [(set_attr "type" "dyn_shift")
3743 (set_attr "length" "4")])
3745 (define_insn "lshrsi3_d"
3746 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3747 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3748 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3751 [(set_attr "type" "dyn_shift")])
3753 ;; Only the single bit shift clobbers the T bit.
3755 (define_insn "lshrsi3_m"
3756 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3757 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3758 (match_operand:SI 2 "const_int_operand" "M")))
3759 (clobber (reg:SI T_REG))]
3760 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3762 [(set_attr "type" "arith")])
3764 (define_insn "lshrsi3_k"
3765 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767 (match_operand:SI 2 "const_int_operand" "P27")))]
3768 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3769 && ! satisfies_constraint_M (operands[2])"
3771 [(set_attr "type" "arith")])
3773 (define_insn "lshrsi3_n"
3774 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776 (match_operand:SI 2 "const_int_operand" "n")))
3777 (clobber (reg:SI T_REG))]
3778 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3780 [(set (attr "length")
3781 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3783 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3785 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3787 (const_string "8")))
3788 (set_attr "type" "arith")])
3791 [(set (match_operand:SI 0 "arith_reg_dest" "")
3792 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3793 (match_operand:SI 2 "const_int_operand" "")))
3794 (clobber (reg:SI T_REG))]
3795 "TARGET_SH1 && reload_completed"
3796 [(use (reg:SI R0_REG))]
3799 gen_shifty_op (LSHIFTRT, operands);
3803 (define_insn "lshrsi3_media"
3804 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3805 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3806 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3811 [(set_attr "type" "arith_media")
3812 (set_attr "highpart" "ignore")])
3814 (define_expand "lshrsi3"
3815 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3816 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3817 (match_operand:SI 2 "nonmemory_operand" "")))
3818 (clobber (reg:SI T_REG))])]
3824 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3827 if (CONST_INT_P (operands[2])
3828 && sh_dynamicalize_shift_p (operands[2]))
3829 operands[2] = force_reg (SImode, operands[2]);
3830 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3832 rtx count = copy_to_mode_reg (SImode, operands[2]);
3833 emit_insn (gen_negsi2 (count, count));
3834 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3837 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3841 ;; ??? This should be a define expand.
3843 (define_insn "ashldi3_k"
3844 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3847 (clobber (reg:SI T_REG))]
3849 "shll %R0\;rotcl %S0"
3850 [(set_attr "length" "4")
3851 (set_attr "type" "arith")])
3853 ;; Expander for DImode shift left with SImode operations.
3855 (define_expand "ashldi3_std"
3856 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3857 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3858 (match_operand:DI 2 "const_int_operand" "n")))]
3859 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3862 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3863 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3864 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3865 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3866 rtx dst = gen_reg_rtx (DImode);
3867 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3868 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3871 tmp0 = gen_reg_rtx (SImode);
3872 tmp1 = gen_reg_rtx (SImode);
3873 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3874 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3875 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3876 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3877 emit_move_insn (operands[0], dst);
3881 (define_insn "ashldi3_media"
3882 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3883 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3884 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3889 [(set_attr "type" "arith_media")])
3891 (define_insn "*ashldisi3_media"
3892 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3893 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3894 (match_operand:DI 2 "const_int_operand" "n")))]
3895 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3896 "shlli.l %1, %2, %0"
3897 [(set_attr "type" "arith_media")
3898 (set_attr "highpart" "ignore")])
3900 (define_expand "ashldi3"
3901 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3902 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3903 (match_operand:DI 2 "immediate_operand" "")))
3904 (clobber (reg:SI T_REG))])]
3910 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3913 if (CONST_INT_P (operands[2])
3914 && INTVAL (operands[2]) == 1)
3916 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3919 else if (CONST_INT_P (operands[2])
3920 && INTVAL (operands[2]) < 32)
3922 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3929 ;; ??? This should be a define expand.
3931 (define_insn "lshrdi3_k"
3932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3933 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3935 (clobber (reg:SI T_REG))]
3937 "shlr %S0\;rotcr %R0"
3938 [(set_attr "length" "4")
3939 (set_attr "type" "arith")])
3941 (define_insn "lshrdi3_media"
3942 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3943 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3946 && (arith_reg_dest (operands[0], DImode)
3947 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3951 [(set_attr "type" "arith_media")])
3953 (define_insn "*lshrdisi3_media"
3954 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3955 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3956 (match_operand:DI 2 "const_int_operand" "n")))]
3957 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3958 "shlri.l %1, %2, %0"
3959 [(set_attr "type" "arith_media")
3960 (set_attr "highpart" "ignore")])
3962 (define_expand "lshrdi3"
3963 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3964 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3965 (match_operand:DI 2 "immediate_operand" "")))
3966 (clobber (reg:SI T_REG))])]
3972 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3975 if (!CONST_INT_P (operands[2])
3976 || INTVAL (operands[2]) != 1)
3980 ;; ??? This should be a define expand.
3982 (define_insn "ashrdi3_k"
3983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3984 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3986 (clobber (reg:SI T_REG))]
3988 "shar %S0\;rotcr %R0"
3989 [(set_attr "length" "4")
3990 (set_attr "type" "arith")])
3992 (define_insn "ashrdi3_media"
3993 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3994 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3995 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3997 && (arith_reg_dest (operands[0], DImode)
3998 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4002 [(set_attr "type" "arith_media")])
4004 (define_insn "*ashrdisi3_media"
4005 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4006 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4007 (match_operand:DI 2 "const_int_operand" "n")))]
4008 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4009 "shari.l %1, %2, %0"
4010 [(set_attr "type" "arith_media")
4011 (set_attr "highpart" "ignore")])
4013 (define_insn "ashrdisi3_media_high"
4014 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4016 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4017 (match_operand:DI 2 "const_int_operand" "n"))))]
4018 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4020 [(set_attr "type" "arith_media")])
4022 (define_insn "ashrdisi3_media_opaque"
4023 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4024 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4025 (match_operand:DI 2 "const_int_operand" "n")]
4029 [(set_attr "type" "arith_media")])
4031 (define_expand "ashrdi3"
4032 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034 (match_operand:DI 2 "immediate_operand" "")))
4035 (clobber (reg:SI T_REG))])]
4041 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4044 if (!CONST_INT_P (operands[2])
4045 || INTVAL (operands[2]) != 1)
4049 ;; combined left/right shift
4052 [(set (match_operand:SI 0 "register_operand" "")
4053 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4054 (match_operand:SI 2 "const_int_operand" ""))
4055 (match_operand:SI 3 "const_int_operand" "")))]
4056 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4057 [(use (reg:SI R0_REG))]
4058 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4064 (match_operand:SI 2 "const_int_operand" ""))
4065 (match_operand:SI 3 "const_int_operand" "")))
4066 (clobber (reg:SI T_REG))]
4067 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4068 [(use (reg:SI R0_REG))]
4069 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4073 [(set (match_operand:SI 0 "register_operand" "=r")
4074 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4075 (match_operand:SI 2 "const_int_operand" "n"))
4076 (match_operand:SI 3 "const_int_operand" "n")))
4077 (clobber (reg:SI T_REG))]
4078 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4080 [(set (attr "length")
4081 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4083 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4085 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4087 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4089 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4091 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4093 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4094 (const_string "16")]
4095 (const_string "18")))
4096 (set_attr "type" "arith")])
4099 [(set (match_operand:SI 0 "register_operand" "=z")
4100 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101 (match_operand:SI 2 "const_int_operand" "n"))
4102 (match_operand:SI 3 "const_int_operand" "n")))
4103 (clobber (reg:SI T_REG))]
4104 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4106 [(set (attr "length")
4107 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4109 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4111 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4113 (const_string "10")))
4114 (set_attr "type" "arith")])
4116 ;; shift left / and combination with a scratch register: The combine pass
4117 ;; does not accept the individual instructions, even though they are
4118 ;; cheap. But it needs a precise description so that it is usable after
4120 (define_insn "and_shl_scratch"
4121 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4125 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4126 (match_operand:SI 2 "const_int_operand" "N,n"))
4127 (match_operand:SI 3 "" "0,r"))
4128 (match_operand:SI 4 "const_int_operand" "n,n"))
4129 (match_operand:SI 5 "const_int_operand" "n,n")))
4130 (clobber (reg:SI T_REG))]
4133 [(set (attr "length")
4134 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4136 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4138 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4140 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4141 (const_string "10")]
4142 (const_string "12")))
4143 (set_attr "type" "arith")])
4146 [(set (match_operand:SI 0 "register_operand" "")
4150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4151 (match_operand:SI 2 "const_int_operand" ""))
4152 (match_operand:SI 3 "register_operand" ""))
4153 (match_operand:SI 4 "const_int_operand" ""))
4154 (match_operand:SI 5 "const_int_operand" "")))
4155 (clobber (reg:SI T_REG))]
4157 [(use (reg:SI R0_REG))]
4160 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4162 if (INTVAL (operands[2]))
4164 gen_shifty_op (LSHIFTRT, operands);
4166 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4167 operands[2] = operands[4];
4168 gen_shifty_op (ASHIFT, operands);
4169 if (INTVAL (operands[5]))
4171 operands[2] = operands[5];
4172 gen_shifty_op (LSHIFTRT, operands);
4177 ;; signed left/right shift combination.
4179 [(set (match_operand:SI 0 "register_operand" "")
4181 (ashift:SI (match_operand:SI 1 "register_operand" "")
4182 (match_operand:SI 2 "const_int_operand" ""))
4183 (match_operand:SI 3 "const_int_operand" "")
4185 (clobber (reg:SI T_REG))]
4187 [(use (reg:SI R0_REG))]
4188 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4191 (define_insn "shl_sext_ext"
4192 [(set (match_operand:SI 0 "register_operand" "=r")
4194 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4195 (match_operand:SI 2 "const_int_operand" "n"))
4196 (match_operand:SI 3 "const_int_operand" "n")
4198 (clobber (reg:SI T_REG))]
4199 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4201 [(set (attr "length")
4202 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4204 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4206 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4208 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4210 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4212 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4214 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4216 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4217 (const_string "16")]
4218 (const_string "18")))
4219 (set_attr "type" "arith")])
4221 (define_insn "shl_sext_sub"
4222 [(set (match_operand:SI 0 "register_operand" "=z")
4224 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4225 (match_operand:SI 2 "const_int_operand" "n"))
4226 (match_operand:SI 3 "const_int_operand" "n")
4228 (clobber (reg:SI T_REG))]
4229 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4231 [(set (attr "length")
4232 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4234 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4236 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4238 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4239 (const_string "12")]
4240 (const_string "14")))
4241 (set_attr "type" "arith")])
4243 ;; These patterns are found in expansions of DImode shifts by 16, and
4244 ;; allow the xtrct instruction to be generated from C source.
4246 (define_insn "xtrct_left"
4247 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4248 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4250 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4254 [(set_attr "type" "arith")])
4256 (define_insn "xtrct_right"
4257 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4258 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4260 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4264 [(set_attr "type" "arith")])
4266 ;; -------------------------------------------------------------------------
4268 ;; -------------------------------------------------------------------------
4271 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4272 (neg:SI (plus:SI (reg:SI T_REG)
4273 (match_operand:SI 1 "arith_reg_operand" "r"))))
4275 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4279 [(set_attr "type" "arith")])
4281 (define_insn "*negdi_media"
4282 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4283 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4286 [(set_attr "type" "arith_media")])
4288 (define_expand "negdi2"
4289 [(set (match_operand:DI 0 "arith_reg_operand" "")
4290 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4296 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4297 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4299 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4300 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4302 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4303 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4305 emit_insn (gen_clrt ());
4306 emit_insn (gen_negc (low_dst, low_src));
4307 emit_insn (gen_negc (high_dst, high_src));
4312 (define_insn "negsi2"
4313 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4314 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4317 [(set_attr "type" "arith")])
4319 (define_insn "one_cmplsi2"
4320 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4321 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4324 [(set_attr "type" "arith")])
4326 (define_expand "one_cmpldi2"
4327 [(set (match_operand:DI 0 "arith_reg_dest" "")
4328 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4330 "TARGET_SHMEDIA" "")
4332 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4333 This can be used as some kind of conditional execution, which is useful
4336 [(set (match_operand:SI 0 "arith_reg_dest" "")
4337 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4338 (match_operand:SI 1 "arith_reg_operand" ""))
4342 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4343 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4347 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4348 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4349 (match_operand:SI 1 "arith_reg_operand" "0")
4350 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4352 "bf 0f\;neg %2,%0\\n0:"
4353 [(set_attr "type" "arith") ;; poor approximation
4354 (set_attr "length" "4")])
4357 ;; -------------------------------------------------------------------------
4358 ;; Zero extension instructions
4359 ;; -------------------------------------------------------------------------
4361 (define_insn "zero_extendsidi2"
4362 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4363 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4365 "addz.l %1, r63, %0"
4366 [(set_attr "type" "arith_media")
4367 (set_attr "highpart" "extend")])
4369 (define_insn "zero_extendhidi2"
4370 [(set (match_operand:DI 0 "register_operand" "=r,r")
4371 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4376 [(set_attr "type" "*,load_media")
4377 (set (attr "highpart")
4378 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4379 (const_string "user")]
4380 (const_string "ignore")))])
4383 [(set (match_operand:DI 0 "register_operand" "")
4384 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4385 "TARGET_SHMEDIA && reload_completed"
4386 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4387 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4390 if (GET_CODE (operands[1]) == TRUNCATE)
4391 operands[1] = XEXP (operands[1], 0);
4394 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4395 ;; reload the entire truncate expression.
4396 (define_insn_and_split "*loaddi_trunc"
4397 [(set (match_operand 0 "any_register_operand" "=r")
4398 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4399 "TARGET_SHMEDIA && reload_completed"
4401 "TARGET_SHMEDIA && reload_completed"
4402 [(set (match_dup 0) (match_dup 1))]
4403 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4405 (define_insn "zero_extendqidi2"
4406 [(set (match_operand:DI 0 "register_operand" "=r,r")
4407 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4412 [(set_attr "type" "arith_media,load_media")
4413 (set (attr "highpart")
4414 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4415 (const_string "user")]
4416 (const_string "ignore")))])
4418 (define_expand "zero_extendhisi2"
4419 [(set (match_operand:SI 0 "arith_reg_operand" "")
4420 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4424 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4425 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4428 (define_insn "*zero_extendhisi2_compact"
4429 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4430 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4433 [(set_attr "type" "arith")])
4435 (define_insn "*zero_extendhisi2_media"
4436 [(set (match_operand:SI 0 "register_operand" "=r,r")
4437 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4442 [(set_attr "type" "arith_media,load_media")
4443 (set (attr "highpart")
4444 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4445 (const_string "user")]
4446 (const_string "ignore")))])
4449 [(set (match_operand:SI 0 "register_operand" "")
4450 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4451 "TARGET_SHMEDIA && reload_completed"
4452 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4453 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4456 rtx op1 = operands[1];
4458 if (GET_CODE (op1) == TRUNCATE)
4459 op1 = XEXP (op1, 0);
4461 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4462 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4465 (define_expand "zero_extendqisi2"
4466 [(set (match_operand:SI 0 "arith_reg_operand" "")
4467 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4471 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4472 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4475 (define_insn "*zero_extendqisi2_compact"
4476 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4477 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4480 [(set_attr "type" "arith")])
4482 (define_insn "*zero_extendqisi2_media"
4483 [(set (match_operand:SI 0 "register_operand" "=r,r")
4484 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4489 [(set_attr "type" "arith_media,load_media")
4490 (set (attr "highpart")
4491 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4492 (const_string "user")]
4493 (const_string "ignore")))])
4495 (define_insn "zero_extendqihi2"
4496 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4497 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4500 [(set_attr "type" "arith")])
4502 ;; -------------------------------------------------------------------------
4503 ;; Sign extension instructions
4504 ;; -------------------------------------------------------------------------
4506 ;; ??? This should be a define expand.
4507 ;; ??? Or perhaps it should be dropped?
4509 ;; convert_move generates good code for SH[1-4].
4510 (define_insn "extendsidi2"
4511 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4512 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4518 [(set_attr "type" "arith_media,load_media,fpconv_media")
4519 (set (attr "highpart")
4520 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4521 (const_string "user")]
4522 (const_string "extend")))])
4524 (define_insn "extendhidi2"
4525 [(set (match_operand:DI 0 "register_operand" "=r,r")
4526 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4531 [(set_attr "type" "*,load_media")
4532 (set (attr "highpart")
4533 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4534 (const_string "user")]
4535 (const_string "ignore")))])
4538 [(set (match_operand:DI 0 "register_operand" "")
4539 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4540 "TARGET_SHMEDIA && reload_completed"
4541 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4542 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4545 if (GET_CODE (operands[1]) == TRUNCATE)
4546 operands[1] = XEXP (operands[1], 0);
4549 (define_insn "extendqidi2"
4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
4551 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4556 [(set_attr "type" "*,load_media")
4557 (set (attr "highpart")
4558 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559 (const_string "user")]
4560 (const_string "ignore")))])
4563 [(set (match_operand:DI 0 "register_operand" "")
4564 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4565 "TARGET_SHMEDIA && reload_completed"
4566 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4567 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4570 if (GET_CODE (operands[1]) == TRUNCATE)
4571 operands[1] = XEXP (operands[1], 0);
4574 (define_expand "extendhisi2"
4575 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4576 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4580 (define_insn "*extendhisi2_compact"
4581 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4582 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4587 [(set_attr "type" "arith,load")])
4589 (define_insn "*extendhisi2_media"
4590 [(set (match_operand:SI 0 "register_operand" "=r,r")
4591 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4596 [(set_attr "type" "arith_media,load_media")
4597 (set (attr "highpart")
4598 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4599 (const_string "user")]
4600 (const_string "ignore")))])
4603 [(set (match_operand:SI 0 "register_operand" "")
4604 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4605 "TARGET_SHMEDIA && reload_completed"
4606 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4607 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4610 rtx op1 = operands[1];
4611 if (GET_CODE (op1) == TRUNCATE)
4612 op1 = XEXP (op1, 0);
4614 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4615 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4618 (define_expand "extendqisi2"
4619 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4620 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4624 (define_insn "*extendqisi2_compact"
4625 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4626 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4631 [(set_attr "type" "arith,load")
4632 (set_attr_alternative "length"
4635 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4636 (const_int 4) (const_int 2))])])
4638 (define_insn "*extendqisi2_media"
4639 [(set (match_operand:SI 0 "register_operand" "=r,r")
4640 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4645 [(set_attr "type" "arith_media,load_media")
4646 (set (attr "highpart")
4647 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4648 (const_string "user")]
4649 (const_string "ignore")))])
4652 [(set (match_operand:SI 0 "register_operand" "")
4653 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4654 "TARGET_SHMEDIA && reload_completed"
4655 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4656 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4659 rtx op1 = operands[1];
4660 if (GET_CODE (op1) == TRUNCATE)
4661 op1 = XEXP (op1, 0);
4663 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4664 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4667 (define_insn "extendqihi2"
4668 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4669 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4674 [(set_attr "type" "arith,load")
4675 (set_attr_alternative "length"
4678 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4679 (const_int 4) (const_int 2))])])
4681 /* It would seem useful to combine the truncXi patterns into the movXi
4682 patterns, but unary operators are ignored when matching constraints,
4683 so we need separate patterns. */
4684 (define_insn "truncdisi2"
4685 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4686 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4695 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_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 "extend")))])
4701 (define_insn "truncdihi2"
4702 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4703 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4706 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4708 [(set_attr "type" "arith_media,store_media")
4709 (set_attr "length" "8,4")
4710 (set (attr "highpart")
4711 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712 (const_string "user")]
4713 (const_string "extend")))])
4715 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4716 ; Because we use zero extension, we can't provide signed QImode compares
4717 ; using a simple compare or conditional branch insn.
4718 (define_insn "truncdiqi2"
4719 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4720 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4725 [(set_attr "type" "arith_media,store")
4726 (set (attr "highpart")
4727 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4728 (const_string "user")]
4729 (const_string "extend")))])
4730 ;; -------------------------------------------------------------------------
4731 ;; Move instructions
4732 ;; -------------------------------------------------------------------------
4734 ;; define push and pop so it is easy for sh.c
4735 ;; We can't use push and pop on SHcompact because the stack must always
4736 ;; be 8-byte aligned.
4738 (define_expand "push"
4739 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4740 (match_operand:SI 0 "register_operand" "r,l,x"))]
4741 "TARGET_SH1 && ! TARGET_SH5"
4744 (define_expand "pop"
4745 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4746 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4747 "TARGET_SH1 && ! TARGET_SH5"
4750 (define_expand "push_e"
4751 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4752 (match_operand:SF 0 "" ""))
4753 (use (reg:PSI FPSCR_REG))
4754 (clobber (scratch:SI))])]
4755 "TARGET_SH1 && ! TARGET_SH5"
4758 (define_insn "push_fpul"
4759 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4760 "TARGET_SH2E && ! TARGET_SH5"
4762 [(set_attr "type" "fstore")
4763 (set_attr "late_fp_use" "yes")
4764 (set_attr "hit_stack" "yes")])
4766 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4768 (define_expand "push_4"
4769 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4770 (match_operand:DF 0 "" ""))
4771 (use (reg:PSI FPSCR_REG))
4772 (clobber (scratch:SI))])]
4773 "TARGET_SH1 && ! TARGET_SH5"
4776 (define_expand "pop_e"
4777 [(parallel [(set (match_operand:SF 0 "" "")
4778 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4779 (use (reg:PSI FPSCR_REG))
4780 (clobber (scratch:SI))])]
4781 "TARGET_SH1 && ! TARGET_SH5"
4784 (define_insn "pop_fpul"
4785 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4786 "TARGET_SH2E && ! TARGET_SH5"
4788 [(set_attr "type" "load")
4789 (set_attr "hit_stack" "yes")])
4791 (define_expand "pop_4"
4792 [(parallel [(set (match_operand:DF 0 "" "")
4793 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4794 (use (reg:PSI FPSCR_REG))
4795 (clobber (scratch:SI))])]
4796 "TARGET_SH1 && ! TARGET_SH5"
4799 (define_expand "push_fpscr"
4804 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4805 gen_rtx_PRE_DEC (Pmode,
4806 stack_pointer_rtx)),
4808 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4812 (define_expand "pop_fpscr"
4817 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4818 gen_frame_mem (PSImode,
4819 gen_rtx_POST_INC (Pmode,
4820 stack_pointer_rtx))));
4821 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4825 ;; These two patterns can happen as the result of optimization, when
4826 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4827 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4830 [(set (reg:SI T_REG) (const_int 0))]
4835 [(set (reg:SI T_REG) (const_int 1))]
4839 ;; t/r must come after r/r, lest reload will try to reload stuff like
4840 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4841 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4842 (define_insn "movsi_i"
4843 [(set (match_operand:SI 0 "general_movdst_operand"
4844 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4845 (match_operand:SI 1 "general_movsrc_operand"
4846 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4850 && (register_operand (operands[0], SImode)
4851 || register_operand (operands[1], SImode))"
4869 [(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")
4870 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4872 ;; t/r must come after r/r, lest reload will try to reload stuff like
4873 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4874 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4875 ;; will require a reload.
4876 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4877 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4878 (define_insn "movsi_ie"
4879 [(set (match_operand:SI 0 "general_movdst_operand"
4880 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4881 (match_operand:SI 1 "general_movsrc_operand"
4882 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4883 "(TARGET_SH2E || TARGET_SH2A)
4884 && (register_operand (operands[0], SImode)
4885 || register_operand (operands[1], SImode))"
4912 ! move optimized away"
4913 [(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")
4914 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4915 (set_attr_alternative "length"
4923 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4924 (const_int 4) (const_int 2))
4929 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4930 (const_int 4) (const_int 2))
4947 (define_insn "movsi_i_lowpart"
4948 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4949 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4951 && (register_operand (operands[0], SImode)
4952 || register_operand (operands[1], SImode))"
4963 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4965 (define_insn_and_split "load_ra"
4966 [(set (match_operand:SI 0 "general_movdst_operand" "")
4967 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4970 "&& ! currently_expanding_to_rtl"
4971 [(set (match_dup 0) (match_dup 1))]
4974 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4975 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4978 ;; The '?'s in the following constraints may not reflect the time taken
4979 ;; to perform the move. They are there to discourage the use of floating-
4980 ;; point registers for storing integer values.
4981 (define_insn "*movsi_media"
4982 [(set (match_operand:SI 0 "general_movdst_operand"
4983 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4984 (match_operand:SI 1 "general_movsrc_operand"
4985 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4987 && (register_operand (operands[0], SImode)
4988 || sh_register_operand (operands[1], SImode)
4989 || GET_CODE (operands[1]) == TRUNCATE)"
5004 [(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")
5005 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5006 (set (attr "highpart")
5007 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5008 (const_string "user")]
5009 (const_string "ignore")))])
5011 (define_insn "*movsi_media_nofpu"
5012 [(set (match_operand:SI 0 "general_movdst_operand"
5013 "=r,r,r,r,m,*b,r,*b")
5014 (match_operand:SI 1 "general_movsrc_operand"
5015 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5017 && (register_operand (operands[0], SImode)
5018 || sh_register_operand (operands[1], SImode)
5019 || GET_CODE (operands[1]) == TRUNCATE)"
5029 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5030 (set_attr "length" "4,4,8,4,4,4,4,12")
5031 (set (attr "highpart")
5032 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5033 (const_string "user")]
5034 (const_string "ignore")))])
5036 (define_expand "movsi_const"
5037 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5038 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5039 (const_int 16)] UNSPEC_EXTRACT_S16)))
5041 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5042 (const:SI (unspec:SI [(match_dup 1)
5043 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5044 "TARGET_SHMEDIA && reload_completed
5045 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5048 if (GET_CODE (operands[1]) == LABEL_REF
5049 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5050 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5051 else if (GOTOFF_P (operands[1]))
5053 rtx unspec = XEXP (operands[1], 0);
5055 if (! UNSPEC_GOTOFF_P (unspec))
5057 unspec = XEXP (unspec, 0);
5058 if (! UNSPEC_GOTOFF_P (unspec))
5061 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5062 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5063 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5067 (define_expand "movsi_const_16bit"
5068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5069 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5070 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5071 "TARGET_SHMEDIA && flag_pic && reload_completed
5072 && GET_CODE (operands[1]) == SYMBOL_REF"
5076 [(set (match_operand:SI 0 "arith_reg_dest" "")
5077 (match_operand:SI 1 "immediate_operand" ""))]
5078 "TARGET_SHMEDIA && reload_completed
5079 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5083 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5085 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5091 [(set (match_operand:SI 0 "register_operand" "")
5092 (match_operand:SI 1 "immediate_operand" ""))]
5093 "TARGET_SHMEDIA && reload_completed
5094 && ((CONST_INT_P (operands[1])
5095 && ! satisfies_constraint_I16 (operands[1]))
5096 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5097 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5099 (define_expand "movsi"
5100 [(set (match_operand:SI 0 "general_movdst_operand" "")
5101 (match_operand:SI 1 "general_movsrc_operand" ""))]
5103 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5105 (define_expand "ic_invalidate_line"
5106 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5107 (match_dup 1)] UNSPEC_ICACHE)
5108 (clobber (scratch:SI))])]
5109 "TARGET_HARD_SH4 || TARGET_SH5"
5114 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5117 else if (TARGET_SHCOMPACT)
5119 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5120 operands[1] = force_reg (Pmode, operands[1]);
5121 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5124 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5126 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5129 operands[0] = force_reg (Pmode, operands[0]);
5130 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5134 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5135 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5136 ;; the requirement *1*00 for associative address writes. The alignment of
5137 ;; %0 implies that its least significant bit is cleared,
5138 ;; thus we clear the V bit of a matching entry if there is one.
5139 (define_insn "ic_invalidate_line_i"
5140 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5141 (match_operand:SI 1 "register_operand" "r")]
5143 (clobber (match_scratch:SI 2 "=&r"))]
5145 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5146 [(set_attr "length" "8")
5147 (set_attr "type" "cwb")])
5149 (define_insn "ic_invalidate_line_sh4a"
5150 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5152 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5153 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5154 [(set_attr "length" "16")
5155 (set_attr "type" "cwb")])
5157 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5158 ;; an add in the code that calculates the address.
5159 (define_insn "ic_invalidate_line_media"
5160 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5163 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5164 [(set_attr "length" "16")
5165 (set_attr "type" "invalidate_line_media")])
5167 (define_insn "ic_invalidate_line_compact"
5168 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5169 (match_operand:SI 1 "register_operand" "r")]
5171 (clobber (reg:SI PR_REG))]
5174 [(set_attr "type" "sfunc")
5175 (set_attr "needs_delay_slot" "yes")])
5177 (define_expand "initialize_trampoline"
5178 [(match_operand:SI 0 "" "")
5179 (match_operand:SI 1 "" "")
5180 (match_operand:SI 2 "" "")]
5186 tramp = force_reg (Pmode, operands[0]);
5187 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5189 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5190 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5192 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5196 (define_insn "initialize_trampoline_compact"
5197 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5198 (match_operand:SI 1 "register_operand" "r")
5199 (reg:SI R2_REG) (reg:SI R3_REG)]
5202 (clobber (reg:SI PR_REG))]
5205 [(set_attr "type" "sfunc")
5206 (set_attr "needs_delay_slot" "yes")])
5208 (define_insn "movqi_i"
5209 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5210 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5212 && (arith_reg_operand (operands[0], QImode)
5213 || arith_reg_operand (operands[1], QImode))"
5222 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5223 (set_attr_alternative "length"
5227 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5228 (const_int 4) (const_int 2))
5230 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5231 (const_int 4) (const_int 2))
5236 (define_insn "*movqi_media"
5237 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5238 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5240 && (arith_reg_operand (operands[0], QImode)
5241 || extend_reg_or_0_operand (operands[1], QImode))"
5247 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5248 (set (attr "highpart")
5249 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5250 (const_string "user")]
5251 (const_string "ignore")))])
5253 (define_expand "movqi"
5254 [(set (match_operand:QI 0 "general_operand" "")
5255 (match_operand:QI 1 "general_operand" ""))]
5257 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5259 (define_expand "reload_inqi"
5260 [(set (match_operand:SI 2 "" "=&r")
5261 (match_operand:QI 1 "inqhi_operand" ""))
5262 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5263 (truncate:QI (match_dup 3)))]
5267 rtx inner = XEXP (operands[1], 0);
5268 int regno = REGNO (inner);
5270 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5271 operands[1] = gen_rtx_REG (SImode, regno);
5272 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5275 /* When storing r0, we have to avoid reg+reg addressing. */
5276 (define_insn "movhi_i"
5277 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5278 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5280 && (arith_reg_operand (operands[0], HImode)
5281 || arith_reg_operand (operands[1], HImode))
5282 && (!MEM_P (operands[0])
5283 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5284 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5285 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5295 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5297 (define_insn "*movhi_media"
5298 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5299 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5301 && (arith_reg_operand (operands[0], HImode)
5302 || arith_reg_or_0_operand (operands[1], HImode))"
5309 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5310 (set (attr "highpart")
5311 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5312 (const_string "user")]
5313 (const_string "ignore")))])
5316 [(set (match_operand:HI 0 "register_operand" "")
5317 (match_operand:HI 1 "immediate_operand" ""))]
5318 "TARGET_SHMEDIA && reload_completed
5319 && ! satisfies_constraint_I16 (operands[1])"
5320 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5322 (define_expand "movhi"
5323 [(set (match_operand:HI 0 "general_movdst_operand" "")
5324 (match_operand:HI 1 "general_movsrc_operand" ""))]
5326 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5328 (define_expand "reload_inhi"
5329 [(set (match_operand:SI 2 "" "=&r")
5330 (match_operand:HI 1 "inqhi_operand" ""))
5331 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5332 (truncate:HI (match_dup 3)))]
5336 rtx inner = XEXP (operands[1], 0);
5337 int regno = REGNO (inner);
5339 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5340 operands[1] = gen_rtx_REG (SImode, regno);
5341 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5344 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5345 ;; compiled with -m2 -ml -O3 -funroll-loops
5346 (define_insn "*movdi_i"
5347 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5348 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5350 && (arith_reg_operand (operands[0], DImode)
5351 || arith_reg_operand (operands[1], DImode))"
5352 "* return output_movedouble (insn, operands, DImode);"
5353 [(set_attr "length" "4")
5354 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5356 ;; If the output is a register and the input is memory or a register, we have
5357 ;; to be careful and see which word needs to be loaded first.
5360 [(set (match_operand:DI 0 "general_movdst_operand" "")
5361 (match_operand:DI 1 "general_movsrc_operand" ""))]
5362 "TARGET_SH1 && reload_completed"
5363 [(set (match_dup 2) (match_dup 3))
5364 (set (match_dup 4) (match_dup 5))]
5369 if ((MEM_P (operands[0])
5370 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5371 || (MEM_P (operands[1])
5372 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5375 switch (GET_CODE (operands[0]))
5378 regno = REGNO (operands[0]);
5381 regno = subreg_regno (operands[0]);
5391 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5393 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5394 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5395 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5396 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5400 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5401 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5402 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5403 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5406 if (operands[2] == 0 || operands[3] == 0
5407 || operands[4] == 0 || operands[5] == 0)
5411 ;; The '?'s in the following constraints may not reflect the time taken
5412 ;; to perform the move. They are there to discourage the use of floating-
5413 ;; point registers for storing integer values.
5414 (define_insn "*movdi_media"
5415 [(set (match_operand:DI 0 "general_movdst_operand"
5416 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5417 (match_operand:DI 1 "general_movsrc_operand"
5418 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5420 && (register_operand (operands[0], DImode)
5421 || sh_register_operand (operands[1], DImode))"
5436 [(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")
5437 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5439 (define_insn "*movdi_media_nofpu"
5440 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5441 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5443 && (register_operand (operands[0], DImode)
5444 || sh_register_operand (operands[1], DImode))"
5454 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5455 (set_attr "length" "4,4,16,4,4,4,4,*")])
5457 (define_insn "*movdi_media_I16"
5458 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5459 (match_operand:DI 1 "const_int_operand" "I16"))]
5460 "TARGET_SHMEDIA && reload_completed"
5462 [(set_attr "type" "arith_media")
5463 (set_attr "length" "4")])
5466 [(set (match_operand:DI 0 "arith_reg_dest" "")
5467 (match_operand:DI 1 "immediate_operand" ""))]
5468 "TARGET_SHMEDIA && reload_completed
5469 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5470 [(set (match_dup 0) (match_dup 1))]
5475 if (TARGET_SHMEDIA64)
5476 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5478 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5480 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5485 (define_expand "movdi_const"
5486 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5487 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5488 (const_int 48)] UNSPEC_EXTRACT_S16)))
5490 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5491 (const:DI (unspec:DI [(match_dup 1)
5492 (const_int 32)] UNSPEC_EXTRACT_U16))))
5494 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5495 (const:DI (unspec:DI [(match_dup 1)
5496 (const_int 16)] UNSPEC_EXTRACT_U16))))
5498 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5499 (const:DI (unspec:DI [(match_dup 1)
5500 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5501 "TARGET_SHMEDIA64 && reload_completed
5502 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5505 sh_mark_label (operands[1], 4);
5508 (define_expand "movdi_const_32bit"
5509 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5510 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5511 (const_int 16)] UNSPEC_EXTRACT_S16)))
5513 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5514 (const:DI (unspec:DI [(match_dup 1)
5515 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5516 "TARGET_SHMEDIA32 && reload_completed
5517 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5520 sh_mark_label (operands[1], 2);
5523 (define_expand "movdi_const_16bit"
5524 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5525 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5526 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5527 "TARGET_SHMEDIA && flag_pic && reload_completed
5528 && GET_CODE (operands[1]) == SYMBOL_REF"
5532 [(set (match_operand:DI 0 "ext_dest_operand" "")
5533 (match_operand:DI 1 "immediate_operand" ""))]
5534 "TARGET_SHMEDIA && reload_completed
5535 && CONST_INT_P (operands[1])
5536 && ! satisfies_constraint_I16 (operands[1])"
5537 [(set (match_dup 0) (match_dup 2))
5541 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5542 unsigned HOST_WIDE_INT low = val;
5543 unsigned HOST_WIDE_INT high = val;
5544 unsigned HOST_WIDE_INT sign;
5545 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5547 /* Zero-extend the 16 least-significant bits. */
5550 /* Arithmetic shift right the word by 16 bits. */
5552 if (GET_CODE (operands[0]) == SUBREG
5553 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5562 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5568 /* If we can't generate the constant with a two-insn movi / shori
5569 sequence, try some other strategies. */
5570 if (! CONST_OK_FOR_I16 (high))
5572 /* Try constant load / left shift. We know VAL != 0. */
5573 val2 = val ^ (val-1);
5576 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5578 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5579 || (! CONST_OK_FOR_I16 (high >> 16)
5580 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5582 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5583 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5584 GEN_INT (trailing_zeroes));
5588 /* Try constant load / right shift. */
5589 val2 = (val >> 15) + 1;
5590 if (val2 == (val2 & -val2))
5592 int shift = 49 - exact_log2 (val2);
5594 val2 = trunc_int_for_mode (val << shift, DImode);
5595 if (CONST_OK_FOR_I16 (val2))
5597 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5603 val2 = val & 0xffff;
5604 if ((val >> 16 & 0xffff) == val2
5605 && (val >> 32 & 0xffff) == val2
5606 && (val >> 48 & 0xffff) == val2)
5608 val2 = (HOST_WIDE_INT) val >> 48;
5609 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5610 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5613 /* Try movi / mshflo.l */
5614 val2 = (HOST_WIDE_INT) val >> 32;
5615 if (val2 == ((unsigned HOST_WIDE_INT)
5616 trunc_int_for_mode (val, SImode)))
5618 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5622 /* Try movi / mshflo.l w/ r63. */
5623 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5624 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5626 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5632 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5635 operands[2] = GEN_INT (val2);
5639 [(set (match_operand:DI 0 "ext_dest_operand" "")
5640 (match_operand:DI 1 "immediate_operand" ""))]
5641 "TARGET_SHMEDIA && reload_completed
5642 && GET_CODE (operands[1]) == CONST_DOUBLE"
5643 [(set (match_dup 0) (match_dup 2))
5645 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5648 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5649 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650 unsigned HOST_WIDE_INT val = low;
5651 unsigned HOST_WIDE_INT sign;
5653 /* Zero-extend the 16 least-significant bits. */
5655 operands[1] = GEN_INT (val);
5657 /* Arithmetic shift right the double-word by 16 bits. */
5659 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5662 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5666 /* This will only be true if high is a sign-extension of low, i.e.,
5667 it must be either 0 or (unsigned)-1, and be zero iff the
5668 most-significant bit of low is set. */
5669 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5670 operands[2] = GEN_INT (low);
5672 operands[2] = immed_double_const (low, high, DImode);
5675 (define_insn "shori_media"
5676 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5677 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5679 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5680 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5684 [(set_attr "type" "arith_media,*")])
5686 (define_insn "*shori_media_si"
5687 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5688 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5690 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5694 (define_expand "movdi"
5695 [(set (match_operand:DI 0 "general_movdst_operand" "")
5696 (match_operand:DI 1 "general_movsrc_operand" ""))]
5698 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5700 (define_insn "movdf_media"
5701 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5702 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5704 && (register_operand (operands[0], DFmode)
5705 || sh_register_operand (operands[1], DFmode))"
5716 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5718 (define_insn "movdf_media_nofpu"
5719 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5720 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5722 && (register_operand (operands[0], DFmode)
5723 || sh_register_operand (operands[1], DFmode))"
5729 [(set_attr "type" "arith_media,*,load_media,store_media")])
5732 [(set (match_operand:DF 0 "arith_reg_dest" "")
5733 (match_operand:DF 1 "immediate_operand" ""))]
5734 "TARGET_SHMEDIA && reload_completed"
5735 [(set (match_dup 3) (match_dup 2))]
5738 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5740 REAL_VALUE_TYPE value;
5742 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5743 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5745 if (HOST_BITS_PER_WIDE_INT >= 64)
5746 operands[2] = immed_double_const ((unsigned long) values[endian]
5747 | ((HOST_WIDE_INT) values[1 - endian]
5751 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5752 operands[2] = immed_double_const (values[endian], values[1 - endian],
5756 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5759 ;; ??? This should be a define expand.
5761 (define_insn "movdf_k"
5762 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5763 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5765 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5766 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5767 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5768 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5769 && (arith_reg_operand (operands[0], DFmode)
5770 || arith_reg_operand (operands[1], DFmode))"
5771 "* return output_movedouble (insn, operands, DFmode);"
5772 [(set_attr "length" "4")
5773 (set_attr "type" "move,pcload,load,store")])
5775 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5776 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5777 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5778 ;; the d/m/c/X alternative, which is split later into single-precision
5779 ;; instructions. And when not optimizing, no splits are done before fixing
5780 ;; up pcloads, so we need usable length information for that.
5781 (define_insn "movdf_i4"
5782 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5783 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5784 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5785 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5786 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5787 && (arith_reg_operand (operands[0], DFmode)
5788 || arith_reg_operand (operands[1], DFmode))"
5790 switch (which_alternative)
5794 return "fmov %1,%0";
5795 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5796 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5798 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5801 return "fmov.d %1,%0";
5806 [(set_attr_alternative "length"
5807 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5809 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5810 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5811 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5813 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5814 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5815 ;; increment or decrement r15 explicitly.
5817 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5818 (const_int 10) (const_int 8))
5820 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5821 (const_int 10) (const_int 8))])
5822 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5823 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5824 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5825 (const_string "double")
5826 (const_string "none")))])
5828 ;; Moving DFmode between fp/general registers through memory
5829 ;; (the top of the stack) is faster than moving through fpul even for
5830 ;; little endian. Because the type of an instruction is important for its
5831 ;; scheduling, it is beneficial to split these operations, rather than
5832 ;; emitting them in one single chunk, even if this will expose a stack
5833 ;; use that will prevent scheduling of other stack accesses beyond this
5836 [(set (match_operand:DF 0 "register_operand" "")
5837 (match_operand:DF 1 "register_operand" ""))
5838 (use (match_operand:PSI 2 "fpscr_operand" ""))
5839 (clobber (match_scratch:SI 3 "=X"))]
5840 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5841 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5847 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5849 emit_move_insn (stack_pointer_rtx,
5850 plus_constant (stack_pointer_rtx, -8));
5851 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5854 tos = gen_tmp_stack_mem (DFmode,
5855 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5856 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5857 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5858 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5859 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5860 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5862 tos = gen_tmp_stack_mem (DFmode,
5863 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5864 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5865 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5866 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5868 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5872 ;; local-alloc sometimes allocates scratch registers even when not required,
5873 ;; so we must be prepared to handle these.
5875 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5877 [(set (match_operand:DF 0 "general_movdst_operand" "")
5878 (match_operand:DF 1 "general_movsrc_operand" ""))
5879 (use (match_operand:PSI 2 "fpscr_operand" ""))
5880 (clobber (match_scratch:SI 3 ""))]
5881 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5883 && true_regnum (operands[0]) < 16
5884 && true_regnum (operands[1]) < 16"
5885 [(set (match_dup 0) (match_dup 1))]
5888 /* If this was a reg <-> mem operation with base + index reg addressing,
5889 we have to handle this in a special way. */
5890 rtx mem = operands[0];
5892 if (! memory_operand (mem, DFmode))
5897 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5898 mem = SUBREG_REG (mem);
5901 rtx addr = XEXP (mem, 0);
5902 if (GET_CODE (addr) == PLUS
5903 && REG_P (XEXP (addr, 0))
5904 && REG_P (XEXP (addr, 1)))
5907 rtx reg0 = gen_rtx_REG (Pmode, 0);
5908 rtx regop = operands[store_p], word0 ,word1;
5910 if (GET_CODE (regop) == SUBREG)
5911 alter_subreg (®op);
5912 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5916 mem = copy_rtx (mem);
5917 PUT_MODE (mem, SImode);
5918 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5919 alter_subreg (&word0);
5920 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5921 alter_subreg (&word1);
5922 if (store_p || ! refers_to_regno_p (REGNO (word0),
5923 REGNO (word0) + 1, addr, 0))
5926 ? gen_movsi_ie (mem, word0)
5927 : gen_movsi_ie (word0, mem));
5928 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5929 mem = copy_rtx (mem);
5931 ? gen_movsi_ie (mem, word1)
5932 : gen_movsi_ie (word1, mem));
5933 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5937 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5938 emit_insn (gen_movsi_ie (word1, mem));
5939 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5940 mem = copy_rtx (mem);
5941 emit_insn (gen_movsi_ie (word0, mem));
5948 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5950 [(set (match_operand:DF 0 "register_operand" "")
5951 (match_operand:DF 1 "memory_operand" ""))
5952 (use (match_operand:PSI 2 "fpscr_operand" ""))
5953 (clobber (reg:SI R0_REG))]
5954 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5955 [(parallel [(set (match_dup 0) (match_dup 1))
5957 (clobber (scratch:SI))])]
5960 (define_expand "reload_indf__frn"
5961 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5962 (match_operand:DF 1 "immediate_operand" "FQ"))
5963 (use (reg:PSI FPSCR_REG))
5964 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5968 (define_expand "reload_outdf__RnFRm"
5969 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5970 (match_operand:DF 1 "register_operand" "af,r"))
5971 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5975 ;; Simplify no-op moves.
5977 [(set (match_operand:SF 0 "register_operand" "")
5978 (match_operand:SF 1 "register_operand" ""))
5979 (use (match_operand:PSI 2 "fpscr_operand" ""))
5980 (clobber (match_scratch:SI 3 ""))]
5981 "TARGET_SH2E && reload_completed
5982 && true_regnum (operands[0]) == true_regnum (operands[1])"
5983 [(set (match_dup 0) (match_dup 0))]
5986 ;; fmovd substitute post-reload splits
5988 [(set (match_operand:DF 0 "register_operand" "")
5989 (match_operand:DF 1 "register_operand" ""))
5990 (use (match_operand:PSI 2 "fpscr_operand" ""))
5991 (clobber (match_scratch:SI 3 ""))]
5992 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5993 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5994 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5998 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5999 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6000 gen_rtx_REG (SFmode, src), operands[2]));
6001 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6002 gen_rtx_REG (SFmode, src + 1), operands[2]));
6007 [(set (match_operand:DF 0 "register_operand" "")
6008 (mem:DF (match_operand:SI 1 "register_operand" "")))
6009 (use (match_operand:PSI 2 "fpscr_operand" ""))
6010 (clobber (match_scratch:SI 3 ""))]
6011 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6012 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6013 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6017 int regno = true_regnum (operands[0]);
6019 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6021 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6022 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6023 regno + !! TARGET_LITTLE_ENDIAN),
6024 mem2, operands[2]));
6025 add_reg_note (insn, REG_INC, operands[1]);
6026 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027 regno + ! TARGET_LITTLE_ENDIAN),
6028 change_address (mem, SFmode, NULL_RTX),
6034 [(set (match_operand:DF 0 "register_operand" "")
6035 (match_operand:DF 1 "memory_operand" ""))
6036 (use (match_operand:PSI 2 "fpscr_operand" ""))
6037 (clobber (match_scratch:SI 3 ""))]
6038 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6039 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6042 int regno = true_regnum (operands[0]);
6044 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6045 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6046 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6048 operands[1] = copy_rtx (mem2);
6049 addr = XEXP (mem2, 0);
6051 switch (GET_CODE (addr))
6054 /* This is complicated. If the register is an arithmetic register
6055 we can just fall through to the REG+DISP case below. Otherwise
6056 we have to use a combination of POST_INC and REG addressing... */
6057 if (! arith_reg_operand (operands[1], SFmode))
6059 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6060 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6061 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6063 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6065 /* If we have modified the stack pointer, the value that we have
6066 read with post-increment might be modified by an interrupt,
6067 so write it back. */
6068 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6069 emit_insn (gen_push_e (reg0));
6071 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6077 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6078 operands[1] = copy_rtx (operands[1]);
6079 XEXP (operands[1], 0) = plus_constant (addr, 4);
6080 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6084 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6085 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6087 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6088 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6100 [(set (match_operand:DF 0 "memory_operand" "")
6101 (match_operand:DF 1 "register_operand" ""))
6102 (use (match_operand:PSI 2 "fpscr_operand" ""))
6103 (clobber (match_scratch:SI 3 ""))]
6104 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6105 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6108 int regno = true_regnum (operands[1]);
6110 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6111 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6113 operands[0] = copy_rtx (operands[0]);
6114 PUT_MODE (operands[0], SFmode);
6115 addr = XEXP (operands[0], 0);
6117 switch (GET_CODE (addr))
6120 /* This is complicated. If the register is an arithmetic register
6121 we can just fall through to the REG+DISP case below. Otherwise
6122 we have to use a combination of REG and PRE_DEC addressing... */
6123 if (! arith_reg_operand (operands[0], SFmode))
6125 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6126 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6128 operands[0] = copy_rtx (operands[0]);
6129 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6131 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6132 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6138 /* Since REG+DISP addressing has already been decided upon by gcc
6139 we can rely upon it having chosen an arithmetic register as the
6140 register component of the address. Just emit the lower numbered
6141 register first, to the lower address, then the higher numbered
6142 register to the higher address. */
6143 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6145 operands[0] = copy_rtx (operands[0]);
6146 XEXP (operands[0], 0) = plus_constant (addr, 4);
6148 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6152 /* This is easy. Output the word to go to the higher address
6153 first (ie the word in the higher numbered register) then the
6154 word to go to the lower address. */
6156 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6157 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6159 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6160 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6172 ;; If the output is a register and the input is memory or a register, we have
6173 ;; to be careful and see which word needs to be loaded first.
6176 [(set (match_operand:DF 0 "general_movdst_operand" "")
6177 (match_operand:DF 1 "general_movsrc_operand" ""))]
6178 "TARGET_SH1 && reload_completed"
6179 [(set (match_dup 2) (match_dup 3))
6180 (set (match_dup 4) (match_dup 5))]
6185 if ((MEM_P (operands[0])
6186 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6187 || (MEM_P (operands[1])
6188 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6191 switch (GET_CODE (operands[0]))
6194 regno = REGNO (operands[0]);
6197 regno = subreg_regno (operands[0]);
6207 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6209 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6210 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6211 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6212 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6216 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6217 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6218 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6219 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6222 if (operands[2] == 0 || operands[3] == 0
6223 || operands[4] == 0 || operands[5] == 0)
6227 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6228 ;; used only once, let combine add in the index again.
6231 [(set (match_operand:SI 0 "register_operand" "")
6232 (match_operand:SI 1 "" ""))
6233 (clobber (match_operand 2 "register_operand" ""))]
6234 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6235 && ALLOW_INDEXED_ADDRESS"
6236 [(use (reg:SI R0_REG))]
6239 rtx addr, reg, const_int;
6241 if (!MEM_P (operands[1]))
6243 addr = XEXP (operands[1], 0);
6244 if (GET_CODE (addr) != PLUS)
6246 reg = XEXP (addr, 0);
6247 const_int = XEXP (addr, 1);
6248 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6249 && CONST_INT_P (const_int)))
6251 emit_move_insn (operands[2], const_int);
6252 emit_move_insn (operands[0],
6253 change_address (operands[1], VOIDmode,
6254 gen_rtx_PLUS (SImode, reg, operands[2])));
6259 [(set (match_operand:SI 1 "" "")
6260 (match_operand:SI 0 "register_operand" ""))
6261 (clobber (match_operand 2 "register_operand" ""))]
6262 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6263 && ALLOW_INDEXED_ADDRESS"
6264 [(use (reg:SI R0_REG))]
6267 rtx addr, reg, const_int;
6269 if (!MEM_P (operands[1]))
6271 addr = XEXP (operands[1], 0);
6272 if (GET_CODE (addr) != PLUS)
6274 reg = XEXP (addr, 0);
6275 const_int = XEXP (addr, 1);
6276 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6277 && CONST_INT_P (const_int)))
6279 emit_move_insn (operands[2], const_int);
6280 emit_move_insn (change_address (operands[1], VOIDmode,
6281 gen_rtx_PLUS (SImode, reg, operands[2])),
6286 (define_expand "movdf"
6287 [(set (match_operand:DF 0 "general_movdst_operand" "")
6288 (match_operand:DF 1 "general_movsrc_operand" ""))]
6292 if (prepare_move_operands (operands, DFmode)) DONE;
6295 if (TARGET_SHMEDIA_FPU)
6296 emit_insn (gen_movdf_media (operands[0], operands[1]));
6298 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6301 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6303 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6308 ;;This is incompatible with the way gcc uses subregs.
6309 ;;(define_insn "movv2sf_i"
6310 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6311 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6312 ;; "TARGET_SHMEDIA_FPU
6313 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6314 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6318 ;; fst%M0.p %m0, %1"
6319 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6321 (define_insn_and_split "movv2sf_i"
6322 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6323 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6324 "TARGET_SHMEDIA_FPU"
6326 "TARGET_SHMEDIA_FPU && reload_completed"
6327 [(set (match_dup 0) (match_dup 1))]
6330 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6331 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6334 (define_expand "movv2sf"
6335 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6336 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6337 "TARGET_SHMEDIA_FPU"
6340 if (prepare_move_operands (operands, V2SFmode))
6344 (define_expand "addv2sf3"
6345 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6346 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6347 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6348 "TARGET_SHMEDIA_FPU"
6351 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6355 (define_expand "subv2sf3"
6356 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6357 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6358 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6359 "TARGET_SHMEDIA_FPU"
6362 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6366 (define_expand "mulv2sf3"
6367 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6368 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6369 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6370 "TARGET_SHMEDIA_FPU"
6373 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6377 (define_expand "divv2sf3"
6378 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6379 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6380 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6381 "TARGET_SHMEDIA_FPU"
6384 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6388 (define_insn_and_split "*movv4sf_i"
6389 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6390 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6391 "TARGET_SHMEDIA_FPU"
6393 "&& reload_completed"
6399 for (i = 0; i < 4/2; i++)
6403 if (MEM_P (operands[0]))
6404 x = adjust_address (operands[0], V2SFmode,
6405 i * GET_MODE_SIZE (V2SFmode));
6407 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6409 if (MEM_P (operands[1]))
6410 y = adjust_address (operands[1], V2SFmode,
6411 i * GET_MODE_SIZE (V2SFmode));
6413 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6415 emit_insn (gen_movv2sf_i (x, y));
6420 [(set_attr "length" "8")])
6422 (define_expand "movv4sf"
6423 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6424 (match_operand:V4SF 1 "general_operand" ""))]
6425 "TARGET_SHMEDIA_FPU"
6428 if (prepare_move_operands (operands, V4SFmode))
6432 (define_insn_and_split "*movv16sf_i"
6433 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6434 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6435 "TARGET_SHMEDIA_FPU"
6437 "&& reload_completed"
6443 for (i = 0; i < 16/2; i++)
6447 if (MEM_P (operands[0]))
6448 x = adjust_address (operands[0], V2SFmode,
6449 i * GET_MODE_SIZE (V2SFmode));
6452 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6456 if (MEM_P (operands[1]))
6457 y = adjust_address (operands[1], V2SFmode,
6458 i * GET_MODE_SIZE (V2SFmode));
6461 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6465 emit_insn (gen_movv2sf_i (x, y));
6470 [(set_attr "length" "32")])
6472 (define_expand "movv16sf"
6473 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6474 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6475 "TARGET_SHMEDIA_FPU"
6478 if (prepare_move_operands (operands, V16SFmode))
6482 (define_insn "movsf_media"
6483 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6484 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6486 && (register_operand (operands[0], SFmode)
6487 || sh_register_operand (operands[1], SFmode))"
6498 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6499 (set (attr "highpart")
6500 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6501 (const_string "user")]
6502 (const_string "ignore")))])
6504 (define_insn "movsf_media_nofpu"
6505 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6506 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6508 && (register_operand (operands[0], SFmode)
6509 || sh_register_operand (operands[1], SFmode))"
6515 [(set_attr "type" "arith_media,*,load_media,store_media")
6516 (set (attr "highpart")
6517 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6518 (const_string "user")]
6519 (const_string "ignore")))])
6522 [(set (match_operand:SF 0 "arith_reg_dest" "")
6523 (match_operand:SF 1 "immediate_operand" ""))]
6524 "TARGET_SHMEDIA && reload_completed
6525 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6526 [(set (match_dup 3) (match_dup 2))]
6530 REAL_VALUE_TYPE value;
6532 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6533 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6534 operands[2] = GEN_INT (values);
6536 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6539 (define_insn "movsf_i"
6540 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6541 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6544 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6545 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6546 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6547 && (arith_reg_operand (operands[0], SFmode)
6548 || arith_reg_operand (operands[1], SFmode))"
6557 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6559 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6560 ;; update_flow_info would not know where to put REG_EQUAL notes
6561 ;; when the destination changes mode.
6562 (define_insn "movsf_ie"
6563 [(set (match_operand:SF 0 "general_movdst_operand"
6564 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6565 (match_operand:SF 1 "general_movsrc_operand"
6566 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6567 (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"))
6568 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6571 && (arith_reg_operand (operands[0], SFmode)
6572 || arith_reg_operand (operands[1], SFmode)
6573 || arith_reg_operand (operands[3], SImode)
6574 || (fpul_operand (operands[0], SFmode)
6575 && memory_operand (operands[1], SFmode)
6576 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6577 || (fpul_operand (operands[1], SFmode)
6578 && memory_operand (operands[0], SFmode)
6579 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6599 ! move optimized away"
6600 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6601 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6602 (set_attr_alternative "length"
6609 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6610 (const_int 4) (const_int 2))
6612 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613 (const_int 4) (const_int 2))
6616 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617 (const_int 4) (const_int 2))
6619 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6620 (const_int 4) (const_int 2))
6630 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631 (const_string "single")
6632 (const_string "single")))])
6635 [(set (match_operand:SF 0 "register_operand" "")
6636 (match_operand:SF 1 "register_operand" ""))
6637 (use (match_operand:PSI 2 "fpscr_operand" ""))
6638 (clobber (reg:SI FPUL_REG))]
6640 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6642 (clobber (scratch:SI))])
6643 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6645 (clobber (scratch:SI))])]
6648 (define_expand "movsf"
6649 [(set (match_operand:SF 0 "general_movdst_operand" "")
6650 (match_operand:SF 1 "general_movsrc_operand" ""))]
6654 if (prepare_move_operands (operands, SFmode))
6658 if (TARGET_SHMEDIA_FPU)
6659 emit_insn (gen_movsf_media (operands[0], operands[1]));
6661 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6666 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6671 (define_insn "mov_nop"
6672 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6675 [(set_attr "length" "0")
6676 (set_attr "type" "nil")])
6678 (define_expand "reload_insf__frn"
6679 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680 (match_operand:SF 1 "immediate_operand" "FQ"))
6681 (use (reg:PSI FPSCR_REG))
6682 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6686 (define_expand "reload_insi__i_fpul"
6687 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688 (match_operand:SI 1 "immediate_operand" "i"))
6689 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6693 (define_expand "ptabs"
6694 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6698 if (!TARGET_PT_FIXED)
6700 rtx eq = operands[1];
6702 /* ??? For canonical RTL we really should remove any CONST from EQ
6703 before wrapping it in the AND, and finally wrap the EQ into a
6704 const if is constant. However, for reload we must expose the
6705 input register or symbolic constant, and we can't have
6706 different insn structures outside of the operands for different
6707 alternatives of the same pattern. */
6708 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6711 = (gen_rtx_IF_THEN_ELSE
6714 gen_rtx_MEM (PDImode, operands[1]),
6715 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716 PDImode, operands[1])));
6720 ;; expanded by ptabs expander.
6721 (define_insn "*extendsipdi_media"
6722 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6727 (mem:PDI (match_dup 1))
6728 (sign_extend:PDI (match_dup 1))))]
6729 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6733 [(set_attr "type" "ptabs_media,pt_media")
6734 (set_attr "length" "4,*")])
6736 (define_insn "*truncdipdi_media"
6737 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6742 (mem:PDI (match_dup 1))
6743 (truncate:PDI (match_dup 1))))]
6744 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6748 [(set_attr "type" "ptabs_media,pt_media")
6749 (set_attr "length" "4,*")])
6751 (define_insn "*movsi_y"
6752 [(set (match_operand:SI 0 "register_operand" "=y,y")
6753 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754 (clobber (match_scratch:SI 2 "=&z,r"))]
6756 && (reload_in_progress || reload_completed)"
6758 [(set_attr "length" "4")
6759 (set_attr "type" "pcload,move")])
6762 [(set (match_operand:SI 0 "register_operand" "")
6763 (match_operand:SI 1 "immediate_operand" ""))
6764 (clobber (match_operand:SI 2 "register_operand" ""))]
6766 [(set (match_dup 2) (match_dup 1))
6767 (set (match_dup 0) (match_dup 2))]
6771 [(set (match_operand:SI 0 "register_operand" "")
6772 (match_operand:SI 1 "memory_operand" ""))
6773 (clobber (reg:SI R0_REG))]
6775 [(set (match_dup 0) (match_dup 1))]
6778 ;; ------------------------------------------------------------------------
6779 ;; Define the real conditional branch instructions.
6780 ;; ------------------------------------------------------------------------
6782 (define_insn "branch_true"
6783 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784 (label_ref (match_operand 0 "" ""))
6787 "* return output_branch (1, insn, operands);"
6788 [(set_attr "type" "cbranch")])
6790 (define_insn "branch_false"
6791 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792 (label_ref (match_operand 0 "" ""))
6795 "* return output_branch (0, insn, operands);"
6796 [(set_attr "type" "cbranch")])
6798 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799 ;; which destination is too far away.
6800 ;; The const_int_operand is distinct for each branch target; it avoids
6801 ;; unwanted matches with redundant_insn.
6802 (define_insn "block_branch_redirect"
6803 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6806 [(set_attr "length" "0")])
6808 ;; This one has the additional purpose to record a possible scratch register
6809 ;; for the following branch.
6810 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6811 ;; because the insn then might be deemed dead and deleted. And we can't
6812 ;; make the use in the jump insn explicit because that would disable
6813 ;; delay slot scheduling from the target.
6814 (define_insn "indirect_jump_scratch"
6815 [(set (match_operand:SI 0 "register_operand" "=r")
6816 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6820 [(set_attr "length" "0")])
6822 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823 ;; being pulled into the delay slot of a condbranch that has been made to
6824 ;; jump around the unconditional jump because it was out of range.
6825 (define_insn "stuff_delay_slot"
6827 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6828 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6831 [(set_attr "length" "0")
6832 (set_attr "cond_delay_slot" "yes")])
6834 ;; Conditional branch insns
6836 (define_expand "cbranchint4_media"
6838 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6839 [(match_operand 1 "" "")
6840 (match_operand 2 "" "")])
6841 (match_operand 3 "" "")
6846 enum machine_mode mode = GET_MODE (operands[1]);
6847 if (mode == VOIDmode)
6848 mode = GET_MODE (operands[2]);
6849 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6851 operands[1] = force_reg (mode, operands[1]);
6852 if (CONSTANT_P (operands[2])
6853 && (! satisfies_constraint_I06 (operands[2])))
6854 operands[2] = force_reg (mode, operands[2]);
6858 if (operands[1] != const0_rtx)
6859 operands[1] = force_reg (mode, operands[1]);
6860 if (operands[2] != const0_rtx)
6861 operands[2] = force_reg (mode, operands[2]);
6863 switch (GET_CODE (operands[0]))
6869 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6870 VOIDmode, operands[2], operands[1]);
6871 operands[1] = XEXP (operands[0], 0);
6872 operands[2] = XEXP (operands[0], 1);
6875 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6876 VOIDmode, operands[1], operands[2]);
6879 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6882 (define_expand "cbranchfp4_media"
6884 (if_then_else (match_operator 0 "sh_float_comparison_operator"
6885 [(match_operand 1 "" "")
6886 (match_operand 2 "" "")])
6887 (match_operand 3 "" "")
6892 rtx tmp = gen_reg_rtx (SImode);
6894 if (GET_CODE (operands[0]) == NE)
6895 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6897 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6898 operands[1], operands[2]);
6900 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6902 if (GET_CODE (cmp) == GET_CODE (operands[0]))
6903 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6905 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6907 operands[2] = const0_rtx;
6908 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6911 (define_insn "*beq_media_i"
6913 (if_then_else (match_operator 3 "equality_comparison_operator"
6914 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6915 (match_operand:DI 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_insn "*beq_media_i32"
6926 (if_then_else (match_operator 3 "equality_comparison_operator"
6927 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6928 (match_operand:SI 2 "arith_operand" "r,I06")])
6929 (match_operand 0 "target_operand" "b,b")
6934 b%o3i%' %1, %2, %0%>"
6935 [(set_attr "type" "cbranch_media")])
6937 (define_insn "*bgt_media_i"
6939 (if_then_else (match_operator 3 "greater_comparison_operator"
6940 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6941 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6942 (match_operand 0 "target_operand" "b")
6945 "b%o3%' %N1, %N2, %0%>"
6946 [(set_attr "type" "cbranch_media")])
6948 (define_insn "*bgt_media_i32"
6950 (if_then_else (match_operator 3 "greater_comparison_operator"
6951 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6952 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6953 (match_operand 0 "target_operand" "b")
6956 "b%o3%' %N1, %N2, %0%>"
6957 [(set_attr "type" "cbranch_media")])
6959 ;; These are only needed to make invert_jump() happy - otherwise, jump
6960 ;; optimization will be silently disabled.
6961 (define_insn "*blt_media_i"
6963 (if_then_else (match_operator 3 "less_comparison_operator"
6964 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6965 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6966 (match_operand 0 "target_operand" "b")
6969 "b%o3%' %N2, %N1, %0%>"
6970 [(set_attr "type" "cbranch_media")])
6972 (define_insn "*blt_media_i32"
6974 (if_then_else (match_operator 3 "less_comparison_operator"
6975 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6976 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6977 (match_operand 0 "target_operand" "b")
6980 "b%o3%' %N2, %N1, %0%>"
6981 [(set_attr "type" "cbranch_media")])
6983 ;; combiner splitter for test-and-branch on single bit in register. This
6984 ;; is endian dependent because the non-paradoxical subreg looks different
6989 (match_operator 3 "equality_comparison_operator"
6990 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
6991 "extend_reg_operand" "")
6995 "const_int_operand" "")) 0)
6997 (match_operand 0 "target_operand" "")
6999 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7000 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7001 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7002 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7006 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7007 operands[6] = (GET_CODE (operands[3]) == EQ
7008 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7009 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7012 ; operand 0 is the loop count pseudo register
7013 ; operand 1 is the number of loop iterations or 0 if it is unknown
7014 ; operand 2 is the maximum number of loop iterations
7015 ; operand 3 is the number of levels of enclosed loops
7016 ; operand 4 is the label to jump to at the top of the loop
7018 (define_expand "doloop_end"
7019 [(parallel [(set (pc) (if_then_else
7020 (ne:SI (match_operand:SI 0 "" "")
7022 (label_ref (match_operand 4 "" ""))
7025 (plus:SI (match_dup 0) (const_int -1)))
7026 (clobber (reg:SI T_REG))])]
7030 if (GET_MODE (operands[0]) != SImode)
7035 (define_insn_and_split "doloop_end_split"
7037 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7039 (label_ref (match_operand 1 "" ""))
7042 (plus (match_dup 0) (const_int -1)))
7043 (clobber (reg:SI T_REG))]
7047 [(parallel [(set (reg:SI T_REG)
7048 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7050 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7051 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7052 (label_ref (match_operand 1 "" ""))
7055 [(set_attr "type" "cbranch")])
7058 ;; ------------------------------------------------------------------------
7059 ;; Jump and linkage insns
7060 ;; ------------------------------------------------------------------------
7062 (define_insn "jump_compact"
7064 (label_ref (match_operand 0 "" "")))]
7065 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7068 /* The length is 16 if the delay slot is unfilled. */
7069 if (get_attr_length(insn) > 4)
7070 return output_far_jump(insn, operands[0]);
7072 return \"bra %l0%#\";
7074 [(set_attr "type" "jump")
7075 (set_attr "needs_delay_slot" "yes")])
7077 ;; ??? It would be much saner to explicitly use the scratch register
7078 ;; in the jump insn, and have indirect_jump_scratch only set it,
7079 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7080 ;; from the target then, as it uses simplejump_p.
7081 ;;(define_insn "jump_compact_far"
7083 ;; (label_ref (match_operand 0 "" "")))
7084 ;; (use (match_operand 1 "register_operand" "r")]
7086 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7087 ;; [(set_attr "type" "jump")
7088 ;; (set_attr "needs_delay_slot" "yes")])
7090 (define_insn "jump_media"
7092 (match_operand 0 "target_operand" "b"))]
7095 [(set_attr "type" "jump_media")])
7097 (define_expand "jump"
7099 (label_ref (match_operand 0 "" "")))]
7104 emit_jump_insn (gen_jump_compact (operands[0]));
7105 else if (TARGET_SHMEDIA)
7107 if (reload_in_progress || reload_completed)
7109 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7115 (define_insn "force_mode_for_call"
7116 [(use (reg:PSI FPSCR_REG))]
7119 [(set_attr "length" "0")
7120 (set (attr "fp_mode")
7121 (if_then_else (eq_attr "fpu_single" "yes")
7122 (const_string "single") (const_string "double")))])
7124 (define_insn "calli"
7125 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7126 (match_operand 1 "" ""))
7127 (use (reg:PSI FPSCR_REG))
7128 (clobber (reg:SI PR_REG))]
7132 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7133 return \"jsr/n\\t@%0\";
7135 return \"jsr\\t@%0%#\";
7138 [(set_attr "type" "call")
7139 (set (attr "fp_mode")
7140 (if_then_else (eq_attr "fpu_single" "yes")
7141 (const_string "single") (const_string "double")))
7142 (set_attr "needs_delay_slot" "yes")
7143 (set_attr "fp_set" "unknown")])
7145 ;; This is TBR relative jump instruction for SH2A architecture.
7146 ;; Its use is enabled assigning an attribute "function_vector"
7147 ;; and the vector number to a function during its declaration.
7149 (define_insn "calli_tbr_rel"
7150 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7151 (match_operand 1 "" ""))
7152 (use (reg:PSI FPSCR_REG))
7153 (clobber (reg:SI PR_REG))]
7154 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7157 unsigned HOST_WIDE_INT vect_num;
7158 vect_num = sh2a_get_function_vector_number (operands[0]);
7159 operands[2] = GEN_INT (vect_num * 4);
7161 return \"jsr/n\\t@@(%O2,tbr)\";
7163 [(set_attr "type" "call")
7164 (set (attr "fp_mode")
7165 (if_then_else (eq_attr "fpu_single" "yes")
7166 (const_string "single") (const_string "double")))
7167 (set_attr "needs_delay_slot" "no")
7168 (set_attr "fp_set" "unknown")])
7170 ;; This is a pc-rel call, using bsrf, for use with PIC.
7172 (define_insn "calli_pcrel"
7173 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7174 (match_operand 1 "" ""))
7175 (use (reg:PSI FPSCR_REG))
7176 (use (reg:SI PIC_REG))
7177 (use (match_operand 2 "" ""))
7178 (clobber (reg:SI PR_REG))]
7181 [(set_attr "type" "call")
7182 (set (attr "fp_mode")
7183 (if_then_else (eq_attr "fpu_single" "yes")
7184 (const_string "single") (const_string "double")))
7185 (set_attr "needs_delay_slot" "yes")
7186 (set_attr "fp_set" "unknown")])
7188 (define_insn_and_split "call_pcrel"
7189 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7190 (match_operand 1 "" ""))
7191 (use (reg:PSI FPSCR_REG))
7192 (use (reg:SI PIC_REG))
7193 (clobber (reg:SI PR_REG))
7194 (clobber (match_scratch:SI 2 "=r"))]
7201 rtx lab = PATTERN (gen_call_site ());
7203 if (SYMBOL_REF_LOCAL_P (operands[0]))
7204 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7206 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7207 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7210 [(set_attr "type" "call")
7211 (set (attr "fp_mode")
7212 (if_then_else (eq_attr "fpu_single" "yes")
7213 (const_string "single") (const_string "double")))
7214 (set_attr "needs_delay_slot" "yes")
7215 (set_attr "fp_set" "unknown")])
7217 (define_insn "call_compact"
7218 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7219 (match_operand 1 "" ""))
7220 (match_operand 2 "immediate_operand" "n")
7221 (use (reg:SI R0_REG))
7222 (use (reg:SI R1_REG))
7223 (use (reg:PSI FPSCR_REG))
7224 (clobber (reg:SI PR_REG))]
7225 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7227 [(set_attr "type" "call")
7228 (set (attr "fp_mode")
7229 (if_then_else (eq_attr "fpu_single" "yes")
7230 (const_string "single") (const_string "double")))
7231 (set_attr "needs_delay_slot" "yes")])
7233 (define_insn "call_compact_rettramp"
7234 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7235 (match_operand 1 "" ""))
7236 (match_operand 2 "immediate_operand" "n")
7237 (use (reg:SI R0_REG))
7238 (use (reg:SI R1_REG))
7239 (use (reg:PSI FPSCR_REG))
7240 (clobber (reg:SI R10_REG))
7241 (clobber (reg:SI PR_REG))]
7242 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7244 [(set_attr "type" "call")
7245 (set (attr "fp_mode")
7246 (if_then_else (eq_attr "fpu_single" "yes")
7247 (const_string "single") (const_string "double")))
7248 (set_attr "needs_delay_slot" "yes")])
7250 (define_insn "call_media"
7251 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7252 (match_operand 1 "" ""))
7253 (clobber (reg:DI PR_MEDIA_REG))]
7256 [(set_attr "type" "jump_media")])
7258 (define_insn "call_valuei"
7259 [(set (match_operand 0 "" "=rf")
7260 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7261 (match_operand 2 "" "")))
7262 (use (reg:PSI FPSCR_REG))
7263 (clobber (reg:SI PR_REG))]
7267 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7268 return \"jsr/n\\t@%1\";
7270 return \"jsr\\t@%1%#\";
7272 [(set_attr "type" "call")
7273 (set (attr "fp_mode")
7274 (if_then_else (eq_attr "fpu_single" "yes")
7275 (const_string "single") (const_string "double")))
7276 (set_attr "needs_delay_slot" "yes")
7277 (set_attr "fp_set" "unknown")])
7279 ;; This is TBR relative jump instruction for SH2A architecture.
7280 ;; Its use is enabled assigning an attribute "function_vector"
7281 ;; and the vector number to a function during its declaration.
7283 (define_insn "call_valuei_tbr_rel"
7284 [(set (match_operand 0 "" "=rf")
7285 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7286 (match_operand 2 "" "")))
7287 (use (reg:PSI FPSCR_REG))
7288 (clobber (reg:SI PR_REG))]
7289 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7292 unsigned HOST_WIDE_INT vect_num;
7293 vect_num = sh2a_get_function_vector_number (operands[1]);
7294 operands[3] = GEN_INT (vect_num * 4);
7296 return \"jsr/n\\t@@(%O3,tbr)\";
7298 [(set_attr "type" "call")
7299 (set (attr "fp_mode")
7300 (if_then_else (eq_attr "fpu_single" "yes")
7301 (const_string "single") (const_string "double")))
7302 (set_attr "needs_delay_slot" "no")
7303 (set_attr "fp_set" "unknown")])
7305 (define_insn "call_valuei_pcrel"
7306 [(set (match_operand 0 "" "=rf")
7307 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7308 (match_operand 2 "" "")))
7309 (use (reg:PSI FPSCR_REG))
7310 (use (reg:SI PIC_REG))
7311 (use (match_operand 3 "" ""))
7312 (clobber (reg:SI PR_REG))]
7315 [(set_attr "type" "call")
7316 (set (attr "fp_mode")
7317 (if_then_else (eq_attr "fpu_single" "yes")
7318 (const_string "single") (const_string "double")))
7319 (set_attr "needs_delay_slot" "yes")
7320 (set_attr "fp_set" "unknown")])
7322 (define_insn_and_split "call_value_pcrel"
7323 [(set (match_operand 0 "" "=rf")
7324 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7325 (match_operand 2 "" "")))
7326 (use (reg:PSI FPSCR_REG))
7327 (use (reg:SI PIC_REG))
7328 (clobber (reg:SI PR_REG))
7329 (clobber (match_scratch:SI 3 "=r"))]
7336 rtx lab = PATTERN (gen_call_site ());
7338 if (SYMBOL_REF_LOCAL_P (operands[1]))
7339 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7341 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7342 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7343 operands[2], copy_rtx (lab)));
7346 [(set_attr "type" "call")
7347 (set (attr "fp_mode")
7348 (if_then_else (eq_attr "fpu_single" "yes")
7349 (const_string "single") (const_string "double")))
7350 (set_attr "needs_delay_slot" "yes")
7351 (set_attr "fp_set" "unknown")])
7353 (define_insn "call_value_compact"
7354 [(set (match_operand 0 "" "=rf")
7355 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7356 (match_operand 2 "" "")))
7357 (match_operand 3 "immediate_operand" "n")
7358 (use (reg:SI R0_REG))
7359 (use (reg:SI R1_REG))
7360 (use (reg:PSI FPSCR_REG))
7361 (clobber (reg:SI PR_REG))]
7362 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7364 [(set_attr "type" "call")
7365 (set (attr "fp_mode")
7366 (if_then_else (eq_attr "fpu_single" "yes")
7367 (const_string "single") (const_string "double")))
7368 (set_attr "needs_delay_slot" "yes")])
7370 (define_insn "call_value_compact_rettramp"
7371 [(set (match_operand 0 "" "=rf")
7372 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7373 (match_operand 2 "" "")))
7374 (match_operand 3 "immediate_operand" "n")
7375 (use (reg:SI R0_REG))
7376 (use (reg:SI R1_REG))
7377 (use (reg:PSI FPSCR_REG))
7378 (clobber (reg:SI R10_REG))
7379 (clobber (reg:SI PR_REG))]
7380 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7382 [(set_attr "type" "call")
7383 (set (attr "fp_mode")
7384 (if_then_else (eq_attr "fpu_single" "yes")
7385 (const_string "single") (const_string "double")))
7386 (set_attr "needs_delay_slot" "yes")])
7388 (define_insn "call_value_media"
7389 [(set (match_operand 0 "" "=rf")
7390 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7391 (match_operand 2 "" "")))
7392 (clobber (reg:DI PR_MEDIA_REG))]
7395 [(set_attr "type" "jump_media")])
7397 (define_expand "call"
7398 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7399 (match_operand 1 "" ""))
7400 (match_operand 2 "" "")
7401 (use (reg:PSI FPSCR_REG))
7402 (clobber (reg:SI PR_REG))])]
7408 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7409 emit_call_insn (gen_call_media (operands[0], operands[1]));
7412 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7414 rtx cookie_rtx = operands[2];
7415 long cookie = INTVAL (cookie_rtx);
7416 rtx func = XEXP (operands[0], 0);
7421 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7423 rtx reg = gen_reg_rtx (Pmode);
7425 emit_insn (gen_symGOTPLT2reg (reg, func));
7429 func = legitimize_pic_address (func, Pmode, 0);
7432 r0 = gen_rtx_REG (SImode, R0_REG);
7433 r1 = gen_rtx_REG (SImode, R1_REG);
7435 /* Since such a call function may use all call-clobbered
7436 registers, we force a mode switch earlier, so that we don't
7437 run out of registers when adjusting fpscr for the call. */
7438 emit_insn (gen_force_mode_for_call ());
7441 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7443 operands[0] = force_reg (SImode, operands[0]);
7445 emit_move_insn (r0, func);
7446 emit_move_insn (r1, cookie_rtx);
7448 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7449 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7452 emit_call_insn (gen_call_compact (operands[0], operands[1],
7457 else if (TARGET_SHCOMPACT && flag_pic
7458 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7459 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7461 rtx reg = gen_reg_rtx (Pmode);
7463 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7464 XEXP (operands[0], 0) = reg;
7466 if (!flag_pic && TARGET_SH2A
7467 && MEM_P (operands[0])
7468 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7470 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7472 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7477 if (flag_pic && TARGET_SH2
7478 && MEM_P (operands[0])
7479 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7481 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7486 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7487 operands[1] = operands[2];
7490 emit_call_insn (gen_calli (operands[0], operands[1]));
7494 (define_insn "call_pop_compact"
7495 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7496 (match_operand 1 "" ""))
7497 (match_operand 2 "immediate_operand" "n")
7498 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7499 (match_operand 3 "immediate_operand" "n")))
7500 (use (reg:SI R0_REG))
7501 (use (reg:SI R1_REG))
7502 (use (reg:PSI FPSCR_REG))
7503 (clobber (reg:SI PR_REG))]
7504 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7506 [(set_attr "type" "call")
7507 (set (attr "fp_mode")
7508 (if_then_else (eq_attr "fpu_single" "yes")
7509 (const_string "single") (const_string "double")))
7510 (set_attr "needs_delay_slot" "yes")])
7512 (define_insn "call_pop_compact_rettramp"
7513 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7514 (match_operand 1 "" ""))
7515 (match_operand 2 "immediate_operand" "n")
7516 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7517 (match_operand 3 "immediate_operand" "n")))
7518 (use (reg:SI R0_REG))
7519 (use (reg:SI R1_REG))
7520 (use (reg:PSI FPSCR_REG))
7521 (clobber (reg:SI R10_REG))
7522 (clobber (reg:SI PR_REG))]
7523 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7525 [(set_attr "type" "call")
7526 (set (attr "fp_mode")
7527 (if_then_else (eq_attr "fpu_single" "yes")
7528 (const_string "single") (const_string "double")))
7529 (set_attr "needs_delay_slot" "yes")])
7531 (define_expand "call_pop"
7532 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7533 (match_operand 1 "" ""))
7534 (match_operand 2 "" "")
7535 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7536 (match_operand 3 "" "")))])]
7545 gcc_assert (operands[2] && INTVAL (operands[2]));
7546 cookie_rtx = operands[2];
7547 cookie = INTVAL (cookie_rtx);
7548 func = XEXP (operands[0], 0);
7552 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7554 rtx reg = gen_reg_rtx (Pmode);
7555 emit_insn (gen_symGOTPLT2reg (reg, func));
7559 func = legitimize_pic_address (func, Pmode, 0);
7562 r0 = gen_rtx_REG (SImode, R0_REG);
7563 r1 = gen_rtx_REG (SImode, R1_REG);
7565 /* Since such a call function may use all call-clobbered
7566 registers, we force a mode switch earlier, so that we don't
7567 run out of registers when adjusting fpscr for the call. */
7568 emit_insn (gen_force_mode_for_call ());
7570 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7572 operands[0] = force_reg (SImode, operands[0]);
7574 emit_move_insn (r0, func);
7575 emit_move_insn (r1, cookie_rtx);
7577 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7578 emit_call_insn (gen_call_pop_compact_rettramp
7579 (operands[0], operands[1], operands[2], operands[3]));
7581 emit_call_insn (gen_call_pop_compact
7582 (operands[0], operands[1], operands[2], operands[3]));
7587 (define_expand "call_value"
7588 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7589 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7590 (match_operand 2 "" "")))
7591 (match_operand 3 "" "")
7592 (use (reg:PSI FPSCR_REG))
7593 (clobber (reg:SI PR_REG))])]
7599 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7600 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7604 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7606 rtx cookie_rtx = operands[3];
7607 long cookie = INTVAL (cookie_rtx);
7608 rtx func = XEXP (operands[1], 0);
7613 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7615 rtx reg = gen_reg_rtx (Pmode);
7617 emit_insn (gen_symGOTPLT2reg (reg, func));
7621 func = legitimize_pic_address (func, Pmode, 0);
7624 r0 = gen_rtx_REG (SImode, R0_REG);
7625 r1 = gen_rtx_REG (SImode, R1_REG);
7627 /* Since such a call function may use all call-clobbered
7628 registers, we force a mode switch earlier, so that we don't
7629 run out of registers when adjusting fpscr for the call. */
7630 emit_insn (gen_force_mode_for_call ());
7633 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7635 operands[1] = force_reg (SImode, operands[1]);
7637 emit_move_insn (r0, func);
7638 emit_move_insn (r1, cookie_rtx);
7640 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7641 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7646 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7647 operands[2], operands[3]));
7651 else if (TARGET_SHCOMPACT && flag_pic
7652 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7653 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7655 rtx reg = gen_reg_rtx (Pmode);
7657 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7658 XEXP (operands[1], 0) = reg;
7660 if (!flag_pic && TARGET_SH2A
7661 && MEM_P (operands[1])
7662 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7664 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7666 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7667 XEXP (operands[1], 0), operands[2]));
7671 if (flag_pic && TARGET_SH2
7672 && MEM_P (operands[1])
7673 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7675 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7680 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7682 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7686 (define_insn "sibcalli"
7687 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7688 (match_operand 1 "" ""))
7689 (use (reg:PSI FPSCR_REG))
7693 [(set_attr "needs_delay_slot" "yes")
7694 (set (attr "fp_mode")
7695 (if_then_else (eq_attr "fpu_single" "yes")
7696 (const_string "single") (const_string "double")))
7697 (set_attr "type" "jump_ind")])
7699 (define_insn "sibcalli_pcrel"
7700 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7701 (match_operand 1 "" ""))
7702 (use (match_operand 2 "" ""))
7703 (use (reg:PSI FPSCR_REG))
7707 [(set_attr "needs_delay_slot" "yes")
7708 (set (attr "fp_mode")
7709 (if_then_else (eq_attr "fpu_single" "yes")
7710 (const_string "single") (const_string "double")))
7711 (set_attr "type" "jump_ind")])
7713 ;; This uses an unspec to describe that the symbol_ref is very close.
7714 (define_insn "sibcalli_thunk"
7715 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7717 (match_operand 1 "" ""))
7718 (use (reg:PSI FPSCR_REG))
7722 [(set_attr "needs_delay_slot" "yes")
7723 (set (attr "fp_mode")
7724 (if_then_else (eq_attr "fpu_single" "yes")
7725 (const_string "single") (const_string "double")))
7726 (set_attr "type" "jump")
7727 (set_attr "length" "2")])
7729 (define_insn_and_split "sibcall_pcrel"
7730 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7731 (match_operand 1 "" ""))
7732 (use (reg:PSI FPSCR_REG))
7733 (clobber (match_scratch:SI 2 "=k"))
7741 rtx lab = PATTERN (gen_call_site ());
7744 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7745 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7747 SIBLING_CALL_P (call_insn) = 1;
7750 [(set_attr "needs_delay_slot" "yes")
7751 (set (attr "fp_mode")
7752 (if_then_else (eq_attr "fpu_single" "yes")
7753 (const_string "single") (const_string "double")))
7754 (set_attr "type" "jump_ind")])
7756 (define_insn "sibcall_compact"
7757 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7758 (match_operand 1 "" ""))
7760 (use (match_operand:SI 2 "register_operand" "z,x"))
7761 (use (reg:SI R1_REG))
7762 (use (reg:PSI FPSCR_REG))
7763 ;; We want to make sure the `x' above will only match MACH_REG
7764 ;; because sibcall_epilogue may clobber MACL_REG.
7765 (clobber (reg:SI MACL_REG))]
7769 jmp @%0\\n sts %2, r0"
7770 [(set_attr "needs_delay_slot" "yes,no")
7771 (set_attr "length" "2,4")
7772 (set (attr "fp_mode") (const_string "single"))
7773 (set_attr "type" "jump_ind")])
7775 (define_insn "sibcall_media"
7776 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7777 (match_operand 1 "" ""))
7778 (use (reg:SI PR_MEDIA_REG))
7782 [(set_attr "type" "jump_media")])
7784 (define_expand "sibcall"
7786 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7787 (match_operand 1 "" ""))
7788 (match_operand 2 "" "")
7789 (use (reg:PSI FPSCR_REG))
7796 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7797 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7800 else if (TARGET_SHCOMPACT && operands[2]
7801 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7803 rtx cookie_rtx = operands[2];
7804 long cookie = INTVAL (cookie_rtx);
7805 rtx func = XEXP (operands[0], 0);
7810 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7812 rtx reg = gen_reg_rtx (Pmode);
7814 emit_insn (gen_symGOT2reg (reg, func));
7818 func = legitimize_pic_address (func, Pmode, 0);
7821 /* FIXME: if we could tell whether all argument registers are
7822 already taken, we could decide whether to force the use of
7823 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7824 simple way to tell. We could use the CALL_COOKIE, but we
7825 can't currently tell a register used for regular argument
7826 passing from one that is unused. If we leave it up to reload
7827 to decide which register to use, it seems to always choose
7828 R0_REG, which leaves no available registers in SIBCALL_REGS
7829 to hold the address of the trampoline. */
7830 mach = gen_rtx_REG (SImode, MACH_REG);
7831 r1 = gen_rtx_REG (SImode, R1_REG);
7833 /* Since such a call function may use all call-clobbered
7834 registers, we force a mode switch earlier, so that we don't
7835 run out of registers when adjusting fpscr for the call. */
7836 emit_insn (gen_force_mode_for_call ());
7839 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7841 operands[0] = force_reg (SImode, operands[0]);
7843 /* We don't need a return trampoline, since the callee will
7844 return directly to the upper caller. */
7845 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7847 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7848 cookie_rtx = GEN_INT (cookie);
7851 emit_move_insn (mach, func);
7852 emit_move_insn (r1, cookie_rtx);
7854 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7857 else if (TARGET_SHCOMPACT && flag_pic
7858 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7859 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7861 rtx reg = gen_reg_rtx (Pmode);
7863 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7864 XEXP (operands[0], 0) = reg;
7866 if (flag_pic && TARGET_SH2
7867 && MEM_P (operands[0])
7868 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7869 /* The PLT needs the PIC register, but the epilogue would have
7870 to restore it, so we can only use PC-relative PIC calls for
7871 static functions. */
7872 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7874 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7878 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7880 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7884 (define_insn "sibcall_valuei"
7885 [(set (match_operand 0 "" "=rf")
7886 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7887 (match_operand 2 "" "")))
7888 (use (reg:PSI FPSCR_REG))
7892 [(set_attr "needs_delay_slot" "yes")
7893 (set (attr "fp_mode")
7894 (if_then_else (eq_attr "fpu_single" "yes")
7895 (const_string "single") (const_string "double")))
7896 (set_attr "type" "jump_ind")])
7898 (define_insn "sibcall_valuei_pcrel"
7899 [(set (match_operand 0 "" "=rf")
7900 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7901 (match_operand 2 "" "")))
7902 (use (match_operand 3 "" ""))
7903 (use (reg:PSI FPSCR_REG))
7907 [(set_attr "needs_delay_slot" "yes")
7908 (set (attr "fp_mode")
7909 (if_then_else (eq_attr "fpu_single" "yes")
7910 (const_string "single") (const_string "double")))
7911 (set_attr "type" "jump_ind")])
7913 (define_insn_and_split "sibcall_value_pcrel"
7914 [(set (match_operand 0 "" "=rf")
7915 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7916 (match_operand 2 "" "")))
7917 (use (reg:PSI FPSCR_REG))
7918 (clobber (match_scratch:SI 3 "=k"))
7926 rtx lab = PATTERN (gen_call_site ());
7929 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7930 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7934 SIBLING_CALL_P (call_insn) = 1;
7937 [(set_attr "needs_delay_slot" "yes")
7938 (set (attr "fp_mode")
7939 (if_then_else (eq_attr "fpu_single" "yes")
7940 (const_string "single") (const_string "double")))
7941 (set_attr "type" "jump_ind")])
7943 (define_insn "sibcall_value_compact"
7944 [(set (match_operand 0 "" "=rf,rf")
7945 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7946 (match_operand 2 "" "")))
7948 (use (match_operand:SI 3 "register_operand" "z,x"))
7949 (use (reg:SI R1_REG))
7950 (use (reg:PSI FPSCR_REG))
7951 ;; We want to make sure the `x' above will only match MACH_REG
7952 ;; because sibcall_epilogue may clobber MACL_REG.
7953 (clobber (reg:SI MACL_REG))]
7957 jmp @%1\\n sts %3, r0"
7958 [(set_attr "needs_delay_slot" "yes,no")
7959 (set_attr "length" "2,4")
7960 (set (attr "fp_mode") (const_string "single"))
7961 (set_attr "type" "jump_ind")])
7963 (define_insn "sibcall_value_media"
7964 [(set (match_operand 0 "" "=rf")
7965 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7966 (match_operand 2 "" "")))
7967 (use (reg:SI PR_MEDIA_REG))
7971 [(set_attr "type" "jump_media")])
7973 (define_expand "sibcall_value"
7975 [(set (match_operand 0 "arith_reg_operand" "")
7976 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7977 (match_operand 2 "" "")))
7978 (match_operand 3 "" "")
7979 (use (reg:PSI FPSCR_REG))
7986 operands[1] = shmedia_prepare_call_address (operands[1], 1);
7987 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
7991 else if (TARGET_SHCOMPACT && operands[3]
7992 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7994 rtx cookie_rtx = operands[3];
7995 long cookie = INTVAL (cookie_rtx);
7996 rtx func = XEXP (operands[1], 0);
8001 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8003 rtx reg = gen_reg_rtx (Pmode);
8005 emit_insn (gen_symGOT2reg (reg, func));
8009 func = legitimize_pic_address (func, Pmode, 0);
8012 /* FIXME: if we could tell whether all argument registers are
8013 already taken, we could decide whether to force the use of
8014 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8015 simple way to tell. We could use the CALL_COOKIE, but we
8016 can't currently tell a register used for regular argument
8017 passing from one that is unused. If we leave it up to reload
8018 to decide which register to use, it seems to always choose
8019 R0_REG, which leaves no available registers in SIBCALL_REGS
8020 to hold the address of the trampoline. */
8021 mach = gen_rtx_REG (SImode, MACH_REG);
8022 r1 = gen_rtx_REG (SImode, R1_REG);
8024 /* Since such a call function may use all call-clobbered
8025 registers, we force a mode switch earlier, so that we don't
8026 run out of registers when adjusting fpscr for the call. */
8027 emit_insn (gen_force_mode_for_call ());
8030 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8032 operands[1] = force_reg (SImode, operands[1]);
8034 /* We don't need a return trampoline, since the callee will
8035 return directly to the upper caller. */
8036 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8038 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8039 cookie_rtx = GEN_INT (cookie);
8042 emit_move_insn (mach, func);
8043 emit_move_insn (r1, cookie_rtx);
8045 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8046 operands[2], mach));
8049 else if (TARGET_SHCOMPACT && flag_pic
8050 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8051 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8053 rtx reg = gen_reg_rtx (Pmode);
8055 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8056 XEXP (operands[1], 0) = reg;
8058 if (flag_pic && TARGET_SH2
8059 && MEM_P (operands[1])
8060 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8061 /* The PLT needs the PIC register, but the epilogue would have
8062 to restore it, so we can only use PC-relative PIC calls for
8063 static functions. */
8064 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8066 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8067 XEXP (operands[1], 0),
8072 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8074 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8078 (define_insn "call_value_pop_compact"
8079 [(set (match_operand 0 "" "=rf")
8080 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8081 (match_operand 2 "" "")))
8082 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8083 (match_operand 4 "immediate_operand" "n")))
8084 (match_operand 3 "immediate_operand" "n")
8085 (use (reg:SI R0_REG))
8086 (use (reg:SI R1_REG))
8087 (use (reg:PSI FPSCR_REG))
8088 (clobber (reg:SI PR_REG))]
8089 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8091 [(set_attr "type" "call")
8092 (set (attr "fp_mode")
8093 (if_then_else (eq_attr "fpu_single" "yes")
8094 (const_string "single") (const_string "double")))
8095 (set_attr "needs_delay_slot" "yes")])
8097 (define_insn "call_value_pop_compact_rettramp"
8098 [(set (match_operand 0 "" "=rf")
8099 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8100 (match_operand 2 "" "")))
8101 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8102 (match_operand 4 "immediate_operand" "n")))
8103 (match_operand 3 "immediate_operand" "n")
8104 (use (reg:SI R0_REG))
8105 (use (reg:SI R1_REG))
8106 (use (reg:PSI FPSCR_REG))
8107 (clobber (reg:SI R10_REG))
8108 (clobber (reg:SI PR_REG))]
8109 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8111 [(set_attr "type" "call")
8112 (set (attr "fp_mode")
8113 (if_then_else (eq_attr "fpu_single" "yes")
8114 (const_string "single") (const_string "double")))
8115 (set_attr "needs_delay_slot" "yes")])
8117 (define_expand "call_value_pop"
8118 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8119 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8120 (match_operand 2 "" "")))
8121 (match_operand 3 "" "")
8122 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8123 (match_operand 4 "" "")))])]
8132 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8133 cookie_rtx = operands[3];
8134 cookie = INTVAL (cookie_rtx);
8135 func = XEXP (operands[1], 0);
8139 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8141 rtx reg = gen_reg_rtx (Pmode);
8143 emit_insn (gen_symGOTPLT2reg (reg, func));
8147 func = legitimize_pic_address (func, Pmode, 0);
8150 r0 = gen_rtx_REG (SImode, R0_REG);
8151 r1 = gen_rtx_REG (SImode, R1_REG);
8153 /* Since such a call function may use all call-clobbered
8154 registers, we force a mode switch earlier, so that we don't
8155 run out of registers when adjusting fpscr for the call. */
8156 emit_insn (gen_force_mode_for_call ());
8158 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8160 operands[1] = force_reg (SImode, operands[1]);
8162 emit_move_insn (r0, func);
8163 emit_move_insn (r1, cookie_rtx);
8165 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8166 emit_call_insn (gen_call_value_pop_compact_rettramp
8167 (operands[0], operands[1], operands[2],
8168 operands[3], operands[4]));
8170 emit_call_insn (gen_call_value_pop_compact
8171 (operands[0], operands[1], operands[2],
8172 operands[3], operands[4]));
8177 (define_expand "sibcall_epilogue"
8182 sh_expand_epilogue (1);
8183 if (TARGET_SHCOMPACT)
8187 /* If epilogue clobbers r0, preserve it in macl. */
8188 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8189 if ((set = single_set (insn))
8190 && REG_P (SET_DEST (set))
8191 && REGNO (SET_DEST (set)) == R0_REG)
8193 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8194 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8196 /* We can't tell at this point whether the sibcall is a
8197 sibcall_compact and, if it is, whether it uses r0 or
8198 mach as operand 2, so let the instructions that
8199 preserve r0 be optimized away if r0 turns out to be
8201 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8202 emit_move_insn (r0, tmp);
8209 (define_insn "indirect_jump_compact"
8211 (match_operand:SI 0 "arith_reg_operand" "r"))]
8214 [(set_attr "needs_delay_slot" "yes")
8215 (set_attr "type" "jump_ind")])
8217 (define_expand "indirect_jump"
8219 (match_operand 0 "register_operand" ""))]
8223 if (GET_MODE (operands[0]) != Pmode)
8224 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8227 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8228 ;; which can be present in structured code from indirect jumps which can not
8229 ;; be present in structured code. This allows -fprofile-arcs to work.
8231 ;; For SH1 processors.
8232 (define_insn "casesi_jump_1"
8234 (match_operand:SI 0 "register_operand" "r"))
8235 (use (label_ref (match_operand 1 "" "")))]
8238 [(set_attr "needs_delay_slot" "yes")
8239 (set_attr "type" "jump_ind")])
8241 ;; For all later processors.
8242 (define_insn "casesi_jump_2"
8243 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8244 (label_ref (match_operand 1 "" ""))))
8245 (use (label_ref (match_operand 2 "" "")))]
8247 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8249 [(set_attr "needs_delay_slot" "yes")
8250 (set_attr "type" "jump_ind")])
8252 (define_insn "casesi_jump_media"
8253 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8254 (use (label_ref (match_operand 1 "" "")))]
8257 [(set_attr "type" "jump_media")])
8259 ;; Call subroutine returning any type.
8260 ;; ??? This probably doesn't work.
8262 (define_expand "untyped_call"
8263 [(parallel [(call (match_operand 0 "" "")
8265 (match_operand 1 "" "")
8266 (match_operand 2 "" "")])]
8267 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8272 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8274 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8276 rtx set = XVECEXP (operands[2], 0, i);
8277 emit_move_insn (SET_DEST (set), SET_SRC (set));
8280 /* The optimizer does not know that the call sets the function value
8281 registers we stored in the result block. We avoid problems by
8282 claiming that all hard registers are used and clobbered at this
8284 emit_insn (gen_blockage ());
8289 ;; ------------------------------------------------------------------------
8291 ;; ------------------------------------------------------------------------
8294 [(set (reg:SI T_REG)
8295 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8296 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8299 [(set_attr "type" "arith")])
8306 ;; Load address of a label. This is only generated by the casesi expand,
8307 ;; and by machine_dependent_reorg (fixing up fp moves).
8308 ;; This must use unspec, because this only works for labels that are
8312 [(set (reg:SI R0_REG)
8313 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8316 [(set_attr "in_delay_slot" "no")
8317 (set_attr "type" "arith")])
8319 ;; machine_dependent_reorg will make this a `mova'.
8320 (define_insn "mova_const"
8321 [(set (reg:SI R0_REG)
8322 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8325 [(set_attr "in_delay_slot" "no")
8326 (set_attr "type" "arith")])
8328 (define_expand "GOTaddr2picreg"
8329 [(set (reg:SI R0_REG)
8330 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8332 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8333 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8336 if (TARGET_VXWORKS_RTP)
8338 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8339 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8340 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8344 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8345 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8349 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8350 rtx pic = operands[0];
8351 rtx lab = PATTERN (gen_call_site ());
8354 equiv = operands[1];
8355 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8356 UNSPEC_PCREL_SYMOFF);
8357 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8359 if (Pmode == SImode)
8361 emit_insn (gen_movsi_const (pic, operands[1]));
8362 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8366 emit_insn (gen_movdi_const (pic, operands[1]));
8367 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8370 insn = emit_move_insn (operands[0], tr);
8372 set_unique_reg_note (insn, REG_EQUAL, equiv);
8379 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8382 (define_expand "vxworks_picreg"
8383 [(set (reg:SI PIC_REG)
8384 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8385 (set (reg:SI R0_REG)
8386 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8387 (set (reg:SI PIC_REG)
8388 (mem:SI (reg:SI PIC_REG)))
8389 (set (reg:SI PIC_REG)
8390 (mem:SI (plus:SI (reg:SI PIC_REG)
8392 "TARGET_VXWORKS_RTP")
8395 [(set (match_operand 0 "target_reg_operand" "=b")
8396 (const (unspec [(match_operand 1 "" "Csy")]
8397 UNSPEC_DATALABEL)))]
8398 "TARGET_SHMEDIA && flag_pic
8399 && satisfies_constraint_Csy (operands[1])"
8400 "ptb/u datalabel %1, %0"
8401 [(set_attr "type" "ptabs_media")
8402 (set_attr "length" "*")])
8404 (define_insn "ptrel_si"
8405 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8406 (plus:SI (match_operand:SI 1 "register_operand" "r")
8408 (match_operand:SI 2 "" "")]
8410 "%O2: ptrel/u %1, %0"
8411 [(set_attr "type" "ptabs_media")])
8413 (define_insn "ptrel_di"
8414 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8415 (plus:DI (match_operand:DI 1 "register_operand" "r")
8417 (match_operand:DI 2 "" "")]
8419 "%O2: ptrel/u %1, %0"
8420 [(set_attr "type" "ptabs_media")])
8422 (define_expand "builtin_setjmp_receiver"
8423 [(match_operand 0 "" "")]
8427 emit_insn (gen_GOTaddr2picreg ());
8431 (define_expand "call_site"
8432 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8436 static HOST_WIDE_INT i = 0;
8437 operands[0] = GEN_INT (i);
8441 (define_expand "sym_label2reg"
8442 [(set (match_operand:SI 0 "" "")
8443 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8444 (const (plus:SI (match_operand:SI 2 "" "")
8449 (define_expand "symGOT_load"
8450 [(set (match_dup 2) (match_operand 1 "" ""))
8451 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8452 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8458 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8459 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8463 rtx reg = operands[2];
8465 if (Pmode == DImode)
8468 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8470 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8475 emit_insn (gen_movsi_const (reg, operands[1]));
8477 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8481 emit_move_insn (operands[2], operands[1]);
8483 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8485 gen_rtx_REG (Pmode, PIC_REG)));
8487 /* When stack protector inserts codes after the result is set to
8488 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8489 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8490 when rX is a GOT address for the guard symbol. Ugly but doesn't
8491 matter because this is a rare situation. */
8493 && flag_stack_protect
8494 && GET_CODE (operands[1]) == CONST
8495 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8496 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8497 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8498 \"__stack_chk_guard\") == 0)
8499 emit_insn (gen_blockage ());
8501 /* N.B. This is not constant for a GOTPLT relocation. */
8502 mem = gen_rtx_MEM (Pmode, operands[3]);
8503 MEM_NOTRAP_P (mem) = 1;
8504 /* ??? Should we have a special alias set for the GOT? */
8505 insn = emit_move_insn (operands[0], mem);
8510 (define_expand "sym2GOT"
8511 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8515 (define_expand "symGOT2reg"
8516 [(match_operand 0 "" "") (match_operand 1 "" "")]
8522 gotsym = gen_sym2GOT (operands[1]);
8523 PUT_MODE (gotsym, Pmode);
8524 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8526 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8531 (define_expand "symGOTPLT2reg"
8532 [(match_operand 0 "" "") (match_operand 1 "" "")]
8536 rtx pltsym = gen_rtx_CONST (Pmode,
8537 gen_rtx_UNSPEC (Pmode,
8538 gen_rtvec (1, operands[1]),
8540 emit_insn (gen_symGOT_load (operands[0], pltsym));
8544 (define_expand "sym2GOTOFF"
8545 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8549 (define_expand "symGOTOFF2reg"
8550 [(match_operand 0 "" "") (match_operand 1 "" "")]
8554 rtx gotoffsym, insn;
8555 rtx t = (!can_create_pseudo_p ()
8557 : gen_reg_rtx (GET_MODE (operands[0])));
8559 gotoffsym = gen_sym2GOTOFF (operands[1]);
8560 PUT_MODE (gotoffsym, Pmode);
8561 emit_move_insn (t, gotoffsym);
8562 insn = emit_move_insn (operands[0],
8563 gen_rtx_PLUS (Pmode, t,
8564 gen_rtx_REG (Pmode, PIC_REG)));
8566 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8571 (define_expand "symPLT_label2reg"
8572 [(set (match_operand:SI 0 "" "")
8575 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8576 (const:SI (plus:SI (match_operand:SI 2 "" "")
8577 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8578 ;; Even though the PIC register is not really used by the call
8579 ;; sequence in which this is expanded, the PLT code assumes the PIC
8580 ;; register is set, so we must not skip its initialization. Since
8581 ;; we only use this expand as part of calling sequences, and never
8582 ;; to take the address of a function, this is the best point to
8583 ;; insert the (use). Using the PLT to take the address of a
8584 ;; function would be wrong, not only because the PLT entry could
8585 ;; then be called from a function that doesn't initialize the PIC
8586 ;; register to the proper GOT, but also because pointers to the
8587 ;; same function might not compare equal, should they be set by
8588 ;; different shared libraries.
8589 (use (reg:SI PIC_REG))]
8593 (define_expand "sym2PIC"
8594 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8598 ;; TLS code generation.
8599 ;; ??? this should be a define_insn_and_split
8600 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8601 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8604 (define_insn "tls_global_dynamic"
8605 [(set (match_operand:SI 0 "register_operand" "=&z")
8606 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8609 (use (reg:PSI FPSCR_REG))
8610 (use (reg:SI PIC_REG))
8611 (clobber (reg:SI PR_REG))
8612 (clobber (scratch:SI))]
8618 \\tmova\\t2f,r0\\n\\
8619 \\tmov.l\\t2f,r1\\n\\
8622 \\tadd\\tr12,r4\\n\\
8626 1:\\t.long\\t%a1@TLSGD\\n\\
8627 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8630 [(set_attr "type" "tls_load")
8631 (set_attr "length" "26")])
8633 (define_insn "tls_local_dynamic"
8634 [(set (match_operand:SI 0 "register_operand" "=&z")
8635 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8638 (use (reg:PSI FPSCR_REG))
8639 (use (reg:SI PIC_REG))
8640 (clobber (reg:SI PR_REG))
8641 (clobber (scratch:SI))]
8647 \\tmova\\t2f,r0\\n\\
8648 \\tmov.l\\t2f,r1\\n\\
8651 \\tadd\\tr12,r4\\n\\
8655 1:\\t.long\\t%a1@TLSLDM\\n\\
8656 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8659 [(set_attr "type" "tls_load")
8660 (set_attr "length" "26")])
8662 (define_expand "sym2DTPOFF"
8663 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8667 (define_expand "symDTPOFF2reg"
8668 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8672 rtx dtpoffsym, insn;
8673 rtx t = (!can_create_pseudo_p ()
8675 : gen_reg_rtx (GET_MODE (operands[0])));
8677 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8678 PUT_MODE (dtpoffsym, Pmode);
8679 emit_move_insn (t, dtpoffsym);
8680 insn = emit_move_insn (operands[0],
8681 gen_rtx_PLUS (Pmode, t, operands[2]));
8685 (define_expand "sym2GOTTPOFF"
8686 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8690 (define_insn "tls_initial_exec"
8691 [(set (match_operand:SI 0 "register_operand" "=&r")
8692 (unspec:SI [(match_operand:SI 1 "" "")]
8694 (use (reg:SI GBR_REG))
8695 (use (reg:SI PIC_REG))
8696 (clobber (reg:SI R0_REG))]
8702 \\tstc\\tgbr,%0\\n\\
8703 \\tmov.l\\t@(r0,r12),r0\\n\\
8707 1:\\t.long\\t%a1\\n\\
8710 [(set_attr "type" "tls_load")
8711 (set_attr "length" "16")])
8713 (define_expand "sym2TPOFF"
8714 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8718 (define_expand "symTPOFF2reg"
8719 [(match_operand 0 "" "") (match_operand 1 "" "")]
8725 tpoffsym = gen_sym2TPOFF (operands[1]);
8726 PUT_MODE (tpoffsym, Pmode);
8727 insn = emit_move_insn (operands[0], tpoffsym);
8731 (define_insn "load_gbr"
8732 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8733 (use (reg:SI GBR_REG))]
8736 [(set_attr "type" "tls_load")])
8738 ;; case instruction for switch statements.
8740 ;; Operand 0 is index
8741 ;; operand 1 is the minimum bound
8742 ;; operand 2 is the maximum bound - minimum bound + 1
8743 ;; operand 3 is CODE_LABEL for the table;
8744 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8746 (define_expand "casesi"
8747 [(match_operand:SI 0 "arith_reg_operand" "")
8748 (match_operand:SI 1 "arith_reg_operand" "")
8749 (match_operand:SI 2 "arith_reg_operand" "")
8750 (match_operand 3 "" "") (match_operand 4 "" "")]
8754 rtx reg = gen_reg_rtx (SImode);
8755 rtx reg2 = gen_reg_rtx (SImode);
8758 rtx reg = gen_reg_rtx (DImode);
8759 rtx reg2 = gen_reg_rtx (DImode);
8760 rtx reg3 = gen_reg_rtx (Pmode);
8761 rtx reg4 = gen_reg_rtx (Pmode);
8762 rtx reg5 = gen_reg_rtx (Pmode);
8765 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8766 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8767 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8769 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8770 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8771 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8772 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8773 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8774 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8775 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8776 (Pmode, operands[3])));
8777 /* Messy: can we subreg to clean this up? */
8778 if (Pmode == DImode)
8779 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8781 load = gen_casesi_load_media (reg4,
8782 gen_rtx_SUBREG (DImode, reg3, 0),
8784 PUT_MODE (SET_SRC (load), Pmode);
8786 /* ??? The following add could be eliminated if we used ptrel. */
8787 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8788 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8792 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8793 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8794 /* If optimizing, casesi_worker depends on the mode of the instruction
8795 before label it 'uses' - operands[3]. */
8796 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8798 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8800 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8802 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8803 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8804 operands[3], but to lab. We will fix this up in
8805 machine_dependent_reorg. */
8810 (define_expand "casesi_0"
8811 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8812 (set (match_dup 4) (minus:SI (match_dup 4)
8813 (match_operand:SI 1 "arith_operand" "")))
8815 (gtu:SI (match_dup 4)
8816 (match_operand:SI 2 "arith_reg_operand" "")))
8818 (if_then_else (ne (reg:SI T_REG)
8820 (label_ref (match_operand 3 "" ""))
8825 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8826 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8827 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8829 (define_insn "casesi_worker_0"
8830 [(set (match_operand:SI 0 "register_operand" "=r,r")
8831 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8832 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8833 (clobber (match_scratch:SI 3 "=X,1"))
8834 (clobber (match_scratch:SI 4 "=&z,z"))]
8839 [(set (match_operand:SI 0 "register_operand" "")
8840 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8841 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8842 (clobber (match_scratch:SI 3 ""))
8843 (clobber (match_scratch:SI 4 ""))]
8844 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8845 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8846 (parallel [(set (match_dup 0)
8847 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8848 (label_ref (match_dup 2))] UNSPEC_CASESI))
8849 (clobber (match_dup 3))])
8850 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8851 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8854 [(set (match_operand:SI 0 "register_operand" "")
8855 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8856 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8857 (clobber (match_scratch:SI 3 ""))
8858 (clobber (match_scratch:SI 4 ""))]
8859 "TARGET_SH2 && reload_completed"
8860 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8861 (parallel [(set (match_dup 0)
8862 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8863 (label_ref (match_dup 2))] UNSPEC_CASESI))
8864 (clobber (match_dup 3))])]
8865 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8867 (define_insn "casesi_worker_1"
8868 [(set (match_operand:SI 0 "register_operand" "=r,r")
8869 (unspec:SI [(reg:SI R0_REG)
8870 (match_operand:SI 1 "register_operand" "0,r")
8871 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8872 (clobber (match_scratch:SI 3 "=X,1"))]
8876 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8878 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8880 switch (GET_MODE (diff_vec))
8883 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8885 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8887 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8888 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8889 return \"mov.b @(r0,%1),%0\";
8894 [(set_attr "length" "4")])
8896 (define_insn "casesi_worker_2"
8897 [(set (match_operand:SI 0 "register_operand" "=r,r")
8898 (unspec:SI [(reg:SI R0_REG)
8899 (match_operand:SI 1 "register_operand" "0,r")
8900 (label_ref (match_operand 2 "" ""))
8901 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8902 (clobber (match_operand:SI 4 "" "=X,1"))]
8903 "TARGET_SH2 && reload_completed && flag_pic"
8906 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8909 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8911 switch (GET_MODE (diff_vec))
8914 output_asm_insn (\"shll2 %1\", operands);
8915 load = \"mov.l @(r0,%1),%0\"; break;
8917 output_asm_insn (\"add %1,%1\", operands);
8918 load = \"mov.w @(r0,%1),%0\"; break;
8920 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8921 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8923 load = \"mov.b @(r0,%1),%0\";
8928 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8931 [(set_attr "length" "8")])
8933 (define_insn "casesi_shift_media"
8934 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8935 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8936 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8941 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8943 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8945 switch (GET_MODE (diff_vec))
8948 return \"shlli %1, 2, %0\";
8950 return \"shlli %1, 1, %0\";
8952 if (rtx_equal_p (operands[0], operands[1]))
8954 return \"add %1, r63, %0\";
8959 [(set_attr "type" "arith_media")])
8961 (define_insn "casesi_load_media"
8962 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8963 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8964 (match_operand:DI 2 "arith_reg_operand" "r")
8965 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8969 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8971 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8973 switch (GET_MODE (diff_vec))
8976 return \"ldx.l %1, %2, %0\";
8979 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8980 return \"ldx.uw %1, %2, %0\";
8982 return \"ldx.w %1, %2, %0\";
8984 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8985 return \"ldx.ub %1, %2, %0\";
8986 return \"ldx.b %1, %2, %0\";
8991 [(set_attr "type" "load_media")])
8993 (define_expand "return"
8995 "reload_completed && ! sh_need_epilogue ()"
9000 emit_jump_insn (gen_return_media ());
9004 if (TARGET_SHCOMPACT
9005 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9007 emit_jump_insn (gen_shcompact_return_tramp ());
9012 (define_insn "*return_i"
9014 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9015 && (crtl->args.info.call_cookie
9016 & CALL_COOKIE_RET_TRAMP (1)))
9018 && lookup_attribute (\"trap_exit\",
9019 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9022 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9023 && !current_function_interrupt)
9028 [(set_attr "type" "return")
9029 (set_attr "needs_delay_slot" "yes")])
9031 ;; trapa has no delay slot.
9032 (define_insn "*return_trapa"
9034 "TARGET_SH1 && !TARGET_SHCOMPACT
9035 && reload_completed"
9037 [(set_attr "type" "return")])
9039 (define_expand "shcompact_return_tramp"
9042 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9045 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9047 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9048 emit_jump_insn (gen_shcompact_return_tramp_i ());
9052 (define_insn "shcompact_return_tramp_i"
9053 [(parallel [(return) (use (reg:SI R0_REG))])]
9055 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9057 [(set_attr "type" "jump_ind")
9058 (set_attr "needs_delay_slot" "yes")])
9060 (define_insn "return_media_i"
9061 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9062 "TARGET_SHMEDIA && reload_completed"
9064 [(set_attr "type" "jump_media")])
9066 (define_insn "return_media_rte"
9068 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9070 [(set_attr "type" "jump_media")])
9072 (define_expand "return_media"
9074 "TARGET_SHMEDIA && reload_completed"
9077 int tr_regno = sh_media_register_for_return ();
9080 if (current_function_interrupt)
9082 emit_jump_insn (gen_return_media_rte ());
9087 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9089 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9091 tr = gen_rtx_REG (Pmode, tr_regno);
9092 emit_move_insn (tr, r18);
9095 tr = gen_rtx_REG (Pmode, tr_regno);
9097 emit_jump_insn (gen_return_media_i (tr));
9101 (define_insn "shcompact_preserve_incoming_args"
9102 [(set (match_operand:SI 0 "register_operand" "+r")
9103 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9106 [(set_attr "length" "0")])
9108 (define_insn "shcompact_incoming_args"
9109 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9110 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9111 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9112 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9113 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9114 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9115 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9116 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9117 (set (mem:BLK (reg:SI MACL_REG))
9118 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9119 (use (reg:SI R0_REG))
9120 (clobber (reg:SI R0_REG))
9121 (clobber (reg:SI MACL_REG))
9122 (clobber (reg:SI MACH_REG))
9123 (clobber (reg:SI PR_REG))]
9126 [(set_attr "needs_delay_slot" "yes")])
9128 (define_insn "shmedia_save_restore_regs_compact"
9129 [(set (reg:SI SP_REG)
9130 (plus:SI (reg:SI SP_REG)
9131 (match_operand:SI 0 "immediate_operand" "i")))
9132 (use (reg:SI R0_REG))
9133 (clobber (reg:SI PR_REG))]
9135 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9136 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9138 [(set_attr "needs_delay_slot" "yes")])
9140 (define_expand "prologue"
9143 "sh_expand_prologue (); DONE;")
9145 (define_expand "epilogue"
9150 sh_expand_epilogue (0);
9151 emit_jump_insn (gen_return ());
9155 (define_expand "eh_return"
9156 [(use (match_operand 0 "register_operand" ""))]
9159 rtx ra = operands[0];
9161 if (TARGET_SHMEDIA64)
9162 emit_insn (gen_eh_set_ra_di (ra));
9164 emit_insn (gen_eh_set_ra_si (ra));
9169 ;; Clobber the return address on the stack. We can't expand this
9170 ;; until we know where it will be put in the stack frame.
9172 (define_insn "eh_set_ra_si"
9173 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9175 (clobber (match_scratch:SI 1 "=&r"))]
9176 "! TARGET_SHMEDIA64"
9179 (define_insn "eh_set_ra_di"
9180 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9182 (clobber (match_scratch:DI 1 "=&r"))]
9187 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9189 (clobber (match_scratch 1 ""))]
9194 sh_set_return_address (operands[0], operands[1]);
9198 (define_insn "blockage"
9199 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9202 [(set_attr "length" "0")])
9204 ;; ------------------------------------------------------------------------
9206 ;; ------------------------------------------------------------------------
9209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9210 (eq:SI (reg:SI T_REG) (const_int 1)))]
9213 [(set_attr "type" "arith")])
9215 (define_expand "cstore4_media"
9216 [(set (match_operand:SI 0 "register_operand" "=r")
9217 (match_operator:SI 1 "sh_float_comparison_operator"
9218 [(match_operand 2 "logical_operand" "")
9219 (match_operand 3 "cmp_operand" "")]))]
9223 enum machine_mode mode = GET_MODE (operands[2]);
9224 enum rtx_code code = GET_CODE (operands[1]);
9226 if (mode == VOIDmode)
9227 mode = GET_MODE (operands[3]);
9228 if (operands[2] == const0_rtx)
9230 if (code == EQ || code == NE)
9231 operands[2] = operands[3], operands[3] = const0_rtx;
9234 operands[2] = force_reg (mode, operands[2]);
9235 if (operands[3] != const0_rtx)
9236 operands[3] = force_reg (mode, operands[3]);
9242 swap = invert = !FLOAT_MODE_P (mode);
9247 swap = FLOAT_MODE_P (mode), invert = !swap;
9252 swap = true, invert = false;
9259 swap = invert = false;
9263 swap = invert = true;
9272 rtx tem = operands[2];
9273 operands[2] = operands[3];
9275 code = swap_condition (code);
9280 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9281 code = reverse_condition (code);
9282 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9283 emit_insn (gen_cstore4_media (tem, operands[1],
9284 operands[2], operands[3]));
9287 operands[3] = const0_rtx;
9290 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9293 (define_expand "cstoresi4"
9294 [(set (match_operand:SI 0 "register_operand" "=r")
9295 (match_operator:SI 1 "comparison_operator"
9296 [(match_operand:SI 2 "cmpsi_operand" "")
9297 (match_operand:SI 3 "arith_operand" "")]))]
9298 "TARGET_SH1 || TARGET_SHMEDIA"
9299 "if (TARGET_SHMEDIA)
9301 emit_insn (gen_cstore4_media (operands[0], operands[1],
9302 operands[2], operands[3]));
9306 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9307 && sh_expand_t_scc (operands))
9310 if (! currently_expanding_to_rtl)
9313 sh_emit_compare_and_set (operands, SImode);
9317 (define_expand "cstoredi4"
9318 [(set (match_operand:SI 0 "register_operand" "=r")
9319 (match_operator:SI 1 "comparison_operator"
9320 [(match_operand:DI 2 "arith_operand" "")
9321 (match_operand:DI 3 "arith_operand" "")]))]
9322 "TARGET_SH2 || TARGET_SHMEDIA"
9323 "if (TARGET_SHMEDIA)
9325 emit_insn (gen_cstore4_media (operands[0], operands[1],
9326 operands[2], operands[3]));
9330 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9331 && sh_expand_t_scc (operands))
9334 if (! currently_expanding_to_rtl)
9337 sh_emit_compare_and_set (operands, DImode);
9343 ;; sne moves the complement of the T reg to DEST like this:
9347 ;; This is better than xoring compare result with 1 because it does
9348 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9351 (define_expand "movnegt"
9352 [(set (match_dup 1) (const_int -1))
9353 (parallel [(set (match_operand:SI 0 "" "")
9354 (neg:SI (plus:SI (reg:SI T_REG)
9357 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9362 operands[1] = gen_reg_rtx (SImode);
9366 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9367 ;; This prevents a regression that occurred when we switched from xor to
9371 [(set (match_operand:SI 0 "arith_reg_dest" "")
9372 (plus:SI (reg:SI T_REG)
9375 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9376 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9379 (define_expand "cstoresf4"
9380 [(set (match_operand:SI 0 "register_operand" "=r")
9381 (match_operator:SI 1 "sh_float_comparison_operator"
9382 [(match_operand:SF 2 "arith_operand" "")
9383 (match_operand:SF 3 "arith_operand" "")]))]
9384 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9385 "if (TARGET_SHMEDIA)
9387 emit_insn (gen_cstore4_media (operands[0], operands[1],
9388 operands[2], operands[3]));
9392 if (! currently_expanding_to_rtl)
9395 sh_emit_compare_and_set (operands, SFmode);
9399 (define_expand "cstoredf4"
9400 [(set (match_operand:SI 0 "register_operand" "=r")
9401 (match_operator:SI 1 "sh_float_comparison_operator"
9402 [(match_operand:DF 2 "arith_operand" "")
9403 (match_operand:DF 3 "arith_operand" "")]))]
9404 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9405 "if (TARGET_SHMEDIA)
9407 emit_insn (gen_cstore4_media (operands[0], operands[1],
9408 operands[2], operands[3]));
9412 if (! currently_expanding_to_rtl)
9415 sh_emit_compare_and_set (operands, DFmode);
9420 ;; -------------------------------------------------------------------------
9421 ;; Instructions to cope with inline literal tables
9422 ;; -------------------------------------------------------------------------
9424 ; 2 byte integer in line
9426 (define_insn "consttable_2"
9427 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9428 (match_operand 1 "" "")]
9433 if (operands[1] != const0_rtx)
9434 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9437 [(set_attr "length" "2")
9438 (set_attr "in_delay_slot" "no")])
9440 ; 4 byte integer in line
9442 (define_insn "consttable_4"
9443 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9444 (match_operand 1 "" "")]
9449 if (operands[1] != const0_rtx)
9451 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9452 mark_symbol_refs_as_used (operands[0]);
9456 [(set_attr "length" "4")
9457 (set_attr "in_delay_slot" "no")])
9459 ; 8 byte integer in line
9461 (define_insn "consttable_8"
9462 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9463 (match_operand 1 "" "")]
9468 if (operands[1] != const0_rtx)
9469 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9472 [(set_attr "length" "8")
9473 (set_attr "in_delay_slot" "no")])
9475 ; 4 byte floating point
9477 (define_insn "consttable_sf"
9478 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9479 (match_operand 1 "" "")]
9484 if (operands[1] != const0_rtx)
9487 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9488 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9492 [(set_attr "length" "4")
9493 (set_attr "in_delay_slot" "no")])
9495 ; 8 byte floating point
9497 (define_insn "consttable_df"
9498 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9499 (match_operand 1 "" "")]
9504 if (operands[1] != const0_rtx)
9507 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9508 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9512 [(set_attr "length" "8")
9513 (set_attr "in_delay_slot" "no")])
9515 ;; Alignment is needed for some constant tables; it may also be added for
9516 ;; Instructions at the start of loops, or after unconditional branches.
9517 ;; ??? We would get more accurate lengths if we did instruction
9518 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9519 ;; here is too conservative.
9521 ; align to a two byte boundary
9523 (define_expand "align_2"
9524 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9528 ; align to a four byte boundary
9529 ;; align_4 and align_log are instructions for the starts of loops, or
9530 ;; after unconditional branches, which may take up extra room.
9532 (define_expand "align_4"
9533 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9537 ; align to a cache line boundary
9539 (define_insn "align_log"
9540 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9543 [(set_attr "length" "0")
9544 (set_attr "in_delay_slot" "no")])
9546 ; emitted at the end of the literal table, used to emit the
9547 ; 32bit branch labels if needed.
9549 (define_insn "consttable_end"
9550 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9552 "* return output_jump_label_table ();"
9553 [(set_attr "in_delay_slot" "no")])
9555 ; emitted at the end of the window in the literal table.
9557 (define_insn "consttable_window_end"
9558 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9561 [(set_attr "length" "0")
9562 (set_attr "in_delay_slot" "no")])
9564 ;; -------------------------------------------------------------------------
9566 ;; -------------------------------------------------------------------------
9568 ;; String/block move insn.
9570 (define_expand "movmemsi"
9571 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9572 (mem:BLK (match_operand:BLK 1 "" "")))
9573 (use (match_operand:SI 2 "nonmemory_operand" ""))
9574 (use (match_operand:SI 3 "immediate_operand" ""))
9575 (clobber (reg:SI PR_REG))
9576 (clobber (reg:SI R4_REG))
9577 (clobber (reg:SI R5_REG))
9578 (clobber (reg:SI R0_REG))])]
9579 "TARGET_SH1 && ! TARGET_SH5"
9582 if(expand_block_move (operands))
9587 (define_insn "block_move_real"
9588 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9589 (mem:BLK (reg:SI R5_REG)))
9590 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9591 (clobber (reg:SI PR_REG))
9592 (clobber (reg:SI R0_REG))])]
9593 "TARGET_SH1 && ! TARGET_HARD_SH4"
9595 [(set_attr "type" "sfunc")
9596 (set_attr "needs_delay_slot" "yes")])
9598 (define_insn "block_lump_real"
9599 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9600 (mem:BLK (reg:SI R5_REG)))
9601 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9602 (use (reg:SI R6_REG))
9603 (clobber (reg:SI PR_REG))
9604 (clobber (reg:SI T_REG))
9605 (clobber (reg:SI R4_REG))
9606 (clobber (reg:SI R5_REG))
9607 (clobber (reg:SI R6_REG))
9608 (clobber (reg:SI R0_REG))])]
9609 "TARGET_SH1 && ! TARGET_HARD_SH4"
9611 [(set_attr "type" "sfunc")
9612 (set_attr "needs_delay_slot" "yes")])
9614 (define_insn "block_move_real_i4"
9615 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9616 (mem:BLK (reg:SI R5_REG)))
9617 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9618 (clobber (reg:SI PR_REG))
9619 (clobber (reg:SI R0_REG))
9620 (clobber (reg:SI R1_REG))
9621 (clobber (reg:SI R2_REG))])]
9624 [(set_attr "type" "sfunc")
9625 (set_attr "needs_delay_slot" "yes")])
9627 (define_insn "block_lump_real_i4"
9628 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9629 (mem:BLK (reg:SI R5_REG)))
9630 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9631 (use (reg:SI R6_REG))
9632 (clobber (reg:SI PR_REG))
9633 (clobber (reg:SI T_REG))
9634 (clobber (reg:SI R4_REG))
9635 (clobber (reg:SI R5_REG))
9636 (clobber (reg:SI R6_REG))
9637 (clobber (reg:SI R0_REG))
9638 (clobber (reg:SI R1_REG))
9639 (clobber (reg:SI R2_REG))
9640 (clobber (reg:SI R3_REG))])]
9643 [(set_attr "type" "sfunc")
9644 (set_attr "needs_delay_slot" "yes")])
9646 ;; -------------------------------------------------------------------------
9647 ;; Floating point instructions.
9648 ;; -------------------------------------------------------------------------
9650 ;; ??? All patterns should have a type attribute.
9652 (define_expand "movpsi"
9653 [(set (match_operand:PSI 0 "register_operand" "")
9654 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9655 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9658 ;; The c / m alternative is a fake to guide reload to load directly into
9659 ;; fpscr, since reload doesn't know how to use post-increment.
9660 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9661 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9662 ;; predicate after reload.
9663 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9664 ;; like a mac -> gpr move.
9665 (define_insn "fpu_switch"
9666 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9667 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9669 && (! reload_completed
9670 || true_regnum (operands[0]) != FPSCR_REG
9671 || !MEM_P (operands[1])
9672 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9674 ! precision stays the same
9683 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9684 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9687 [(set (reg:PSI FPSCR_REG)
9688 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9689 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9692 rtx fpscr, mem, new_insn;
9694 fpscr = SET_DEST (PATTERN (curr_insn));
9695 mem = SET_SRC (PATTERN (curr_insn));
9696 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9698 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9699 add_reg_note (new_insn, REG_INC, operands[0]);
9704 [(set (reg:PSI FPSCR_REG)
9705 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9706 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9707 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9710 rtx fpscr, mem, new_insn;
9712 fpscr = SET_DEST (PATTERN (curr_insn));
9713 mem = SET_SRC (PATTERN (curr_insn));
9714 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9716 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9717 add_reg_note (new_insn, REG_INC, operands[0]);
9719 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9720 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9724 ;; ??? This uses the fp unit, but has no type indicating that.
9725 ;; If we did that, this would either give a bogus latency or introduce
9726 ;; a bogus FIFO constraint.
9727 ;; Since this insn is currently only used for prologues/epilogues,
9728 ;; it is probably best to claim no function unit, which matches the
9730 (define_insn "toggle_sz"
9731 [(set (reg:PSI FPSCR_REG)
9732 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9733 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9735 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9737 ;; There's no way we can use it today, since optimize mode switching
9738 ;; doesn't enable us to know from which mode we're switching to the
9739 ;; mode it requests, to tell whether we can use a relative mode switch
9740 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9742 (define_insn "toggle_pr"
9743 [(set (reg:PSI FPSCR_REG)
9744 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9745 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9747 [(set_attr "type" "fpscr_toggle")])
9749 (define_expand "addsf3"
9750 [(set (match_operand:SF 0 "arith_reg_operand" "")
9751 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9752 (match_operand:SF 2 "arith_reg_operand" "")))]
9753 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9758 expand_sf_binop (&gen_addsf3_i, operands);
9763 (define_insn "*addsf3_media"
9764 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9765 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9766 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9767 "TARGET_SHMEDIA_FPU"
9769 [(set_attr "type" "fparith_media")])
9771 (define_insn_and_split "unary_sf_op"
9772 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9777 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9778 (match_operator:SF 2 "unary_float_operator"
9779 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9780 (parallel [(match_operand 4
9781 "const_int_operand" "n")]))]))
9782 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9783 "TARGET_SHMEDIA_FPU"
9785 "TARGET_SHMEDIA_FPU && reload_completed"
9786 [(set (match_dup 5) (match_dup 6))]
9789 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9790 rtx op1 = gen_rtx_REG (SFmode,
9791 (true_regnum (operands[1])
9792 + (INTVAL (operands[4]) ^ endian)));
9794 operands[7] = gen_rtx_REG (SFmode,
9795 (true_regnum (operands[0])
9796 + (INTVAL (operands[3]) ^ endian)));
9797 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9799 [(set_attr "type" "fparith_media")])
9801 (define_insn_and_split "binary_sf_op0"
9802 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9804 (match_operator:SF 3 "binary_float_operator"
9805 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9806 (parallel [(const_int 0)]))
9807 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9808 (parallel [(const_int 0)]))])
9811 (parallel [(const_int 1)]))))]
9812 "TARGET_SHMEDIA_FPU"
9814 "&& reload_completed"
9815 [(set (match_dup 4) (match_dup 5))]
9818 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9819 rtx op1 = gen_rtx_REG (SFmode,
9820 true_regnum (operands[1]) + endian);
9821 rtx op2 = gen_rtx_REG (SFmode,
9822 true_regnum (operands[2]) + endian);
9824 operands[4] = gen_rtx_REG (SFmode,
9825 true_regnum (operands[0]) + endian);
9826 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9828 [(set_attr "type" "fparith_media")])
9830 (define_insn_and_split "binary_sf_op1"
9831 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9835 (parallel [(const_int 0)]))
9836 (match_operator:SF 3 "binary_float_operator"
9837 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9838 (parallel [(const_int 1)]))
9839 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9840 (parallel [(const_int 1)]))])))]
9841 "TARGET_SHMEDIA_FPU"
9843 "&& reload_completed"
9844 [(set (match_dup 4) (match_dup 5))]
9847 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9848 rtx op1 = gen_rtx_REG (SFmode,
9849 true_regnum (operands[1]) + (1 ^ endian));
9850 rtx op2 = gen_rtx_REG (SFmode,
9851 true_regnum (operands[2]) + (1 ^ endian));
9853 operands[4] = gen_rtx_REG (SFmode,
9854 true_regnum (operands[0]) + (1 ^ endian));
9855 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9857 [(set_attr "type" "fparith_media")])
9859 (define_insn "addsf3_i"
9860 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9861 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9862 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9863 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9866 [(set_attr "type" "fp")
9867 (set_attr "fp_mode" "single")])
9869 (define_expand "subsf3"
9870 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9871 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9872 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9873 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9878 expand_sf_binop (&gen_subsf3_i, operands);
9883 (define_insn "*subsf3_media"
9884 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9885 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9886 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9887 "TARGET_SHMEDIA_FPU"
9889 [(set_attr "type" "fparith_media")])
9891 (define_insn "subsf3_i"
9892 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9893 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9894 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9895 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9898 [(set_attr "type" "fp")
9899 (set_attr "fp_mode" "single")])
9901 (define_expand "mulsf3"
9902 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9903 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9904 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9905 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9908 (define_insn "*mulsf3_media"
9909 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9910 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9911 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9912 "TARGET_SHMEDIA_FPU"
9914 [(set_attr "type" "fparith_media")])
9916 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9917 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9918 ;; we start out with a mulsf pattern that does not depend on fpscr.
9919 ;; This is split after combine to introduce the dependency, in order to
9920 ;; get mode switching and scheduling right.
9921 (define_insn_and_split "mulsf3_ie"
9922 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9923 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9924 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9927 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9931 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9935 [(set_attr "type" "fp")])
9937 (define_insn "mulsf3_i4"
9938 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9939 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9940 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9941 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9944 [(set_attr "type" "fp")
9945 (set_attr "fp_mode" "single")])
9947 (define_insn "mac_media"
9948 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9949 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9950 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9951 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9952 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9954 [(set_attr "type" "fparith_media")])
9956 (define_insn "*macsf3"
9957 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9959 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9960 (match_operand:SF 3 "arith_reg_operand" "0")))
9961 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9962 "TARGET_SH2E && TARGET_FMAC"
9964 [(set_attr "type" "fp")
9965 (set_attr "fp_mode" "single")])
9967 (define_expand "divsf3"
9968 [(set (match_operand:SF 0 "arith_reg_operand" "")
9969 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9970 (match_operand:SF 2 "arith_reg_operand" "")))]
9971 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9976 expand_sf_binop (&gen_divsf3_i, operands);
9981 (define_insn "*divsf3_media"
9982 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9983 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9984 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9985 "TARGET_SHMEDIA_FPU"
9987 [(set_attr "type" "fdiv_media")])
9989 (define_insn "divsf3_i"
9990 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
9991 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
9992 (match_operand:SF 2 "arith_reg_operand" "f")))
9993 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9996 [(set_attr "type" "fdiv")
9997 (set_attr "fp_mode" "single")])
9999 (define_insn "floatdisf2"
10000 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10001 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10002 "TARGET_SHMEDIA_FPU"
10004 [(set_attr "type" "fpconv_media")])
10006 (define_expand "floatsisf2"
10007 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10008 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10009 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10012 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10014 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10019 (define_insn "*floatsisf2_media"
10020 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10021 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10022 "TARGET_SHMEDIA_FPU"
10024 [(set_attr "type" "fpconv_media")])
10026 (define_insn "floatsisf2_i4"
10027 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10028 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10029 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10030 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10032 [(set_attr "type" "fp")
10033 (set_attr "fp_mode" "single")])
10035 (define_insn "*floatsisf2_ie"
10036 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10037 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10038 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10040 [(set_attr "type" "fp")])
10042 (define_insn "fix_truncsfdi2"
10043 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10044 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10045 "TARGET_SHMEDIA_FPU"
10047 [(set_attr "type" "fpconv_media")])
10049 (define_expand "fix_truncsfsi2"
10050 [(set (match_operand:SI 0 "fpul_operand" "=y")
10051 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10052 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10055 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10057 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10062 (define_insn "*fix_truncsfsi2_media"
10063 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10064 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10065 "TARGET_SHMEDIA_FPU"
10067 [(set_attr "type" "fpconv_media")])
10069 (define_insn "fix_truncsfsi2_i4"
10070 [(set (match_operand:SI 0 "fpul_operand" "=y")
10071 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10072 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10073 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10075 [(set_attr "type" "ftrc_s")
10076 (set_attr "fp_mode" "single")])
10078 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10079 ;; fix_truncsfsi2_i4.
10080 ;; (define_insn "fix_truncsfsi2_i4_2"
10081 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10082 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10083 ;; (use (reg:PSI FPSCR_REG))
10084 ;; (clobber (reg:SI FPUL_REG))]
10087 ;; [(set_attr "length" "4")
10088 ;; (set_attr "fp_mode" "single")])
10091 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10092 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10093 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10094 ;; (clobber (reg:SI FPUL_REG))]
10096 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10097 ;; (use (match_dup 2))])
10098 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10100 (define_insn "*fixsfsi"
10101 [(set (match_operand:SI 0 "fpul_operand" "=y")
10102 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10103 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10105 [(set_attr "type" "fp")])
10107 (define_insn "cmpgtsf_t"
10108 [(set (reg:SI T_REG)
10109 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10110 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10111 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10113 [(set_attr "type" "fp_cmp")
10114 (set_attr "fp_mode" "single")])
10116 (define_insn "cmpeqsf_t"
10117 [(set (reg:SI T_REG)
10118 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10119 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10120 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10122 [(set_attr "type" "fp_cmp")
10123 (set_attr "fp_mode" "single")])
10125 (define_insn "ieee_ccmpeqsf_t"
10126 [(set (reg:SI T_REG)
10127 (ior:SI (reg:SI T_REG)
10128 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10129 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10130 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10131 "* return output_ieee_ccmpeq (insn, operands);"
10132 [(set_attr "length" "4")])
10135 (define_insn "cmpgtsf_t_i4"
10136 [(set (reg:SI T_REG)
10137 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10138 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10139 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10140 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10142 [(set_attr "type" "fp_cmp")
10143 (set_attr "fp_mode" "single")])
10145 (define_insn "cmpeqsf_t_i4"
10146 [(set (reg:SI T_REG)
10147 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10148 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10149 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10150 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10152 [(set_attr "type" "fp_cmp")
10153 (set_attr "fp_mode" "single")])
10155 (define_insn "*ieee_ccmpeqsf_t_4"
10156 [(set (reg:SI T_REG)
10157 (ior:SI (reg:SI T_REG)
10158 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10159 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10160 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10161 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10162 "* return output_ieee_ccmpeq (insn, operands);"
10163 [(set_attr "length" "4")
10164 (set_attr "fp_mode" "single")])
10166 (define_insn "cmpeqsf_media"
10167 [(set (match_operand:SI 0 "register_operand" "=r")
10168 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10169 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10170 "TARGET_SHMEDIA_FPU"
10171 "fcmpeq.s %1, %2, %0"
10172 [(set_attr "type" "fcmp_media")])
10174 (define_insn "cmpgtsf_media"
10175 [(set (match_operand:SI 0 "register_operand" "=r")
10176 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10177 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10178 "TARGET_SHMEDIA_FPU"
10179 "fcmpgt.s %1, %2, %0"
10180 [(set_attr "type" "fcmp_media")])
10182 (define_insn "cmpgesf_media"
10183 [(set (match_operand:SI 0 "register_operand" "=r")
10184 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10185 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10186 "TARGET_SHMEDIA_FPU"
10187 "fcmpge.s %1, %2, %0"
10188 [(set_attr "type" "fcmp_media")])
10190 (define_insn "cmpunsf_media"
10191 [(set (match_operand:SI 0 "register_operand" "=r")
10192 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10193 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10194 "TARGET_SHMEDIA_FPU"
10195 "fcmpun.s %1, %2, %0"
10196 [(set_attr "type" "fcmp_media")])
10198 (define_expand "cbranchsf4"
10200 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10201 [(match_operand:SF 1 "arith_operand" "")
10202 (match_operand:SF 2 "arith_operand" "")])
10203 (match_operand 3 "" "")
10205 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10208 if (TARGET_SHMEDIA)
10209 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10212 sh_emit_compare_and_branch (operands, SFmode);
10216 (define_expand "negsf2"
10217 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10218 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10219 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10224 expand_sf_unop (&gen_negsf2_i, operands);
10229 (define_insn "*negsf2_media"
10230 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10231 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10232 "TARGET_SHMEDIA_FPU"
10234 [(set_attr "type" "fmove_media")])
10236 (define_insn "negsf2_i"
10237 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10238 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10239 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10242 [(set_attr "type" "fmove")
10243 (set_attr "fp_mode" "single")])
10245 (define_expand "sqrtsf2"
10246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10247 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10248 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10253 expand_sf_unop (&gen_sqrtsf2_i, operands);
10258 (define_insn "*sqrtsf2_media"
10259 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10260 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10261 "TARGET_SHMEDIA_FPU"
10263 [(set_attr "type" "fdiv_media")])
10265 (define_insn "sqrtsf2_i"
10266 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10267 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10268 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10271 [(set_attr "type" "fdiv")
10272 (set_attr "fp_mode" "single")])
10274 (define_insn "rsqrtsf2"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10277 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10278 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10279 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10280 && operands[1] == CONST1_RTX (SFmode)"
10282 [(set_attr "type" "fsrra")
10283 (set_attr "fp_mode" "single")])
10285 (define_insn "fsca"
10286 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10288 (unspec:SF [(mult:SF
10289 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10290 (match_operand:SF 2 "immediate_operand" "i"))
10292 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10294 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10295 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10296 && operands[2] == sh_fsca_int2sf ()"
10298 [(set_attr "type" "fsca")
10299 (set_attr "fp_mode" "single")])
10301 (define_expand "sinsf2"
10302 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10303 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10305 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10308 rtx scaled = gen_reg_rtx (SFmode);
10309 rtx truncated = gen_reg_rtx (SImode);
10310 rtx fsca = gen_reg_rtx (V2SFmode);
10311 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10313 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10314 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10315 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10316 get_fpscr_rtx ()));
10317 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10321 (define_expand "cossf2"
10322 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10323 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10325 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10328 rtx scaled = gen_reg_rtx (SFmode);
10329 rtx truncated = gen_reg_rtx (SImode);
10330 rtx fsca = gen_reg_rtx (V2SFmode);
10331 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10333 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10334 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10335 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10336 get_fpscr_rtx ()));
10337 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10341 (define_expand "sindf2"
10342 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10343 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10345 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10348 rtx scaled = gen_reg_rtx (DFmode);
10349 rtx truncated = gen_reg_rtx (SImode);
10350 rtx fsca = gen_reg_rtx (V2SFmode);
10351 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10352 rtx sfresult = gen_reg_rtx (SFmode);
10354 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10355 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10356 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10357 get_fpscr_rtx ()));
10358 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10359 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10363 (define_expand "cosdf2"
10364 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10365 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10367 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10370 rtx scaled = gen_reg_rtx (DFmode);
10371 rtx truncated = gen_reg_rtx (SImode);
10372 rtx fsca = gen_reg_rtx (V2SFmode);
10373 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10374 rtx sfresult = gen_reg_rtx (SFmode);
10376 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10377 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10378 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10379 get_fpscr_rtx ()));
10380 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10381 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10385 (define_expand "abssf2"
10386 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10387 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10388 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10393 expand_sf_unop (&gen_abssf2_i, operands);
10398 (define_insn "*abssf2_media"
10399 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10400 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10401 "TARGET_SHMEDIA_FPU"
10403 [(set_attr "type" "fmove_media")])
10405 (define_insn "abssf2_i"
10406 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10407 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10408 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10411 [(set_attr "type" "fmove")
10412 (set_attr "fp_mode" "single")])
10414 (define_expand "adddf3"
10415 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10416 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10417 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10418 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10421 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10423 expand_df_binop (&gen_adddf3_i, operands);
10428 (define_insn "*adddf3_media"
10429 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10430 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10431 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10432 "TARGET_SHMEDIA_FPU"
10433 "fadd.d %1, %2, %0"
10434 [(set_attr "type" "dfparith_media")])
10436 (define_insn "adddf3_i"
10437 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10438 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10439 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10440 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10441 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10443 [(set_attr "type" "dfp_arith")
10444 (set_attr "fp_mode" "double")])
10446 (define_expand "subdf3"
10447 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10448 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10449 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10450 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10453 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10455 expand_df_binop (&gen_subdf3_i, operands);
10460 (define_insn "*subdf3_media"
10461 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10462 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10463 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10464 "TARGET_SHMEDIA_FPU"
10465 "fsub.d %1, %2, %0"
10466 [(set_attr "type" "dfparith_media")])
10468 (define_insn "subdf3_i"
10469 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10470 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10471 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10472 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10473 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10475 [(set_attr "type" "dfp_arith")
10476 (set_attr "fp_mode" "double")])
10478 (define_expand "muldf3"
10479 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10480 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10481 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10482 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10485 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10487 expand_df_binop (&gen_muldf3_i, operands);
10492 (define_insn "*muldf3_media"
10493 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10494 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10495 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10496 "TARGET_SHMEDIA_FPU"
10497 "fmul.d %1, %2, %0"
10498 [(set_attr "type" "dfmul_media")])
10500 (define_insn "muldf3_i"
10501 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10502 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10503 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10504 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10505 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10507 [(set_attr "type" "dfp_mul")
10508 (set_attr "fp_mode" "double")])
10510 (define_expand "divdf3"
10511 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10512 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10513 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10514 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10517 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10519 expand_df_binop (&gen_divdf3_i, operands);
10524 (define_insn "*divdf3_media"
10525 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10526 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10527 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10528 "TARGET_SHMEDIA_FPU"
10529 "fdiv.d %1, %2, %0"
10530 [(set_attr "type" "dfdiv_media")])
10532 (define_insn "divdf3_i"
10533 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10534 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10535 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10536 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10537 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10539 [(set_attr "type" "dfdiv")
10540 (set_attr "fp_mode" "double")])
10542 (define_insn "floatdidf2"
10543 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10544 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10545 "TARGET_SHMEDIA_FPU"
10547 [(set_attr "type" "dfpconv_media")])
10549 (define_expand "floatsidf2"
10550 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10551 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10552 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10555 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10557 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10558 get_fpscr_rtx ()));
10563 (define_insn "*floatsidf2_media"
10564 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10565 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10566 "TARGET_SHMEDIA_FPU"
10568 [(set_attr "type" "dfpconv_media")])
10570 (define_insn "floatsidf2_i"
10571 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10572 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10573 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10574 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10576 [(set_attr "type" "dfp_conv")
10577 (set_attr "fp_mode" "double")])
10579 (define_insn "fix_truncdfdi2"
10580 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10581 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10582 "TARGET_SHMEDIA_FPU"
10584 [(set_attr "type" "dfpconv_media")])
10586 (define_expand "fix_truncdfsi2"
10587 [(set (match_operand:SI 0 "fpul_operand" "")
10588 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10589 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10592 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10594 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10595 get_fpscr_rtx ()));
10600 (define_insn "*fix_truncdfsi2_media"
10601 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10602 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10603 "TARGET_SHMEDIA_FPU"
10605 [(set_attr "type" "dfpconv_media")])
10607 (define_insn "fix_truncdfsi2_i"
10608 [(set (match_operand:SI 0 "fpul_operand" "=y")
10609 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10610 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10611 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10613 [(set_attr "type" "dfp_conv")
10614 (set_attr "dfp_comp" "no")
10615 (set_attr "fp_mode" "double")])
10617 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10618 ;; fix_truncdfsi2_i.
10619 ;; (define_insn "fix_truncdfsi2_i4"
10620 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10621 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10622 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10623 ;; (clobber (reg:SI FPUL_REG))]
10626 ;; [(set_attr "length" "4")
10627 ;; (set_attr "fp_mode" "double")])
10630 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10631 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10632 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10633 ;; (clobber (reg:SI FPUL_REG))]
10635 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10636 ;; (use (match_dup 2))])
10637 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10639 (define_insn "cmpgtdf_t"
10640 [(set (reg:SI T_REG)
10641 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10642 (match_operand:DF 1 "arith_reg_operand" "f")))
10643 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10644 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10646 [(set_attr "type" "dfp_cmp")
10647 (set_attr "fp_mode" "double")])
10649 (define_insn "cmpeqdf_t"
10650 [(set (reg:SI T_REG)
10651 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10652 (match_operand:DF 1 "arith_reg_operand" "f")))
10653 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10654 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10656 [(set_attr "type" "dfp_cmp")
10657 (set_attr "fp_mode" "double")])
10659 (define_insn "*ieee_ccmpeqdf_t"
10660 [(set (reg:SI T_REG)
10661 (ior:SI (reg:SI T_REG)
10662 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10663 (match_operand:DF 1 "arith_reg_operand" "f"))))
10664 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10665 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10666 "* return output_ieee_ccmpeq (insn, operands);"
10667 [(set_attr "length" "4")
10668 (set_attr "fp_mode" "double")])
10670 (define_insn "cmpeqdf_media"
10671 [(set (match_operand:SI 0 "register_operand" "=r")
10672 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10673 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10674 "TARGET_SHMEDIA_FPU"
10675 "fcmpeq.d %1,%2,%0"
10676 [(set_attr "type" "fcmp_media")])
10678 (define_insn "cmpgtdf_media"
10679 [(set (match_operand:SI 0 "register_operand" "=r")
10680 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10681 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10682 "TARGET_SHMEDIA_FPU"
10683 "fcmpgt.d %1,%2,%0"
10684 [(set_attr "type" "fcmp_media")])
10686 (define_insn "cmpgedf_media"
10687 [(set (match_operand:SI 0 "register_operand" "=r")
10688 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10689 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10690 "TARGET_SHMEDIA_FPU"
10691 "fcmpge.d %1,%2,%0"
10692 [(set_attr "type" "fcmp_media")])
10694 (define_insn "cmpundf_media"
10695 [(set (match_operand:SI 0 "register_operand" "=r")
10696 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10697 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10698 "TARGET_SHMEDIA_FPU"
10699 "fcmpun.d %1,%2,%0"
10700 [(set_attr "type" "fcmp_media")])
10702 (define_expand "cbranchdf4"
10704 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10705 [(match_operand:DF 1 "arith_operand" "")
10706 (match_operand:DF 2 "arith_operand" "")])
10707 (match_operand 3 "" "")
10709 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10712 if (TARGET_SHMEDIA)
10713 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10716 sh_emit_compare_and_branch (operands, DFmode);
10721 (define_expand "negdf2"
10722 [(set (match_operand:DF 0 "arith_reg_operand" "")
10723 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10724 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10727 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10729 expand_df_unop (&gen_negdf2_i, operands);
10734 (define_insn "*negdf2_media"
10735 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10736 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10737 "TARGET_SHMEDIA_FPU"
10739 [(set_attr "type" "fmove_media")])
10741 (define_insn "negdf2_i"
10742 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10743 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10744 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10745 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10747 [(set_attr "type" "fmove")
10748 (set_attr "fp_mode" "double")])
10750 (define_expand "sqrtdf2"
10751 [(set (match_operand:DF 0 "arith_reg_operand" "")
10752 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10753 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10756 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10758 expand_df_unop (&gen_sqrtdf2_i, operands);
10763 (define_insn "*sqrtdf2_media"
10764 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10765 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10766 "TARGET_SHMEDIA_FPU"
10768 [(set_attr "type" "dfdiv_media")])
10770 (define_insn "sqrtdf2_i"
10771 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10772 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10773 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10774 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10776 [(set_attr "type" "dfdiv")
10777 (set_attr "fp_mode" "double")])
10779 (define_expand "absdf2"
10780 [(set (match_operand:DF 0 "arith_reg_operand" "")
10781 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10782 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10785 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10787 expand_df_unop (&gen_absdf2_i, operands);
10792 (define_insn "*absdf2_media"
10793 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10794 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10795 "TARGET_SHMEDIA_FPU"
10797 [(set_attr "type" "fmove_media")])
10799 (define_insn "absdf2_i"
10800 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10801 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10802 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10803 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10805 [(set_attr "type" "fmove")
10806 (set_attr "fp_mode" "double")])
10808 (define_expand "extendsfdf2"
10809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10810 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10811 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10814 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10816 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10817 get_fpscr_rtx ()));
10822 (define_insn "*extendsfdf2_media"
10823 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10824 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10825 "TARGET_SHMEDIA_FPU"
10827 [(set_attr "type" "dfpconv_media")])
10829 (define_insn "extendsfdf2_i4"
10830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10831 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10832 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10833 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10835 [(set_attr "type" "fp")
10836 (set_attr "fp_mode" "double")])
10838 (define_expand "truncdfsf2"
10839 [(set (match_operand:SF 0 "fpul_operand" "")
10840 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10841 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10844 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10846 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10847 get_fpscr_rtx ()));
10852 (define_insn "*truncdfsf2_media"
10853 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10854 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10855 "TARGET_SHMEDIA_FPU"
10857 [(set_attr "type" "dfpconv_media")])
10859 (define_insn "truncdfsf2_i4"
10860 [(set (match_operand:SF 0 "fpul_operand" "=y")
10861 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10862 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10863 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10865 [(set_attr "type" "fp")
10866 (set_attr "fp_mode" "double")])
10868 ;; Bit field extract patterns. These give better code for packed bitfields,
10869 ;; because they allow auto-increment addresses to be generated.
10871 (define_expand "insv"
10872 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10873 (match_operand:SI 1 "immediate_operand" "")
10874 (match_operand:SI 2 "immediate_operand" ""))
10875 (match_operand:SI 3 "general_operand" ""))]
10876 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10879 rtx addr_target, orig_address, shift_reg, qi_val;
10880 HOST_WIDE_INT bitsize, size, v = 0;
10881 rtx x = operands[3];
10883 if (TARGET_SH2A && TARGET_BITOPS
10884 && (satisfies_constraint_Sbw (operands[0])
10885 || satisfies_constraint_Sbv (operands[0]))
10886 && satisfies_constraint_M (operands[1])
10887 && satisfies_constraint_K03 (operands[2]))
10889 if (satisfies_constraint_N (operands[3]))
10891 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10894 else if (satisfies_constraint_M (operands[3]))
10896 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10899 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10900 && satisfies_constraint_M (operands[1]))
10902 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10905 else if (REG_P (operands[3])
10906 && satisfies_constraint_M (operands[1]))
10908 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10909 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10913 /* ??? expmed doesn't care for non-register predicates. */
10914 if (! memory_operand (operands[0], VOIDmode)
10915 || ! immediate_operand (operands[1], VOIDmode)
10916 || ! immediate_operand (operands[2], VOIDmode)
10917 || ! general_operand (x, VOIDmode))
10919 /* If this isn't a 16 / 24 / 32 bit field, or if
10920 it doesn't start on a byte boundary, then fail. */
10921 bitsize = INTVAL (operands[1]);
10922 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10923 || (INTVAL (operands[2]) % 8) != 0)
10926 size = bitsize / 8;
10927 orig_address = XEXP (operands[0], 0);
10928 shift_reg = gen_reg_rtx (SImode);
10929 if (CONST_INT_P (x))
10932 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10936 emit_insn (gen_movsi (shift_reg, operands[3]));
10937 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10939 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10941 operands[0] = replace_equiv_address (operands[0], addr_target);
10942 emit_insn (gen_movqi (operands[0], qi_val));
10946 if (CONST_INT_P (x))
10948 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10951 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10952 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10954 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10955 emit_insn (gen_movqi (operands[0], qi_val));
10961 (define_insn "movua"
10962 [(set (match_operand:SI 0 "register_operand" "=z")
10963 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10967 [(set_attr "type" "movua")])
10969 ;; We shouldn't need this, but cse replaces increments with references
10970 ;; to other regs before flow has a chance to create post_inc
10971 ;; addressing modes, and only postreload's cse_move2add brings the
10972 ;; increments back to a usable form.
10974 [(set (match_operand:SI 0 "register_operand" "")
10975 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10976 (const_int 32) (const_int 0)))
10977 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10978 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10979 [(set (match_operand:SI 0 "register_operand" "")
10980 (sign_extract:SI (mem:SI (post_inc:SI
10981 (match_operand:SI 1 "register_operand" "")))
10982 (const_int 32) (const_int 0)))]
10985 (define_expand "extv"
10986 [(set (match_operand:SI 0 "register_operand" "")
10987 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
10988 (match_operand 2 "const_int_operand" "")
10989 (match_operand 3 "const_int_operand" "")))]
10990 "TARGET_SH4A_ARCH || TARGET_SH2A"
10992 if (TARGET_SH2A && TARGET_BITOPS
10993 && (satisfies_constraint_Sbw (operands[1])
10994 || satisfies_constraint_Sbv (operands[1]))
10995 && satisfies_constraint_M (operands[2])
10996 && satisfies_constraint_K03 (operands[3]))
10998 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
10999 if (REGNO (operands[0]) != T_REG)
11000 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11003 if (TARGET_SH4A_ARCH
11004 && INTVAL (operands[2]) == 32
11005 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11006 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11008 rtx src = adjust_address (operands[1], BLKmode, 0);
11009 set_mem_size (src, GEN_INT (4));
11010 emit_insn (gen_movua (operands[0], src));
11017 (define_expand "extzv"
11018 [(set (match_operand:SI 0 "register_operand" "")
11019 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11020 (match_operand 2 "const_int_operand" "")
11021 (match_operand 3 "const_int_operand" "")))]
11022 "TARGET_SH4A_ARCH || TARGET_SH2A"
11024 if (TARGET_SH2A && TARGET_BITOPS
11025 && (satisfies_constraint_Sbw (operands[1])
11026 || satisfies_constraint_Sbv (operands[1]))
11027 && satisfies_constraint_M (operands[2])
11028 && satisfies_constraint_K03 (operands[3]))
11030 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11031 if (REGNO (operands[0]) != T_REG)
11032 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11035 if (TARGET_SH4A_ARCH
11036 && INTVAL (operands[2]) == 32
11037 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11038 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11040 rtx src = adjust_address (operands[1], BLKmode, 0);
11041 set_mem_size (src, GEN_INT (4));
11042 emit_insn (gen_movua (operands[0], src));
11049 ;; SH2A instructions for bitwise operations.
11051 ;; Clear a bit in a memory location.
11052 (define_insn "bclr_m2a"
11053 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11055 (not:QI (ashift:QI (const_int 1)
11056 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11058 "TARGET_SH2A && TARGET_BITOPS"
11061 bclr.b\\t%1,@(0,%t0)"
11062 [(set_attr "length" "4,4")])
11064 (define_insn "bclrmem_m2a"
11065 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11066 (and:QI (match_dup 0)
11067 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11068 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11071 bclr.b\\t%W1,@(0,%t0)"
11072 [(set_attr "length" "4,4")])
11074 ;; Set a bit in a memory location.
11075 (define_insn "bset_m2a"
11076 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11078 (ashift:QI (const_int 1)
11079 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11081 "TARGET_SH2A && TARGET_BITOPS"
11084 bset.b\\t%1,@(0,%t0)"
11085 [(set_attr "length" "4,4")])
11087 (define_insn "bsetmem_m2a"
11088 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11089 (ior:QI (match_dup 0)
11090 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11091 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11094 bset.b\\t%V1,@(0,%t0)"
11095 [(set_attr "length" "4,4")])
11097 ;;; Transfer the contents of the T bit to a specified bit of memory.
11098 (define_insn "bst_m2a"
11099 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11100 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11102 (not:QI (ashift:QI (const_int 1)
11103 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11106 (ashift:QI (const_int 1) (match_dup 1))
11108 "TARGET_SH2A && TARGET_BITOPS"
11111 bst.b\\t%1,@(0,%t0)"
11112 [(set_attr "length" "4")])
11114 ;; Store a specified bit of memory in the T bit.
11115 (define_insn "bld_m2a"
11116 [(set (reg:SI T_REG)
11118 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11120 (match_operand 1 "const_int_operand" "K03,K03")))]
11121 "TARGET_SH2A && TARGET_BITOPS"
11124 bld.b\\t%1,@(0,%t0)"
11125 [(set_attr "length" "4,4")])
11127 ;; Store a specified bit of memory in the T bit.
11128 (define_insn "bldsign_m2a"
11129 [(set (reg:SI T_REG)
11131 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11133 (match_operand 1 "const_int_operand" "K03,K03")))]
11134 "TARGET_SH2A && TARGET_BITOPS"
11137 bld.b\\t%1,@(0,%t0)"
11138 [(set_attr "length" "4,4")])
11140 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11141 (define_insn "bld_reg"
11142 [(set (reg:SI T_REG)
11143 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11145 (match_operand 1 "const_int_operand" "K03")))]
11149 (define_insn "*bld_regqi"
11150 [(set (reg:SI T_REG)
11151 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11153 (match_operand 1 "const_int_operand" "K03")))]
11157 ;; Take logical and of a specified bit of memory with the T bit and
11158 ;; store its result in the T bit.
11159 (define_insn "band_m2a"
11160 [(set (reg:SI T_REG)
11161 (and:SI (reg:SI T_REG)
11163 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11165 (match_operand 1 "const_int_operand" "K03,K03"))))]
11166 "TARGET_SH2A && TARGET_BITOPS"
11169 band.b\\t%1,@(0,%t0)"
11170 [(set_attr "length" "4,4")])
11172 (define_insn "bandreg_m2a"
11173 [(set (match_operand:SI 0 "register_operand" "=r,r")
11174 (and:SI (zero_extract:SI
11175 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11177 (match_operand 2 "const_int_operand" "K03,K03"))
11178 (match_operand:SI 3 "register_operand" "r,r")))]
11179 "TARGET_SH2A && TARGET_BITOPS"
11181 band.b\\t%2,%1\;movt\\t%0
11182 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11183 [(set_attr "length" "6,6")])
11185 ;; Take logical or of a specified bit of memory with the T bit and
11186 ;; store its result in the T bit.
11187 (define_insn "bor_m2a"
11188 [(set (reg:SI T_REG)
11189 (ior:SI (reg:SI T_REG)
11191 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11193 (match_operand 1 "const_int_operand" "K03,K03"))))]
11194 "TARGET_SH2A && TARGET_BITOPS"
11197 bor.b\\t%1,@(0,%t0)"
11198 [(set_attr "length" "4,4")])
11200 (define_insn "borreg_m2a"
11201 [(set (match_operand:SI 0 "register_operand" "=r,r")
11202 (ior:SI (zero_extract:SI
11203 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11205 (match_operand 2 "const_int_operand" "K03,K03"))
11206 (match_operand:SI 3 "register_operand" "=r,r")))]
11207 "TARGET_SH2A && TARGET_BITOPS"
11209 bor.b\\t%2,%1\;movt\\t%0
11210 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11211 [(set_attr "length" "6,6")])
11213 ;; Take exclusive or of a specified bit of memory with the T bit and
11214 ;; store its result in the T bit.
11215 (define_insn "bxor_m2a"
11216 [(set (reg:SI T_REG)
11217 (xor:SI (reg:SI T_REG)
11219 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11221 (match_operand 1 "const_int_operand" "K03,K03"))))]
11222 "TARGET_SH2A && TARGET_BITOPS"
11225 bxor.b\\t%1,@(0,%t0)"
11226 [(set_attr "length" "4,4")])
11228 (define_insn "bxorreg_m2a"
11229 [(set (match_operand:SI 0 "register_operand" "=r,r")
11230 (xor:SI (zero_extract:SI
11231 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11233 (match_operand 2 "const_int_operand" "K03,K03"))
11234 (match_operand:SI 3 "register_operand" "=r,r")))]
11235 "TARGET_SH2A && TARGET_BITOPS"
11237 bxor.b\\t%2,%1\;movt\\t%0
11238 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11239 [(set_attr "length" "6,6")])
11242 ;; -------------------------------------------------------------------------
11244 ;; -------------------------------------------------------------------------
11245 ;; This matches cases where the bit in a memory location is set.
11247 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11248 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11250 (ior:SI (match_dup 0)
11251 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11253 (match_operand 3 "arith_reg_operand" "r,r"))]
11254 "TARGET_SH2A && TARGET_BITOPS
11255 && satisfies_constraint_Pso (operands[2])
11256 && REGNO (operands[0]) == REGNO (operands[3])"
11257 [(set (match_dup 1)
11258 (ior:QI (match_dup 1)
11262 ;; This matches cases where the bit in a memory location is cleared.
11264 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11265 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11267 (and:SI (match_dup 0)
11268 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11270 (match_operand 3 "arith_reg_operand" "r,r"))]
11271 "TARGET_SH2A && TARGET_BITOPS
11272 && satisfies_constraint_Psz (operands[2])
11273 && REGNO (operands[0]) == REGNO (operands[3])"
11274 [(set (match_dup 1)
11275 (and:QI (match_dup 1)
11279 ;; This matches cases where a stack pointer increment at the start of the
11280 ;; epilogue combines with a stack slot read loading the return value.
11283 [(set (match_operand:SI 0 "arith_reg_operand" "")
11284 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11285 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11286 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11289 ;; See the comment on the dt combiner pattern above.
11292 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11293 (plus:SI (match_dup 0)
11295 (set (reg:SI T_REG)
11296 (eq:SI (match_dup 0)
11301 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11302 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11303 ;; reload when the constant is too large for a reg+offset address.
11305 ;; ??? We would get much better code if this was done in reload. This would
11306 ;; require modifying find_reloads_address to recognize that if the constant
11307 ;; is out-of-range for an immediate add, then we get better code by reloading
11308 ;; the constant into a register than by reloading the sum into a register,
11309 ;; since the former is one instruction shorter if the address does not need
11310 ;; to be offsettable. Unfortunately this does not work, because there is
11311 ;; only one register, r0, that can be used as an index register. This register
11312 ;; is also the function return value register. So, if we try to force reload
11313 ;; to use double-reg addresses, then we end up with some instructions that
11314 ;; need to use r0 twice. The only way to fix this is to change the calling
11315 ;; convention so that r0 is not used to return values.
11318 [(set (match_operand:SI 0 "register_operand" "=r")
11319 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11320 (set (mem:SI (match_dup 0))
11321 (match_operand:SI 2 "general_movsrc_operand" ""))]
11322 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11323 "mov.l %2,@(%0,%1)")
11326 [(set (match_operand:SI 0 "register_operand" "=r")
11327 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11328 (set (match_operand:SI 2 "general_movdst_operand" "")
11329 (mem:SI (match_dup 0)))]
11330 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11331 "mov.l @(%0,%1),%2")
11334 [(set (match_operand:SI 0 "register_operand" "=r")
11335 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11336 (set (mem:HI (match_dup 0))
11337 (match_operand:HI 2 "general_movsrc_operand" ""))]
11338 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11339 "mov.w %2,@(%0,%1)")
11342 [(set (match_operand:SI 0 "register_operand" "=r")
11343 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344 (set (match_operand:HI 2 "general_movdst_operand" "")
11345 (mem:HI (match_dup 0)))]
11346 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11347 "mov.w @(%0,%1),%2")
11350 [(set (match_operand:SI 0 "register_operand" "=r")
11351 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11352 (set (mem:QI (match_dup 0))
11353 (match_operand:QI 2 "general_movsrc_operand" ""))]
11354 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11355 "mov.b %2,@(%0,%1)")
11358 [(set (match_operand:SI 0 "register_operand" "=r")
11359 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11360 (set (match_operand:QI 2 "general_movdst_operand" "")
11361 (mem:QI (match_dup 0)))]
11362 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11363 "mov.b @(%0,%1),%2")
11366 [(set (match_operand:SI 0 "register_operand" "=r")
11367 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11368 (set (mem:SF (match_dup 0))
11369 (match_operand:SF 2 "general_movsrc_operand" ""))]
11370 "TARGET_SH1 && REGNO (operands[0]) == 0
11371 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11372 || (GET_CODE (operands[2]) == SUBREG
11373 && REGNO (SUBREG_REG (operands[2])) < 16))
11374 && reg_unused_after (operands[0], insn)"
11375 "mov.l %2,@(%0,%1)")
11378 [(set (match_operand:SI 0 "register_operand" "=r")
11379 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11380 (set (match_operand:SF 2 "general_movdst_operand" "")
11382 (mem:SF (match_dup 0)))]
11383 "TARGET_SH1 && REGNO (operands[0]) == 0
11384 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11385 || (GET_CODE (operands[2]) == SUBREG
11386 && REGNO (SUBREG_REG (operands[2])) < 16))
11387 && reg_unused_after (operands[0], insn)"
11388 "mov.l @(%0,%1),%2")
11391 [(set (match_operand:SI 0 "register_operand" "=r")
11392 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11393 (set (mem:SF (match_dup 0))
11394 (match_operand:SF 2 "general_movsrc_operand" ""))]
11395 "TARGET_SH2E && REGNO (operands[0]) == 0
11396 && ((REG_P (operands[2])
11397 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11398 || (GET_CODE (operands[2]) == SUBREG
11399 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11400 && reg_unused_after (operands[0], insn)"
11401 "fmov{.s|} %2,@(%0,%1)")
11404 [(set (match_operand:SI 0 "register_operand" "=r")
11405 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11406 (set (match_operand:SF 2 "general_movdst_operand" "")
11408 (mem:SF (match_dup 0)))]
11409 "TARGET_SH2E && REGNO (operands[0]) == 0
11410 && ((REG_P (operands[2])
11411 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11412 || (GET_CODE (operands[2]) == SUBREG
11413 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11414 && reg_unused_after (operands[0], insn)"
11415 "fmov{.s|} @(%0,%1),%2")
11417 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11418 (define_insn "sp_switch_1"
11419 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11423 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11424 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11425 return \"mov r0,r15\";
11427 [(set_attr "length" "10")])
11429 ;; Switch back to the original stack for interrupt functions with the
11430 ;; sp_switch attribute. */
11431 (define_insn "sp_switch_2"
11434 "mov.l @r15+,r15\;mov.l @r15+,r0"
11435 [(set_attr "length" "4")])
11437 ;; Integer vector moves
11439 (define_expand "movv8qi"
11440 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11441 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11443 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11445 (define_insn "movv8qi_i"
11446 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11447 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11449 && (register_operand (operands[0], V8QImode)
11450 || sh_register_operand (operands[1], V8QImode))"
11457 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11458 (set_attr "length" "4,4,16,4,4")])
11461 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11462 (subreg:V8QI (const_int 0) 0))]
11464 [(set (match_dup 0)
11465 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11466 (const_int 0) (const_int 0) (const_int 0)
11467 (const_int 0) (const_int 0)]))])
11470 [(set (match_operand 0 "arith_reg_dest" "")
11471 (match_operand 1 "sh_rep_vec" ""))]
11472 "TARGET_SHMEDIA && reload_completed
11473 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11474 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11475 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11476 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11477 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11478 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11479 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11480 [(set (match_dup 0) (match_dup 1))
11484 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11485 rtx elt1 = XVECEXP (operands[1], 0, 1);
11488 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11492 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11493 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11495 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11496 operands[1] = XVECEXP (operands[1], 0, 0);
11499 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11501 = GEN_INT (TARGET_LITTLE_ENDIAN
11502 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11503 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11506 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11508 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11514 [(set (match_operand 0 "arith_reg_dest" "")
11515 (match_operand 1 "sh_const_vec" ""))]
11516 "TARGET_SHMEDIA && reload_completed
11517 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11518 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11519 [(set (match_dup 0) (match_dup 1))]
11522 rtx v = operands[1];
11523 enum machine_mode new_mode
11524 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11526 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11528 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11531 (define_expand "movv2hi"
11532 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11533 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11535 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11537 (define_insn "movv2hi_i"
11538 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11539 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11541 && (register_operand (operands[0], V2HImode)
11542 || sh_register_operand (operands[1], V2HImode))"
11549 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11550 (set_attr "length" "4,4,16,4,4")
11551 (set (attr "highpart")
11552 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11553 (const_string "user")]
11554 (const_string "ignore")))])
11556 (define_expand "movv4hi"
11557 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11558 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11560 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11562 (define_insn "movv4hi_i"
11563 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11564 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11566 && (register_operand (operands[0], V4HImode)
11567 || sh_register_operand (operands[1], V4HImode))"
11574 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11575 (set_attr "length" "4,4,16,4,4")
11576 (set_attr "highpart" "depend")])
11578 (define_expand "movv2si"
11579 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11580 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11582 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11584 (define_insn "movv2si_i"
11585 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11586 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11588 && (register_operand (operands[0], V2SImode)
11589 || sh_register_operand (operands[1], V2SImode))"
11596 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11597 (set_attr "length" "4,4,16,4,4")
11598 (set_attr "highpart" "depend")])
11600 ;; Multimedia Intrinsics
11602 (define_insn "absv2si2"
11603 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11604 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11607 [(set_attr "type" "mcmp_media")
11608 (set_attr "highpart" "depend")])
11610 (define_insn "absv4hi2"
11611 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11612 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11615 [(set_attr "type" "mcmp_media")
11616 (set_attr "highpart" "depend")])
11618 (define_insn "addv2si3"
11619 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11620 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11621 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11623 "madd.l %1, %2, %0"
11624 [(set_attr "type" "arith_media")
11625 (set_attr "highpart" "depend")])
11627 (define_insn "addv4hi3"
11628 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11629 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11630 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11632 "madd.w %1, %2, %0"
11633 [(set_attr "type" "arith_media")
11634 (set_attr "highpart" "depend")])
11636 (define_insn_and_split "addv2hi3"
11637 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11638 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11639 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11646 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11647 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11648 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11649 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11650 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11652 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11653 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11656 [(set_attr "highpart" "must_split")])
11658 (define_insn "ssaddv2si3"
11659 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11660 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11661 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11663 "madds.l %1, %2, %0"
11664 [(set_attr "type" "mcmp_media")
11665 (set_attr "highpart" "depend")])
11667 (define_insn "usaddv8qi3"
11668 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11669 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11670 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11672 "madds.ub %1, %2, %0"
11673 [(set_attr "type" "mcmp_media")
11674 (set_attr "highpart" "depend")])
11676 (define_insn "ssaddv4hi3"
11677 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11678 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11679 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11681 "madds.w %1, %2, %0"
11682 [(set_attr "type" "mcmp_media")
11683 (set_attr "highpart" "depend")])
11685 (define_insn "negcmpeqv8qi"
11686 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11687 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11688 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11690 "mcmpeq.b %N1, %N2, %0"
11691 [(set_attr "type" "mcmp_media")
11692 (set_attr "highpart" "depend")])
11694 (define_insn "negcmpeqv2si"
11695 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11696 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11697 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11699 "mcmpeq.l %N1, %N2, %0"
11700 [(set_attr "type" "mcmp_media")
11701 (set_attr "highpart" "depend")])
11703 (define_insn "negcmpeqv4hi"
11704 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11705 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11706 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11708 "mcmpeq.w %N1, %N2, %0"
11709 [(set_attr "type" "mcmp_media")
11710 (set_attr "highpart" "depend")])
11712 (define_insn "negcmpgtuv8qi"
11713 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11714 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11715 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11717 "mcmpgt.ub %N1, %N2, %0"
11718 [(set_attr "type" "mcmp_media")
11719 (set_attr "highpart" "depend")])
11721 (define_insn "negcmpgtv2si"
11722 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11723 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11724 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11726 "mcmpgt.l %N1, %N2, %0"
11727 [(set_attr "type" "mcmp_media")
11728 (set_attr "highpart" "depend")])
11730 (define_insn "negcmpgtv4hi"
11731 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11732 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11733 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11735 "mcmpgt.w %N1, %N2, %0"
11736 [(set_attr "type" "mcmp_media")
11737 (set_attr "highpart" "depend")])
11739 (define_insn "mcmv"
11740 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11741 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11742 (match_operand:DI 2 "arith_reg_operand" "r"))
11743 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11744 (not:DI (match_dup 2)))))]
11747 [(set_attr "type" "arith_media")
11748 (set_attr "highpart" "depend")])
11750 (define_insn "mcnvs_lw"
11751 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11753 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11754 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11756 "mcnvs.lw %N1, %N2, %0"
11757 [(set_attr "type" "mcmp_media")])
11759 (define_insn "mcnvs_wb"
11760 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11762 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11763 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11765 "mcnvs.wb %N1, %N2, %0"
11766 [(set_attr "type" "mcmp_media")])
11768 (define_insn "mcnvs_wub"
11769 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11771 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11772 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11774 "mcnvs.wub %N1, %N2, %0"
11775 [(set_attr "type" "mcmp_media")])
11777 (define_insn "mextr_rl"
11778 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11779 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11780 (match_operand:HI 3 "mextr_bit_offset" "i"))
11781 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11782 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11783 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11786 static char templ[21];
11788 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11789 (int) INTVAL (operands[3]) >> 3);
11792 [(set_attr "type" "arith_media")])
11794 (define_insn "*mextr_lr"
11795 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11796 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11797 (match_operand:HI 3 "mextr_bit_offset" "i"))
11798 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11799 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11800 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11803 static char templ[21];
11805 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11806 (int) INTVAL (operands[4]) >> 3);
11809 [(set_attr "type" "arith_media")])
11811 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11812 ; vector then varies depending on endianness.
11813 (define_expand "mextr1"
11814 [(match_operand:DI 0 "arith_reg_dest" "")
11815 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11816 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11820 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11821 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11825 (define_expand "mextr2"
11826 [(match_operand:DI 0 "arith_reg_dest" "")
11827 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11828 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11832 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11833 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11837 (define_expand "mextr3"
11838 [(match_operand:DI 0 "arith_reg_dest" "")
11839 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11840 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11844 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11845 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11849 (define_expand "mextr4"
11850 [(match_operand:DI 0 "arith_reg_dest" "")
11851 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11852 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11856 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11857 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11861 (define_expand "mextr5"
11862 [(match_operand:DI 0 "arith_reg_dest" "")
11863 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11864 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11868 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11869 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11873 (define_expand "mextr6"
11874 [(match_operand:DI 0 "arith_reg_dest" "")
11875 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11876 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11880 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11881 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11885 (define_expand "mextr7"
11886 [(match_operand:DI 0 "arith_reg_dest" "")
11887 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11888 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11892 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11893 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11897 (define_expand "mmacfx_wl"
11898 [(match_operand:V2SI 0 "arith_reg_dest" "")
11899 (match_operand:V2HI 1 "extend_reg_operand" "")
11900 (match_operand:V2HI 2 "extend_reg_operand" "")
11901 (match_operand:V2SI 3 "arith_reg_operand" "")]
11905 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11906 operands[1], operands[2]));
11910 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11912 (define_insn "mmacfx_wl_i"
11913 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11915 (match_operand:V2SI 1 "arith_reg_operand" "0")
11920 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11921 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11924 "mmacfx.wl %2, %3, %0"
11925 [(set_attr "type" "mac_media")
11926 (set_attr "highpart" "depend")])
11928 (define_expand "mmacnfx_wl"
11929 [(match_operand:V2SI 0 "arith_reg_dest" "")
11930 (match_operand:V2HI 1 "extend_reg_operand" "")
11931 (match_operand:V2HI 2 "extend_reg_operand" "")
11932 (match_operand:V2SI 3 "arith_reg_operand" "")]
11936 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11937 operands[1], operands[2]));
11941 (define_insn "mmacnfx_wl_i"
11942 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11944 (match_operand:V2SI 1 "arith_reg_operand" "0")
11949 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11950 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11953 "mmacnfx.wl %2, %3, %0"
11954 [(set_attr "type" "mac_media")
11955 (set_attr "highpart" "depend")])
11957 (define_insn "mulv2si3"
11958 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11959 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11960 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11962 "mmul.l %1, %2, %0"
11963 [(set_attr "type" "d2mpy_media")
11964 (set_attr "highpart" "depend")])
11966 (define_insn "mulv4hi3"
11967 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11968 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11969 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11971 "mmul.w %1, %2, %0"
11972 [(set_attr "type" "dmpy_media")
11973 (set_attr "highpart" "depend")])
11975 (define_insn "mmulfx_l"
11976 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11980 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11981 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11984 "mmulfx.l %1, %2, %0"
11985 [(set_attr "type" "d2mpy_media")
11986 (set_attr "highpart" "depend")])
11988 (define_insn "mmulfx_w"
11989 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11993 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11994 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11997 "mmulfx.w %1, %2, %0"
11998 [(set_attr "type" "dmpy_media")
11999 (set_attr "highpart" "depend")])
12001 (define_insn "mmulfxrp_w"
12002 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12007 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12008 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12012 "mmulfxrp.w %1, %2, %0"
12013 [(set_attr "type" "dmpy_media")
12014 (set_attr "highpart" "depend")])
12017 (define_expand "mmulhi_wl"
12018 [(match_operand:V2SI 0 "arith_reg_dest" "")
12019 (match_operand:V4HI 1 "arith_reg_operand" "")
12020 (match_operand:V4HI 2 "arith_reg_operand" "")]
12024 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12025 (operands[0], operands[1], operands[2]));
12029 (define_expand "mmullo_wl"
12030 [(match_operand:V2SI 0 "arith_reg_dest" "")
12031 (match_operand:V4HI 1 "arith_reg_operand" "")
12032 (match_operand:V4HI 2 "arith_reg_operand" "")]
12036 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12037 (operands[0], operands[1], operands[2]));
12041 (define_insn "mmul23_wl"
12042 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12045 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12046 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12047 (parallel [(const_int 2) (const_int 3)])))]
12049 "* return (TARGET_LITTLE_ENDIAN
12050 ? \"mmulhi.wl %1, %2, %0\"
12051 : \"mmullo.wl %1, %2, %0\");"
12052 [(set_attr "type" "dmpy_media")
12053 (set (attr "highpart")
12054 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12055 (const_string "user")))])
12057 (define_insn "mmul01_wl"
12058 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12061 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12062 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12063 (parallel [(const_int 0) (const_int 1)])))]
12065 "* return (TARGET_LITTLE_ENDIAN
12066 ? \"mmullo.wl %1, %2, %0\"
12067 : \"mmulhi.wl %1, %2, %0\");"
12068 [(set_attr "type" "dmpy_media")
12069 (set (attr "highpart")
12070 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12071 (const_string "user")))])
12074 (define_expand "mmulsum_wq"
12075 [(match_operand:DI 0 "arith_reg_dest" "")
12076 (match_operand:V4HI 1 "arith_reg_operand" "")
12077 (match_operand:V4HI 2 "arith_reg_operand" "")
12078 (match_operand:DI 3 "arith_reg_operand" "")]
12082 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12083 operands[1], operands[2]));
12087 (define_insn "mmulsum_wq_i"
12088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12089 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12094 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12095 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12096 (parallel [(const_int 0)]))
12097 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12098 (sign_extend:V4DI (match_dup 3)))
12099 (parallel [(const_int 1)])))
12101 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12102 (sign_extend:V4DI (match_dup 3)))
12103 (parallel [(const_int 2)]))
12104 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12105 (sign_extend:V4DI (match_dup 3)))
12106 (parallel [(const_int 3)]))))))]
12108 "mmulsum.wq %2, %3, %0"
12109 [(set_attr "type" "mac_media")])
12111 (define_expand "mperm_w"
12112 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12113 (match_operand:V4HI 1 "arith_reg_operand" "r")
12114 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12118 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12119 (operands[0], operands[1], operands[2]));
12123 ; This use of vec_select isn't exactly correct according to rtl.texi
12124 ; (because not constant), but it seems a straightforward extension.
12125 (define_insn "mperm_w_little"
12126 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12128 (match_operand:V4HI 1 "arith_reg_operand" "r")
12130 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12131 (const_int 2) (const_int 0))
12132 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12133 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12134 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12135 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12136 "mperm.w %1, %N2, %0"
12137 [(set_attr "type" "arith_media")])
12139 (define_insn "mperm_w_big"
12140 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12142 (match_operand:V4HI 1 "arith_reg_operand" "r")
12144 [(zero_extract:QI (not:QI (match_operand:QI 2
12145 "extend_reg_or_0_operand" "rZ"))
12146 (const_int 2) (const_int 0))
12147 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12148 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12149 (zero_extract:QI (not:QI (match_dup 2))
12150 (const_int 2) (const_int 6))])))]
12151 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12152 "mperm.w %1, %N2, %0"
12153 [(set_attr "type" "arith_media")])
12155 (define_insn "mperm_w0"
12156 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12157 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12158 "trunc_hi_operand" "r"))))]
12160 "mperm.w %1, r63, %0"
12161 [(set_attr "type" "arith_media")
12162 (set_attr "highpart" "ignore")])
12164 (define_expand "msad_ubq"
12165 [(match_operand:DI 0 "arith_reg_dest" "")
12166 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12167 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12168 (match_operand:DI 3 "arith_reg_operand" "")]
12172 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12173 operands[1], operands[2]));
12177 (define_insn "msad_ubq_i"
12178 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12183 (match_operand:DI 1 "arith_reg_operand" "0")
12184 (abs:DI (vec_select:DI
12187 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12189 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12190 (parallel [(const_int 0)]))))
12191 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12192 (zero_extend:V8DI (match_dup 3)))
12193 (parallel [(const_int 1)]))))
12195 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12196 (zero_extend:V8DI (match_dup 3)))
12197 (parallel [(const_int 2)])))
12198 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12199 (zero_extend:V8DI (match_dup 3)))
12200 (parallel [(const_int 3)])))))
12203 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12204 (zero_extend:V8DI (match_dup 3)))
12205 (parallel [(const_int 4)])))
12206 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12207 (zero_extend:V8DI (match_dup 3)))
12208 (parallel [(const_int 5)]))))
12210 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12211 (zero_extend:V8DI (match_dup 3)))
12212 (parallel [(const_int 6)])))
12213 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12214 (zero_extend:V8DI (match_dup 3)))
12215 (parallel [(const_int 7)])))))))]
12217 "msad.ubq %N2, %N3, %0"
12218 [(set_attr "type" "mac_media")])
12220 (define_insn "mshalds_l"
12221 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12224 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12225 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12226 (const_int 31)))))]
12228 "mshalds.l %1, %2, %0"
12229 [(set_attr "type" "mcmp_media")
12230 (set_attr "highpart" "depend")])
12232 (define_insn "mshalds_w"
12233 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12236 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12237 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12238 (const_int 15)))))]
12240 "mshalds.w %1, %2, %0"
12241 [(set_attr "type" "mcmp_media")
12242 (set_attr "highpart" "depend")])
12244 (define_insn "ashrv2si3"
12245 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12246 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12247 (match_operand:DI 2 "arith_reg_operand" "r")))]
12249 "mshard.l %1, %2, %0"
12250 [(set_attr "type" "arith_media")
12251 (set_attr "highpart" "depend")])
12253 (define_insn "ashrv4hi3"
12254 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12255 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12256 (match_operand:DI 2 "arith_reg_operand" "r")))]
12258 "mshard.w %1, %2, %0"
12259 [(set_attr "type" "arith_media")
12260 (set_attr "highpart" "depend")])
12262 (define_insn "mshards_q"
12263 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12265 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12266 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12268 "mshards.q %1, %N2, %0"
12269 [(set_attr "type" "mcmp_media")])
12271 (define_expand "mshfhi_b"
12272 [(match_operand:V8QI 0 "arith_reg_dest" "")
12273 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12274 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12278 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12279 (operands[0], operands[1], operands[2]));
12283 (define_expand "mshflo_b"
12284 [(match_operand:V8QI 0 "arith_reg_dest" "")
12285 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12286 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12290 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12291 (operands[0], operands[1], operands[2]));
12295 (define_insn "mshf4_b"
12297 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12299 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12300 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12301 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12302 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12304 "* return (TARGET_LITTLE_ENDIAN
12305 ? \"mshfhi.b %N1, %N2, %0\"
12306 : \"mshflo.b %N1, %N2, %0\");"
12307 [(set_attr "type" "arith_media")
12308 (set (attr "highpart")
12309 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12310 (const_string "user")))])
12312 (define_insn "mshf0_b"
12314 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12316 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12317 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12318 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12319 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12321 "* return (TARGET_LITTLE_ENDIAN
12322 ? \"mshflo.b %N1, %N2, %0\"
12323 : \"mshfhi.b %N1, %N2, %0\");"
12324 [(set_attr "type" "arith_media")
12325 (set (attr "highpart")
12326 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12327 (const_string "user")))])
12329 (define_expand "mshfhi_l"
12330 [(match_operand:V2SI 0 "arith_reg_dest" "")
12331 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12332 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12336 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12337 (operands[0], operands[1], operands[2]));
12341 (define_expand "mshflo_l"
12342 [(match_operand:V2SI 0 "arith_reg_dest" "")
12343 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12344 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12348 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12349 (operands[0], operands[1], operands[2]));
12353 (define_insn "mshf4_l"
12354 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12356 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12357 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12358 (parallel [(const_int 1) (const_int 3)])))]
12360 "* return (TARGET_LITTLE_ENDIAN
12361 ? \"mshfhi.l %N1, %N2, %0\"
12362 : \"mshflo.l %N1, %N2, %0\");"
12363 [(set_attr "type" "arith_media")
12364 (set (attr "highpart")
12365 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12366 (const_string "user")))])
12368 (define_insn "mshf0_l"
12369 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12371 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12372 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12373 (parallel [(const_int 0) (const_int 2)])))]
12375 "* return (TARGET_LITTLE_ENDIAN
12376 ? \"mshflo.l %N1, %N2, %0\"
12377 : \"mshfhi.l %N1, %N2, %0\");"
12378 [(set_attr "type" "arith_media")
12379 (set (attr "highpart")
12380 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12381 (const_string "user")))])
12383 (define_expand "mshfhi_w"
12384 [(match_operand:V4HI 0 "arith_reg_dest" "")
12385 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12386 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12390 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12391 (operands[0], operands[1], operands[2]));
12395 (define_expand "mshflo_w"
12396 [(match_operand:V4HI 0 "arith_reg_dest" "")
12397 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12398 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12402 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12403 (operands[0], operands[1], operands[2]));
12407 (define_insn "mshf4_w"
12408 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12410 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12411 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12412 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12414 "* return (TARGET_LITTLE_ENDIAN
12415 ? \"mshfhi.w %N1, %N2, %0\"
12416 : \"mshflo.w %N1, %N2, %0\");"
12417 [(set_attr "type" "arith_media")
12418 (set (attr "highpart")
12419 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12420 (const_string "user")))])
12422 (define_insn "mshf0_w"
12423 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12425 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12426 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12427 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12429 "* return (TARGET_LITTLE_ENDIAN
12430 ? \"mshflo.w %N1, %N2, %0\"
12431 : \"mshfhi.w %N1, %N2, %0\");"
12432 [(set_attr "type" "arith_media")
12433 (set (attr "highpart")
12434 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12435 (const_string "user")))])
12437 (define_insn "mshflo_w_x"
12438 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12440 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12441 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12442 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12444 "mshflo.w %N1, %N2, %0"
12445 [(set_attr "type" "arith_media")
12446 (set_attr "highpart" "ignore")])
12448 /* These are useful to expand ANDs and as combiner patterns. */
12449 (define_insn_and_split "mshfhi_l_di"
12450 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12451 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12453 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12454 (const_int -4294967296))))]
12457 mshfhi.l %N1, %N2, %0
12459 "TARGET_SHMEDIA && reload_completed
12460 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12461 [(set (match_dup 3) (match_dup 4))
12462 (set (match_dup 5) (match_dup 6))]
12465 operands[3] = gen_lowpart (SImode, operands[0]);
12466 operands[4] = gen_highpart (SImode, operands[1]);
12467 operands[5] = gen_highpart (SImode, operands[0]);
12468 operands[6] = gen_highpart (SImode, operands[2]);
12470 [(set_attr "type" "arith_media")])
12472 (define_insn "*mshfhi_l_di_rev"
12473 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12474 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12475 (const_int -4294967296))
12476 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12479 "mshfhi.l %N2, %N1, %0"
12480 [(set_attr "type" "arith_media")])
12483 [(set (match_operand:DI 0 "arith_reg_dest" "")
12484 (ior:DI (zero_extend:DI (match_operand:SI 1
12485 "extend_reg_or_0_operand" ""))
12486 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12487 (const_int -4294967296))))
12488 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12493 emit_insn (gen_ashldi3_media (operands[3],
12494 simplify_gen_subreg (DImode, operands[1],
12497 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12501 (define_insn "mshflo_l_di"
12502 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12503 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12504 (const_int 4294967295))
12505 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12509 "mshflo.l %N1, %N2, %0"
12510 [(set_attr "type" "arith_media")
12511 (set_attr "highpart" "ignore")])
12513 (define_insn "*mshflo_l_di_rev"
12514 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12515 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12517 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12518 (const_int 4294967295))))]
12521 "mshflo.l %N2, %N1, %0"
12522 [(set_attr "type" "arith_media")
12523 (set_attr "highpart" "ignore")])
12525 ;; Combiner pattern for trampoline initialization.
12526 (define_insn_and_split "*double_shori"
12527 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12528 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12530 (match_operand:DI 2 "const_int_operand" "n")))]
12532 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12534 "rtx_equal_p (operands[0], operands[1])"
12538 HOST_WIDE_INT v = INTVAL (operands[2]);
12540 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12541 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12544 [(set_attr "highpart" "ignore")])
12547 (define_insn "*mshflo_l_di_x"
12548 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12549 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12551 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12555 "mshflo.l %N1, %N2, %0"
12556 [(set_attr "type" "arith_media")
12557 (set_attr "highpart" "ignore")])
12559 (define_insn_and_split "concat_v2sf"
12560 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12561 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12562 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12563 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12567 mshflo.l %N1, %N2, %0
12570 "TARGET_SHMEDIA && reload_completed
12571 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12572 [(set (match_dup 3) (match_dup 1))
12573 (set (match_dup 4) (match_dup 2))]
12576 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12577 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12579 [(set_attr "type" "arith_media")
12580 (set_attr "highpart" "ignore")])
12582 (define_insn "*mshflo_l_di_x_rev"
12583 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12584 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12586 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12589 "mshflo.l %N2, %N1, %0"
12590 [(set_attr "type" "arith_media")
12591 (set_attr "highpart" "ignore")])
12593 (define_insn "ashlv2si3"
12594 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12595 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12596 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12598 "mshlld.l %1, %2, %0"
12599 [(set_attr "type" "arith_media")
12600 (set_attr "highpart" "depend")])
12603 [(set (match_operand 0 "any_register_operand" "")
12604 (match_operator 3 "shift_operator"
12605 [(match_operand 1 "any_register_operand" "")
12606 (match_operand 2 "shift_count_reg_operand" "")]))]
12607 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12608 [(set (match_dup 0) (match_dup 3))]
12611 rtx count = operands[2];
12612 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12614 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12615 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12616 || GET_CODE (count) == TRUNCATE)
12617 count = XEXP (count, 0);
12618 inner_mode = GET_MODE (count);
12619 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12620 subreg_lowpart_offset (outer_mode, inner_mode));
12621 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12622 operands[1], count);
12625 (define_insn "ashlv4hi3"
12626 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12627 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12628 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12630 "mshlld.w %1, %2, %0"
12631 [(set_attr "type" "arith_media")
12632 (set_attr "highpart" "depend")])
12634 (define_insn "lshrv2si3"
12635 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12636 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12637 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12639 "mshlrd.l %1, %2, %0"
12640 [(set_attr "type" "arith_media")
12641 (set_attr "highpart" "depend")])
12643 (define_insn "lshrv4hi3"
12644 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12645 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12646 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12648 "mshlrd.w %1, %2, %0"
12649 [(set_attr "type" "arith_media")
12650 (set_attr "highpart" "depend")])
12652 (define_insn "subv2si3"
12653 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12654 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12655 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12657 "msub.l %N1, %2, %0"
12658 [(set_attr "type" "arith_media")
12659 (set_attr "highpart" "depend")])
12661 (define_insn "subv4hi3"
12662 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12663 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12664 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12666 "msub.w %N1, %2, %0"
12667 [(set_attr "type" "arith_media")
12668 (set_attr "highpart" "depend")])
12670 (define_insn_and_split "subv2hi3"
12671 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12672 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12673 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12680 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12681 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12682 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12683 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12684 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12686 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12687 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12690 [(set_attr "highpart" "must_split")])
12692 (define_insn "sssubv2si3"
12693 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12694 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12695 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12697 "msubs.l %N1, %2, %0"
12698 [(set_attr "type" "mcmp_media")
12699 (set_attr "highpart" "depend")])
12701 (define_insn "ussubv8qi3"
12702 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12703 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12704 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12706 "msubs.ub %N1, %2, %0"
12707 [(set_attr "type" "mcmp_media")
12708 (set_attr "highpart" "depend")])
12710 (define_insn "sssubv4hi3"
12711 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12712 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12713 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12715 "msubs.w %N1, %2, %0"
12716 [(set_attr "type" "mcmp_media")
12717 (set_attr "highpart" "depend")])
12719 ;; Floating Point Intrinsics
12721 (define_insn "fcosa_s"
12722 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12723 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12727 [(set_attr "type" "atrans_media")])
12729 (define_insn "fsina_s"
12730 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12731 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12735 [(set_attr "type" "atrans_media")])
12737 (define_insn "fipr"
12738 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12739 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12740 "fp_arith_reg_operand" "f")
12741 (match_operand:V4SF 2
12742 "fp_arith_reg_operand" "f"))
12743 (parallel [(const_int 0)]))
12744 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12745 (parallel [(const_int 1)])))
12746 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12747 (parallel [(const_int 2)]))
12748 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12749 (parallel [(const_int 3)])))))]
12751 "fipr.s %1, %2, %0"
12752 [(set_attr "type" "fparith_media")])
12754 (define_insn "fsrra_s"
12755 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12756 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12760 [(set_attr "type" "atrans_media")])
12762 (define_insn "ftrv"
12763 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12767 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12768 (parallel [(const_int 0) (const_int 5)
12769 (const_int 10) (const_int 15)]))
12770 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12772 (vec_select:V4SF (match_dup 1)
12773 (parallel [(const_int 4) (const_int 9)
12774 (const_int 14) (const_int 3)]))
12775 (vec_select:V4SF (match_dup 2)
12776 (parallel [(const_int 1) (const_int 2)
12777 (const_int 3) (const_int 0)]))))
12780 (vec_select:V4SF (match_dup 1)
12781 (parallel [(const_int 8) (const_int 13)
12782 (const_int 2) (const_int 7)]))
12783 (vec_select:V4SF (match_dup 2)
12784 (parallel [(const_int 2) (const_int 3)
12785 (const_int 0) (const_int 1)])))
12787 (vec_select:V4SF (match_dup 1)
12788 (parallel [(const_int 12) (const_int 1)
12789 (const_int 6) (const_int 11)]))
12790 (vec_select:V4SF (match_dup 2)
12791 (parallel [(const_int 3) (const_int 0)
12792 (const_int 1) (const_int 2)]))))))]
12794 "ftrv.s %1, %2, %0"
12795 [(set_attr "type" "fparith_media")])
12797 (define_insn "ldhi_l"
12798 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12800 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12803 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12807 [(set_attr "type" "load_media")])
12809 (define_insn "ldhi_q"
12810 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12812 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12815 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12819 [(set_attr "type" "load_media")])
12821 (define_insn_and_split "*ldhi_q_comb0"
12822 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12824 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12825 "register_operand" "r")
12826 (match_operand:SI 2
12827 "ua_offset" "I06"))
12830 (plus:SI (and:SI (match_dup 1) (const_int 7))
12833 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12837 "emit_insn (gen_ldhi_q (operands[0],
12838 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12842 (define_insn_and_split "*ldhi_q_comb1"
12843 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12845 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12846 "register_operand" "r")
12847 (match_operand:SI 2
12848 "ua_offset" "I06"))
12851 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12852 "ua_offset" "I06"))
12856 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12857 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12861 "emit_insn (gen_ldhi_q (operands[0],
12862 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12866 (define_insn "ldlo_l"
12867 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12869 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12871 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12872 (and:SI (match_dup 1) (const_int 3))))]
12875 [(set_attr "type" "load_media")])
12877 (define_insn "ldlo_q"
12878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12880 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12882 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12883 (and:SI (match_dup 1) (const_int 7))))]
12886 [(set_attr "type" "load_media")])
12888 (define_insn_and_split "*ldlo_q_comb0"
12889 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12891 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12892 (match_operand:SI 2 "ua_offset" "I06"))
12894 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12895 (and:SI (match_dup 1) (const_int 7))))]
12896 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12900 "emit_insn (gen_ldlo_q (operands[0],
12901 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12904 (define_insn_and_split "*ldlo_q_comb1"
12905 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12907 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12908 (match_operand:SI 2 "ua_offset" "I06"))
12910 (minus:SI (const_int 8)
12911 (and:SI (plus:SI (match_dup 1)
12912 (match_operand:SI 3 "ua_offset" "I06"))
12914 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12915 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12916 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12920 "emit_insn (gen_ldlo_q (operands[0],
12921 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12924 (define_insn "sthi_l"
12925 [(set (zero_extract:SI
12926 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12929 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12931 (match_operand:SI 1 "arith_reg_operand" "r"))]
12934 [(set_attr "type" "ustore_media")])
12936 ;; All unaligned stores are considered to be 'narrow' because they typically
12937 ;; operate on less that a quadword, and when they operate on a full quadword,
12938 ;; the vanilla store high / store low sequence will cause a stall if not
12939 ;; scheduled apart.
12940 (define_insn "sthi_q"
12941 [(set (zero_extract:DI
12942 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12945 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12947 (match_operand:DI 1 "arith_reg_operand" "r"))]
12950 [(set_attr "type" "ustore_media")])
12952 (define_insn_and_split "*sthi_q_comb0"
12953 [(set (zero_extract:DI
12954 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12955 "register_operand" "r")
12956 (match_operand:SI 1 "ua_offset"
12960 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12962 (match_operand:DI 2 "arith_reg_operand" "r"))]
12963 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12967 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12971 (define_insn_and_split "*sthi_q_comb1"
12972 [(set (zero_extract:DI
12973 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12974 "register_operand" "r")
12975 (match_operand:SI 1 "ua_offset"
12979 (plus:SI (and:SI (plus:SI (match_dup 0)
12980 (match_operand:SI 2 "ua_offset" "I06"))
12984 (match_operand:DI 3 "arith_reg_operand" "r"))]
12985 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12986 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12990 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12994 ;; This is highpart user because the address is used as full 64 bit.
12995 (define_insn "stlo_l"
12996 [(set (zero_extract:SI
12997 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12999 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13000 (and:SI (match_dup 0) (const_int 3)))
13001 (match_operand:SI 1 "arith_reg_operand" "r"))]
13004 [(set_attr "type" "ustore_media")])
13006 (define_insn "stlo_q"
13007 [(set (zero_extract:DI
13008 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13010 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13011 (and:SI (match_dup 0) (const_int 7)))
13012 (match_operand:DI 1 "arith_reg_operand" "r"))]
13015 [(set_attr "type" "ustore_media")])
13017 (define_insn_and_split "*stlo_q_comb0"
13018 [(set (zero_extract:DI
13019 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13020 (match_operand:SI 1 "ua_offset" "I06"))
13022 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13023 (and:SI (match_dup 0) (const_int 7)))
13024 (match_operand:DI 2 "arith_reg_operand" "r"))]
13025 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13029 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13033 (define_insn_and_split "*stlo_q_comb1"
13034 [(set (zero_extract:DI
13035 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13036 (match_operand:SI 1 "ua_offset" "I06"))
13038 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13039 (match_operand:SI 2
13040 "ua_offset" "I06"))
13042 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13043 (match_operand:DI 3 "arith_reg_operand" "r"))]
13044 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13048 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13052 (define_insn "ldhi_l64"
13053 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13055 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13058 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13062 [(set_attr "type" "load_media")])
13064 (define_insn "ldhi_q64"
13065 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13067 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13070 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13074 [(set_attr "type" "load_media")])
13076 (define_insn "ldlo_l64"
13077 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13079 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13081 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13082 (and:DI (match_dup 1) (const_int 3))))]
13085 [(set_attr "type" "load_media")])
13087 (define_insn "ldlo_q64"
13088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13090 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13092 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13093 (and:DI (match_dup 1) (const_int 7))))]
13096 [(set_attr "type" "load_media")])
13098 (define_insn "sthi_l64"
13099 [(set (zero_extract:SI
13100 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13103 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13105 (match_operand:SI 1 "arith_reg_operand" "r"))]
13108 [(set_attr "type" "ustore_media")])
13110 (define_insn "sthi_q64"
13111 [(set (zero_extract:DI
13112 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13115 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13117 (match_operand:DI 1 "arith_reg_operand" "r"))]
13120 [(set_attr "type" "ustore_media")])
13122 (define_insn "stlo_l64"
13123 [(set (zero_extract:SI
13124 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13126 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13127 (and:DI (match_dup 0) (const_int 3)))
13128 (match_operand:SI 1 "arith_reg_operand" "r"))]
13131 [(set_attr "type" "ustore_media")])
13133 (define_insn "stlo_q64"
13134 [(set (zero_extract:DI
13135 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13137 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13138 (and:DI (match_dup 0) (const_int 7)))
13139 (match_operand:DI 1 "arith_reg_operand" "r"))]
13142 [(set_attr "type" "ustore_media")])
13145 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13146 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13150 [(set_attr "type" "arith_media")])
13152 (define_insn "nsbsi"
13153 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13155 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13159 [(set_attr "type" "arith_media")])
13161 (define_insn "nsbdi"
13162 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13164 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13168 [(set_attr "type" "arith_media")])
13170 (define_expand "ffsdi2"
13171 [(set (match_operand:DI 0 "arith_reg_dest" "")
13172 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13176 rtx scratch = gen_reg_rtx (DImode);
13179 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13180 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13181 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13182 emit_insn (gen_nsbdi (scratch, scratch));
13183 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13184 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13185 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13186 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13191 (define_expand "ffssi2"
13192 [(set (match_operand:SI 0 "arith_reg_dest" "")
13193 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13197 rtx scratch = gen_reg_rtx (SImode);
13198 rtx discratch = gen_reg_rtx (DImode);
13201 emit_insn (gen_adddi3 (discratch,
13202 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13204 emit_insn (gen_andcdi3 (discratch,
13205 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13207 emit_insn (gen_nsbsi (scratch, discratch));
13208 last = emit_insn (gen_subsi3 (operands[0],
13209 force_reg (SImode, GEN_INT (63)), scratch));
13210 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13215 (define_insn "byterev"
13216 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13217 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13218 (parallel [(const_int 7) (const_int 6) (const_int 5)
13219 (const_int 4) (const_int 3) (const_int 2)
13220 (const_int 1) (const_int 0)])))]
13223 [(set_attr "type" "arith_media")])
13225 (define_insn "*prefetch_media"
13226 [(prefetch (match_operand:QI 0 "address_operand" "p")
13227 (match_operand:SI 1 "const_int_operand" "n")
13228 (match_operand:SI 2 "const_int_operand" "n"))]
13232 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13233 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13236 [(set_attr "type" "other")])
13238 (define_insn "*prefetch_i4"
13239 [(prefetch (match_operand:SI 0 "register_operand" "r")
13240 (match_operand:SI 1 "const_int_operand" "n")
13241 (match_operand:SI 2 "const_int_operand" "n"))]
13242 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13245 return \"pref @%0\";
13247 [(set_attr "type" "other")])
13249 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13250 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13251 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13252 (define_expand "prefetch"
13253 [(prefetch (match_operand 0 "address_operand" "p")
13254 (match_operand:SI 1 "const_int_operand" "n")
13255 (match_operand:SI 2 "const_int_operand" "n"))]
13256 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13257 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13260 if (GET_MODE (operands[0]) != Pmode
13261 || !CONST_INT_P (operands[1])
13262 || !CONST_INT_P (operands[2]))
13264 if (! TARGET_SHMEDIA)
13265 operands[0] = force_reg (Pmode, operands[0]);
13268 (define_insn "prefetch_m2a"
13269 [(prefetch (match_operand:SI 0 "register_operand" "r")
13270 (match_operand:SI 1 "const_int_operand" "n")
13271 (match_operand:SI 2 "const_int_operand" "n"))]
13274 [(set_attr "type" "other")])
13276 (define_insn "alloco_i"
13277 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13278 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13284 if (GET_CODE (operands[0]) == PLUS)
13286 xops[0] = XEXP (operands[0], 0);
13287 xops[1] = XEXP (operands[0], 1);
13291 xops[0] = operands[0];
13292 xops[1] = const0_rtx;
13294 output_asm_insn (\"alloco %0, %1\", xops);
13297 [(set_attr "type" "other")])
13300 [(set (match_operand 0 "any_register_operand" "")
13301 (match_operand 1 "" ""))]
13302 "TARGET_SHMEDIA && reload_completed"
13303 [(set (match_dup 0) (match_dup 1))]
13308 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13313 ; Stack Protector Patterns
13315 (define_expand "stack_protect_set"
13316 [(set (match_operand 0 "memory_operand" "")
13317 (match_operand 1 "memory_operand" ""))]
13320 if (TARGET_SHMEDIA)
13322 if (TARGET_SHMEDIA64)
13323 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13325 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13328 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13333 (define_insn "stack_protect_set_si"
13334 [(set (match_operand:SI 0 "memory_operand" "=m")
13335 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13336 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13338 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13339 [(set_attr "type" "other")
13340 (set_attr "length" "6")])
13342 (define_insn "stack_protect_set_si_media"
13343 [(set (match_operand:SI 0 "memory_operand" "=m")
13344 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13345 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13347 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13348 [(set_attr "type" "other")
13349 (set_attr "length" "12")])
13351 (define_insn "stack_protect_set_di_media"
13352 [(set (match_operand:DI 0 "memory_operand" "=m")
13353 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13354 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13356 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13357 [(set_attr "type" "other")
13358 (set_attr "length" "12")])
13360 (define_expand "stack_protect_test"
13361 [(match_operand 0 "memory_operand" "")
13362 (match_operand 1 "memory_operand" "")
13363 (match_operand 2 "" "")]
13366 if (TARGET_SHMEDIA)
13368 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13371 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13372 if (TARGET_SHMEDIA64)
13374 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13376 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13380 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13382 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13387 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13388 emit_jump_insn (gen_branch_true (operands[2]));
13394 (define_insn "stack_protect_test_si"
13395 [(set (reg:SI T_REG)
13396 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13397 (match_operand:SI 1 "memory_operand" "m")]
13399 (set (match_scratch:SI 2 "=&r") (const_int 0))
13400 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13402 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13403 [(set_attr "type" "other")
13404 (set_attr "length" "10")])
13406 (define_insn "stack_protect_test_si_media"
13407 [(set (match_operand:SI 0 "register_operand" "=&r")
13408 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13409 (match_operand:SI 2 "memory_operand" "m")]
13411 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13413 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13414 [(set_attr "type" "other")
13415 (set_attr "length" "16")])
13417 (define_insn "stack_protect_test_di_media"
13418 [(set (match_operand:DI 0 "register_operand" "=&r")
13419 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13420 (match_operand:DI 2 "memory_operand" "m")]
13422 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13424 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13425 [(set_attr "type" "other")
13426 (set_attr "length" "16")])