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 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))]
650 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
652 ;; -------------------------------------------------------------------------
653 ;; SImode unsigned integer comparisons
654 ;; -------------------------------------------------------------------------
656 (define_insn_and_split "cmpgeusi_t"
658 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
659 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
662 "&& operands[1] == CONST0_RTX (SImode)"
666 emit_insn (gen_sett ());
669 [(set_attr "type" "mt_group")])
671 (define_insn "cmpgtusi_t"
673 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
674 (match_operand:SI 1 "arith_reg_operand" "r")))]
677 [(set_attr "type" "mt_group")])
679 ;; We save the compare operands in the cmpxx patterns and use them when
680 ;; we generate the branch.
682 (define_expand "cmpsi"
684 (compare (match_operand:SI 0 "cmpsi_operand" "")
685 (match_operand:SI 1 "arith_operand" "")))]
686 "TARGET_SH1 || TARGET_SHMEDIA"
689 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
690 && GET_CODE (operands[1]) != CONST_INT)
691 operands[0] = copy_to_mode_reg (SImode, operands[0]);
692 sh_compare_op0 = operands[0];
693 sh_compare_op1 = operands[1];
697 ;; -------------------------------------------------------------------------
698 ;; DImode compare and branch
699 ;; -------------------------------------------------------------------------
702 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
703 ;; Therefore, we aim to have a set of three branches that go straight to the
704 ;; destination, i.e. only one of them is taken at any one time.
705 ;; This mechanism should also be slightly better for the sh4-200.
707 (define_expand "cbranchdi4"
709 (if_then_else (match_operator 0 "comparison_operator"
710 [(match_operand:DI 1 "arith_operand" "")
711 (match_operand:DI 2 "arith_operand" "")])
712 (label_ref (match_operand 3 "" ""))
714 (clobber (match_dup 4))
715 (clobber (reg:SI T_REG))]
719 enum rtx_code comparison;
721 if (TARGET_EXPAND_CBRANCHDI4)
723 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
726 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
727 if (comparison != GET_CODE (operands[0]))
729 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
730 operands[4] = gen_rtx_SCRATCH (SImode);
733 (define_insn_and_split "cbranchdi4_i"
735 (if_then_else (match_operator 0 "comparison_operator"
736 [(match_operand:DI 1 "arith_operand" "r,r")
737 (match_operand:DI 2 "arith_operand" "rN,i")])
738 (label_ref (match_operand 3 "" ""))
740 (clobber (match_scratch:SI 4 "=X,&r"))
741 (clobber (reg:SI T_REG))]
744 "&& reload_completed"
748 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
753 ;; -------------------------------------------------------------------------
754 ;; DImode signed integer comparisons
755 ;; -------------------------------------------------------------------------
759 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
760 (match_operand:DI 1 "arith_operand" "r"))
763 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
765 [(set_attr "length" "6")
766 (set_attr "type" "arith3b")])
768 (define_insn "cmpeqdi_t"
770 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
771 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
774 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
775 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
776 [(set_attr "length" "6")
777 (set_attr "type" "arith3b")])
781 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
782 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
783 ;; If we applied this split when not optimizing, it would only be
784 ;; applied during the machine-dependent reorg, when no new basic blocks
786 "TARGET_SH1 && reload_completed && optimize"
787 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
788 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
789 (label_ref (match_dup 6))
791 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
796 = gen_rtx_REG (SImode,
797 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
799 = (operands[1] == const0_rtx
801 : gen_rtx_REG (SImode,
802 true_regnum (operands[1])
803 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
804 operands[4] = gen_lowpart (SImode, operands[0]);
805 operands[5] = gen_lowpart (SImode, operands[1]);
806 operands[6] = gen_label_rtx ();
809 (define_insn "cmpgtdi_t"
811 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
815 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
816 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
817 [(set_attr "length" "8")
818 (set_attr "type" "arith3")])
820 (define_insn "cmpgedi_t"
822 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
823 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
826 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
828 [(set_attr "length" "8,2")
829 (set_attr "type" "arith3,mt_group")])
831 ;; -------------------------------------------------------------------------
832 ;; DImode unsigned integer comparisons
833 ;; -------------------------------------------------------------------------
835 (define_insn "cmpgeudi_t"
837 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
838 (match_operand:DI 1 "arith_reg_operand" "r")))]
840 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
841 [(set_attr "length" "8")
842 (set_attr "type" "arith3")])
844 (define_insn "cmpgtudi_t"
846 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
847 (match_operand:DI 1 "arith_reg_operand" "r")))]
849 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
850 [(set_attr "length" "8")
851 (set_attr "type" "arith3")])
853 (define_insn "cmpeqsi_media"
854 [(set (match_operand:SI 0 "register_operand" "=r")
855 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
856 (match_operand:SI 2 "cmp_operand" "Nr")))]
859 [(set_attr "type" "cmp_media")])
861 (define_insn "cmpeqdi_media"
862 [(set (match_operand:SI 0 "register_operand" "=r")
863 (eq:SI (match_operand:DI 1 "register_operand" "%r")
864 (match_operand:DI 2 "cmp_operand" "Nr")))]
867 [(set_attr "type" "cmp_media")])
869 (define_insn "cmpgtsi_media"
870 [(set (match_operand:SI 0 "register_operand" "=r")
871 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
872 (match_operand:SI 2 "cmp_operand" "rN")))]
875 [(set_attr "type" "cmp_media")])
877 (define_insn "cmpgtdi_media"
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
880 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
883 [(set_attr "type" "cmp_media")])
885 (define_insn "cmpgtusi_media"
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
888 (match_operand:SI 2 "cmp_operand" "rN")))]
890 "cmpgtu %N1, %N2, %0"
891 [(set_attr "type" "cmp_media")])
893 (define_insn "cmpgtudi_media"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
896 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
898 "cmpgtu %N1, %N2, %0"
899 [(set_attr "type" "cmp_media")])
901 ; These two patterns are for combine.
902 (define_insn "*cmpne0sisi_media"
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
907 [(set_attr "type" "cmp_media")])
909 ;; We save the compare operands in the cmpxx patterns and use them when
910 ;; we generate the branch.
912 (define_expand "cmpdi"
914 (compare (match_operand:DI 0 "arith_operand" "")
915 (match_operand:DI 1 "arith_operand" "")))]
916 "TARGET_SH2 || TARGET_SHMEDIA"
919 sh_compare_op0 = operands[0];
920 sh_compare_op1 = operands[1];
923 ;; -------------------------------------------------------------------------
924 ;; Conditional move instructions
925 ;; -------------------------------------------------------------------------
927 ;; The insn names may seem reversed, but note that cmveq performs the move
928 ;; if op1 == 0, and cmvne does it if op1 != 0.
930 (define_insn "movdicc_false"
931 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
932 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
934 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
935 (match_operand:DI 3 "arith_reg_operand" "0")))]
938 [(set_attr "type" "arith_media")])
940 (define_insn "movdicc_true"
941 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
942 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
944 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
945 (match_operand:DI 3 "arith_reg_operand" "0")))]
948 [(set_attr "type" "arith_media")])
951 [(set (match_operand:DI 0 "arith_reg_dest" "")
952 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
953 [(match_operand:DI 1 "arith_reg_operand" "")
955 (match_operand:DI 2 "arith_reg_dest" "")
957 (set (match_dup 2) (match_dup 0))]
958 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
960 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
963 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
964 VOIDmode, operands[1], CONST0_RTX (DImode));
968 [(set (match_operand:DI 0 "general_movdst_operand" "")
969 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
970 (set (match_operand:DI 2 "arith_reg_dest" "")
971 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
972 [(match_operand:DI 3 "arith_reg_operand" "")
976 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
978 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
981 (define_expand "movdicc"
982 [(set (match_operand:DI 0 "register_operand" "")
983 (if_then_else:DI (match_operand 1 "comparison_operator" "")
984 (match_operand:DI 2 "register_operand" "")
985 (match_operand:DI 3 "register_operand" "")))]
989 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
990 && GET_MODE (sh_compare_op0) == DImode
991 && sh_compare_op1 == const0_rtx)
992 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
993 sh_compare_op0, sh_compare_op1);
998 if (!can_create_pseudo_p ())
1001 tmp = gen_reg_rtx (DImode);
1003 switch (GET_CODE (operands[1]))
1006 emit_insn (gen_seq (tmp));
1007 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011 emit_insn (gen_seq (tmp));
1012 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016 emit_insn (gen_sgt (tmp));
1017 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1021 emit_insn (gen_slt (tmp));
1022 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1026 emit_insn (gen_slt (tmp));
1027 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1031 emit_insn (gen_sgt (tmp));
1032 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1036 emit_insn (gen_sgtu (tmp));
1037 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1041 emit_insn (gen_sltu (tmp));
1042 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1046 emit_insn (gen_sltu (tmp));
1047 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1051 emit_insn (gen_sgtu (tmp));
1052 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1056 emit_insn (gen_sunordered (tmp));
1057 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1061 emit_insn (gen_sunordered (tmp));
1062 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1079 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1080 ;; SImode to DImode.
1081 (define_insn "movsicc_false"
1082 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1083 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1085 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1086 (match_operand:SI 3 "arith_reg_operand" "0")))]
1089 [(set_attr "type" "arith_media")])
1091 (define_insn "movsicc_true"
1092 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1093 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1095 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1096 (match_operand:SI 3 "arith_reg_operand" "0")))]
1099 [(set_attr "type" "arith_media")])
1102 [(set (match_operand:SI 0 "arith_reg_dest" "")
1103 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1104 [(match_operand:SI 1 "arith_reg_operand" "")
1106 (match_operand:SI 2 "arith_reg_dest" "")
1108 (set (match_dup 2) (match_dup 0))]
1109 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1111 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1114 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1115 VOIDmode, operands[1], CONST0_RTX (SImode));
1119 [(set (match_operand:SI 0 "general_movdst_operand" "")
1120 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1121 (set (match_operand:SI 2 "arith_reg_dest" "")
1122 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1123 [(match_operand:SI 3 "arith_reg_operand" "")
1127 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1128 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1130 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1133 replace_rtx (operands[4], operands[0], operands[1]);
1137 [(set (match_operand 0 "any_register_operand" "")
1138 (match_operand 1 "any_register_operand" ""))
1139 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1140 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1141 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1142 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1143 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1144 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1145 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1146 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1147 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1148 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1149 && (REGNO_REG_CLASS (REGNO (operands[0]))
1150 == REGNO_REG_CLASS (REGNO (operands[2])))
1151 && (REGNO_REG_CLASS (REGNO (operands[1]))
1152 == REGNO_REG_CLASS (REGNO (operands[0])))"
1153 [(set (match_dup 0) (match_dup 3))
1154 (set (match_dup 4) (match_dup 5))]
1157 rtx set1, set2, insn2;
1158 rtx replacements[4];
1160 /* We want to replace occurrences of operands[0] with operands[1] and
1161 operands[2] with operands[0] in operands[4]/operands[5].
1162 Doing just two replace_rtx calls naively would result in the second
1163 replacement undoing all that the first did if operands[1] and operands[2]
1164 are identical, so we must do this simultaneously. */
1165 replacements[0] = operands[0];
1166 replacements[1] = operands[1];
1167 replacements[2] = operands[2];
1168 replacements[3] = operands[0];
1169 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1170 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1171 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1174 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1175 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1176 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1177 /* The operands array is aliased to recog_data.operand, which gets
1178 clobbered by extract_insn, so finish with it now. */
1179 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1180 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1181 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1182 always uses emit_insn. */
1183 /* Check that we don't violate matching constraints or earlyclobbers. */
1184 extract_insn (emit_insn (set1));
1185 if (! constrain_operands (1))
1187 insn2 = emit (set2);
1188 if (GET_CODE (insn2) == BARRIER)
1190 extract_insn (insn2);
1191 if (! constrain_operands (1))
1195 tmp = replacements[0];
1196 replacements[0] = replacements[1];
1197 replacements[1] = tmp;
1198 tmp = replacements[2];
1199 replacements[2] = replacements[3];
1200 replacements[3] = tmp;
1201 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1202 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1203 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1209 ;; The register allocator is rather clumsy in handling multi-way conditional
1210 ;; moves, so allow the combiner to make them, and we split them up after
1212 (define_insn_and_split "*movsicc_umin"
1213 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1214 (umin:SI (if_then_else:SI
1215 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1217 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1218 (match_operand:SI 3 "register_operand" "0"))
1219 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1220 (clobber (match_scratch:SI 5 "=&r"))]
1221 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1223 "TARGET_SHMEDIA && reload_completed"
1227 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1229 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1230 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1235 (define_insn "*movsicc_t_false"
1236 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1237 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1238 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1239 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1240 "TARGET_PRETEND_CMOVE
1241 && (arith_reg_operand (operands[1], SImode)
1242 || (immediate_operand (operands[1], SImode)
1243 && satisfies_constraint_I08 (operands[1])))"
1244 "bt 0f\;mov %1,%0\\n0:"
1245 [(set_attr "type" "mt_group,arith") ;; poor approximation
1246 (set_attr "length" "4")])
1248 (define_insn "*movsicc_t_true"
1249 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1250 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1251 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1252 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1253 "TARGET_PRETEND_CMOVE
1254 && (arith_reg_operand (operands[1], SImode)
1255 || (immediate_operand (operands[1], SImode)
1256 && satisfies_constraint_I08 (operands[1])))"
1257 "bf 0f\;mov %1,%0\\n0:"
1258 [(set_attr "type" "mt_group,arith") ;; poor approximation
1259 (set_attr "length" "4")])
1261 (define_expand "movsicc"
1262 [(set (match_operand:SI 0 "arith_reg_dest" "")
1263 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1264 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1265 (match_operand:SI 3 "arith_reg_operand" "")))]
1266 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1269 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1270 && GET_MODE (sh_compare_op0) == SImode
1272 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1273 && sh_compare_op1 == const0_rtx)
1274 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1275 sh_compare_op0, sh_compare_op1);
1276 else if (TARGET_PRETEND_CMOVE)
1278 enum rtx_code code = GET_CODE (operands[1]);
1279 enum rtx_code new_code = code;
1282 if (! currently_expanding_to_rtl)
1286 case LT: case LE: case LEU: case LTU:
1287 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1290 new_code = reverse_condition (code);
1292 case EQ: case GT: case GE: case GEU: case GTU:
1297 tmp = prepare_scc_operands (new_code);
1298 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1305 if (!can_create_pseudo_p ())
1308 tmp = gen_reg_rtx (SImode);
1310 switch (GET_CODE (operands[1]))
1313 emit_insn (gen_seq (tmp));
1314 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1318 emit_insn (gen_seq (tmp));
1319 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1323 emit_insn (gen_sgt (tmp));
1324 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1328 emit_insn (gen_slt (tmp));
1329 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1333 emit_insn (gen_slt (tmp));
1334 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1338 emit_insn (gen_sgt (tmp));
1339 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1343 emit_insn (gen_sgtu (tmp));
1344 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1348 emit_insn (gen_sltu (tmp));
1349 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1353 emit_insn (gen_sltu (tmp));
1354 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1358 emit_insn (gen_sgtu (tmp));
1359 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1363 emit_insn (gen_sunordered (tmp));
1364 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1368 emit_insn (gen_sunordered (tmp));
1369 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1386 (define_expand "movqicc"
1387 [(set (match_operand:QI 0 "register_operand" "")
1388 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1389 (match_operand:QI 2 "register_operand" "")
1390 (match_operand:QI 3 "register_operand" "")))]
1394 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1395 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1396 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1397 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1401 ;; -------------------------------------------------------------------------
1402 ;; Addition instructions
1403 ;; -------------------------------------------------------------------------
1405 (define_expand "adddi3"
1406 [(set (match_operand:DI 0 "arith_reg_operand" "")
1407 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1408 (match_operand:DI 2 "arith_operand" "")))]
1414 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1416 operands[2] = force_reg (DImode, operands[2]);
1417 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1422 (define_insn "*adddi3_media"
1423 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1425 (match_operand:DI 2 "arith_operand" "r,I10")))]
1430 [(set_attr "type" "arith_media")])
1432 (define_insn "*adddisi3_media"
1433 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1434 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1435 (match_operand:DI 2 "arith_operand" "r,I10")))]
1440 [(set_attr "type" "arith_media")
1441 (set_attr "highpart" "ignore")])
1443 (define_insn "adddi3z_media"
1444 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1446 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1447 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1449 "addz.l %1, %N2, %0"
1450 [(set_attr "type" "arith_media")
1451 (set_attr "highpart" "ignore")])
1453 (define_insn "adddi3_compact"
1454 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1455 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1456 (match_operand:DI 2 "arith_reg_operand" "r")))
1457 (clobber (reg:SI T_REG))]
1460 [(set_attr "length" "6")])
1463 [(set (match_operand:DI 0 "arith_reg_dest" "")
1464 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1465 (match_operand:DI 2 "arith_reg_operand" "")))
1466 (clobber (reg:SI T_REG))]
1467 "TARGET_SH1 && reload_completed"
1471 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1472 high0 = gen_rtx_REG (SImode,
1473 true_regnum (operands[0])
1474 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1475 high2 = gen_rtx_REG (SImode,
1476 true_regnum (operands[2])
1477 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1478 emit_insn (gen_clrt ());
1479 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1480 emit_insn (gen_addc1 (high0, high0, high2));
1485 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1486 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1487 (match_operand:SI 2 "arith_reg_operand" "r"))
1490 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1493 [(set_attr "type" "arith")])
1495 (define_insn "addc1"
1496 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1497 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1498 (match_operand:SI 2 "arith_reg_operand" "r"))
1500 (clobber (reg:SI T_REG))]
1503 [(set_attr "type" "arith")])
1505 (define_expand "addsi3"
1506 [(set (match_operand:SI 0 "arith_reg_operand" "")
1507 (plus:SI (match_operand:SI 1 "arith_operand" "")
1508 (match_operand:SI 2 "arith_operand" "")))]
1513 operands[1] = force_reg (SImode, operands[1]);
1516 (define_insn "addsi3_media"
1517 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1518 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1519 (match_operand:SI 2 "arith_operand" "r,I10")))]
1524 [(set_attr "type" "arith_media")
1525 (set_attr "highpart" "ignore")])
1527 (define_insn "addsidi3_media"
1528 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1529 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1531 (match_operand:SI 2 "arith_operand"
1537 [(set_attr "type" "arith_media")
1538 (set_attr "highpart" "ignore")])
1540 (define_insn "*addsi3_compact"
1541 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1542 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1543 (match_operand:SI 2 "arith_operand" "rI08")))]
1546 [(set_attr "type" "arith")])
1548 ;; -------------------------------------------------------------------------
1549 ;; Subtraction instructions
1550 ;; -------------------------------------------------------------------------
1552 (define_expand "subdi3"
1553 [(set (match_operand:DI 0 "arith_reg_operand" "")
1554 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1555 (match_operand:DI 2 "arith_reg_operand" "")))]
1561 operands[1] = force_reg (DImode, operands[1]);
1562 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1567 (define_insn "*subdi3_media"
1568 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1569 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1570 (match_operand:DI 2 "arith_reg_operand" "r")))]
1573 [(set_attr "type" "arith_media")])
1575 (define_insn "subdisi3_media"
1576 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1577 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1578 (match_operand:DI 2 "arith_reg_operand" "r")))]
1581 [(set_attr "type" "arith_media")
1582 (set_attr "highpart" "ignore")])
1584 (define_insn "subdi3_compact"
1585 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1586 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1587 (match_operand:DI 2 "arith_reg_operand" "r")))
1588 (clobber (reg:SI T_REG))]
1591 [(set_attr "length" "6")])
1594 [(set (match_operand:DI 0 "arith_reg_dest" "")
1595 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1596 (match_operand:DI 2 "arith_reg_operand" "")))
1597 (clobber (reg:SI T_REG))]
1598 "TARGET_SH1 && reload_completed"
1602 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1603 high0 = gen_rtx_REG (SImode,
1604 true_regnum (operands[0])
1605 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1606 high2 = gen_rtx_REG (SImode,
1607 true_regnum (operands[2])
1608 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1609 emit_insn (gen_clrt ());
1610 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1611 emit_insn (gen_subc1 (high0, high0, high2));
1616 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1617 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1618 (match_operand:SI 2 "arith_reg_operand" "r"))
1621 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1626 [(set_attr "type" "arith")])
1628 (define_insn "subc1"
1629 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1630 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1631 (match_operand:SI 2 "arith_reg_operand" "r"))
1633 (clobber (reg:SI T_REG))]
1636 [(set_attr "type" "arith")])
1638 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1639 ;; pattern for this case. This helps multimedia applications that compute
1640 ;; the sum of absolute differences.
1641 (define_insn "mov_neg_si_t"
1642 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1645 [(set_attr "type" "arith")])
1647 (define_insn "*subsi3_internal"
1648 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1649 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1650 (match_operand:SI 2 "arith_reg_operand" "r")))]
1653 [(set_attr "type" "arith")])
1655 (define_insn_and_split "*subsi3_media"
1656 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1657 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1658 (match_operand:SI 2 "extend_reg_operand" "r")))]
1660 && (operands[1] != constm1_rtx
1661 || (GET_CODE (operands[2]) != TRUNCATE
1662 && GET_CODE (operands[2]) != SUBREG))"
1664 "operands[1] == constm1_rtx"
1665 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1667 [(set_attr "type" "arith_media")
1668 (set_attr "highpart" "ignore")])
1671 [(set (match_operand:SI 0 "arith_reg_dest" "")
1672 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1673 "general_extend_operand"
1675 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1676 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1677 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1681 [(set (match_operand:SI 0 "arith_reg_dest" "")
1682 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1683 "general_extend_operand"
1685 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1686 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1687 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1689 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1690 ;; will sometimes save one instruction. Otherwise we might get
1691 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1694 (define_expand "subsi3"
1695 [(set (match_operand:SI 0 "arith_reg_operand" "")
1696 (minus:SI (match_operand:SI 1 "arith_operand" "")
1697 (match_operand:SI 2 "arith_reg_operand" "")))]
1701 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1703 emit_insn (gen_negsi2 (operands[0], operands[2]));
1704 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1709 if (!can_create_pseudo_p ()
1710 && ! arith_reg_or_0_operand (operands[1], SImode))
1712 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1713 operands[1] = force_reg (SImode, operands[1]);
1717 ;; -------------------------------------------------------------------------
1718 ;; Division instructions
1719 ;; -------------------------------------------------------------------------
1721 ;; We take advantage of the library routines which don't clobber as many
1722 ;; registers as a normal function call would.
1724 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1725 ;; also has an effect on the register that holds the address of the sfunc.
1726 ;; To make this work, we have an extra dummy insn that shows the use
1727 ;; of this register for reorg.
1729 (define_insn "use_sfunc_addr"
1730 [(set (reg:SI PR_REG)
1731 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1732 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1734 [(set_attr "length" "0")])
1736 (define_insn "udivsi3_sh2a"
1737 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1738 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1739 (match_operand:SI 2 "arith_reg_operand" "z")))]
1742 [(set_attr "type" "arith")
1743 (set_attr "in_delay_slot" "no")])
1745 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1746 ;; hard register 0. If we used hard register 0, then the next instruction
1747 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1748 ;; gets allocated to a stack slot that needs its address reloaded, then
1749 ;; there is nothing to prevent reload from using r0 to reload the address.
1750 ;; This reload would clobber the value in r0 we are trying to store.
1751 ;; If we let reload allocate r0, then this problem can never happen.
1753 (define_insn "udivsi3_i1"
1754 [(set (match_operand:SI 0 "register_operand" "=z")
1755 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1756 (clobber (reg:SI T_REG))
1757 (clobber (reg:SI PR_REG))
1758 (clobber (reg:SI R4_REG))
1759 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1760 "TARGET_SH1 && ! TARGET_SH4"
1762 [(set_attr "type" "sfunc")
1763 (set_attr "needs_delay_slot" "yes")])
1765 ; Since shmedia-nofpu code could be linked against shcompact code, and
1766 ; the udivsi3 libcall has the same name, we must consider all registers
1767 ; clobbered that are in the union of the registers clobbered by the
1768 ; shmedia and the shcompact implementation. Note, if the shcompact
1769 ; implementation actually used shcompact code, we'd need to clobber
1770 ; also r23 and fr23.
1771 (define_insn "udivsi3_i1_media"
1772 [(set (match_operand:SI 0 "register_operand" "=z")
1773 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1774 (clobber (reg:SI T_MEDIA_REG))
1775 (clobber (reg:SI PR_MEDIA_REG))
1776 (clobber (reg:SI R20_REG))
1777 (clobber (reg:SI R21_REG))
1778 (clobber (reg:SI R22_REG))
1779 (clobber (reg:DI TR0_REG))
1780 (clobber (reg:DI TR1_REG))
1781 (clobber (reg:DI TR2_REG))
1782 (use (match_operand 1 "target_reg_operand" "b"))]
1783 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1785 [(set_attr "type" "sfunc")
1786 (set_attr "needs_delay_slot" "yes")])
1788 (define_expand "udivsi3_i4_media"
1790 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1792 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1793 (set (match_dup 5) (float:DF (match_dup 3)))
1794 (set (match_dup 6) (float:DF (match_dup 4)))
1795 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1796 (set (match_dup 8) (fix:DI (match_dup 7)))
1797 (set (match_operand:SI 0 "register_operand" "")
1798 (truncate:SI (match_dup 8)))]
1799 "TARGET_SHMEDIA_FPU"
1802 operands[3] = gen_reg_rtx (DImode);
1803 operands[4] = gen_reg_rtx (DImode);
1804 operands[5] = gen_reg_rtx (DFmode);
1805 operands[6] = gen_reg_rtx (DFmode);
1806 operands[7] = gen_reg_rtx (DFmode);
1807 operands[8] = gen_reg_rtx (DImode);
1810 (define_insn "udivsi3_i4"
1811 [(set (match_operand:SI 0 "register_operand" "=y")
1812 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1813 (clobber (reg:SI T_REG))
1814 (clobber (reg:SI PR_REG))
1815 (clobber (reg:DF DR0_REG))
1816 (clobber (reg:DF DR2_REG))
1817 (clobber (reg:DF DR4_REG))
1818 (clobber (reg:SI R0_REG))
1819 (clobber (reg:SI R1_REG))
1820 (clobber (reg:SI R4_REG))
1821 (clobber (reg:SI R5_REG))
1822 (use (reg:PSI FPSCR_REG))
1823 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1824 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1826 [(set_attr "type" "sfunc")
1827 (set_attr "fp_mode" "double")
1828 (set_attr "needs_delay_slot" "yes")])
1830 (define_insn "udivsi3_i4_single"
1831 [(set (match_operand:SI 0 "register_operand" "=y")
1832 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1833 (clobber (reg:SI T_REG))
1834 (clobber (reg:SI PR_REG))
1835 (clobber (reg:DF DR0_REG))
1836 (clobber (reg:DF DR2_REG))
1837 (clobber (reg:DF DR4_REG))
1838 (clobber (reg:SI R0_REG))
1839 (clobber (reg:SI R1_REG))
1840 (clobber (reg:SI R4_REG))
1841 (clobber (reg:SI R5_REG))
1842 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1845 [(set_attr "type" "sfunc")
1846 (set_attr "needs_delay_slot" "yes")])
1848 (define_insn "udivsi3_i4_int"
1849 [(set (match_operand:SI 0 "register_operand" "=z")
1850 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1851 (clobber (reg:SI T_REG))
1852 (clobber (reg:SI R1_REG))
1853 (clobber (reg:SI PR_REG))
1854 (clobber (reg:SI MACH_REG))
1855 (clobber (reg:SI MACL_REG))
1856 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1859 [(set_attr "type" "sfunc")
1860 (set_attr "needs_delay_slot" "yes")])
1863 (define_expand "udivsi3"
1864 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1865 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1866 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1867 (parallel [(set (match_operand:SI 0 "register_operand" "")
1868 (udiv:SI (reg:SI R4_REG)
1870 (clobber (reg:SI T_REG))
1871 (clobber (reg:SI PR_REG))
1872 (clobber (reg:SI R4_REG))
1873 (use (match_dup 3))])]
1879 operands[3] = gen_reg_rtx (Pmode);
1880 /* Emit the move of the address to a pseudo outside of the libcall. */
1881 if (TARGET_DIVIDE_CALL_TABLE)
1883 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1884 that causes problems when the divide code is supposed to come from a
1885 separate library. Division by zero is undefined, so dividing 1 can be
1886 implemented by comparing with the divisor. */
1887 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1889 emit_insn (gen_cmpsi (operands[1], operands[2]));
1890 emit_insn (gen_sgeu (operands[0]));
1893 else if (operands[2] == const0_rtx)
1895 emit_move_insn (operands[0], operands[2]);
1898 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1899 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1901 else if (TARGET_DIVIDE_CALL_FP)
1903 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1904 if (TARGET_FPU_SINGLE)
1905 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1907 last = gen_udivsi3_i4 (operands[0], operands[3]);
1909 else if (TARGET_SHMEDIA_FPU)
1911 operands[1] = force_reg (SImode, operands[1]);
1912 operands[2] = force_reg (SImode, operands[2]);
1913 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1916 else if (TARGET_SH2A)
1918 operands[1] = force_reg (SImode, operands[1]);
1919 operands[2] = force_reg (SImode, operands[2]);
1920 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1923 else if (TARGET_SH5)
1925 function_symbol (operands[3],
1926 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1930 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1931 else if (TARGET_FPU_ANY)
1932 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1934 last = gen_udivsi3_i1 (operands[0], operands[3]);
1938 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1939 last = gen_udivsi3_i1 (operands[0], operands[3]);
1941 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1942 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1947 (define_insn "divsi3_sh2a"
1948 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1949 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1950 (match_operand:SI 2 "arith_reg_operand" "z")))]
1953 [(set_attr "type" "arith")
1954 (set_attr "in_delay_slot" "no")])
1956 (define_insn "divsi3_i1"
1957 [(set (match_operand:SI 0 "register_operand" "=z")
1958 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959 (clobber (reg:SI T_REG))
1960 (clobber (reg:SI PR_REG))
1961 (clobber (reg:SI R1_REG))
1962 (clobber (reg:SI R2_REG))
1963 (clobber (reg:SI R3_REG))
1964 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1965 "TARGET_SH1 && ! TARGET_SH4"
1967 [(set_attr "type" "sfunc")
1968 (set_attr "needs_delay_slot" "yes")])
1970 (define_insn "divsi3_i1_media"
1971 [(set (match_operand:SI 0 "register_operand" "=z")
1972 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973 (clobber (reg:SI T_MEDIA_REG))
1974 (clobber (reg:SI PR_MEDIA_REG))
1975 (clobber (reg:SI R1_REG))
1976 (clobber (reg:SI R20_REG))
1977 (clobber (reg:SI R21_REG))
1978 (clobber (reg:SI TR0_REG))
1979 (use (match_operand 1 "target_reg_operand" "b"))]
1980 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1982 [(set_attr "type" "sfunc")])
1984 (define_insn "divsi3_media_2"
1985 [(set (match_operand:SI 0 "register_operand" "=z")
1986 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1987 (clobber (reg:SI T_MEDIA_REG))
1988 (clobber (reg:SI PR_MEDIA_REG))
1989 (clobber (reg:SI R1_REG))
1990 (clobber (reg:SI R21_REG))
1991 (clobber (reg:SI TR0_REG))
1992 (use (reg:SI R20_REG))
1993 (use (match_operand 1 "target_reg_operand" "b"))]
1994 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1996 [(set_attr "type" "sfunc")])
1998 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1999 ;; hard reg clobbers and data dependencies that we need when we want
2000 ;; to rematerialize the division into a call.
2001 (define_insn_and_split "divsi_inv_call"
2002 [(set (match_operand:SI 0 "register_operand" "=r")
2003 (div:SI (match_operand:SI 1 "register_operand" "r")
2004 (match_operand:SI 2 "register_operand" "r")))
2005 (clobber (reg:SI R4_REG))
2006 (clobber (reg:SI R5_REG))
2007 (clobber (reg:SI T_MEDIA_REG))
2008 (clobber (reg:SI PR_MEDIA_REG))
2009 (clobber (reg:SI R1_REG))
2010 (clobber (reg:SI R21_REG))
2011 (clobber (reg:SI TR0_REG))
2012 (clobber (reg:SI R20_REG))
2013 (use (match_operand:SI 3 "register_operand" "r"))]
2016 "&& (high_life_started || reload_completed)"
2017 [(set (match_dup 0) (match_dup 3))]
2019 [(set_attr "highpart" "must_split")])
2021 ;; This is the combiner pattern for -mdiv=inv:call .
2022 (define_insn_and_split "*divsi_inv_call_combine"
2023 [(set (match_operand:SI 0 "register_operand" "=z")
2024 (div:SI (match_operand:SI 1 "register_operand" "r")
2025 (match_operand:SI 2 "register_operand" "r")))
2026 (clobber (reg:SI R4_REG))
2027 (clobber (reg:SI R5_REG))
2028 (clobber (reg:SI T_MEDIA_REG))
2029 (clobber (reg:SI PR_MEDIA_REG))
2030 (clobber (reg:SI R1_REG))
2031 (clobber (reg:SI R21_REG))
2032 (clobber (reg:SI TR0_REG))
2033 (clobber (reg:SI R20_REG))
2034 (use (unspec:SI [(match_dup 1)
2035 (match_operand:SI 3 "" "")
2036 (unspec:SI [(match_operand:SI 4 "" "")
2038 (match_operand:DI 5 "" "")]
2040 (match_operand:DI 6 "" "")
2043 UNSPEC_DIV_INV_M3))]
2046 "&& (high_life_started || reload_completed)"
2050 const char *name = sh_divsi3_libfunc;
2051 enum sh_function_kind kind = SFUNC_GOT;
2054 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2055 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2056 while (TARGET_DIVIDE_INV_CALL2)
2058 rtx x = operands[3];
2060 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2062 x = XVECEXP (x, 0, 0);
2063 name = \"__sdivsi3_2\";
2064 kind = SFUNC_STATIC;
2065 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2068 sym = function_symbol (NULL, name, kind);
2069 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2072 [(set_attr "highpart" "must_split")])
2074 (define_expand "divsi3_i4_media"
2075 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2076 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2077 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2078 (set (match_operand:SI 0 "register_operand" "=r")
2079 (fix:SI (match_dup 5)))]
2080 "TARGET_SHMEDIA_FPU"
2083 operands[3] = gen_reg_rtx (DFmode);
2084 operands[4] = gen_reg_rtx (DFmode);
2085 operands[5] = gen_reg_rtx (DFmode);
2088 (define_insn "divsi3_i4"
2089 [(set (match_operand:SI 0 "register_operand" "=y")
2090 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091 (clobber (reg:SI PR_REG))
2092 (clobber (reg:DF DR0_REG))
2093 (clobber (reg:DF DR2_REG))
2094 (use (reg:PSI FPSCR_REG))
2095 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2098 [(set_attr "type" "sfunc")
2099 (set_attr "fp_mode" "double")
2100 (set_attr "needs_delay_slot" "yes")])
2102 (define_insn "divsi3_i4_single"
2103 [(set (match_operand:SI 0 "register_operand" "=y")
2104 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2105 (clobber (reg:SI PR_REG))
2106 (clobber (reg:DF DR0_REG))
2107 (clobber (reg:DF DR2_REG))
2108 (clobber (reg:SI R2_REG))
2109 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2112 [(set_attr "type" "sfunc")
2113 (set_attr "needs_delay_slot" "yes")])
2115 (define_insn "divsi3_i4_int"
2116 [(set (match_operand:SI 0 "register_operand" "=z")
2117 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2118 (clobber (reg:SI T_REG))
2119 (clobber (reg:SI PR_REG))
2120 (clobber (reg:SI R1_REG))
2121 (clobber (reg:SI MACH_REG))
2122 (clobber (reg:SI MACL_REG))
2123 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2126 [(set_attr "type" "sfunc")
2127 (set_attr "needs_delay_slot" "yes")])
2129 (define_expand "divsi3"
2130 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2131 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2132 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2133 (parallel [(set (match_operand:SI 0 "register_operand" "")
2134 (div:SI (reg:SI R4_REG)
2136 (clobber (reg:SI T_REG))
2137 (clobber (reg:SI PR_REG))
2138 (clobber (reg:SI R1_REG))
2139 (clobber (reg:SI R2_REG))
2140 (clobber (reg:SI R3_REG))
2141 (use (match_dup 3))])]
2147 operands[3] = gen_reg_rtx (Pmode);
2148 /* Emit the move of the address to a pseudo outside of the libcall. */
2149 if (TARGET_DIVIDE_CALL_TABLE)
2151 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2152 last = gen_divsi3_i4_int (operands[0], operands[3]);
2154 else if (TARGET_DIVIDE_CALL_FP)
2156 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2157 if (TARGET_FPU_SINGLE)
2158 last = gen_divsi3_i4_single (operands[0], operands[3]);
2160 last = gen_divsi3_i4 (operands[0], operands[3]);
2162 else if (TARGET_SH2A)
2164 operands[1] = force_reg (SImode, operands[1]);
2165 operands[2] = force_reg (SImode, operands[2]);
2166 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2169 else if (TARGET_DIVIDE_INV)
2171 rtx dividend = operands[1];
2172 rtx divisor = operands[2];
2174 rtx nsb_res = gen_reg_rtx (DImode);
2175 rtx norm64 = gen_reg_rtx (DImode);
2176 rtx tab_ix = gen_reg_rtx (DImode);
2177 rtx norm32 = gen_reg_rtx (SImode);
2178 rtx i92 = force_reg (DImode, GEN_INT (92));
2179 rtx scratch0a = gen_reg_rtx (DImode);
2180 rtx scratch0b = gen_reg_rtx (DImode);
2181 rtx inv0 = gen_reg_rtx (SImode);
2182 rtx scratch1a = gen_reg_rtx (DImode);
2183 rtx scratch1b = gen_reg_rtx (DImode);
2184 rtx shift = gen_reg_rtx (DImode);
2186 rtx inv1 = gen_reg_rtx (SImode);
2187 rtx scratch2a = gen_reg_rtx (DImode);
2188 rtx scratch2b = gen_reg_rtx (SImode);
2189 rtx inv2 = gen_reg_rtx (SImode);
2190 rtx scratch3a = gen_reg_rtx (DImode);
2191 rtx scratch3b = gen_reg_rtx (DImode);
2192 rtx scratch3c = gen_reg_rtx (DImode);
2193 rtx scratch3d = gen_reg_rtx (SImode);
2194 rtx scratch3e = gen_reg_rtx (DImode);
2195 rtx result = gen_reg_rtx (SImode);
2197 if (! arith_reg_or_0_operand (dividend, SImode))
2198 dividend = force_reg (SImode, dividend);
2199 if (! arith_reg_operand (divisor, SImode))
2200 divisor = force_reg (SImode, divisor);
2201 if (flag_pic && Pmode != DImode)
2203 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2204 tab_base = gen_datalabel_ref (tab_base);
2205 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2209 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2210 tab_base = gen_datalabel_ref (tab_base);
2211 tab_base = force_reg (DImode, tab_base);
2213 if (TARGET_DIVIDE_INV20U)
2214 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2216 i2p27 = GEN_INT (0);
2217 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2218 i43 = force_reg (DImode, GEN_INT (43));
2221 emit_insn (gen_nsbdi (nsb_res,
2222 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2223 emit_insn (gen_ashldi3_media (norm64,
2224 gen_rtx_SUBREG (DImode, divisor, 0),
2226 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2227 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2228 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2229 inv0, scratch0a, scratch0b,
2230 scratch1a, scratch1b));
2231 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2232 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2234 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2236 scratch3a, scratch3b, scratch3c,
2237 scratch2a, scratch2b, scratch3d, scratch3e));
2238 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2239 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2240 else if (TARGET_DIVIDE_INV_FP)
2241 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2242 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2243 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2244 gen_reg_rtx (DFmode)));
2246 emit_move_insn (operands[0], result);
2249 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2251 operands[1] = force_reg (SImode, operands[1]);
2252 operands[2] = force_reg (SImode, operands[2]);
2253 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2256 else if (TARGET_SH5)
2258 if (TARGET_DIVIDE_CALL2)
2260 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2261 tab_base = gen_datalabel_ref (tab_base);
2262 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2264 if (TARGET_FPU_ANY && TARGET_SH1)
2265 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2266 else if (TARGET_DIVIDE_CALL2)
2267 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2269 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2272 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2273 (operands[0], operands[3]));
2274 else if (TARGET_FPU_ANY)
2275 last = gen_divsi3_i4_single (operands[0], operands[3]);
2277 last = gen_divsi3_i1 (operands[0], operands[3]);
2281 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2282 last = gen_divsi3_i1 (operands[0], operands[3]);
2284 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2285 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2290 ;; operands: scratch, tab_base, tab_ix
2291 ;; These are unspecs because we could generate an indexed addressing mode
2292 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2293 ;; confuse reload. See PR27117.
2295 (define_insn "divsi_inv_qitable"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2298 (match_operand:DI 2 "register_operand" "r")]
2299 UNSPEC_DIV_INV_TABLE)))]
2303 [(set_attr "type" "load_media")
2304 (set_attr "highpart" "user")])
2306 ;; operands: scratch, tab_base, tab_ix
2307 (define_insn "divsi_inv_hitable"
2308 [(set (match_operand:DI 0 "register_operand" "=r")
2309 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2310 (match_operand:DI 2 "register_operand" "r")]
2311 UNSPEC_DIV_INV_TABLE)))]
2315 [(set_attr "type" "load_media")
2316 (set_attr "highpart" "user")])
2318 ;; operands: inv0, tab_base, tab_ix, norm32
2319 ;; scratch equiv in sdivsi3_2: r19, r21
2320 (define_expand "divsi_inv_m0"
2321 [(set (match_operand:SI 0 "register_operand" "=r")
2322 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2323 (match_operand:DI 2 "register_operand" "r")
2324 (match_operand:SI 3 "register_operand" "r")]
2326 (clobber (match_operand:DI 4 "register_operand" "=r"))
2327 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2335 ldx.ub r20, r21, r19 // u0.8
2337 muls.l r25, r19, r19 // s2.38
2338 ldx.w r20, r21, r21 // s2.14
2339 shari r19, 24, r19 // truncate to s2.14
2340 sub r21, r19, r19 // some 11 bit inverse in s1.14
2343 rtx inv0 = operands[0];
2344 rtx tab_base = operands[1];
2345 rtx tab_ix = operands[2];
2346 rtx norm32 = operands[3];
2347 rtx scratch0 = operands[4];
2348 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2349 rtx scratch1 = operands[5];
2351 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2352 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2353 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2354 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2355 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2356 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2360 ;; operands: inv1, tab_base, tab_ix, norm32
2361 (define_insn_and_split "divsi_inv_m1"
2362 [(set (match_operand:SI 0 "register_operand" "=r")
2363 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2364 (match_operand:DI 2 "register_operand" "r")
2365 (match_operand:SI 3 "register_operand" "r")]
2367 (clobber (match_operand:SI 4 "register_operand" "=r"))
2368 (clobber (match_operand:DI 5 "register_operand" "=r"))
2369 (clobber (match_operand:DI 6 "register_operand" "=r"))
2370 (clobber (match_operand:DI 7 "register_operand" "=r"))
2371 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2374 "&& !can_create_pseudo_p ()"
2379 muls.l r19, r19, r18 // u0.28
2380 muls.l r25, r18, r18 // s2.58
2381 shlli r19, 45, r0 // multiply by two and convert to s2.58
2383 shari r18, 28, r18 // some 18 bit inverse in s1.30
2386 rtx inv1 = operands[0];
2387 rtx tab_base = operands[1];
2388 rtx tab_ix = operands[2];
2389 rtx norm32 = operands[3];
2390 rtx inv0 = operands[4];
2391 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2392 rtx scratch0a = operands[5];
2393 rtx scratch0b = operands[6];
2394 rtx scratch0 = operands[7];
2395 rtx scratch1 = operands[8];
2396 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2398 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2399 scratch0a, scratch0b));
2400 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2401 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2402 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2403 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2404 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2408 ;; operands: inv2, norm32, inv1, i92
2409 (define_insn_and_split "divsi_inv_m2"
2410 [(set (match_operand:SI 0 "register_operand" "=r")
2411 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2412 (match_operand:SI 2 "register_operand" "r")
2413 (match_operand:DI 3 "register_operand" "r")]
2415 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2418 "&& !can_create_pseudo_p ()"
2423 muls.l r18, r25, r0 // s2.60
2424 shari r0, 16, r0 // s-16.44
2426 muls.l r0, r18, r19 // s-16.74
2427 shari r19, 30, r19 // s-16.44
2429 rtx inv2 = operands[0];
2430 rtx norm32 = operands[1];
2431 rtx inv1 = operands[2];
2432 rtx i92 = operands[3];
2433 rtx scratch0 = operands[4];
2434 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2436 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2437 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2438 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2439 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2440 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2444 (define_insn_and_split "divsi_inv_m3"
2445 [(set (match_operand:SI 0 "register_operand" "=r")
2446 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2447 (match_operand:SI 2 "register_operand" "r")
2448 (match_operand:SI 3 "register_operand" "r")
2449 (match_operand:DI 4 "register_operand" "r")
2450 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2451 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2453 (clobber (match_operand:DI 7 "register_operand" "=r"))
2454 (clobber (match_operand:DI 8 "register_operand" "=r"))
2455 (clobber (match_operand:DI 9 "register_operand" "=r"))
2456 (clobber (match_operand:DI 10 "register_operand" "=r"))
2457 (clobber (match_operand:SI 11 "register_operand" "=r"))
2458 (clobber (match_operand:SI 12 "register_operand" "=r"))
2459 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2462 "&& !can_create_pseudo_p ()"
2467 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2468 r0: scratch0 r19: scratch1 r21: scratch2
2470 muls.l r18, r4, r25 // s32.30
2471 muls.l r19, r4, r19 // s15.30
2473 shari r19, 14, r19 // s18.-14
2479 rtx result = operands[0];
2480 rtx dividend = operands[1];
2481 rtx inv1 = operands[2];
2482 rtx inv2 = operands[3];
2483 rtx shift = operands[4];
2484 rtx scratch0 = operands[7];
2485 rtx scratch1 = operands[8];
2486 rtx scratch2 = operands[9];
2488 if (satisfies_constraint_N (dividend))
2490 emit_move_insn (result, dividend);
2494 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2495 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2496 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2497 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2498 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2499 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2500 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2504 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2505 ;; inv1: tab_base, tab_ix, norm32
2506 ;; inv2: norm32, inv1, i92
2507 (define_insn_and_split "divsi_inv_m1_3"
2508 [(set (match_operand:SI 0 "register_operand" "=r")
2509 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2510 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2511 (match_operand:DI 3 "register_operand" "r")
2512 (match_operand:SI 4 "register_operand" "r")]
2514 (unspec:SI [(match_dup 4)
2515 (unspec:SI [(match_dup 2)
2517 (match_dup 4)] UNSPEC_DIV_INV_M1)
2518 (match_operand:SI 5 "" "")]
2520 (match_operand:DI 6 "register_operand" "r")
2521 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2522 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2524 (clobber (match_operand:DI 9 "register_operand" "=r"))
2525 (clobber (match_operand:DI 10 "register_operand" "=r"))
2526 (clobber (match_operand:DI 11 "register_operand" "=r"))
2527 (clobber (match_operand:DI 12 "register_operand" "=r"))
2528 (clobber (match_operand:SI 13 "register_operand" "=r"))
2529 (clobber (match_operand:SI 14 "register_operand" "=r"))
2530 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2532 && (TARGET_DIVIDE_INV_MINLAT
2533 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2535 "&& !can_create_pseudo_p ()"
2539 rtx result = operands[0];
2540 rtx dividend = operands[1];
2541 rtx tab_base = operands[2];
2542 rtx tab_ix = operands[3];
2543 rtx norm32 = operands[4];
2544 /* rtx i92 = operands[5]; */
2545 rtx shift = operands[6];
2546 rtx i2p27 = operands[7];
2547 rtx i43 = operands[8];
2548 rtx scratch0 = operands[9];
2549 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2550 rtx scratch1 = operands[10];
2551 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2552 rtx scratch2 = operands[11];
2553 rtx scratch3 = operands[12];
2554 rtx scratch4 = operands[13];
2555 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2556 rtx scratch5 = operands[14];
2557 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2558 rtx scratch6 = operands[15];
2560 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2561 scratch0, scratch1));
2562 /* inv0 == scratch4 */
2563 if (! TARGET_DIVIDE_INV20U)
2565 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2567 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2571 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2572 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2574 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2575 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2576 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2577 /* inv1 == scratch4 */
2579 if (TARGET_DIVIDE_INV_MINLAT)
2581 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2582 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2583 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2584 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2585 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2586 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2587 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2588 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2589 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2590 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2591 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2595 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2596 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2597 emit_insn (gen_nsbdi (scratch6,
2598 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2599 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2600 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2601 emit_insn (gen_divsi_inv20 (scratch2,
2602 norm32, scratch4, dividend,
2603 scratch6, scratch3, i43,
2604 /* scratch0 may be shared with i2p27. */
2605 scratch0, scratch1, scratch5,
2606 label, label, i2p27));
2608 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2609 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2613 (define_insn "divsi_inv20"
2614 [(set (match_operand:DI 0 "register_operand" "=&r")
2615 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2616 (match_operand:SI 2 "register_operand" "r")
2617 (match_operand:SI 3 "register_operand" "r")
2618 (match_operand:DI 4 "register_operand" "r")
2619 (match_operand:DI 5 "register_operand" "r")
2620 (match_operand:DI 6 "register_operand" "r")
2621 (match_operand:DI 12 "register_operand" "r")
2622 (match_operand 10 "target_operand" "b")
2623 (match_operand 11 "immediate_operand" "i")]
2625 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2626 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2627 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2629 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2632 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2633 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2634 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2635 %10 label (tr), %11 label (imm)
2637 muls.l inv1, norm32, scratch0 // s2.60
2638 muls.l inv1, dividend, result // s32.30
2639 xor i2p27, result_sign, round_scratch
2640 bge/u dividend_nsb, i43, tr.. (label)
2641 shari scratch0, 16, scratch0 // s-16.44
2642 muls.l sratch0_si, inv1, scratch0 // s-16.74
2643 sub result, round_scratch, result
2644 shari dividend, 14, scratch1 // s19.-14
2645 shari scratch0, 30, scratch0 // s-16.44
2646 muls.l scratch0, scratch1, round_scratch // s15.30
2648 sub result, round_scratch, result */
2650 int likely = TARGET_DIVIDE_INV20L;
2652 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2653 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2654 output_asm_insn (likely
2655 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2656 : \"bge/u\t%4, %6, %10\", operands);
2657 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2658 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2659 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2661 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2662 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2665 (define_insn_and_split "divsi_inv_fp"
2666 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2667 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2668 (match_operand:SI 2 "register_operand" "rf")))
2669 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2670 (clobber (match_operand:SI 4 "register_operand" "=r"))
2671 (clobber (match_operand:SI 5 "register_operand" "=r"))
2672 (clobber (match_operand:DF 6 "register_operand" "=r"))
2673 (clobber (match_operand:DF 7 "register_operand" "=r"))
2674 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2675 "TARGET_SHMEDIA_FPU"
2677 "&& (high_life_started || reload_completed)"
2678 [(set (match_dup 0) (match_dup 3))]
2680 [(set_attr "highpart" "must_split")])
2682 ;; If a matching group of divide-by-inverse instructions is in the same
2683 ;; basic block after gcse & loop optimizations, we want to transform them
2684 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2685 (define_insn_and_split "*divsi_inv_fp_combine"
2686 [(set (match_operand:SI 0 "register_operand" "=f")
2687 (div:SI (match_operand:SI 1 "register_operand" "f")
2688 (match_operand:SI 2 "register_operand" "f")))
2689 (use (unspec:SI [(match_dup 1)
2690 (match_operand:SI 3 "" "")
2691 (unspec:SI [(match_operand:SI 4 "" "")
2693 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2694 (match_operand:DI 6 "" "")
2696 (const_int 0)] UNSPEC_DIV_INV_M3))
2697 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2698 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2699 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2700 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2701 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2702 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2705 [(set (match_dup 9) (float:DF (match_dup 1)))
2706 (set (match_dup 10) (float:DF (match_dup 2)))
2707 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2709 (fix:SI (match_dup 11)))
2710 (set (match_dup 0) (match_dup 8))]
2713 if (! fp_arith_reg_operand (operands[1], SImode))
2715 emit_move_insn (operands[7], operands[1]);
2716 operands[1] = operands[7];
2718 if (! fp_arith_reg_operand (operands[2], SImode))
2720 emit_move_insn (operands[8], operands[2]);
2721 operands[2] = operands[8];
2724 [(set_attr "highpart" "must_split")])
2726 ;; -------------------------------------------------------------------------
2727 ;; Multiplication instructions
2728 ;; -------------------------------------------------------------------------
2730 (define_insn "umulhisi3_i"
2731 [(set (reg:SI MACL_REG)
2732 (mult:SI (zero_extend:SI
2733 (match_operand:HI 0 "arith_reg_operand" "r"))
2735 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2738 [(set_attr "type" "smpy")])
2740 (define_insn "mulhisi3_i"
2741 [(set (reg:SI MACL_REG)
2742 (mult:SI (sign_extend:SI
2743 (match_operand:HI 0 "arith_reg_operand" "r"))
2745 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2748 [(set_attr "type" "smpy")])
2750 (define_expand "mulhisi3"
2751 [(set (reg:SI MACL_REG)
2752 (mult:SI (sign_extend:SI
2753 (match_operand:HI 1 "arith_reg_operand" ""))
2755 (match_operand:HI 2 "arith_reg_operand" ""))))
2756 (set (match_operand:SI 0 "arith_reg_operand" "")
2763 macl = gen_rtx_REG (SImode, MACL_REG);
2765 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2766 insn = get_insns ();
2768 /* expand_binop can't find a suitable code in umul_widen_optab to
2769 make a REG_EQUAL note from, so make one here.
2770 See also smulsi3_highpart.
2771 ??? Alternatively, we could put this at the calling site of expand_binop,
2772 i.e. expand_expr. */
2773 /* Use emit_libcall_block for loop invariant code motion and to make
2774 a REG_EQUAL note. */
2775 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2780 (define_expand "umulhisi3"
2781 [(set (reg:SI MACL_REG)
2782 (mult:SI (zero_extend:SI
2783 (match_operand:HI 1 "arith_reg_operand" ""))
2785 (match_operand:HI 2 "arith_reg_operand" ""))))
2786 (set (match_operand:SI 0 "arith_reg_operand" "")
2793 macl = gen_rtx_REG (SImode, MACL_REG);
2795 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2796 insn = get_insns ();
2798 /* expand_binop can't find a suitable code in umul_widen_optab to
2799 make a REG_EQUAL note from, so make one here.
2800 See also smulsi3_highpart.
2801 ??? Alternatively, we could put this at the calling site of expand_binop,
2802 i.e. expand_expr. */
2803 /* Use emit_libcall_block for loop invariant code motion and to make
2804 a REG_EQUAL note. */
2805 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2810 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2811 ;; a call to a routine which clobbers known registers.
2814 [(set (match_operand:SI 1 "register_operand" "=z")
2815 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2816 (clobber (reg:SI MACL_REG))
2817 (clobber (reg:SI T_REG))
2818 (clobber (reg:SI PR_REG))
2819 (clobber (reg:SI R3_REG))
2820 (clobber (reg:SI R2_REG))
2821 (clobber (reg:SI R1_REG))
2822 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2825 [(set_attr "type" "sfunc")
2826 (set_attr "needs_delay_slot" "yes")])
2828 (define_expand "mulsi3_call"
2829 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2830 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2831 (parallel[(set (match_operand:SI 0 "register_operand" "")
2832 (mult:SI (reg:SI R4_REG)
2834 (clobber (reg:SI MACL_REG))
2835 (clobber (reg:SI T_REG))
2836 (clobber (reg:SI PR_REG))
2837 (clobber (reg:SI R3_REG))
2838 (clobber (reg:SI R2_REG))
2839 (clobber (reg:SI R1_REG))
2840 (use (match_operand:SI 3 "register_operand" ""))])]
2844 (define_insn "mul_r"
2845 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2846 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2847 (match_operand:SI 2 "arith_reg_operand" "z")))]
2850 [(set_attr "type" "dmpy")])
2852 (define_insn "mul_l"
2853 [(set (reg:SI MACL_REG)
2854 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2855 (match_operand:SI 1 "arith_reg_operand" "r")))]
2858 [(set_attr "type" "dmpy")])
2860 (define_expand "mulsi3"
2861 [(set (reg:SI MACL_REG)
2862 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2863 (match_operand:SI 2 "arith_reg_operand" "")))
2864 (set (match_operand:SI 0 "arith_reg_operand" "")
2871 /* The address must be set outside the libcall,
2872 since it goes into a pseudo. */
2873 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2874 rtx addr = force_reg (SImode, sym);
2875 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2881 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2883 emit_insn (gen_mul_l (operands[1], operands[2]));
2884 /* consec_sets_giv can only recognize the first insn that sets a
2885 giv as the giv insn. So we must tag this also with a REG_EQUAL
2887 emit_insn (gen_movsi_i ((operands[0]), macl));
2892 (define_insn "mulsidi3_i"
2893 [(set (reg:SI MACH_REG)
2897 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2898 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2900 (set (reg:SI MACL_REG)
2901 (mult:SI (match_dup 0)
2905 [(set_attr "type" "dmpy")])
2907 (define_expand "mulsidi3"
2908 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2909 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2910 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2911 "TARGET_SH2 || TARGET_SHMEDIA"
2916 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2922 (define_insn "mulsidi3_media"
2923 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2924 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2925 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2928 [(set_attr "type" "dmpy_media")
2929 (set_attr "highpart" "ignore")])
2931 (define_insn "mulsidi3_compact"
2932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2934 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2935 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2936 (clobber (reg:SI MACH_REG))
2937 (clobber (reg:SI MACL_REG))]
2942 [(set (match_operand:DI 0 "arith_reg_dest" "")
2944 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2945 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2946 (clobber (reg:SI MACH_REG))
2947 (clobber (reg:SI MACL_REG))]
2952 rtx low_dst = gen_lowpart (SImode, operands[0]);
2953 rtx high_dst = gen_highpart (SImode, operands[0]);
2955 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2957 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2958 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2959 /* We need something to tag the possible REG_EQUAL notes on to. */
2960 emit_move_insn (operands[0], operands[0]);
2964 (define_insn "umulsidi3_i"
2965 [(set (reg:SI MACH_REG)
2969 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2970 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2972 (set (reg:SI MACL_REG)
2973 (mult:SI (match_dup 0)
2977 [(set_attr "type" "dmpy")])
2979 (define_expand "umulsidi3"
2980 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2981 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2982 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2983 "TARGET_SH2 || TARGET_SHMEDIA"
2988 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2994 (define_insn "umulsidi3_media"
2995 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2996 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2997 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3000 [(set_attr "type" "dmpy_media")
3001 (set_attr "highpart" "ignore")])
3003 (define_insn "umulsidi3_compact"
3004 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3006 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3007 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3008 (clobber (reg:SI MACH_REG))
3009 (clobber (reg:SI MACL_REG))]
3014 [(set (match_operand:DI 0 "arith_reg_dest" "")
3015 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3016 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3017 (clobber (reg:SI MACH_REG))
3018 (clobber (reg:SI MACL_REG))]
3023 rtx low_dst = gen_lowpart (SImode, operands[0]);
3024 rtx high_dst = gen_highpart (SImode, operands[0]);
3026 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3028 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3029 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3030 /* We need something to tag the possible REG_EQUAL notes on to. */
3031 emit_move_insn (operands[0], operands[0]);
3035 (define_insn "smulsi3_highpart_i"
3036 [(set (reg:SI MACH_REG)
3040 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3041 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3043 (clobber (reg:SI MACL_REG))]
3046 [(set_attr "type" "dmpy")])
3048 (define_expand "smulsi3_highpart"
3050 [(set (reg:SI MACH_REG)
3054 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3055 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3057 (clobber (reg:SI MACL_REG))])
3058 (set (match_operand:SI 0 "arith_reg_operand" "")
3065 mach = gen_rtx_REG (SImode, MACH_REG);
3067 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3068 insn = get_insns ();
3070 /* expand_binop can't find a suitable code in mul_highpart_optab to
3071 make a REG_EQUAL note from, so make one here.
3072 See also {,u}mulhisi.
3073 ??? Alternatively, we could put this at the calling site of expand_binop,
3074 i.e. expand_mult_highpart. */
3075 /* Use emit_libcall_block for loop invariant code motion and to make
3076 a REG_EQUAL note. */
3077 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3082 (define_insn "umulsi3_highpart_i"
3083 [(set (reg:SI MACH_REG)
3087 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3088 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3090 (clobber (reg:SI MACL_REG))]
3093 [(set_attr "type" "dmpy")])
3095 (define_expand "umulsi3_highpart"
3097 [(set (reg:SI MACH_REG)
3101 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3102 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3104 (clobber (reg:SI MACL_REG))])
3105 (set (match_operand:SI 0 "arith_reg_operand" "")
3112 mach = gen_rtx_REG (SImode, MACH_REG);
3114 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3115 insn = get_insns ();
3117 /* Use emit_libcall_block for loop invariant code motion and to make
3118 a REG_EQUAL note. */
3119 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3124 (define_insn_and_split "muldi3"
3125 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3126 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3127 (match_operand:DI 2 "arith_reg_operand" "r")))
3128 (clobber (match_scratch:DI 3 "=&r"))
3129 (clobber (match_scratch:DI 4 "=r"))]
3136 rtx op3_v2si, op2_v2si;
3138 op3_v2si = operands[3];
3139 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3141 op3_v2si = XEXP (op3_v2si, 0);
3142 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3144 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3145 op2_v2si = operands[2];
3146 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3148 op2_v2si = XEXP (op2_v2si, 0);
3149 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3151 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3152 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3153 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3154 emit_insn (gen_umulsidi3_media (operands[4],
3155 sh_gen_truncate (SImode, operands[1], 0),
3156 sh_gen_truncate (SImode, operands[2], 0)));
3157 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3158 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3159 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3160 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3165 ;; -------------------------------------------------------------------------
3166 ;; Logical operations
3167 ;; -------------------------------------------------------------------------
3169 (define_insn "*andsi3_compact"
3170 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3171 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3172 (match_operand:SI 2 "logical_operand" "r,K08")))]
3175 [(set_attr "type" "arith")])
3177 (define_insn "*andsi3_media"
3178 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3179 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3180 (match_operand:SI 2 "logical_operand" "r,I10")))]
3185 [(set_attr "type" "arith_media")])
3187 (define_insn "*andsi3_bclr"
3188 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3189 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3190 (match_operand:SI 2 "const_int_operand" "Psz")))]
3191 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3193 [(set_attr "type" "arith")])
3195 ;; If the constant is 255, then emit an extu.b instruction instead of an
3196 ;; and, since that will give better code.
3198 (define_expand "andsi3"
3199 [(set (match_operand:SI 0 "arith_reg_operand" "")
3200 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3201 (match_operand:SI 2 "logical_operand" "")))]
3206 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3208 emit_insn (gen_zero_extendqisi2 (operands[0],
3209 gen_lowpart (QImode, operands[1])));
3214 (define_insn_and_split "anddi3"
3215 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3216 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3217 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3224 && ! logical_operand (operands[2], DImode)"
3228 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3229 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3231 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3234 [(set_attr "type" "arith_media")])
3236 (define_insn "andcsi3"
3237 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3238 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3239 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3242 [(set_attr "type" "arith_media")])
3244 (define_insn "andcdi3"
3245 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3246 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3247 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3250 [(set_attr "type" "arith_media")])
3252 (define_expand "iorsi3"
3253 [(set (match_operand:SI 0 "arith_reg_operand" "")
3254 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3255 (match_operand:SI 2 "logical_operand" "")))]
3259 (define_insn "*iorsi3_compact"
3260 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3261 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3262 (match_operand:SI 2 "logical_operand" "r,K08")))]
3264 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3266 [(set_attr "type" "arith")])
3268 (define_insn "*iorsi3_media"
3269 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3270 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3271 (match_operand:SI 2 "logical_operand" "r,I10")))]
3276 [(set_attr "type" "arith_media")])
3278 (define_insn "*iorsi3_bset"
3279 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3280 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3281 (match_operand:SI 2 "const_int_operand" "Pso")))]
3282 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3284 [(set_attr "type" "arith")])
3286 (define_insn "iordi3"
3287 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3288 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3289 (match_operand:DI 2 "logical_operand" "r,I10")))]
3294 [(set_attr "type" "arith_media")])
3296 (define_insn_and_split "*logical_sidi3"
3297 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3298 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3299 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3300 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3303 "&& reload_completed"
3304 [(set (match_dup 0) (match_dup 3))]
3308 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3309 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3310 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3313 (define_insn_and_split "*logical_sidisi3"
3314 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315 (truncate:SI (sign_extend:DI
3316 (match_operator:SI 3 "logical_operator"
3317 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3318 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3322 [(set (match_dup 0) (match_dup 3))])
3324 (define_insn_and_split "*logical_sidi3_2"
3325 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3326 (sign_extend:DI (truncate:SI (sign_extend:DI
3327 (match_operator:SI 3 "logical_operator"
3328 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3329 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3333 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3335 (define_expand "xorsi3"
3336 [(set (match_operand:SI 0 "arith_reg_operand" "")
3337 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3338 (match_operand:SI 2 "xor_operand" "")))]
3342 (define_insn "*xorsi3_compact"
3343 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3344 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3345 (match_operand:SI 2 "logical_operand" "K08,r")))]
3348 [(set_attr "type" "arith")])
3350 (define_insn "*xorsi3_media"
3351 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3352 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3353 (match_operand:SI 2 "xor_operand" "r,I06")))]
3358 [(set_attr "type" "arith_media")])
3360 ;; Store the complements of the T bit in a register.
3361 (define_insn "xorsi3_movrt"
3362 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3363 (xor:SI (reg:SI T_REG)
3367 [(set_attr "type" "arith")])
3369 (define_insn "xordi3"
3370 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3371 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3372 (match_operand:DI 2 "xor_operand" "r,I06")))]
3377 [(set_attr "type" "arith_media")])
3379 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3380 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3382 [(set (match_operand:DI 0 "arith_reg_dest" "")
3383 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3384 [(match_operand 1 "any_register_operand" "")
3385 (match_operand 2 "any_register_operand" "")])))]
3387 [(set (match_dup 5) (match_dup 4))
3388 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3391 enum machine_mode inmode = GET_MODE (operands[1]);
3394 if (GET_CODE (operands[0]) == SUBREG)
3396 offset = SUBREG_BYTE (operands[0]);
3397 operands[0] = SUBREG_REG (operands[0]);
3399 gcc_assert (GET_CODE (operands[0]) == REG);
3400 if (! TARGET_LITTLE_ENDIAN)
3401 offset += 8 - GET_MODE_SIZE (inmode);
3402 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3405 ;; -------------------------------------------------------------------------
3406 ;; Shifts and rotates
3407 ;; -------------------------------------------------------------------------
3409 (define_expand "rotldi3"
3410 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3411 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3412 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3414 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3416 (define_insn "rotldi3_mextr"
3417 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3418 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3419 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3423 static char templ[16];
3425 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3426 8 - (int) (INTVAL (operands[2]) >> 3));
3429 [(set_attr "type" "arith_media")])
3431 (define_expand "rotrdi3"
3432 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3433 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3434 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3436 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3438 (define_insn "rotrdi3_mextr"
3439 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3440 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3441 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3445 static char templ[16];
3447 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3450 [(set_attr "type" "arith_media")])
3453 [(set (match_operand:DI 0 "arith_reg_dest" "")
3454 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3455 "ua_address_operand" "")))
3456 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3458 (clobber (match_operand:DI 3 "register_operand" ""))]
3460 [(match_dup 4) (match_dup 5)]
3463 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3464 (operands[3], operands[1]));
3465 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3466 GEN_INT (56), GEN_INT (8));
3469 (define_insn "rotlsi3_1"
3470 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3471 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3474 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3477 [(set_attr "type" "arith")])
3479 (define_insn "rotlsi3_31"
3480 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3481 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3483 (clobber (reg:SI T_REG))]
3486 [(set_attr "type" "arith")])
3488 (define_insn "rotlsi3_16"
3489 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3490 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3494 [(set_attr "type" "arith")])
3496 (define_expand "rotlsi3"
3497 [(set (match_operand:SI 0 "arith_reg_dest" "")
3498 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3499 (match_operand:SI 2 "immediate_operand" "")))]
3503 static const char rot_tab[] = {
3504 000, 000, 000, 000, 000, 000, 010, 001,
3505 001, 001, 011, 013, 003, 003, 003, 003,
3506 003, 003, 003, 003, 003, 013, 012, 002,
3507 002, 002, 010, 000, 000, 000, 000, 000,
3512 if (GET_CODE (operands[2]) != CONST_INT)
3514 count = INTVAL (operands[2]);
3515 choice = rot_tab[count];
3516 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3522 emit_move_insn (operands[0], operands[1]);
3523 count -= (count & 16) * 2;
3526 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3533 parts[0] = gen_reg_rtx (SImode);
3534 parts[1] = gen_reg_rtx (SImode);
3535 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3536 emit_move_insn (parts[choice-1], operands[1]);
3537 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3538 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3539 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3540 count = (count & ~16) - 8;
3544 for (; count > 0; count--)
3545 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3546 for (; count < 0; count++)
3547 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3552 (define_insn "*rotlhi3_8"
3553 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3554 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3558 [(set_attr "type" "arith")])
3560 (define_expand "rotlhi3"
3561 [(set (match_operand:HI 0 "arith_reg_operand" "")
3562 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3563 (match_operand:HI 2 "immediate_operand" "")))]
3567 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3574 (define_insn "ashlsi3_sh2a"
3575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577 (match_operand:SI 2 "arith_reg_operand" "r")))]
3580 [(set_attr "type" "arith")
3581 (set_attr "length" "4")])
3583 ;; This pattern is used by init_expmed for computing the costs of shift
3586 (define_insn_and_split "ashlsi3_std"
3587 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3588 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3589 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3590 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3592 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3600 && GET_CODE (operands[2]) == CONST_INT
3601 && ! satisfies_constraint_P27 (operands[2])"
3602 [(set (match_dup 3) (match_dup 2))
3604 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3605 (clobber (match_dup 4))])]
3606 "operands[4] = gen_rtx_SCRATCH (SImode);"
3607 [(set_attr "length" "*,*,*,4")
3608 (set_attr "type" "dyn_shift,arith,arith,arith")])
3610 (define_insn "ashlhi3_k"
3611 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3612 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3613 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3614 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3618 [(set_attr "type" "arith")])
3620 (define_insn "ashlsi3_n"
3621 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3622 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3623 (match_operand:SI 2 "const_int_operand" "n")))
3624 (clobber (reg:SI T_REG))]
3625 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3627 [(set (attr "length")
3628 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3630 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3632 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3634 (const_string "8")))
3635 (set_attr "type" "arith")])
3638 [(set (match_operand:SI 0 "arith_reg_dest" "")
3639 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3640 (match_operand:SI 2 "const_int_operand" "")))
3641 (clobber (reg:SI T_REG))]
3642 "TARGET_SH1 && reload_completed"
3643 [(use (reg:SI R0_REG))]
3646 gen_shifty_op (ASHIFT, operands);
3650 (define_insn "ashlsi3_media"
3651 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3652 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3653 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3658 [(set_attr "type" "arith_media")
3659 (set_attr "highpart" "ignore")])
3661 (define_expand "ashlsi3"
3662 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3663 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3664 (match_operand:SI 2 "nonmemory_operand" "")))
3665 (clobber (reg:SI T_REG))])]
3671 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3674 if (GET_CODE (operands[2]) == CONST_INT
3675 && sh_dynamicalize_shift_p (operands[2]))
3676 operands[2] = force_reg (SImode, operands[2]);
3679 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3682 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3686 (define_insn "*ashlhi3_n"
3687 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3688 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3689 (match_operand:HI 2 "const_int_operand" "n")))
3690 (clobber (reg:SI T_REG))]
3693 [(set (attr "length")
3694 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3696 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3698 (const_string "6")))
3699 (set_attr "type" "arith")])
3701 (define_expand "ashlhi3"
3702 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3703 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3704 (match_operand:SI 2 "nonmemory_operand" "")))
3705 (clobber (reg:SI T_REG))])]
3709 if (GET_CODE (operands[2]) != CONST_INT)
3711 /* It may be possible to call gen_ashlhi3 directly with more generic
3712 operands. Make sure operands[1] is a HImode register here. */
3713 if (!arith_reg_operand (operands[1], HImode))
3714 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3718 [(set (match_operand:HI 0 "arith_reg_dest" "")
3719 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3720 (match_operand:HI 2 "const_int_operand" "")))
3721 (clobber (reg:SI T_REG))]
3722 "TARGET_SH1 && reload_completed"
3723 [(use (reg:SI R0_REG))]
3726 gen_shifty_hi_op (ASHIFT, operands);
3731 ; arithmetic shift right
3734 (define_insn "ashrsi3_sh2a"
3735 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3736 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3737 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3740 [(set_attr "type" "dyn_shift")
3741 (set_attr "length" "4")])
3743 (define_insn "ashrsi3_k"
3744 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3745 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3746 (match_operand:SI 2 "const_int_operand" "M")))
3747 (clobber (reg:SI T_REG))]
3748 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3750 [(set_attr "type" "arith")])
3752 ;; We can't do HImode right shifts correctly unless we start out with an
3753 ;; explicit zero / sign extension; doing that would result in worse overall
3754 ;; code, so just let the machine independent code widen the mode.
3755 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3758 ;; ??? This should be a define expand.
3760 (define_insn "ashrsi2_16"
3761 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3762 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3766 [(set_attr "length" "4")])
3769 [(set (match_operand:SI 0 "arith_reg_dest" "")
3770 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3773 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3774 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3775 "operands[2] = gen_lowpart (HImode, operands[0]);")
3777 ;; ??? This should be a define expand.
3779 (define_insn "ashrsi2_31"
3780 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3781 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3783 (clobber (reg:SI T_REG))]
3786 [(set_attr "length" "4")])
3789 [(set (match_operand:SI 0 "arith_reg_dest" "")
3790 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3792 (clobber (reg:SI T_REG))]
3797 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3798 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3803 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3805 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3807 && peep2_reg_dead_p (2, operands[0])
3808 && peep2_reg_dead_p (2, operands[1])"
3812 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3816 (define_insn "ashlsi_c"
3817 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3818 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3820 (lt:SI (match_dup 1) (const_int 0)))]
3823 [(set_attr "type" "arith")])
3825 (define_insn "*ashlsi_c_void"
3826 [(set (reg:SI T_REG)
3827 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3828 (clobber (match_scratch:SI 1 "=0"))]
3829 "TARGET_SH1 && cse_not_expected"
3831 [(set_attr "type" "arith")])
3833 (define_insn "ashrsi3_d"
3834 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3835 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3836 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3839 [(set_attr "type" "dyn_shift")])
3841 (define_insn "ashrsi3_n"
3842 [(set (reg:SI R4_REG)
3843 (ashiftrt:SI (reg:SI R4_REG)
3844 (match_operand:SI 0 "const_int_operand" "i")))
3845 (clobber (reg:SI T_REG))
3846 (clobber (reg:SI PR_REG))
3847 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3850 [(set_attr "type" "sfunc")
3851 (set_attr "needs_delay_slot" "yes")])
3853 (define_insn "ashrsi3_media"
3854 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3855 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3856 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3861 [(set_attr "type" "arith_media")
3862 (set_attr "highpart" "ignore")])
3864 (define_expand "ashrsi3"
3865 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3866 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3867 (match_operand:SI 2 "nonmemory_operand" "")))
3868 (clobber (reg:SI T_REG))])]
3874 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3877 if (expand_ashiftrt (operands))
3883 ;; logical shift right
3885 (define_insn "lshrsi3_sh2a"
3886 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3887 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3888 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3891 [(set_attr "type" "dyn_shift")
3892 (set_attr "length" "4")])
3894 (define_insn "lshrsi3_d"
3895 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3896 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3897 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3900 [(set_attr "type" "dyn_shift")])
3902 ;; Only the single bit shift clobbers the T bit.
3904 (define_insn "lshrsi3_m"
3905 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3906 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3907 (match_operand:SI 2 "const_int_operand" "M")))
3908 (clobber (reg:SI T_REG))]
3909 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3911 [(set_attr "type" "arith")])
3913 (define_insn "lshrsi3_k"
3914 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3915 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3916 (match_operand:SI 2 "const_int_operand" "P27")))]
3917 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3918 && ! satisfies_constraint_M (operands[2])"
3920 [(set_attr "type" "arith")])
3922 (define_insn "lshrsi3_n"
3923 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3924 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3925 (match_operand:SI 2 "const_int_operand" "n")))
3926 (clobber (reg:SI T_REG))]
3927 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3929 [(set (attr "length")
3930 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3932 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3934 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3936 (const_string "8")))
3937 (set_attr "type" "arith")])
3940 [(set (match_operand:SI 0 "arith_reg_dest" "")
3941 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3942 (match_operand:SI 2 "const_int_operand" "")))
3943 (clobber (reg:SI T_REG))]
3944 "TARGET_SH1 && reload_completed"
3945 [(use (reg:SI R0_REG))]
3948 gen_shifty_op (LSHIFTRT, operands);
3952 (define_insn "lshrsi3_media"
3953 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3954 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3955 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3960 [(set_attr "type" "arith_media")
3961 (set_attr "highpart" "ignore")])
3963 (define_expand "lshrsi3"
3964 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3965 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3966 (match_operand:SI 2 "nonmemory_operand" "")))
3967 (clobber (reg:SI T_REG))])]
3973 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3976 if (GET_CODE (operands[2]) == CONST_INT
3977 && sh_dynamicalize_shift_p (operands[2]))
3978 operands[2] = force_reg (SImode, operands[2]);
3979 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3981 rtx count = copy_to_mode_reg (SImode, operands[2]);
3982 emit_insn (gen_negsi2 (count, count));
3983 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3986 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3990 ;; ??? This should be a define expand.
3992 (define_insn "ashldi3_k"
3993 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3994 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3996 (clobber (reg:SI T_REG))]
3998 "shll %R0\;rotcl %S0"
3999 [(set_attr "length" "4")
4000 (set_attr "type" "arith")])
4002 (define_insn "ashldi3_media"
4003 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4004 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4005 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4010 [(set_attr "type" "arith_media")])
4012 (define_insn "*ashldisi3_media"
4013 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4014 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4015 (match_operand:DI 2 "const_int_operand" "n")))]
4016 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4017 "shlli.l %1, %2, %0"
4018 [(set_attr "type" "arith_media")
4019 (set_attr "highpart" "ignore")])
4021 (define_expand "ashldi3"
4022 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4023 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4024 (match_operand:DI 2 "immediate_operand" "")))
4025 (clobber (reg:SI T_REG))])]
4031 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4034 if (GET_CODE (operands[2]) != CONST_INT
4035 || INTVAL (operands[2]) != 1)
4039 ;; ??? This should be a define expand.
4041 (define_insn "lshrdi3_k"
4042 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4043 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4045 (clobber (reg:SI T_REG))]
4047 "shlr %S0\;rotcr %R0"
4048 [(set_attr "length" "4")
4049 (set_attr "type" "arith")])
4051 (define_insn "lshrdi3_media"
4052 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4053 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4054 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4056 && (arith_reg_dest (operands[0], DImode)
4057 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4061 [(set_attr "type" "arith_media")])
4063 (define_insn "*lshrdisi3_media"
4064 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4065 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4066 (match_operand:DI 2 "const_int_operand" "n")))]
4067 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4068 "shlri.l %1, %2, %0"
4069 [(set_attr "type" "arith_media")
4070 (set_attr "highpart" "ignore")])
4072 (define_expand "lshrdi3"
4073 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4074 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4075 (match_operand:DI 2 "immediate_operand" "")))
4076 (clobber (reg:SI T_REG))])]
4082 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4085 if (GET_CODE (operands[2]) != CONST_INT
4086 || INTVAL (operands[2]) != 1)
4090 ;; ??? This should be a define expand.
4092 (define_insn "ashrdi3_k"
4093 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4094 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4096 (clobber (reg:SI T_REG))]
4098 "shar %S0\;rotcr %R0"
4099 [(set_attr "length" "4")
4100 (set_attr "type" "arith")])
4102 (define_insn "ashrdi3_media"
4103 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4104 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4105 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4107 && (arith_reg_dest (operands[0], DImode)
4108 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4112 [(set_attr "type" "arith_media")])
4114 (define_insn "*ashrdisi3_media"
4115 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4116 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4117 (match_operand:DI 2 "const_int_operand" "n")))]
4118 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4119 "shari.l %1, %2, %0"
4120 [(set_attr "type" "arith_media")
4121 (set_attr "highpart" "ignore")])
4123 (define_insn "ashrdisi3_media_high"
4124 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4126 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4127 (match_operand:DI 2 "const_int_operand" "n"))))]
4128 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4130 [(set_attr "type" "arith_media")])
4132 (define_insn "ashrdisi3_media_opaque"
4133 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4134 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4135 (match_operand:DI 2 "const_int_operand" "n")]
4139 [(set_attr "type" "arith_media")])
4141 (define_expand "ashrdi3"
4142 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4143 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4144 (match_operand:DI 2 "immediate_operand" "")))
4145 (clobber (reg:SI T_REG))])]
4151 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4154 if (GET_CODE (operands[2]) != CONST_INT
4155 || INTVAL (operands[2]) != 1)
4159 ;; combined left/right shift
4162 [(set (match_operand:SI 0 "register_operand" "")
4163 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4164 (match_operand:SI 2 "const_int_operand" ""))
4165 (match_operand:SI 3 "const_int_operand" "")))]
4166 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4167 [(use (reg:SI R0_REG))]
4168 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4172 [(set (match_operand:SI 0 "register_operand" "")
4173 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4174 (match_operand:SI 2 "const_int_operand" ""))
4175 (match_operand:SI 3 "const_int_operand" "")))
4176 (clobber (reg:SI T_REG))]
4177 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4178 [(use (reg:SI R0_REG))]
4179 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4183 [(set (match_operand:SI 0 "register_operand" "=r")
4184 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4185 (match_operand:SI 2 "const_int_operand" "n"))
4186 (match_operand:SI 3 "const_int_operand" "n")))
4187 (clobber (reg:SI T_REG))]
4188 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4190 [(set (attr "length")
4191 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4193 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4195 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4197 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4199 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4201 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4203 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4204 (const_string "16")]
4205 (const_string "18")))
4206 (set_attr "type" "arith")])
4209 [(set (match_operand:SI 0 "register_operand" "=z")
4210 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4211 (match_operand:SI 2 "const_int_operand" "n"))
4212 (match_operand:SI 3 "const_int_operand" "n")))
4213 (clobber (reg:SI T_REG))]
4214 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4216 [(set (attr "length")
4217 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4219 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4221 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4223 (const_string "10")))
4224 (set_attr "type" "arith")])
4226 ;; shift left / and combination with a scratch register: The combine pass
4227 ;; does not accept the individual instructions, even though they are
4228 ;; cheap. But it needs a precise description so that it is usable after
4230 (define_insn "and_shl_scratch"
4231 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4235 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4236 (match_operand:SI 2 "const_int_operand" "N,n"))
4237 (match_operand:SI 3 "" "0,r"))
4238 (match_operand:SI 4 "const_int_operand" "n,n"))
4239 (match_operand:SI 5 "const_int_operand" "n,n")))
4240 (clobber (reg:SI T_REG))]
4243 [(set (attr "length")
4244 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4246 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4248 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4250 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4251 (const_string "10")]
4252 (const_string "12")))
4253 (set_attr "type" "arith")])
4256 [(set (match_operand:SI 0 "register_operand" "")
4260 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4261 (match_operand:SI 2 "const_int_operand" ""))
4262 (match_operand:SI 3 "register_operand" ""))
4263 (match_operand:SI 4 "const_int_operand" ""))
4264 (match_operand:SI 5 "const_int_operand" "")))
4265 (clobber (reg:SI T_REG))]
4267 [(use (reg:SI R0_REG))]
4270 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4272 if (INTVAL (operands[2]))
4274 gen_shifty_op (LSHIFTRT, operands);
4276 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4277 operands[2] = operands[4];
4278 gen_shifty_op (ASHIFT, operands);
4279 if (INTVAL (operands[5]))
4281 operands[2] = operands[5];
4282 gen_shifty_op (LSHIFTRT, operands);
4287 ;; signed left/right shift combination.
4289 [(set (match_operand:SI 0 "register_operand" "")
4291 (ashift:SI (match_operand:SI 1 "register_operand" "")
4292 (match_operand:SI 2 "const_int_operand" ""))
4293 (match_operand:SI 3 "const_int_operand" "")
4295 (clobber (reg:SI T_REG))]
4297 [(use (reg:SI R0_REG))]
4298 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4301 (define_insn "shl_sext_ext"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4304 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4305 (match_operand:SI 2 "const_int_operand" "n"))
4306 (match_operand:SI 3 "const_int_operand" "n")
4308 (clobber (reg:SI T_REG))]
4309 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4311 [(set (attr "length")
4312 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4314 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4316 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4318 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4320 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4322 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4324 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4326 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4327 (const_string "16")]
4328 (const_string "18")))
4329 (set_attr "type" "arith")])
4331 (define_insn "shl_sext_sub"
4332 [(set (match_operand:SI 0 "register_operand" "=z")
4334 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4335 (match_operand:SI 2 "const_int_operand" "n"))
4336 (match_operand:SI 3 "const_int_operand" "n")
4338 (clobber (reg:SI T_REG))]
4339 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4341 [(set (attr "length")
4342 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4344 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4346 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4348 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4349 (const_string "12")]
4350 (const_string "14")))
4351 (set_attr "type" "arith")])
4353 ;; These patterns are found in expansions of DImode shifts by 16, and
4354 ;; allow the xtrct instruction to be generated from C source.
4356 (define_insn "xtrct_left"
4357 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4358 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4360 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4364 [(set_attr "type" "arith")])
4366 (define_insn "xtrct_right"
4367 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4368 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4370 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4374 [(set_attr "type" "arith")])
4376 ;; -------------------------------------------------------------------------
4378 ;; -------------------------------------------------------------------------
4381 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4382 (neg:SI (plus:SI (reg:SI T_REG)
4383 (match_operand:SI 1 "arith_reg_operand" "r"))))
4385 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4389 [(set_attr "type" "arith")])
4391 (define_insn "*negdi_media"
4392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4393 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4396 [(set_attr "type" "arith_media")])
4398 (define_expand "negdi2"
4399 [(set (match_operand:DI 0 "arith_reg_operand" "")
4400 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4406 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4407 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4409 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4410 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4412 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4413 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4415 emit_insn (gen_clrt ());
4416 emit_insn (gen_negc (low_dst, low_src));
4417 emit_insn (gen_negc (high_dst, high_src));
4422 (define_insn "negsi2"
4423 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4424 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4427 [(set_attr "type" "arith")])
4429 (define_insn "one_cmplsi2"
4430 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4431 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4434 [(set_attr "type" "arith")])
4436 (define_expand "one_cmpldi2"
4437 [(set (match_operand:DI 0 "arith_reg_dest" "")
4438 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4440 "TARGET_SHMEDIA" "")
4442 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4443 This can be used as some kind of conditional execution, which is useful
4446 [(set (match_operand:SI 0 "arith_reg_dest" "")
4447 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4448 (match_operand:SI 1 "arith_reg_operand" ""))
4452 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4453 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4457 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4458 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4459 (match_operand:SI 1 "arith_reg_operand" "0")
4460 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4462 "bf 0f\;neg %2,%0\\n0:"
4463 [(set_attr "type" "arith") ;; poor approximation
4464 (set_attr "length" "4")])
4467 ;; -------------------------------------------------------------------------
4468 ;; Zero extension instructions
4469 ;; -------------------------------------------------------------------------
4471 (define_insn "zero_extendsidi2"
4472 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4473 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4475 "addz.l %1, r63, %0"
4476 [(set_attr "type" "arith_media")
4477 (set_attr "highpart" "extend")])
4479 (define_insn "zero_extendhidi2"
4480 [(set (match_operand:DI 0 "register_operand" "=r,r")
4481 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4486 [(set_attr "type" "*,load_media")
4487 (set (attr "highpart")
4488 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4489 (const_string "user")]
4490 (const_string "ignore")))])
4493 [(set (match_operand:DI 0 "register_operand" "")
4494 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4495 "TARGET_SHMEDIA && reload_completed"
4496 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4497 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4500 if (GET_CODE (operands[1]) == TRUNCATE)
4501 operands[1] = XEXP (operands[1], 0);
4504 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4505 ;; reload the entire truncate expression.
4506 (define_insn_and_split "*loaddi_trunc"
4507 [(set (match_operand 0 "any_register_operand" "=r")
4508 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4509 "TARGET_SHMEDIA && reload_completed"
4511 "TARGET_SHMEDIA && reload_completed"
4512 [(set (match_dup 0) (match_dup 1))]
4513 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4515 (define_insn "zero_extendqidi2"
4516 [(set (match_operand:DI 0 "register_operand" "=r,r")
4517 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4522 [(set_attr "type" "arith_media,load_media")
4523 (set (attr "highpart")
4524 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4525 (const_string "user")]
4526 (const_string "ignore")))])
4528 (define_expand "zero_extendhisi2"
4529 [(set (match_operand:SI 0 "arith_reg_operand" "")
4530 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4534 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4535 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4538 (define_insn "*zero_extendhisi2_compact"
4539 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4540 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4543 [(set_attr "type" "arith")])
4545 (define_insn "*zero_extendhisi2_media"
4546 [(set (match_operand:SI 0 "register_operand" "=r,r")
4547 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4552 [(set_attr "type" "arith_media,load_media")
4553 (set (attr "highpart")
4554 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4555 (const_string "user")]
4556 (const_string "ignore")))])
4559 [(set (match_operand:SI 0 "register_operand" "")
4560 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4561 "TARGET_SHMEDIA && reload_completed"
4562 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4563 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4566 rtx op1 = operands[1];
4568 if (GET_CODE (op1) == TRUNCATE)
4569 op1 = XEXP (op1, 0);
4571 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4572 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4575 (define_expand "zero_extendqisi2"
4576 [(set (match_operand:SI 0 "arith_reg_operand" "")
4577 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4581 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4582 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4585 (define_insn "*zero_extendqisi2_compact"
4586 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4587 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4590 [(set_attr "type" "arith")])
4592 (define_insn "*zero_extendqisi2_media"
4593 [(set (match_operand:SI 0 "register_operand" "=r,r")
4594 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4599 [(set_attr "type" "arith_media,load_media")
4600 (set (attr "highpart")
4601 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4602 (const_string "user")]
4603 (const_string "ignore")))])
4605 (define_insn "zero_extendqihi2"
4606 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4607 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4610 [(set_attr "type" "arith")])
4612 ;; -------------------------------------------------------------------------
4613 ;; Sign extension instructions
4614 ;; -------------------------------------------------------------------------
4616 ;; ??? This should be a define expand.
4617 ;; ??? Or perhaps it should be dropped?
4619 ;; convert_move generates good code for SH[1-4].
4620 (define_insn "extendsidi2"
4621 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4622 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4628 [(set_attr "type" "arith_media,load_media,fpconv_media")
4629 (set (attr "highpart")
4630 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4631 (const_string "user")]
4632 (const_string "extend")))])
4634 (define_insn "extendhidi2"
4635 [(set (match_operand:DI 0 "register_operand" "=r,r")
4636 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4641 [(set_attr "type" "*,load_media")
4642 (set (attr "highpart")
4643 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4644 (const_string "user")]
4645 (const_string "ignore")))])
4648 [(set (match_operand:DI 0 "register_operand" "")
4649 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4650 "TARGET_SHMEDIA && reload_completed"
4651 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4652 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4655 if (GET_CODE (operands[1]) == TRUNCATE)
4656 operands[1] = XEXP (operands[1], 0);
4659 (define_insn "extendqidi2"
4660 [(set (match_operand:DI 0 "register_operand" "=r,r")
4661 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4666 [(set_attr "type" "*,load_media")
4667 (set (attr "highpart")
4668 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4669 (const_string "user")]
4670 (const_string "ignore")))])
4673 [(set (match_operand:DI 0 "register_operand" "")
4674 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4675 "TARGET_SHMEDIA && reload_completed"
4676 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4677 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4680 if (GET_CODE (operands[1]) == TRUNCATE)
4681 operands[1] = XEXP (operands[1], 0);
4684 (define_expand "extendhisi2"
4685 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4686 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4690 (define_insn "*extendhisi2_compact"
4691 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4692 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4697 [(set_attr "type" "arith,load")])
4699 (define_insn "*extendhisi2_media"
4700 [(set (match_operand:SI 0 "register_operand" "=r,r")
4701 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4706 [(set_attr "type" "arith_media,load_media")
4707 (set (attr "highpart")
4708 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4709 (const_string "user")]
4710 (const_string "ignore")))])
4713 [(set (match_operand:SI 0 "register_operand" "")
4714 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4715 "TARGET_SHMEDIA && reload_completed"
4716 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4717 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4720 rtx op1 = operands[1];
4721 if (GET_CODE (op1) == TRUNCATE)
4722 op1 = XEXP (op1, 0);
4724 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4725 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4728 (define_expand "extendqisi2"
4729 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4730 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4734 (define_insn "*extendqisi2_compact"
4735 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4736 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4741 [(set_attr "type" "arith,load")
4742 (set_attr_alternative "length"
4745 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4746 (const_int 4) (const_int 2))])])
4748 (define_insn "*extendqisi2_media"
4749 [(set (match_operand:SI 0 "register_operand" "=r,r")
4750 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4755 [(set_attr "type" "arith_media,load_media")
4756 (set (attr "highpart")
4757 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4758 (const_string "user")]
4759 (const_string "ignore")))])
4762 [(set (match_operand:SI 0 "register_operand" "")
4763 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4764 "TARGET_SHMEDIA && reload_completed"
4765 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4766 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4769 rtx op1 = operands[1];
4770 if (GET_CODE (op1) == TRUNCATE)
4771 op1 = XEXP (op1, 0);
4773 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4774 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4777 (define_insn "extendqihi2"
4778 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4779 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4784 [(set_attr "type" "arith,load")
4785 (set_attr_alternative "length"
4788 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4789 (const_int 4) (const_int 2))])])
4791 /* It would seem useful to combine the truncXi patterns into the movXi
4792 patterns, but unary operators are ignored when matching constraints,
4793 so we need separate patterns. */
4794 (define_insn "truncdisi2"
4795 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4796 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4805 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4806 (set (attr "highpart")
4807 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4808 (const_string "user")]
4809 (const_string "extend")))])
4811 (define_insn "truncdihi2"
4812 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4813 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4816 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4818 [(set_attr "type" "arith_media,store_media")
4819 (set_attr "length" "8,4")
4820 (set (attr "highpart")
4821 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4822 (const_string "user")]
4823 (const_string "extend")))])
4825 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4826 ; Because we use zero extension, we can't provide signed QImode compares
4827 ; using a simple compare or conditional branch insn.
4828 (define_insn "truncdiqi2"
4829 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4830 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4835 [(set_attr "type" "arith_media,store")
4836 (set (attr "highpart")
4837 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4838 (const_string "user")]
4839 (const_string "extend")))])
4840 ;; -------------------------------------------------------------------------
4841 ;; Move instructions
4842 ;; -------------------------------------------------------------------------
4844 ;; define push and pop so it is easy for sh.c
4845 ;; We can't use push and pop on SHcompact because the stack must always
4846 ;; be 8-byte aligned.
4848 (define_expand "push"
4849 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4850 (match_operand:SI 0 "register_operand" "r,l,x"))]
4851 "TARGET_SH1 && ! TARGET_SH5"
4854 (define_expand "pop"
4855 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4856 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4857 "TARGET_SH1 && ! TARGET_SH5"
4860 (define_expand "push_e"
4861 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4862 (match_operand:SF 0 "" ""))
4863 (use (reg:PSI FPSCR_REG))
4864 (clobber (scratch:SI))])]
4865 "TARGET_SH1 && ! TARGET_SH5"
4868 (define_insn "push_fpul"
4869 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4870 "TARGET_SH2E && ! TARGET_SH5"
4872 [(set_attr "type" "fstore")
4873 (set_attr "late_fp_use" "yes")
4874 (set_attr "hit_stack" "yes")])
4876 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4878 (define_expand "push_4"
4879 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4880 (match_operand:DF 0 "" ""))
4881 (use (reg:PSI FPSCR_REG))
4882 (clobber (scratch:SI))])]
4883 "TARGET_SH1 && ! TARGET_SH5"
4886 (define_expand "pop_e"
4887 [(parallel [(set (match_operand:SF 0 "" "")
4888 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4889 (use (reg:PSI FPSCR_REG))
4890 (clobber (scratch:SI))])]
4891 "TARGET_SH1 && ! TARGET_SH5"
4894 (define_insn "pop_fpul"
4895 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4896 "TARGET_SH2E && ! TARGET_SH5"
4898 [(set_attr "type" "load")
4899 (set_attr "hit_stack" "yes")])
4901 (define_expand "pop_4"
4902 [(parallel [(set (match_operand:DF 0 "" "")
4903 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4904 (use (reg:PSI FPSCR_REG))
4905 (clobber (scratch:SI))])]
4906 "TARGET_SH1 && ! TARGET_SH5"
4909 (define_expand "push_fpscr"
4914 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4915 gen_rtx_PRE_DEC (Pmode,
4916 stack_pointer_rtx)),
4918 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4922 (define_expand "pop_fpscr"
4927 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4928 gen_frame_mem (PSImode,
4929 gen_rtx_POST_INC (Pmode,
4930 stack_pointer_rtx))));
4931 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4935 ;; These two patterns can happen as the result of optimization, when
4936 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4937 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4940 [(set (reg:SI T_REG) (const_int 0))]
4945 [(set (reg:SI T_REG) (const_int 1))]
4949 ;; t/r must come after r/r, lest reload will try to reload stuff like
4950 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4951 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4952 (define_insn "movsi_i"
4953 [(set (match_operand:SI 0 "general_movdst_operand"
4954 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4955 (match_operand:SI 1 "general_movsrc_operand"
4956 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4960 && (register_operand (operands[0], SImode)
4961 || register_operand (operands[1], SImode))"
4979 [(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")
4980 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4982 ;; t/r must come after r/r, lest reload will try to reload stuff like
4983 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4984 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4985 ;; will require a reload.
4986 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4987 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4988 (define_insn "movsi_ie"
4989 [(set (match_operand:SI 0 "general_movdst_operand"
4990 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4991 (match_operand:SI 1 "general_movsrc_operand"
4992 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4993 "(TARGET_SH2E || TARGET_SH2A)
4994 && (register_operand (operands[0], SImode)
4995 || register_operand (operands[1], SImode))"
5022 ! move optimized away"
5023 [(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")
5024 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5025 (set_attr_alternative "length"
5033 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5034 (const_int 4) (const_int 2))
5039 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5040 (const_int 4) (const_int 2))
5057 (define_insn "movsi_i_lowpart"
5058 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5059 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5061 && (register_operand (operands[0], SImode)
5062 || register_operand (operands[1], SImode))"
5073 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5075 (define_insn_and_split "load_ra"
5076 [(set (match_operand:SI 0 "general_movdst_operand" "")
5077 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5080 "&& ! currently_expanding_to_rtl"
5081 [(set (match_dup 0) (match_dup 1))]
5084 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5085 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5088 ;; The '?'s in the following constraints may not reflect the time taken
5089 ;; to perform the move. They are there to discourage the use of floating-
5090 ;; point registers for storing integer values.
5091 (define_insn "*movsi_media"
5092 [(set (match_operand:SI 0 "general_movdst_operand"
5093 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5094 (match_operand:SI 1 "general_movsrc_operand"
5095 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5097 && (register_operand (operands[0], SImode)
5098 || sh_register_operand (operands[1], SImode)
5099 || GET_CODE (operands[1]) == TRUNCATE)"
5114 [(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")
5115 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5116 (set (attr "highpart")
5117 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5118 (const_string "user")]
5119 (const_string "ignore")))])
5121 (define_insn "*movsi_media_nofpu"
5122 [(set (match_operand:SI 0 "general_movdst_operand"
5123 "=r,r,r,r,m,*b,r,*b")
5124 (match_operand:SI 1 "general_movsrc_operand"
5125 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5127 && (register_operand (operands[0], SImode)
5128 || sh_register_operand (operands[1], SImode)
5129 || GET_CODE (operands[1]) == TRUNCATE)"
5139 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5140 (set_attr "length" "4,4,8,4,4,4,4,12")
5141 (set (attr "highpart")
5142 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5143 (const_string "user")]
5144 (const_string "ignore")))])
5146 (define_expand "movsi_const"
5147 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5148 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5149 (const_int 16)] UNSPEC_EXTRACT_S16)))
5151 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5152 (const:SI (unspec:SI [(match_dup 1)
5153 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5154 "TARGET_SHMEDIA && reload_completed
5155 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5158 if (GET_CODE (operands[1]) == LABEL_REF
5159 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5160 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5161 else if (GOTOFF_P (operands[1]))
5163 rtx unspec = XEXP (operands[1], 0);
5165 if (! UNSPEC_GOTOFF_P (unspec))
5167 unspec = XEXP (unspec, 0);
5168 if (! UNSPEC_GOTOFF_P (unspec))
5171 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5172 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5173 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5177 (define_expand "movsi_const_16bit"
5178 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5179 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5180 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5181 "TARGET_SHMEDIA && flag_pic && reload_completed
5182 && GET_CODE (operands[1]) == SYMBOL_REF"
5186 [(set (match_operand:SI 0 "arith_reg_dest" "")
5187 (match_operand:SI 1 "immediate_operand" ""))]
5188 "TARGET_SHMEDIA && reload_completed
5189 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5193 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5195 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5201 [(set (match_operand:SI 0 "register_operand" "")
5202 (match_operand:SI 1 "immediate_operand" ""))]
5203 "TARGET_SHMEDIA && reload_completed
5204 && ((GET_CODE (operands[1]) == CONST_INT
5205 && ! satisfies_constraint_I16 (operands[1]))
5206 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5207 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5209 (define_expand "movsi"
5210 [(set (match_operand:SI 0 "general_movdst_operand" "")
5211 (match_operand:SI 1 "general_movsrc_operand" ""))]
5213 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5215 (define_expand "ic_invalidate_line"
5216 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5217 (match_dup 1)] UNSPEC_ICACHE)
5218 (clobber (scratch:SI))])]
5219 "TARGET_HARD_SH4 || TARGET_SH5"
5224 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5227 else if (TARGET_SHCOMPACT)
5229 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5230 operands[1] = force_reg (Pmode, operands[1]);
5231 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5234 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5236 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5239 operands[0] = force_reg (Pmode, operands[0]);
5240 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5244 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5245 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5246 ;; the requirement *1*00 for associative address writes. The alignment of
5247 ;; %0 implies that its least significant bit is cleared,
5248 ;; thus we clear the V bit of a matching entry if there is one.
5249 (define_insn "ic_invalidate_line_i"
5250 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5251 (match_operand:SI 1 "register_operand" "r")]
5253 (clobber (match_scratch:SI 2 "=&r"))]
5255 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5256 [(set_attr "length" "8")
5257 (set_attr "type" "cwb")])
5259 (define_insn "ic_invalidate_line_sh4a"
5260 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5262 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5263 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5264 [(set_attr "length" "16")
5265 (set_attr "type" "cwb")])
5267 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5268 ;; an add in the code that calculates the address.
5269 (define_insn "ic_invalidate_line_media"
5270 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5273 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5274 [(set_attr "length" "16")
5275 (set_attr "type" "invalidate_line_media")])
5277 (define_insn "ic_invalidate_line_compact"
5278 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5279 (match_operand:SI 1 "register_operand" "r")]
5281 (clobber (reg:SI PR_REG))]
5284 [(set_attr "type" "sfunc")
5285 (set_attr "needs_delay_slot" "yes")])
5287 (define_expand "initialize_trampoline"
5288 [(match_operand:SI 0 "" "")
5289 (match_operand:SI 1 "" "")
5290 (match_operand:SI 2 "" "")]
5296 tramp = force_reg (Pmode, operands[0]);
5297 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5299 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5300 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5302 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5306 (define_insn "initialize_trampoline_compact"
5307 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5308 (match_operand:SI 1 "register_operand" "r")
5309 (reg:SI R2_REG) (reg:SI R3_REG)]
5312 (clobber (reg:SI PR_REG))]
5315 [(set_attr "type" "sfunc")
5316 (set_attr "needs_delay_slot" "yes")])
5318 (define_insn "movqi_i"
5319 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5320 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5322 && (arith_reg_operand (operands[0], QImode)
5323 || arith_reg_operand (operands[1], QImode))"
5332 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5333 (set_attr_alternative "length"
5337 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5338 (const_int 4) (const_int 2))
5340 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5341 (const_int 4) (const_int 2))
5346 (define_insn "*movqi_media"
5347 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5348 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5350 && (arith_reg_operand (operands[0], QImode)
5351 || extend_reg_or_0_operand (operands[1], QImode))"
5357 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5358 (set (attr "highpart")
5359 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5360 (const_string "user")]
5361 (const_string "ignore")))])
5363 (define_expand "movqi"
5364 [(set (match_operand:QI 0 "general_operand" "")
5365 (match_operand:QI 1 "general_operand" ""))]
5367 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5369 (define_expand "reload_inqi"
5370 [(set (match_operand:SI 2 "" "=&r")
5371 (match_operand:QI 1 "inqhi_operand" ""))
5372 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5373 (truncate:QI (match_dup 3)))]
5377 rtx inner = XEXP (operands[1], 0);
5378 int regno = REGNO (inner);
5380 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5381 operands[1] = gen_rtx_REG (SImode, regno);
5382 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5385 /* When storing r0, we have to avoid reg+reg addressing. */
5386 (define_insn "movhi_i"
5387 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5388 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5390 && (arith_reg_operand (operands[0], HImode)
5391 || arith_reg_operand (operands[1], HImode))
5392 && (GET_CODE (operands[0]) != MEM
5393 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5394 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5395 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5405 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5407 (define_insn "*movhi_media"
5408 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5409 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5411 && (arith_reg_operand (operands[0], HImode)
5412 || arith_reg_or_0_operand (operands[1], HImode))"
5419 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5420 (set (attr "highpart")
5421 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5422 (const_string "user")]
5423 (const_string "ignore")))])
5426 [(set (match_operand:HI 0 "register_operand" "")
5427 (match_operand:HI 1 "immediate_operand" ""))]
5428 "TARGET_SHMEDIA && reload_completed
5429 && ! satisfies_constraint_I16 (operands[1])"
5430 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5432 (define_expand "movhi"
5433 [(set (match_operand:HI 0 "general_movdst_operand" "")
5434 (match_operand:HI 1 "general_movsrc_operand" ""))]
5436 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5438 (define_expand "reload_inhi"
5439 [(set (match_operand:SI 2 "" "=&r")
5440 (match_operand:HI 1 "inqhi_operand" ""))
5441 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5442 (truncate:HI (match_dup 3)))]
5446 rtx inner = XEXP (operands[1], 0);
5447 int regno = REGNO (inner);
5449 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5450 operands[1] = gen_rtx_REG (SImode, regno);
5451 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5454 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5455 ;; compiled with -m2 -ml -O3 -funroll-loops
5456 (define_insn "*movdi_i"
5457 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5458 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5460 && (arith_reg_operand (operands[0], DImode)
5461 || arith_reg_operand (operands[1], DImode))"
5462 "* return output_movedouble (insn, operands, DImode);"
5463 [(set_attr "length" "4")
5464 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5466 ;; If the output is a register and the input is memory or a register, we have
5467 ;; to be careful and see which word needs to be loaded first.
5470 [(set (match_operand:DI 0 "general_movdst_operand" "")
5471 (match_operand:DI 1 "general_movsrc_operand" ""))]
5472 "TARGET_SH1 && reload_completed"
5473 [(set (match_dup 2) (match_dup 3))
5474 (set (match_dup 4) (match_dup 5))]
5479 if ((GET_CODE (operands[0]) == MEM
5480 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5481 || (GET_CODE (operands[1]) == MEM
5482 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5485 switch (GET_CODE (operands[0]))
5488 regno = REGNO (operands[0]);
5491 regno = subreg_regno (operands[0]);
5501 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5503 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5504 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5505 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5506 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5510 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5511 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5512 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5513 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5516 if (operands[2] == 0 || operands[3] == 0
5517 || operands[4] == 0 || operands[5] == 0)
5521 ;; The '?'s in the following constraints may not reflect the time taken
5522 ;; to perform the move. They are there to discourage the use of floating-
5523 ;; point registers for storing integer values.
5524 (define_insn "*movdi_media"
5525 [(set (match_operand:DI 0 "general_movdst_operand"
5526 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5527 (match_operand:DI 1 "general_movsrc_operand"
5528 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5530 && (register_operand (operands[0], DImode)
5531 || sh_register_operand (operands[1], DImode))"
5546 [(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")
5547 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5549 (define_insn "*movdi_media_nofpu"
5550 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5551 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5553 && (register_operand (operands[0], DImode)
5554 || sh_register_operand (operands[1], DImode))"
5564 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5565 (set_attr "length" "4,4,16,4,4,4,4,*")])
5567 (define_insn "*movdi_media_I16"
5568 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5569 (match_operand:DI 1 "const_int_operand" "I16"))]
5570 "TARGET_SHMEDIA && reload_completed"
5572 [(set_attr "type" "arith_media")
5573 (set_attr "length" "4")])
5576 [(set (match_operand:DI 0 "arith_reg_dest" "")
5577 (match_operand:DI 1 "immediate_operand" ""))]
5578 "TARGET_SHMEDIA && reload_completed
5579 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5580 [(set (match_dup 0) (match_dup 1))]
5585 if (TARGET_SHMEDIA64)
5586 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5588 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5590 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5595 (define_expand "movdi_const"
5596 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5597 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5598 (const_int 48)] UNSPEC_EXTRACT_S16)))
5600 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5601 (const:DI (unspec:DI [(match_dup 1)
5602 (const_int 32)] UNSPEC_EXTRACT_U16))))
5604 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5605 (const:DI (unspec:DI [(match_dup 1)
5606 (const_int 16)] UNSPEC_EXTRACT_U16))))
5608 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5609 (const:DI (unspec:DI [(match_dup 1)
5610 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5611 "TARGET_SHMEDIA64 && reload_completed
5612 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5615 sh_mark_label (operands[1], 4);
5618 (define_expand "movdi_const_32bit"
5619 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5620 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5621 (const_int 16)] UNSPEC_EXTRACT_S16)))
5623 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5624 (const:DI (unspec:DI [(match_dup 1)
5625 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5626 "TARGET_SHMEDIA32 && reload_completed
5627 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5630 sh_mark_label (operands[1], 2);
5633 (define_expand "movdi_const_16bit"
5634 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5635 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5636 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5637 "TARGET_SHMEDIA && flag_pic && reload_completed
5638 && GET_CODE (operands[1]) == SYMBOL_REF"
5642 [(set (match_operand:DI 0 "ext_dest_operand" "")
5643 (match_operand:DI 1 "immediate_operand" ""))]
5644 "TARGET_SHMEDIA && reload_completed
5645 && GET_CODE (operands[1]) == CONST_INT
5646 && ! satisfies_constraint_I16 (operands[1])"
5647 [(set (match_dup 0) (match_dup 2))
5651 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5652 unsigned HOST_WIDE_INT low = val;
5653 unsigned HOST_WIDE_INT high = val;
5654 unsigned HOST_WIDE_INT sign;
5655 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5657 /* Zero-extend the 16 least-significant bits. */
5660 /* Arithmetic shift right the word by 16 bits. */
5662 if (GET_CODE (operands[0]) == SUBREG
5663 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5672 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5678 /* If we can't generate the constant with a two-insn movi / shori
5679 sequence, try some other strategies. */
5680 if (! CONST_OK_FOR_I16 (high))
5682 /* Try constant load / left shift. We know VAL != 0. */
5683 val2 = val ^ (val-1);
5686 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5688 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5689 || (! CONST_OK_FOR_I16 (high >> 16)
5690 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5692 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5693 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5694 GEN_INT (trailing_zeroes));
5698 /* Try constant load / right shift. */
5699 val2 = (val >> 15) + 1;
5700 if (val2 == (val2 & -val2))
5702 int shift = 49 - exact_log2 (val2);
5704 val2 = trunc_int_for_mode (val << shift, DImode);
5705 if (CONST_OK_FOR_I16 (val2))
5707 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5713 val2 = val & 0xffff;
5714 if ((val >> 16 & 0xffff) == val2
5715 && (val >> 32 & 0xffff) == val2
5716 && (val >> 48 & 0xffff) == val2)
5718 val2 = (HOST_WIDE_INT) val >> 48;
5719 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5720 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5723 /* Try movi / mshflo.l */
5724 val2 = (HOST_WIDE_INT) val >> 32;
5725 if (val2 == ((unsigned HOST_WIDE_INT)
5726 trunc_int_for_mode (val, SImode)))
5728 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5732 /* Try movi / mshflo.l w/ r63. */
5733 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5734 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5736 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5742 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5745 operands[2] = GEN_INT (val2);
5749 [(set (match_operand:DI 0 "ext_dest_operand" "")
5750 (match_operand:DI 1 "immediate_operand" ""))]
5751 "TARGET_SHMEDIA && reload_completed
5752 && GET_CODE (operands[1]) == CONST_DOUBLE"
5753 [(set (match_dup 0) (match_dup 2))
5755 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5758 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5759 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5760 unsigned HOST_WIDE_INT val = low;
5761 unsigned HOST_WIDE_INT sign;
5763 /* Zero-extend the 16 least-significant bits. */
5765 operands[1] = GEN_INT (val);
5767 /* Arithmetic shift right the double-word by 16 bits. */
5769 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5772 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5776 /* This will only be true if high is a sign-extension of low, i.e.,
5777 it must be either 0 or (unsigned)-1, and be zero iff the
5778 most-significant bit of low is set. */
5779 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5780 operands[2] = GEN_INT (low);
5782 operands[2] = immed_double_const (low, high, DImode);
5785 (define_insn "shori_media"
5786 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5787 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5789 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5790 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5794 [(set_attr "type" "arith_media,*")])
5796 (define_insn "*shori_media_si"
5797 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5798 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5800 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5804 (define_expand "movdi"
5805 [(set (match_operand:DI 0 "general_movdst_operand" "")
5806 (match_operand:DI 1 "general_movsrc_operand" ""))]
5808 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5810 (define_insn "movdf_media"
5811 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5812 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5814 && (register_operand (operands[0], DFmode)
5815 || sh_register_operand (operands[1], DFmode))"
5826 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5828 (define_insn "movdf_media_nofpu"
5829 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5830 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5832 && (register_operand (operands[0], DFmode)
5833 || sh_register_operand (operands[1], DFmode))"
5839 [(set_attr "type" "arith_media,*,load_media,store_media")])
5842 [(set (match_operand:DF 0 "arith_reg_dest" "")
5843 (match_operand:DF 1 "immediate_operand" ""))]
5844 "TARGET_SHMEDIA && reload_completed"
5845 [(set (match_dup 3) (match_dup 2))]
5848 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5850 REAL_VALUE_TYPE value;
5852 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5853 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5855 if (HOST_BITS_PER_WIDE_INT >= 64)
5856 operands[2] = immed_double_const ((unsigned long) values[endian]
5857 | ((HOST_WIDE_INT) values[1 - endian]
5861 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5862 operands[2] = immed_double_const (values[endian], values[1 - endian],
5866 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5869 ;; ??? This should be a define expand.
5871 (define_insn "movdf_k"
5872 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5873 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5875 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5876 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5877 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5878 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5879 && (arith_reg_operand (operands[0], DFmode)
5880 || arith_reg_operand (operands[1], DFmode))"
5881 "* return output_movedouble (insn, operands, DFmode);"
5882 [(set_attr "length" "4")
5883 (set_attr "type" "move,pcload,load,store")])
5885 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5886 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5887 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5888 ;; the d/m/c/X alternative, which is split later into single-precision
5889 ;; instructions. And when not optimizing, no splits are done before fixing
5890 ;; up pcloads, so we need usable length information for that.
5891 (define_insn "movdf_i4"
5892 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5893 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5894 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5895 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5896 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5897 && (arith_reg_operand (operands[0], DFmode)
5898 || arith_reg_operand (operands[1], DFmode))"
5910 [(set_attr_alternative "length"
5911 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5913 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5914 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5915 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5917 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5918 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5919 ;; increment or decrement r15 explicitly.
5921 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5922 (const_int 10) (const_int 8))
5924 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5925 (const_int 10) (const_int 8))])
5926 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5927 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5928 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5929 (const_string "double")
5930 (const_string "none")))])
5932 ;; Moving DFmode between fp/general registers through memory
5933 ;; (the top of the stack) is faster than moving through fpul even for
5934 ;; little endian. Because the type of an instruction is important for its
5935 ;; scheduling, it is beneficial to split these operations, rather than
5936 ;; emitting them in one single chunk, even if this will expose a stack
5937 ;; use that will prevent scheduling of other stack accesses beyond this
5940 [(set (match_operand:DF 0 "register_operand" "")
5941 (match_operand:DF 1 "register_operand" ""))
5942 (use (match_operand:PSI 2 "fpscr_operand" ""))
5943 (clobber (match_scratch:SI 3 "=X"))]
5944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5945 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5951 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5953 emit_move_insn (stack_pointer_rtx,
5954 plus_constant (stack_pointer_rtx, -8));
5955 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5958 tos = gen_tmp_stack_mem (DFmode,
5959 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5960 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5961 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5962 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5963 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5964 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5966 tos = gen_tmp_stack_mem (DFmode,
5967 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5968 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5969 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5970 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5972 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5976 ;; local-alloc sometimes allocates scratch registers even when not required,
5977 ;; so we must be prepared to handle these.
5979 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5981 [(set (match_operand:DF 0 "general_movdst_operand" "")
5982 (match_operand:DF 1 "general_movsrc_operand" ""))
5983 (use (match_operand:PSI 2 "fpscr_operand" ""))
5984 (clobber (match_scratch:SI 3 ""))]
5985 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5987 && true_regnum (operands[0]) < 16
5988 && true_regnum (operands[1]) < 16"
5989 [(set (match_dup 0) (match_dup 1))]
5992 /* If this was a reg <-> mem operation with base + index reg addressing,
5993 we have to handle this in a special way. */
5994 rtx mem = operands[0];
5996 if (! memory_operand (mem, DFmode))
6001 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6002 mem = SUBREG_REG (mem);
6003 if (GET_CODE (mem) == MEM)
6005 rtx addr = XEXP (mem, 0);
6006 if (GET_CODE (addr) == PLUS
6007 && GET_CODE (XEXP (addr, 0)) == REG
6008 && GET_CODE (XEXP (addr, 1)) == REG)
6011 rtx reg0 = gen_rtx_REG (Pmode, 0);
6012 rtx regop = operands[store_p], word0 ,word1;
6014 if (GET_CODE (regop) == SUBREG)
6015 alter_subreg (®op);
6016 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6020 mem = copy_rtx (mem);
6021 PUT_MODE (mem, SImode);
6022 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6023 alter_subreg (&word0);
6024 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6025 alter_subreg (&word1);
6026 if (store_p || ! refers_to_regno_p (REGNO (word0),
6027 REGNO (word0) + 1, addr, 0))
6030 ? gen_movsi_ie (mem, word0)
6031 : gen_movsi_ie (word0, mem));
6032 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6033 mem = copy_rtx (mem);
6035 ? gen_movsi_ie (mem, word1)
6036 : gen_movsi_ie (word1, mem));
6037 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6041 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6042 emit_insn (gen_movsi_ie (word1, mem));
6043 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6044 mem = copy_rtx (mem);
6045 emit_insn (gen_movsi_ie (word0, mem));
6052 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6054 [(set (match_operand:DF 0 "register_operand" "")
6055 (match_operand:DF 1 "memory_operand" ""))
6056 (use (match_operand:PSI 2 "fpscr_operand" ""))
6057 (clobber (reg:SI R0_REG))]
6058 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6059 [(parallel [(set (match_dup 0) (match_dup 1))
6061 (clobber (scratch:SI))])]
6064 (define_expand "reload_indf__frn"
6065 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6066 (match_operand:DF 1 "immediate_operand" "FQ"))
6067 (use (reg:PSI FPSCR_REG))
6068 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6072 (define_expand "reload_outdf__RnFRm"
6073 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6074 (match_operand:DF 1 "register_operand" "af,r"))
6075 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6079 ;; Simplify no-op moves.
6081 [(set (match_operand:SF 0 "register_operand" "")
6082 (match_operand:SF 1 "register_operand" ""))
6083 (use (match_operand:PSI 2 "fpscr_operand" ""))
6084 (clobber (match_scratch:SI 3 ""))]
6085 "TARGET_SH2E && reload_completed
6086 && true_regnum (operands[0]) == true_regnum (operands[1])"
6087 [(set (match_dup 0) (match_dup 0))]
6090 ;; fmovd substitute post-reload splits
6092 [(set (match_operand:DF 0 "register_operand" "")
6093 (match_operand:DF 1 "register_operand" ""))
6094 (use (match_operand:PSI 2 "fpscr_operand" ""))
6095 (clobber (match_scratch:SI 3 ""))]
6096 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6097 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6098 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6102 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6103 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6104 gen_rtx_REG (SFmode, src), operands[2]));
6105 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6106 gen_rtx_REG (SFmode, src + 1), operands[2]));
6111 [(set (match_operand:DF 0 "register_operand" "")
6112 (mem:DF (match_operand:SI 1 "register_operand" "")))
6113 (use (match_operand:PSI 2 "fpscr_operand" ""))
6114 (clobber (match_scratch:SI 3 ""))]
6115 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6116 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6117 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6121 int regno = true_regnum (operands[0]);
6123 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6125 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6126 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6127 regno + !! TARGET_LITTLE_ENDIAN),
6128 mem2, operands[2]));
6129 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6130 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6131 regno + ! TARGET_LITTLE_ENDIAN),
6132 change_address (mem, SFmode, NULL_RTX),
6138 [(set (match_operand:DF 0 "register_operand" "")
6139 (match_operand:DF 1 "memory_operand" ""))
6140 (use (match_operand:PSI 2 "fpscr_operand" ""))
6141 (clobber (match_scratch:SI 3 ""))]
6142 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6143 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6147 int regno = true_regnum (operands[0]);
6148 rtx addr, insn, adjust = NULL_RTX;
6149 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6150 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6151 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6153 operands[1] = copy_rtx (mem2);
6154 addr = XEXP (mem2, 0);
6155 if (GET_CODE (addr) != POST_INC)
6157 /* If we have to modify the stack pointer, the value that we have
6158 read with post-increment might be modified by an interrupt,
6159 so write it back. */
6160 if (REGNO (addr) == STACK_POINTER_REGNUM)
6161 adjust = gen_push_e (reg0);
6163 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6164 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6166 addr = XEXP (addr, 0);
6167 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6168 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6169 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6173 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6178 [(set (match_operand:DF 0 "memory_operand" "")
6179 (match_operand:DF 1 "register_operand" ""))
6180 (use (match_operand:PSI 2 "fpscr_operand" ""))
6181 (clobber (match_scratch:SI 3 ""))]
6182 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6183 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6187 int regno = true_regnum (operands[1]);
6188 rtx insn, addr, adjust = NULL_RTX;
6190 operands[0] = copy_rtx (operands[0]);
6191 PUT_MODE (operands[0], SFmode);
6192 insn = emit_insn (gen_movsf_ie (operands[0],
6193 gen_rtx_REG (SFmode,
6194 regno + ! TARGET_LITTLE_ENDIAN),
6196 operands[0] = copy_rtx (operands[0]);
6197 addr = XEXP (operands[0], 0);
6198 if (GET_CODE (addr) != PRE_DEC)
6200 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6201 emit_insn_before (adjust, insn);
6202 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6204 addr = XEXP (addr, 0);
6206 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6207 insn = emit_insn (gen_movsf_ie (operands[0],
6208 gen_rtx_REG (SFmode,
6209 regno + !! TARGET_LITTLE_ENDIAN),
6211 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6215 ;; If the output is a register and the input is memory or a register, we have
6216 ;; to be careful and see which word needs to be loaded first.
6219 [(set (match_operand:DF 0 "general_movdst_operand" "")
6220 (match_operand:DF 1 "general_movsrc_operand" ""))]
6221 "TARGET_SH1 && reload_completed"
6222 [(set (match_dup 2) (match_dup 3))
6223 (set (match_dup 4) (match_dup 5))]
6228 if ((GET_CODE (operands[0]) == MEM
6229 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6230 || (GET_CODE (operands[1]) == MEM
6231 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6234 switch (GET_CODE (operands[0]))
6237 regno = REGNO (operands[0]);
6240 regno = subreg_regno (operands[0]);
6250 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6252 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6253 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6254 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6255 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6259 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6260 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6261 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6262 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6265 if (operands[2] == 0 || operands[3] == 0
6266 || operands[4] == 0 || operands[5] == 0)
6270 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6271 ;; used only once, let combine add in the index again.
6274 [(set (match_operand:SI 0 "register_operand" "")
6275 (match_operand:SI 1 "" ""))
6276 (clobber (match_operand 2 "register_operand" ""))]
6277 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6278 && ALLOW_INDEXED_ADDRESS"
6279 [(use (reg:SI R0_REG))]
6282 rtx addr, reg, const_int;
6284 if (GET_CODE (operands[1]) != MEM)
6286 addr = XEXP (operands[1], 0);
6287 if (GET_CODE (addr) != PLUS)
6289 reg = XEXP (addr, 0);
6290 const_int = XEXP (addr, 1);
6291 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6292 && GET_CODE (const_int) == CONST_INT))
6294 emit_move_insn (operands[2], const_int);
6295 emit_move_insn (operands[0],
6296 change_address (operands[1], VOIDmode,
6297 gen_rtx_PLUS (SImode, reg, operands[2])));
6302 [(set (match_operand:SI 1 "" "")
6303 (match_operand:SI 0 "register_operand" ""))
6304 (clobber (match_operand 2 "register_operand" ""))]
6305 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6306 && ALLOW_INDEXED_ADDRESS"
6307 [(use (reg:SI R0_REG))]
6310 rtx addr, reg, const_int;
6312 if (GET_CODE (operands[1]) != MEM)
6314 addr = XEXP (operands[1], 0);
6315 if (GET_CODE (addr) != PLUS)
6317 reg = XEXP (addr, 0);
6318 const_int = XEXP (addr, 1);
6319 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6320 && GET_CODE (const_int) == CONST_INT))
6322 emit_move_insn (operands[2], const_int);
6323 emit_move_insn (change_address (operands[1], VOIDmode,
6324 gen_rtx_PLUS (SImode, reg, operands[2])),
6329 (define_expand "movdf"
6330 [(set (match_operand:DF 0 "general_movdst_operand" "")
6331 (match_operand:DF 1 "general_movsrc_operand" ""))]
6335 if (prepare_move_operands (operands, DFmode)) DONE;
6338 if (TARGET_SHMEDIA_FPU)
6339 emit_insn (gen_movdf_media (operands[0], operands[1]));
6341 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6344 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6346 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6351 ;;This is incompatible with the way gcc uses subregs.
6352 ;;(define_insn "movv2sf_i"
6353 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6354 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6355 ;; "TARGET_SHMEDIA_FPU
6356 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6357 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6361 ;; fst%M0.p %m0, %1"
6362 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6364 (define_insn_and_split "movv2sf_i"
6365 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6366 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6367 "TARGET_SHMEDIA_FPU"
6369 "TARGET_SHMEDIA_FPU && reload_completed"
6370 [(set (match_dup 0) (match_dup 1))]
6373 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6374 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6377 (define_expand "movv2sf"
6378 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6379 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6380 "TARGET_SHMEDIA_FPU"
6383 if (prepare_move_operands (operands, V2SFmode))
6387 (define_expand "addv2sf3"
6388 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6389 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6390 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6391 "TARGET_SHMEDIA_FPU"
6394 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6398 (define_expand "subv2sf3"
6399 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6400 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6401 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6402 "TARGET_SHMEDIA_FPU"
6405 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6409 (define_expand "mulv2sf3"
6410 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6411 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6412 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6413 "TARGET_SHMEDIA_FPU"
6416 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6420 (define_expand "divv2sf3"
6421 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6422 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6423 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6424 "TARGET_SHMEDIA_FPU"
6427 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6431 (define_insn_and_split "*movv4sf_i"
6432 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6433 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6434 "TARGET_SHMEDIA_FPU"
6436 "&& reload_completed"
6442 for (i = 0; i < 4/2; i++)
6446 if (GET_CODE (operands[0]) == MEM)
6447 x = adjust_address (operands[0], V2SFmode,
6448 i * GET_MODE_SIZE (V2SFmode));
6450 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6452 if (GET_CODE (operands[1]) == MEM)
6453 y = adjust_address (operands[1], V2SFmode,
6454 i * GET_MODE_SIZE (V2SFmode));
6456 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6458 emit_insn (gen_movv2sf_i (x, y));
6463 [(set_attr "length" "8")])
6465 (define_expand "movv4sf"
6466 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6467 (match_operand:V4SF 1 "general_operand" ""))]
6468 "TARGET_SHMEDIA_FPU"
6471 if (prepare_move_operands (operands, V4SFmode))
6475 (define_insn_and_split "*movv16sf_i"
6476 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6477 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6478 "TARGET_SHMEDIA_FPU"
6480 "&& reload_completed"
6486 for (i = 0; i < 16/2; i++)
6490 if (GET_CODE (operands[0]) == MEM)
6491 x = adjust_address (operands[0], V2SFmode,
6492 i * GET_MODE_SIZE (V2SFmode));
6495 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6499 if (GET_CODE (operands[1]) == MEM)
6500 y = adjust_address (operands[1], V2SFmode,
6501 i * GET_MODE_SIZE (V2SFmode));
6504 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6508 emit_insn (gen_movv2sf_i (x, y));
6513 [(set_attr "length" "32")])
6515 (define_expand "movv16sf"
6516 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6517 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6518 "TARGET_SHMEDIA_FPU"
6521 if (prepare_move_operands (operands, V16SFmode))
6525 (define_insn "movsf_media"
6526 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6527 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6529 && (register_operand (operands[0], SFmode)
6530 || sh_register_operand (operands[1], SFmode))"
6541 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6542 (set (attr "highpart")
6543 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6544 (const_string "user")]
6545 (const_string "ignore")))])
6547 (define_insn "movsf_media_nofpu"
6548 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6549 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6551 && (register_operand (operands[0], SFmode)
6552 || sh_register_operand (operands[1], SFmode))"
6558 [(set_attr "type" "arith_media,*,load_media,store_media")
6559 (set (attr "highpart")
6560 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6561 (const_string "user")]
6562 (const_string "ignore")))])
6565 [(set (match_operand:SF 0 "arith_reg_dest" "")
6566 (match_operand:SF 1 "immediate_operand" ""))]
6567 "TARGET_SHMEDIA && reload_completed
6568 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6569 [(set (match_dup 3) (match_dup 2))]
6573 REAL_VALUE_TYPE value;
6575 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6576 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6577 operands[2] = GEN_INT (values);
6579 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6582 (define_insn "movsf_i"
6583 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6584 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6587 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6588 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6589 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6590 && (arith_reg_operand (operands[0], SFmode)
6591 || arith_reg_operand (operands[1], SFmode))"
6600 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6602 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6603 ;; update_flow_info would not know where to put REG_EQUAL notes
6604 ;; when the destination changes mode.
6605 (define_insn "movsf_ie"
6606 [(set (match_operand:SF 0 "general_movdst_operand"
6607 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6608 (match_operand:SF 1 "general_movsrc_operand"
6609 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6610 (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"))
6611 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6614 && (arith_reg_operand (operands[0], SFmode)
6615 || arith_reg_operand (operands[1], SFmode)
6616 || arith_reg_operand (operands[3], SImode)
6617 || (fpul_operand (operands[0], SFmode)
6618 && memory_operand (operands[1], SFmode)
6619 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6620 || (fpul_operand (operands[1], SFmode)
6621 && memory_operand (operands[0], SFmode)
6622 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6642 ! move optimized away"
6643 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6644 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6645 (set_attr_alternative "length"
6652 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6653 (const_int 4) (const_int 2))
6655 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6656 (const_int 4) (const_int 2))
6659 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6660 (const_int 4) (const_int 2))
6662 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6663 (const_int 4) (const_int 2))
6673 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6674 (const_string "single")
6675 (const_string "none")))])
6678 [(set (match_operand:SF 0 "register_operand" "")
6679 (match_operand:SF 1 "register_operand" ""))
6680 (use (match_operand:PSI 2 "fpscr_operand" ""))
6681 (clobber (reg:SI FPUL_REG))]
6683 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6685 (clobber (scratch:SI))])
6686 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6688 (clobber (scratch:SI))])]
6691 (define_expand "movsf"
6692 [(set (match_operand:SF 0 "general_movdst_operand" "")
6693 (match_operand:SF 1 "general_movsrc_operand" ""))]
6697 if (prepare_move_operands (operands, SFmode))
6701 if (TARGET_SHMEDIA_FPU)
6702 emit_insn (gen_movsf_media (operands[0], operands[1]));
6704 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6709 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6714 (define_insn "mov_nop"
6715 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6718 [(set_attr "length" "0")
6719 (set_attr "type" "nil")])
6721 (define_expand "reload_insf__frn"
6722 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6723 (match_operand:SF 1 "immediate_operand" "FQ"))
6724 (use (reg:PSI FPSCR_REG))
6725 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6729 (define_expand "reload_insi__i_fpul"
6730 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6731 (match_operand:SI 1 "immediate_operand" "i"))
6732 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6736 (define_expand "ptabs"
6737 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6741 if (!TARGET_PT_FIXED)
6743 rtx eq = operands[1];
6745 /* ??? For canonical RTL we really should remove any CONST from EQ
6746 before wrapping it in the AND, and finally wrap the EQ into a
6747 const if is constant. However, for reload we must expose the
6748 input register or symbolic constant, and we can't have
6749 different insn structures outside of the operands for different
6750 alternatives of the same pattern. */
6751 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6754 = (gen_rtx_IF_THEN_ELSE
6757 gen_rtx_MEM (PDImode, operands[1]),
6758 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6759 PDImode, operands[1])));
6763 ;; expanded by ptabs expander.
6764 (define_insn "*extendsipdi_media"
6765 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6766 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6770 (mem:PDI (match_dup 1))
6771 (sign_extend:PDI (match_dup 1))))]
6772 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6776 [(set_attr "type" "ptabs_media,pt_media")
6777 (set_attr "length" "4,*")])
6779 (define_insn "*truncdipdi_media"
6780 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6781 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6785 (mem:PDI (match_dup 1))
6786 (truncate:PDI (match_dup 1))))]
6787 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6791 [(set_attr "type" "ptabs_media,pt_media")
6792 (set_attr "length" "4,*")])
6794 (define_insn "*movsi_y"
6795 [(set (match_operand:SI 0 "register_operand" "=y,y")
6796 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6797 (clobber (match_scratch:SI 2 "=&z,r"))]
6799 && (reload_in_progress || reload_completed)"
6801 [(set_attr "length" "4")
6802 (set_attr "type" "pcload,move")])
6805 [(set (match_operand:SI 0 "register_operand" "")
6806 (match_operand:SI 1 "immediate_operand" ""))
6807 (clobber (match_operand:SI 2 "register_operand" ""))]
6809 [(set (match_dup 2) (match_dup 1))
6810 (set (match_dup 0) (match_dup 2))]
6814 [(set (match_operand:SI 0 "register_operand" "")
6815 (match_operand:SI 1 "memory_operand" ""))
6816 (clobber (reg:SI R0_REG))]
6818 [(set (match_dup 0) (match_dup 1))]
6821 ;; ------------------------------------------------------------------------
6822 ;; Define the real conditional branch instructions.
6823 ;; ------------------------------------------------------------------------
6825 (define_insn "branch_true"
6826 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6827 (label_ref (match_operand 0 "" ""))
6830 "* return output_branch (1, insn, operands);"
6831 [(set_attr "type" "cbranch")])
6833 (define_insn "branch_false"
6834 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6835 (label_ref (match_operand 0 "" ""))
6838 "* return output_branch (0, insn, operands);"
6839 [(set_attr "type" "cbranch")])
6841 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6842 ;; which destination is too far away.
6843 ;; The const_int_operand is distinct for each branch target; it avoids
6844 ;; unwanted matches with redundant_insn.
6845 (define_insn "block_branch_redirect"
6846 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6849 [(set_attr "length" "0")])
6851 ;; This one has the additional purpose to record a possible scratch register
6852 ;; for the following branch.
6853 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6854 ;; because the insn then might be deemed dead and deleted. And we can't
6855 ;; make the use in the jump insn explicit because that would disable
6856 ;; delay slot scheduling from the target.
6857 (define_insn "indirect_jump_scratch"
6858 [(set (match_operand:SI 0 "register_operand" "=r")
6859 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6860 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6863 [(set_attr "length" "0")])
6865 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6866 ;; being pulled into the delay slot of a condbranch that has been made to
6867 ;; jump around the unconditional jump because it was out of range.
6868 (define_insn "stuff_delay_slot"
6870 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6871 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6874 [(set_attr "length" "0")
6875 (set_attr "cond_delay_slot" "yes")])
6877 ;; Conditional branch insns
6879 (define_expand "beq_media"
6881 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6882 (match_operand:DI 2 "arith_operand" "r,I06"))
6883 (match_operand 0 "" "")
6886 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6888 (define_insn "*beq_media_i"
6890 (if_then_else (match_operator 3 "equality_comparison_operator"
6891 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6892 (match_operand:DI 2 "arith_operand" "r,I06")])
6893 (match_operand 0 "target_operand" "b,b")
6898 b%o3i%' %1, %2, %0%>"
6899 [(set_attr "type" "cbranch_media")])
6901 (define_insn "*beq_media_i32"
6903 (if_then_else (match_operator 3 "equality_comparison_operator"
6904 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6905 (match_operand:SI 2 "arith_operand" "r,I06")])
6906 (match_operand 0 "target_operand" "b,b")
6911 b%o3i%' %1, %2, %0%>"
6912 [(set_attr "type" "cbranch_media")])
6914 (define_expand "bne_media"
6916 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6917 (match_operand:DI 2 "arith_operand" "r,I06"))
6918 (match_operand 0 "" "")
6921 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6923 (define_expand "bgt_media"
6925 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6926 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6927 (match_operand 0 "" "")
6930 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6932 (define_expand "bge_media"
6934 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6935 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6936 (match_operand 0 "" "")
6939 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6941 (define_expand "bgtu_media"
6943 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6944 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6945 (match_operand 0 "" "")
6948 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6950 (define_expand "bgeu_media"
6952 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6953 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6954 (match_operand 0 "" "")
6957 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6959 (define_insn "*bgt_media_i"
6961 (if_then_else (match_operator 3 "greater_comparison_operator"
6962 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6963 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6964 (match_operand 0 "target_operand" "b")
6967 "b%o3%' %N1, %N2, %0%>"
6968 [(set_attr "type" "cbranch_media")])
6970 (define_insn "*bgt_media_i32"
6972 (if_then_else (match_operator 3 "greater_comparison_operator"
6973 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6974 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6975 (match_operand 0 "target_operand" "b")
6978 "b%o3%' %N1, %N2, %0%>"
6979 [(set_attr "type" "cbranch_media")])
6981 ;; These are only needed to make invert_jump() happy - otherwise, jump
6982 ;; optimization will be silently disabled.
6983 (define_insn "*blt_media_i"
6985 (if_then_else (match_operator 3 "less_comparison_operator"
6986 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6987 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6988 (match_operand 0 "target_operand" "b")
6991 "b%o3%' %N2, %N1, %0%>"
6992 [(set_attr "type" "cbranch_media")])
6994 (define_insn "*blt_media_i32"
6996 (if_then_else (match_operator 3 "less_comparison_operator"
6997 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6998 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6999 (match_operand 0 "target_operand" "b")
7002 "b%o3%' %N2, %N1, %0%>"
7003 [(set_attr "type" "cbranch_media")])
7005 (define_expand "beq"
7007 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7008 (label_ref (match_operand 0 "" ""))
7015 enum machine_mode mode = GET_MODE (sh_compare_op0);
7017 if (mode != DImode && mode != SImode)
7019 rtx tmp = gen_reg_rtx (DImode);
7021 emit_insn (gen_seq (tmp));
7022 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7026 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7027 if (CONSTANT_P (sh_compare_op1)
7028 && (! satisfies_constraint_I06 (sh_compare_op1)))
7029 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030 emit_jump_insn (gen_beq_media (operands[0],
7031 sh_compare_op0, sh_compare_op1));
7035 from_compare (operands, EQ);
7038 (define_expand "bne"
7040 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7041 (label_ref (match_operand 0 "" ""))
7048 enum machine_mode mode = GET_MODE (sh_compare_op0);
7050 if (mode != DImode && mode != SImode)
7052 rtx tmp = gen_reg_rtx (DImode);
7054 emit_insn (gen_seq (tmp));
7055 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7059 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7060 if (CONSTANT_P (sh_compare_op1)
7061 && (! satisfies_constraint_I06 (sh_compare_op1)))
7062 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7063 emit_jump_insn (gen_bne_media (operands[0],
7064 sh_compare_op0, sh_compare_op1));
7068 from_compare (operands, EQ);
7071 (define_expand "bgt"
7073 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7074 (label_ref (match_operand 0 "" ""))
7081 enum machine_mode mode = GET_MODE (sh_compare_op0);
7083 if (mode != DImode && mode != SImode)
7085 rtx tmp = gen_reg_rtx (DImode);
7087 emit_insn (gen_sgt (tmp));
7088 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7092 if (sh_compare_op0 != const0_rtx)
7093 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7094 if (sh_compare_op1 != const0_rtx)
7095 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7096 emit_jump_insn (gen_bgt_media (operands[0],
7097 sh_compare_op0, sh_compare_op1));
7101 from_compare (operands, GT);
7104 (define_expand "blt"
7106 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7107 (label_ref (match_operand 0 "" ""))
7114 enum machine_mode mode = GET_MODE (sh_compare_op0);
7116 if (mode != DImode && mode != SImode)
7118 rtx tmp = gen_reg_rtx (DImode);
7120 emit_insn (gen_slt (tmp));
7121 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7125 if (sh_compare_op0 != const0_rtx)
7126 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7127 if (sh_compare_op1 != const0_rtx)
7128 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7129 emit_jump_insn (gen_bgt_media (operands[0],
7130 sh_compare_op1, sh_compare_op0));
7134 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7136 rtx tmp = sh_compare_op0;
7137 sh_compare_op0 = sh_compare_op1;
7138 sh_compare_op1 = tmp;
7139 emit_insn (gen_bgt (operands[0]));
7142 from_compare (operands, GE);
7145 (define_expand "ble"
7147 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7148 (label_ref (match_operand 0 "" ""))
7155 enum machine_mode mode = GET_MODE (sh_compare_op0);
7157 if (mode != DImode && mode != SImode)
7159 rtx tmp = gen_reg_rtx (DImode);
7161 emit_insn (gen_sle (tmp));
7162 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7166 if (sh_compare_op0 != const0_rtx)
7167 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7168 if (sh_compare_op1 != const0_rtx)
7169 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7170 emit_jump_insn (gen_bge_media (operands[0],
7171 sh_compare_op1, sh_compare_op0));
7177 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7179 rtx tmp = sh_compare_op0;
7180 sh_compare_op0 = sh_compare_op1;
7181 sh_compare_op1 = tmp;
7182 emit_insn (gen_bge (operands[0]));
7185 from_compare (operands, GT);
7188 (define_expand "bge"
7190 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7191 (label_ref (match_operand 0 "" ""))
7198 enum machine_mode mode = GET_MODE (sh_compare_op0);
7200 if (mode != DImode && mode != SImode)
7202 rtx tmp = gen_reg_rtx (DImode);
7204 emit_insn (gen_sge (tmp));
7205 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7209 if (sh_compare_op0 != const0_rtx)
7210 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7211 if (sh_compare_op1 != const0_rtx)
7212 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7213 emit_jump_insn (gen_bge_media (operands[0],
7214 sh_compare_op0, sh_compare_op1));
7220 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7222 rtx tmp = sh_compare_op0;
7223 sh_compare_op0 = sh_compare_op1;
7224 sh_compare_op1 = tmp;
7225 emit_insn (gen_ble (operands[0]));
7228 from_compare (operands, GE);
7231 (define_expand "bgtu"
7233 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7234 (label_ref (match_operand 0 "" ""))
7241 enum machine_mode mode = GET_MODE (sh_compare_op0);
7243 if (sh_compare_op0 != const0_rtx)
7244 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7245 if (sh_compare_op1 != const0_rtx)
7246 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7247 emit_jump_insn (gen_bgtu_media (operands[0],
7248 sh_compare_op0, sh_compare_op1));
7252 from_compare (operands, GTU);
7255 (define_expand "bltu"
7257 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7258 (label_ref (match_operand 0 "" ""))
7265 enum machine_mode mode = GET_MODE (sh_compare_op0);
7267 if (sh_compare_op0 != const0_rtx)
7268 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7269 if (sh_compare_op1 != const0_rtx)
7270 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7271 emit_jump_insn (gen_bgtu_media (operands[0],
7272 sh_compare_op1, sh_compare_op0));
7276 from_compare (operands, GEU);
7279 (define_expand "bgeu"
7281 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7282 (label_ref (match_operand 0 "" ""))
7289 enum machine_mode mode = GET_MODE (sh_compare_op0);
7291 if (sh_compare_op0 != const0_rtx)
7292 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7293 if (sh_compare_op1 != const0_rtx)
7294 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7295 emit_jump_insn (gen_bgeu_media (operands[0],
7296 sh_compare_op0, sh_compare_op1));
7300 from_compare (operands, GEU);
7303 (define_expand "bleu"
7305 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7306 (label_ref (match_operand 0 "" ""))
7313 enum machine_mode mode = GET_MODE (sh_compare_op0);
7315 if (sh_compare_op0 != const0_rtx)
7316 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7317 if (sh_compare_op1 != const0_rtx)
7318 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7319 emit_jump_insn (gen_bgeu_media (operands[0],
7320 sh_compare_op1, sh_compare_op0));
7324 from_compare (operands, GTU);
7327 (define_expand "bunordered"
7328 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7330 (if_then_else (ne (match_dup 1) (const_int 0))
7331 (match_operand 0 "" "")
7336 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7337 operands[1] = gen_reg_rtx (SImode);
7338 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7339 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7342 ;; combiner splitter for test-and-branch on single bit in register. This
7343 ;; is endian dependent because the non-paradoxical subreg looks different
7348 (match_operator 3 "equality_comparison_operator"
7349 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7350 "extend_reg_operand" "")
7354 "const_int_operand" "")) 0)
7356 (match_operand 0 "target_operand" "")
7358 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7359 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7360 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7361 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7365 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7366 operands[6] = (GET_CODE (operands[3]) == EQ
7367 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7368 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7371 ; operand 0 is the loop count pseudo register
7372 ; operand 1 is the number of loop iterations or 0 if it is unknown
7373 ; operand 2 is the maximum number of loop iterations
7374 ; operand 3 is the number of levels of enclosed loops
7375 ; operand 4 is the label to jump to at the top of the loop
7377 (define_expand "doloop_end"
7378 [(parallel [(set (pc) (if_then_else
7379 (ne:SI (match_operand:SI 0 "" "")
7381 (label_ref (match_operand 4 "" ""))
7384 (plus:SI (match_dup 0) (const_int -1)))
7385 (clobber (reg:SI T_REG))])]
7389 if (GET_MODE (operands[0]) != SImode)
7394 (define_insn_and_split "doloop_end_split"
7396 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7398 (label_ref (match_operand 1 "" ""))
7401 (plus (match_dup 0) (const_int -1)))
7402 (clobber (reg:SI T_REG))]
7406 [(parallel [(set (reg:SI T_REG)
7407 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7409 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7410 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7411 (label_ref (match_operand 1 "" ""))
7414 [(set_attr "type" "cbranch")])
7417 ;; ------------------------------------------------------------------------
7418 ;; Jump and linkage insns
7419 ;; ------------------------------------------------------------------------
7421 (define_insn "jump_compact"
7423 (label_ref (match_operand 0 "" "")))]
7424 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7427 /* The length is 16 if the delay slot is unfilled. */
7428 if (get_attr_length(insn) > 4)
7429 return output_far_jump(insn, operands[0]);
7431 return \"bra %l0%#\";
7433 [(set_attr "type" "jump")
7434 (set_attr "needs_delay_slot" "yes")])
7436 ;; ??? It would be much saner to explicitly use the scratch register
7437 ;; in the jump insn, and have indirect_jump_scratch only set it,
7438 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7439 ;; from the target then, as it uses simplejump_p.
7440 ;;(define_insn "jump_compact_far"
7442 ;; (label_ref (match_operand 0 "" "")))
7443 ;; (use (match_operand 1 "register_operand" "r")]
7445 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7446 ;; [(set_attr "type" "jump")
7447 ;; (set_attr "needs_delay_slot" "yes")])
7449 (define_insn "jump_media"
7451 (match_operand 0 "target_operand" "b"))]
7454 [(set_attr "type" "jump_media")])
7456 (define_expand "jump"
7458 (label_ref (match_operand 0 "" "")))]
7463 emit_jump_insn (gen_jump_compact (operands[0]));
7464 else if (TARGET_SHMEDIA)
7466 if (reload_in_progress || reload_completed)
7468 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7474 (define_insn "force_mode_for_call"
7475 [(use (reg:PSI FPSCR_REG))]
7478 [(set_attr "length" "0")
7479 (set (attr "fp_mode")
7480 (if_then_else (eq_attr "fpu_single" "yes")
7481 (const_string "single") (const_string "double")))])
7483 (define_insn "calli"
7484 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7485 (match_operand 1 "" ""))
7486 (use (reg:PSI FPSCR_REG))
7487 (clobber (reg:SI PR_REG))]
7491 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7492 return \"jsr/n\\t@%0\";
7494 return \"jsr\\t@%0%#\";
7497 [(set_attr "type" "call")
7498 (set (attr "fp_mode")
7499 (if_then_else (eq_attr "fpu_single" "yes")
7500 (const_string "single") (const_string "double")))
7501 (set_attr "needs_delay_slot" "yes")
7502 (set_attr "fp_set" "unknown")])
7504 ;; This is TBR relative jump instruction for SH2A architecture.
7505 ;; Its use is enabled assigning an attribute "function_vector"
7506 ;; and the vector number to a function during its declaration.
7508 (define_insn "calli_tbr_rel"
7509 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7510 (match_operand 1 "" ""))
7511 (use (reg:PSI FPSCR_REG))
7512 (clobber (reg:SI PR_REG))]
7513 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7516 unsigned HOST_WIDE_INT vect_num;
7517 vect_num = sh2a_get_function_vector_number (operands[0]);
7518 operands[2] = GEN_INT (vect_num * 4);
7520 return \"jsr/n\\t@@(%O2,tbr)\";
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "no")
7527 (set_attr "fp_set" "unknown")])
7529 ;; This is a pc-rel call, using bsrf, for use with PIC.
7531 (define_insn "calli_pcrel"
7532 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7533 (match_operand 1 "" ""))
7534 (use (reg:PSI FPSCR_REG))
7535 (use (reg:SI PIC_REG))
7536 (use (match_operand 2 "" ""))
7537 (clobber (reg:SI PR_REG))]
7540 [(set_attr "type" "call")
7541 (set (attr "fp_mode")
7542 (if_then_else (eq_attr "fpu_single" "yes")
7543 (const_string "single") (const_string "double")))
7544 (set_attr "needs_delay_slot" "yes")
7545 (set_attr "fp_set" "unknown")])
7547 (define_insn_and_split "call_pcrel"
7548 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7549 (match_operand 1 "" ""))
7550 (use (reg:PSI FPSCR_REG))
7551 (use (reg:SI PIC_REG))
7552 (clobber (reg:SI PR_REG))
7553 (clobber (match_scratch:SI 2 "=r"))]
7560 rtx lab = PATTERN (gen_call_site ());
7562 if (SYMBOL_REF_LOCAL_P (operands[0]))
7563 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7565 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7566 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7569 [(set_attr "type" "call")
7570 (set (attr "fp_mode")
7571 (if_then_else (eq_attr "fpu_single" "yes")
7572 (const_string "single") (const_string "double")))
7573 (set_attr "needs_delay_slot" "yes")
7574 (set_attr "fp_set" "unknown")])
7576 (define_insn "call_compact"
7577 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7578 (match_operand 1 "" ""))
7579 (match_operand 2 "immediate_operand" "n")
7580 (use (reg:SI R0_REG))
7581 (use (reg:SI R1_REG))
7582 (use (reg:PSI FPSCR_REG))
7583 (clobber (reg:SI PR_REG))]
7584 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7586 [(set_attr "type" "call")
7587 (set (attr "fp_mode")
7588 (if_then_else (eq_attr "fpu_single" "yes")
7589 (const_string "single") (const_string "double")))
7590 (set_attr "needs_delay_slot" "yes")])
7592 (define_insn "call_compact_rettramp"
7593 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7594 (match_operand 1 "" ""))
7595 (match_operand 2 "immediate_operand" "n")
7596 (use (reg:SI R0_REG))
7597 (use (reg:SI R1_REG))
7598 (use (reg:PSI FPSCR_REG))
7599 (clobber (reg:SI R10_REG))
7600 (clobber (reg:SI PR_REG))]
7601 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7603 [(set_attr "type" "call")
7604 (set (attr "fp_mode")
7605 (if_then_else (eq_attr "fpu_single" "yes")
7606 (const_string "single") (const_string "double")))
7607 (set_attr "needs_delay_slot" "yes")])
7609 (define_insn "call_media"
7610 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7611 (match_operand 1 "" ""))
7612 (clobber (reg:DI PR_MEDIA_REG))]
7615 [(set_attr "type" "jump_media")])
7617 (define_insn "call_valuei"
7618 [(set (match_operand 0 "" "=rf")
7619 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7620 (match_operand 2 "" "")))
7621 (use (reg:PSI FPSCR_REG))
7622 (clobber (reg:SI PR_REG))]
7626 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7627 return \"jsr/n\\t@%1\";
7629 return \"jsr\\t@%1%#\";
7631 [(set_attr "type" "call")
7632 (set (attr "fp_mode")
7633 (if_then_else (eq_attr "fpu_single" "yes")
7634 (const_string "single") (const_string "double")))
7635 (set_attr "needs_delay_slot" "yes")
7636 (set_attr "fp_set" "unknown")])
7638 ;; This is TBR relative jump instruction for SH2A architecture.
7639 ;; Its use is enabled assigning an attribute "function_vector"
7640 ;; and the vector number to a function during its declaration.
7642 (define_insn "call_valuei_tbr_rel"
7643 [(set (match_operand 0 "" "=rf")
7644 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7645 (match_operand 2 "" "")))
7646 (use (reg:PSI FPSCR_REG))
7647 (clobber (reg:SI PR_REG))]
7648 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7651 unsigned HOST_WIDE_INT vect_num;
7652 vect_num = sh2a_get_function_vector_number (operands[1]);
7653 operands[3] = GEN_INT (vect_num * 4);
7655 return \"jsr/n\\t@@(%O3,tbr)\";
7657 [(set_attr "type" "call")
7658 (set (attr "fp_mode")
7659 (if_then_else (eq_attr "fpu_single" "yes")
7660 (const_string "single") (const_string "double")))
7661 (set_attr "needs_delay_slot" "no")
7662 (set_attr "fp_set" "unknown")])
7664 (define_insn "call_valuei_pcrel"
7665 [(set (match_operand 0 "" "=rf")
7666 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7667 (match_operand 2 "" "")))
7668 (use (reg:PSI FPSCR_REG))
7669 (use (reg:SI PIC_REG))
7670 (use (match_operand 3 "" ""))
7671 (clobber (reg:SI PR_REG))]
7674 [(set_attr "type" "call")
7675 (set (attr "fp_mode")
7676 (if_then_else (eq_attr "fpu_single" "yes")
7677 (const_string "single") (const_string "double")))
7678 (set_attr "needs_delay_slot" "yes")
7679 (set_attr "fp_set" "unknown")])
7681 (define_insn_and_split "call_value_pcrel"
7682 [(set (match_operand 0 "" "=rf")
7683 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7684 (match_operand 2 "" "")))
7685 (use (reg:PSI FPSCR_REG))
7686 (use (reg:SI PIC_REG))
7687 (clobber (reg:SI PR_REG))
7688 (clobber (match_scratch:SI 3 "=r"))]
7695 rtx lab = PATTERN (gen_call_site ());
7697 if (SYMBOL_REF_LOCAL_P (operands[1]))
7698 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7700 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7701 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7702 operands[2], copy_rtx (lab)));
7705 [(set_attr "type" "call")
7706 (set (attr "fp_mode")
7707 (if_then_else (eq_attr "fpu_single" "yes")
7708 (const_string "single") (const_string "double")))
7709 (set_attr "needs_delay_slot" "yes")
7710 (set_attr "fp_set" "unknown")])
7712 (define_insn "call_value_compact"
7713 [(set (match_operand 0 "" "=rf")
7714 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7715 (match_operand 2 "" "")))
7716 (match_operand 3 "immediate_operand" "n")
7717 (use (reg:SI R0_REG))
7718 (use (reg:SI R1_REG))
7719 (use (reg:PSI FPSCR_REG))
7720 (clobber (reg:SI PR_REG))]
7721 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7723 [(set_attr "type" "call")
7724 (set (attr "fp_mode")
7725 (if_then_else (eq_attr "fpu_single" "yes")
7726 (const_string "single") (const_string "double")))
7727 (set_attr "needs_delay_slot" "yes")])
7729 (define_insn "call_value_compact_rettramp"
7730 [(set (match_operand 0 "" "=rf")
7731 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7732 (match_operand 2 "" "")))
7733 (match_operand 3 "immediate_operand" "n")
7734 (use (reg:SI R0_REG))
7735 (use (reg:SI R1_REG))
7736 (use (reg:PSI FPSCR_REG))
7737 (clobber (reg:SI R10_REG))
7738 (clobber (reg:SI PR_REG))]
7739 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7741 [(set_attr "type" "call")
7742 (set (attr "fp_mode")
7743 (if_then_else (eq_attr "fpu_single" "yes")
7744 (const_string "single") (const_string "double")))
7745 (set_attr "needs_delay_slot" "yes")])
7747 (define_insn "call_value_media"
7748 [(set (match_operand 0 "" "=rf")
7749 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7750 (match_operand 2 "" "")))
7751 (clobber (reg:DI PR_MEDIA_REG))]
7754 [(set_attr "type" "jump_media")])
7756 (define_expand "call"
7757 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7758 (match_operand 1 "" ""))
7759 (match_operand 2 "" "")
7760 (use (reg:PSI FPSCR_REG))
7761 (clobber (reg:SI PR_REG))])]
7767 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7768 emit_call_insn (gen_call_media (operands[0], operands[1]));
7771 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7773 rtx cookie_rtx = operands[2];
7774 long cookie = INTVAL (cookie_rtx);
7775 rtx func = XEXP (operands[0], 0);
7780 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7782 rtx reg = gen_reg_rtx (Pmode);
7784 emit_insn (gen_symGOTPLT2reg (reg, func));
7788 func = legitimize_pic_address (func, Pmode, 0);
7791 r0 = gen_rtx_REG (SImode, R0_REG);
7792 r1 = gen_rtx_REG (SImode, R1_REG);
7794 /* Since such a call function may use all call-clobbered
7795 registers, we force a mode switch earlier, so that we don't
7796 run out of registers when adjusting fpscr for the call. */
7797 emit_insn (gen_force_mode_for_call ());
7800 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7802 operands[0] = force_reg (SImode, operands[0]);
7804 emit_move_insn (r0, func);
7805 emit_move_insn (r1, cookie_rtx);
7807 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7808 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7811 emit_call_insn (gen_call_compact (operands[0], operands[1],
7816 else if (TARGET_SHCOMPACT && flag_pic
7817 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7818 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7820 rtx reg = gen_reg_rtx (Pmode);
7822 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7823 XEXP (operands[0], 0) = reg;
7825 if (!flag_pic && TARGET_SH2A
7826 && GET_CODE (operands[0]) == MEM
7827 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7829 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7831 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7836 if (flag_pic && TARGET_SH2
7837 && GET_CODE (operands[0]) == MEM
7838 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7840 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7845 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7846 operands[1] = operands[2];
7849 emit_call_insn (gen_calli (operands[0], operands[1]));
7853 (define_insn "call_pop_compact"
7854 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7855 (match_operand 1 "" ""))
7856 (match_operand 2 "immediate_operand" "n")
7857 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7858 (match_operand 3 "immediate_operand" "n")))
7859 (use (reg:SI R0_REG))
7860 (use (reg:SI R1_REG))
7861 (use (reg:PSI FPSCR_REG))
7862 (clobber (reg:SI PR_REG))]
7863 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7865 [(set_attr "type" "call")
7866 (set (attr "fp_mode")
7867 (if_then_else (eq_attr "fpu_single" "yes")
7868 (const_string "single") (const_string "double")))
7869 (set_attr "needs_delay_slot" "yes")])
7871 (define_insn "call_pop_compact_rettramp"
7872 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7873 (match_operand 1 "" ""))
7874 (match_operand 2 "immediate_operand" "n")
7875 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7876 (match_operand 3 "immediate_operand" "n")))
7877 (use (reg:SI R0_REG))
7878 (use (reg:SI R1_REG))
7879 (use (reg:PSI FPSCR_REG))
7880 (clobber (reg:SI R10_REG))
7881 (clobber (reg:SI PR_REG))]
7882 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7884 [(set_attr "type" "call")
7885 (set (attr "fp_mode")
7886 (if_then_else (eq_attr "fpu_single" "yes")
7887 (const_string "single") (const_string "double")))
7888 (set_attr "needs_delay_slot" "yes")])
7890 (define_expand "call_pop"
7891 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7892 (match_operand 1 "" ""))
7893 (match_operand 2 "" "")
7894 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7895 (match_operand 3 "" "")))])]
7904 gcc_assert (operands[2] && INTVAL (operands[2]));
7905 cookie_rtx = operands[2];
7906 cookie = INTVAL (cookie_rtx);
7907 func = XEXP (operands[0], 0);
7911 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7913 rtx reg = gen_reg_rtx (Pmode);
7914 emit_insn (gen_symGOTPLT2reg (reg, func));
7918 func = legitimize_pic_address (func, Pmode, 0);
7921 r0 = gen_rtx_REG (SImode, R0_REG);
7922 r1 = gen_rtx_REG (SImode, R1_REG);
7924 /* Since such a call function may use all call-clobbered
7925 registers, we force a mode switch earlier, so that we don't
7926 run out of registers when adjusting fpscr for the call. */
7927 emit_insn (gen_force_mode_for_call ());
7929 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7931 operands[0] = force_reg (SImode, operands[0]);
7933 emit_move_insn (r0, func);
7934 emit_move_insn (r1, cookie_rtx);
7936 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7937 emit_call_insn (gen_call_pop_compact_rettramp
7938 (operands[0], operands[1], operands[2], operands[3]));
7940 emit_call_insn (gen_call_pop_compact
7941 (operands[0], operands[1], operands[2], operands[3]));
7946 (define_expand "call_value"
7947 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7948 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7949 (match_operand 2 "" "")))
7950 (match_operand 3 "" "")
7951 (use (reg:PSI FPSCR_REG))
7952 (clobber (reg:SI PR_REG))])]
7958 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7959 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7963 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7965 rtx cookie_rtx = operands[3];
7966 long cookie = INTVAL (cookie_rtx);
7967 rtx func = XEXP (operands[1], 0);
7972 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7974 rtx reg = gen_reg_rtx (Pmode);
7976 emit_insn (gen_symGOTPLT2reg (reg, func));
7980 func = legitimize_pic_address (func, Pmode, 0);
7983 r0 = gen_rtx_REG (SImode, R0_REG);
7984 r1 = gen_rtx_REG (SImode, R1_REG);
7986 /* Since such a call function may use all call-clobbered
7987 registers, we force a mode switch earlier, so that we don't
7988 run out of registers when adjusting fpscr for the call. */
7989 emit_insn (gen_force_mode_for_call ());
7992 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7994 operands[1] = force_reg (SImode, operands[1]);
7996 emit_move_insn (r0, func);
7997 emit_move_insn (r1, cookie_rtx);
7999 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8000 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
8005 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
8006 operands[2], operands[3]));
8010 else if (TARGET_SHCOMPACT && flag_pic
8011 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8012 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8014 rtx reg = gen_reg_rtx (Pmode);
8016 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
8017 XEXP (operands[1], 0) = reg;
8019 if (!flag_pic && TARGET_SH2A
8020 && GET_CODE (operands[1]) == MEM
8021 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8023 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
8025 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
8026 XEXP (operands[1], 0), operands[2]));
8030 if (flag_pic && TARGET_SH2
8031 && GET_CODE (operands[1]) == MEM
8032 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8034 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
8039 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8041 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
8045 (define_insn "sibcalli"
8046 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
8047 (match_operand 1 "" ""))
8048 (use (reg:PSI FPSCR_REG))
8052 [(set_attr "needs_delay_slot" "yes")
8053 (set (attr "fp_mode")
8054 (if_then_else (eq_attr "fpu_single" "yes")
8055 (const_string "single") (const_string "double")))
8056 (set_attr "type" "jump_ind")])
8058 (define_insn "sibcalli_pcrel"
8059 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
8060 (match_operand 1 "" ""))
8061 (use (match_operand 2 "" ""))
8062 (use (reg:PSI FPSCR_REG))
8066 [(set_attr "needs_delay_slot" "yes")
8067 (set (attr "fp_mode")
8068 (if_then_else (eq_attr "fpu_single" "yes")
8069 (const_string "single") (const_string "double")))
8070 (set_attr "type" "jump_ind")])
8072 ;; This uses an unspec to describe that the symbol_ref is very close.
8073 (define_insn "sibcalli_thunk"
8074 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
8076 (match_operand 1 "" ""))
8077 (use (reg:PSI FPSCR_REG))
8081 [(set_attr "needs_delay_slot" "yes")
8082 (set (attr "fp_mode")
8083 (if_then_else (eq_attr "fpu_single" "yes")
8084 (const_string "single") (const_string "double")))
8085 (set_attr "type" "jump")
8086 (set_attr "length" "2")])
8088 (define_insn_and_split "sibcall_pcrel"
8089 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8090 (match_operand 1 "" ""))
8091 (use (reg:PSI FPSCR_REG))
8092 (clobber (match_scratch:SI 2 "=k"))
8100 rtx lab = PATTERN (gen_call_site ());
8103 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8104 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
8106 SIBLING_CALL_P (call_insn) = 1;
8109 [(set_attr "needs_delay_slot" "yes")
8110 (set (attr "fp_mode")
8111 (if_then_else (eq_attr "fpu_single" "yes")
8112 (const_string "single") (const_string "double")))
8113 (set_attr "type" "jump_ind")])
8115 (define_insn "sibcall_compact"
8116 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8117 (match_operand 1 "" ""))
8119 (use (match_operand:SI 2 "register_operand" "z,x"))
8120 (use (reg:SI R1_REG))
8121 (use (reg:PSI FPSCR_REG))
8122 ;; We want to make sure the `x' above will only match MACH_REG
8123 ;; because sibcall_epilogue may clobber MACL_REG.
8124 (clobber (reg:SI MACL_REG))]
8128 jmp @%0\\n sts %2, r0"
8129 [(set_attr "needs_delay_slot" "yes,no")
8130 (set_attr "length" "2,4")
8131 (set (attr "fp_mode") (const_string "single"))
8132 (set_attr "type" "jump_ind")])
8134 (define_insn "sibcall_media"
8135 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8136 (match_operand 1 "" ""))
8137 (use (reg:SI PR_MEDIA_REG))
8141 [(set_attr "type" "jump_media")])
8143 (define_expand "sibcall"
8145 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8146 (match_operand 1 "" ""))
8147 (match_operand 2 "" "")
8148 (use (reg:PSI FPSCR_REG))
8155 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8156 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8159 else if (TARGET_SHCOMPACT && operands[2]
8160 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8162 rtx cookie_rtx = operands[2];
8163 long cookie = INTVAL (cookie_rtx);
8164 rtx func = XEXP (operands[0], 0);
8169 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8171 rtx reg = gen_reg_rtx (Pmode);
8173 emit_insn (gen_symGOT2reg (reg, func));
8177 func = legitimize_pic_address (func, Pmode, 0);
8180 /* FIXME: if we could tell whether all argument registers are
8181 already taken, we could decide whether to force the use of
8182 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8183 simple way to tell. We could use the CALL_COOKIE, but we
8184 can't currently tell a register used for regular argument
8185 passing from one that is unused. If we leave it up to reload
8186 to decide which register to use, it seems to always choose
8187 R0_REG, which leaves no available registers in SIBCALL_REGS
8188 to hold the address of the trampoline. */
8189 mach = gen_rtx_REG (SImode, MACH_REG);
8190 r1 = gen_rtx_REG (SImode, R1_REG);
8192 /* Since such a call function may use all call-clobbered
8193 registers, we force a mode switch earlier, so that we don't
8194 run out of registers when adjusting fpscr for the call. */
8195 emit_insn (gen_force_mode_for_call ());
8198 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8200 operands[0] = force_reg (SImode, operands[0]);
8202 /* We don't need a return trampoline, since the callee will
8203 return directly to the upper caller. */
8204 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8206 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8207 cookie_rtx = GEN_INT (cookie);
8210 emit_move_insn (mach, func);
8211 emit_move_insn (r1, cookie_rtx);
8213 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8216 else if (TARGET_SHCOMPACT && flag_pic
8217 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8218 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8220 rtx reg = gen_reg_rtx (Pmode);
8222 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8223 XEXP (operands[0], 0) = reg;
8225 if (flag_pic && TARGET_SH2
8226 && GET_CODE (operands[0]) == MEM
8227 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8228 /* The PLT needs the PIC register, but the epilogue would have
8229 to restore it, so we can only use PC-relative PIC calls for
8230 static functions. */
8231 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8233 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8237 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8239 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8243 (define_insn "sibcall_valuei"
8244 [(set (match_operand 0 "" "=rf")
8245 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8246 (match_operand 2 "" "")))
8247 (use (reg:PSI FPSCR_REG))
8251 [(set_attr "needs_delay_slot" "yes")
8252 (set (attr "fp_mode")
8253 (if_then_else (eq_attr "fpu_single" "yes")
8254 (const_string "single") (const_string "double")))
8255 (set_attr "type" "jump_ind")])
8257 (define_insn "sibcall_valuei_pcrel"
8258 [(set (match_operand 0 "" "=rf")
8259 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8260 (match_operand 2 "" "")))
8261 (use (match_operand 3 "" ""))
8262 (use (reg:PSI FPSCR_REG))
8266 [(set_attr "needs_delay_slot" "yes")
8267 (set (attr "fp_mode")
8268 (if_then_else (eq_attr "fpu_single" "yes")
8269 (const_string "single") (const_string "double")))
8270 (set_attr "type" "jump_ind")])
8272 (define_insn_and_split "sibcall_value_pcrel"
8273 [(set (match_operand 0 "" "=rf")
8274 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8275 (match_operand 2 "" "")))
8276 (use (reg:PSI FPSCR_REG))
8277 (clobber (match_scratch:SI 3 "=k"))
8285 rtx lab = PATTERN (gen_call_site ());
8288 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8289 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8293 SIBLING_CALL_P (call_insn) = 1;
8296 [(set_attr "needs_delay_slot" "yes")
8297 (set (attr "fp_mode")
8298 (if_then_else (eq_attr "fpu_single" "yes")
8299 (const_string "single") (const_string "double")))
8300 (set_attr "type" "jump_ind")])
8302 (define_insn "sibcall_value_compact"
8303 [(set (match_operand 0 "" "=rf,rf")
8304 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8305 (match_operand 2 "" "")))
8307 (use (match_operand:SI 3 "register_operand" "z,x"))
8308 (use (reg:SI R1_REG))
8309 (use (reg:PSI FPSCR_REG))
8310 ;; We want to make sure the `x' above will only match MACH_REG
8311 ;; because sibcall_epilogue may clobber MACL_REG.
8312 (clobber (reg:SI MACL_REG))]
8316 jmp @%1\\n sts %3, r0"
8317 [(set_attr "needs_delay_slot" "yes,no")
8318 (set_attr "length" "2,4")
8319 (set (attr "fp_mode") (const_string "single"))
8320 (set_attr "type" "jump_ind")])
8322 (define_insn "sibcall_value_media"
8323 [(set (match_operand 0 "" "=rf")
8324 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8325 (match_operand 2 "" "")))
8326 (use (reg:SI PR_MEDIA_REG))
8330 [(set_attr "type" "jump_media")])
8332 (define_expand "sibcall_value"
8334 [(set (match_operand 0 "arith_reg_operand" "")
8335 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8336 (match_operand 2 "" "")))
8337 (match_operand 3 "" "")
8338 (use (reg:PSI FPSCR_REG))
8345 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8346 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8350 else if (TARGET_SHCOMPACT && operands[3]
8351 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8353 rtx cookie_rtx = operands[3];
8354 long cookie = INTVAL (cookie_rtx);
8355 rtx func = XEXP (operands[1], 0);
8360 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8362 rtx reg = gen_reg_rtx (Pmode);
8364 emit_insn (gen_symGOT2reg (reg, func));
8368 func = legitimize_pic_address (func, Pmode, 0);
8371 /* FIXME: if we could tell whether all argument registers are
8372 already taken, we could decide whether to force the use of
8373 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8374 simple way to tell. We could use the CALL_COOKIE, but we
8375 can't currently tell a register used for regular argument
8376 passing from one that is unused. If we leave it up to reload
8377 to decide which register to use, it seems to always choose
8378 R0_REG, which leaves no available registers in SIBCALL_REGS
8379 to hold the address of the trampoline. */
8380 mach = gen_rtx_REG (SImode, MACH_REG);
8381 r1 = gen_rtx_REG (SImode, R1_REG);
8383 /* Since such a call function may use all call-clobbered
8384 registers, we force a mode switch earlier, so that we don't
8385 run out of registers when adjusting fpscr for the call. */
8386 emit_insn (gen_force_mode_for_call ());
8389 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8391 operands[1] = force_reg (SImode, operands[1]);
8393 /* We don't need a return trampoline, since the callee will
8394 return directly to the upper caller. */
8395 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8397 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8398 cookie_rtx = GEN_INT (cookie);
8401 emit_move_insn (mach, func);
8402 emit_move_insn (r1, cookie_rtx);
8404 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8405 operands[2], mach));
8408 else if (TARGET_SHCOMPACT && flag_pic
8409 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8410 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8412 rtx reg = gen_reg_rtx (Pmode);
8414 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8415 XEXP (operands[1], 0) = reg;
8417 if (flag_pic && TARGET_SH2
8418 && GET_CODE (operands[1]) == MEM
8419 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8420 /* The PLT needs the PIC register, but the epilogue would have
8421 to restore it, so we can only use PC-relative PIC calls for
8422 static functions. */
8423 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8425 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8426 XEXP (operands[1], 0),
8431 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8433 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8437 (define_insn "call_value_pop_compact"
8438 [(set (match_operand 0 "" "=rf")
8439 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8440 (match_operand 2 "" "")))
8441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8442 (match_operand 4 "immediate_operand" "n")))
8443 (match_operand 3 "immediate_operand" "n")
8444 (use (reg:SI R0_REG))
8445 (use (reg:SI R1_REG))
8446 (use (reg:PSI FPSCR_REG))
8447 (clobber (reg:SI PR_REG))]
8448 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8450 [(set_attr "type" "call")
8451 (set (attr "fp_mode")
8452 (if_then_else (eq_attr "fpu_single" "yes")
8453 (const_string "single") (const_string "double")))
8454 (set_attr "needs_delay_slot" "yes")])
8456 (define_insn "call_value_pop_compact_rettramp"
8457 [(set (match_operand 0 "" "=rf")
8458 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8459 (match_operand 2 "" "")))
8460 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8461 (match_operand 4 "immediate_operand" "n")))
8462 (match_operand 3 "immediate_operand" "n")
8463 (use (reg:SI R0_REG))
8464 (use (reg:SI R1_REG))
8465 (use (reg:PSI FPSCR_REG))
8466 (clobber (reg:SI R10_REG))
8467 (clobber (reg:SI PR_REG))]
8468 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8470 [(set_attr "type" "call")
8471 (set (attr "fp_mode")
8472 (if_then_else (eq_attr "fpu_single" "yes")
8473 (const_string "single") (const_string "double")))
8474 (set_attr "needs_delay_slot" "yes")])
8476 (define_expand "call_value_pop"
8477 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8478 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8479 (match_operand 2 "" "")))
8480 (match_operand 3 "" "")
8481 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8482 (match_operand 4 "" "")))])]
8491 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8492 cookie_rtx = operands[3];
8493 cookie = INTVAL (cookie_rtx);
8494 func = XEXP (operands[1], 0);
8498 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8500 rtx reg = gen_reg_rtx (Pmode);
8502 emit_insn (gen_symGOTPLT2reg (reg, func));
8506 func = legitimize_pic_address (func, Pmode, 0);
8509 r0 = gen_rtx_REG (SImode, R0_REG);
8510 r1 = gen_rtx_REG (SImode, R1_REG);
8512 /* Since such a call function may use all call-clobbered
8513 registers, we force a mode switch earlier, so that we don't
8514 run out of registers when adjusting fpscr for the call. */
8515 emit_insn (gen_force_mode_for_call ());
8517 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8519 operands[1] = force_reg (SImode, operands[1]);
8521 emit_move_insn (r0, func);
8522 emit_move_insn (r1, cookie_rtx);
8524 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8525 emit_call_insn (gen_call_value_pop_compact_rettramp
8526 (operands[0], operands[1], operands[2],
8527 operands[3], operands[4]));
8529 emit_call_insn (gen_call_value_pop_compact
8530 (operands[0], operands[1], operands[2],
8531 operands[3], operands[4]));
8536 (define_expand "sibcall_epilogue"
8541 sh_expand_epilogue (1);
8542 if (TARGET_SHCOMPACT)
8546 /* If epilogue clobbers r0, preserve it in macl. */
8547 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8548 if ((set = single_set (insn))
8549 && GET_CODE (SET_DEST (set)) == REG
8550 && REGNO (SET_DEST (set)) == R0_REG)
8552 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8553 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8555 /* We can't tell at this point whether the sibcall is a
8556 sibcall_compact and, if it is, whether it uses r0 or
8557 mach as operand 2, so let the instructions that
8558 preserve r0 be optimized away if r0 turns out to be
8560 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8561 emit_move_insn (r0, tmp);
8568 (define_insn "indirect_jump_compact"
8570 (match_operand:SI 0 "arith_reg_operand" "r"))]
8573 [(set_attr "needs_delay_slot" "yes")
8574 (set_attr "type" "jump_ind")])
8576 (define_expand "indirect_jump"
8578 (match_operand 0 "register_operand" ""))]
8582 if (GET_MODE (operands[0]) != Pmode)
8583 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8586 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8587 ;; which can be present in structured code from indirect jumps which can not
8588 ;; be present in structured code. This allows -fprofile-arcs to work.
8590 ;; For SH1 processors.
8591 (define_insn "casesi_jump_1"
8593 (match_operand:SI 0 "register_operand" "r"))
8594 (use (label_ref (match_operand 1 "" "")))]
8597 [(set_attr "needs_delay_slot" "yes")
8598 (set_attr "type" "jump_ind")])
8600 ;; For all later processors.
8601 (define_insn "casesi_jump_2"
8602 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8603 (label_ref (match_operand 1 "" ""))))
8604 (use (label_ref (match_operand 2 "" "")))]
8606 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8608 [(set_attr "needs_delay_slot" "yes")
8609 (set_attr "type" "jump_ind")])
8611 (define_insn "casesi_jump_media"
8612 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8613 (use (label_ref (match_operand 1 "" "")))]
8616 [(set_attr "type" "jump_media")])
8618 ;; Call subroutine returning any type.
8619 ;; ??? This probably doesn't work.
8621 (define_expand "untyped_call"
8622 [(parallel [(call (match_operand 0 "" "")
8624 (match_operand 1 "" "")
8625 (match_operand 2 "" "")])]
8626 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8631 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8633 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8635 rtx set = XVECEXP (operands[2], 0, i);
8636 emit_move_insn (SET_DEST (set), SET_SRC (set));
8639 /* The optimizer does not know that the call sets the function value
8640 registers we stored in the result block. We avoid problems by
8641 claiming that all hard registers are used and clobbered at this
8643 emit_insn (gen_blockage ());
8648 ;; ------------------------------------------------------------------------
8650 ;; ------------------------------------------------------------------------
8653 [(set (reg:SI T_REG)
8654 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8655 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8658 [(set_attr "type" "arith")])
8665 ;; Load address of a label. This is only generated by the casesi expand,
8666 ;; and by machine_dependent_reorg (fixing up fp moves).
8667 ;; This must use unspec, because this only works for labels that are
8671 [(set (reg:SI R0_REG)
8672 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8675 [(set_attr "in_delay_slot" "no")
8676 (set_attr "type" "arith")])
8678 ;; machine_dependent_reorg will make this a `mova'.
8679 (define_insn "mova_const"
8680 [(set (reg:SI R0_REG)
8681 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8684 [(set_attr "in_delay_slot" "no")
8685 (set_attr "type" "arith")])
8687 (define_expand "GOTaddr2picreg"
8688 [(set (reg:SI R0_REG)
8689 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8691 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8692 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8695 if (TARGET_VXWORKS_RTP)
8697 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8698 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8699 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8703 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8704 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8708 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8709 rtx pic = operands[0];
8710 rtx lab = PATTERN (gen_call_site ());
8713 equiv = operands[1];
8714 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8715 UNSPEC_PCREL_SYMOFF);
8716 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8718 if (Pmode == SImode)
8720 emit_insn (gen_movsi_const (pic, operands[1]));
8721 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8725 emit_insn (gen_movdi_const (pic, operands[1]));
8726 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8729 insn = emit_move_insn (operands[0], tr);
8731 set_unique_reg_note (insn, REG_EQUAL, equiv);
8738 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8741 (define_expand "vxworks_picreg"
8742 [(set (reg:SI PIC_REG)
8743 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8744 (set (reg:SI R0_REG)
8745 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8746 (set (reg:SI PIC_REG)
8747 (mem:SI (reg:SI PIC_REG)))
8748 (set (reg:SI PIC_REG)
8749 (mem:SI (plus:SI (reg:SI PIC_REG)
8751 "TARGET_VXWORKS_RTP")
8754 [(set (match_operand 0 "target_reg_operand" "=b")
8755 (const (unspec [(match_operand 1 "" "Csy")]
8756 UNSPEC_DATALABEL)))]
8757 "TARGET_SHMEDIA && flag_pic
8758 && satisfies_constraint_Csy (operands[1])"
8759 "ptb/u datalabel %1, %0"
8760 [(set_attr "type" "ptabs_media")
8761 (set_attr "length" "*")])
8763 (define_insn "ptrel_si"
8764 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8765 (plus:SI (match_operand:SI 1 "register_operand" "r")
8767 (match_operand:SI 2 "" "")]
8769 "%O2: ptrel/u %1, %0"
8770 [(set_attr "type" "ptabs_media")])
8772 (define_insn "ptrel_di"
8773 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8774 (plus:DI (match_operand:DI 1 "register_operand" "r")
8776 (match_operand:DI 2 "" "")]
8778 "%O2: ptrel/u %1, %0"
8779 [(set_attr "type" "ptabs_media")])
8781 (define_expand "builtin_setjmp_receiver"
8782 [(match_operand 0 "" "")]
8786 emit_insn (gen_GOTaddr2picreg ());
8790 (define_expand "call_site"
8791 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8795 static HOST_WIDE_INT i = 0;
8796 operands[0] = GEN_INT (i);
8800 (define_expand "sym_label2reg"
8801 [(set (match_operand:SI 0 "" "")
8802 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8803 (const (plus:SI (match_operand:SI 2 "" "")
8808 (define_expand "symGOT_load"
8809 [(set (match_dup 2) (match_operand 1 "" ""))
8810 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8811 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8817 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8818 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8822 rtx reg = operands[2];
8824 if (Pmode == DImode)
8827 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8829 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8834 emit_insn (gen_movsi_const (reg, operands[1]));
8836 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8840 emit_move_insn (operands[2], operands[1]);
8842 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8844 gen_rtx_REG (Pmode, PIC_REG)));
8846 /* When stack protector inserts codes after the result is set to
8847 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8848 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8849 when rX is a GOT address for the guard symbol. Ugly but doesn't
8850 matter because this is a rare situation. */
8852 && flag_stack_protect
8853 && GET_CODE (operands[1]) == CONST
8854 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8855 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8856 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8857 \"__stack_chk_guard\") == 0)
8858 emit_insn (gen_blockage ());
8860 /* N.B. This is not constant for a GOTPLT relocation. */
8861 mem = gen_rtx_MEM (Pmode, operands[3]);
8862 MEM_NOTRAP_P (mem) = 1;
8863 /* ??? Should we have a special alias set for the GOT? */
8864 insn = emit_move_insn (operands[0], mem);
8869 (define_expand "sym2GOT"
8870 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8874 (define_expand "symGOT2reg"
8875 [(match_operand 0 "" "") (match_operand 1 "" "")]
8881 gotsym = gen_sym2GOT (operands[1]);
8882 PUT_MODE (gotsym, Pmode);
8883 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8885 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8890 (define_expand "symGOTPLT2reg"
8891 [(match_operand 0 "" "") (match_operand 1 "" "")]
8895 rtx pltsym = gen_rtx_CONST (Pmode,
8896 gen_rtx_UNSPEC (Pmode,
8897 gen_rtvec (1, operands[1]),
8899 emit_insn (gen_symGOT_load (operands[0], pltsym));
8903 (define_expand "sym2GOTOFF"
8904 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8908 (define_expand "symGOTOFF2reg"
8909 [(match_operand 0 "" "") (match_operand 1 "" "")]
8913 rtx gotoffsym, insn;
8914 rtx t = (!can_create_pseudo_p ()
8916 : gen_reg_rtx (GET_MODE (operands[0])));
8918 gotoffsym = gen_sym2GOTOFF (operands[1]);
8919 PUT_MODE (gotoffsym, Pmode);
8920 emit_move_insn (t, gotoffsym);
8921 insn = emit_move_insn (operands[0],
8922 gen_rtx_PLUS (Pmode, t,
8923 gen_rtx_REG (Pmode, PIC_REG)));
8925 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8930 (define_expand "symPLT_label2reg"
8931 [(set (match_operand:SI 0 "" "")
8934 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8935 (const:SI (plus:SI (match_operand:SI 2 "" "")
8936 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8937 ;; Even though the PIC register is not really used by the call
8938 ;; sequence in which this is expanded, the PLT code assumes the PIC
8939 ;; register is set, so we must not skip its initialization. Since
8940 ;; we only use this expand as part of calling sequences, and never
8941 ;; to take the address of a function, this is the best point to
8942 ;; insert the (use). Using the PLT to take the address of a
8943 ;; function would be wrong, not only because the PLT entry could
8944 ;; then be called from a function that doesn't initialize the PIC
8945 ;; register to the proper GOT, but also because pointers to the
8946 ;; same function might not compare equal, should they be set by
8947 ;; different shared libraries.
8948 (use (reg:SI PIC_REG))]
8952 (define_expand "sym2PIC"
8953 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8957 ;; TLS code generation.
8958 ;; ??? this should be a define_insn_and_split
8959 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8960 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8963 (define_insn "tls_global_dynamic"
8964 [(set (match_operand:SI 0 "register_operand" "=&z")
8965 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8968 (use (reg:PSI FPSCR_REG))
8969 (use (reg:SI PIC_REG))
8970 (clobber (reg:SI PR_REG))
8971 (clobber (scratch:SI))]
8977 \\tmova\\t2f,r0\\n\\
8978 \\tmov.l\\t2f,r1\\n\\
8981 \\tadd\\tr12,r4\\n\\
8985 1:\\t.long\\t%a1@TLSGD\\n\\
8986 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8989 [(set_attr "type" "tls_load")
8990 (set_attr "length" "26")])
8992 (define_insn "tls_local_dynamic"
8993 [(set (match_operand:SI 0 "register_operand" "=&z")
8994 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8997 (use (reg:PSI FPSCR_REG))
8998 (use (reg:SI PIC_REG))
8999 (clobber (reg:SI PR_REG))
9000 (clobber (scratch:SI))]
9006 \\tmova\\t2f,r0\\n\\
9007 \\tmov.l\\t2f,r1\\n\\
9010 \\tadd\\tr12,r4\\n\\
9014 1:\\t.long\\t%a1@TLSLDM\\n\\
9015 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9018 [(set_attr "type" "tls_load")
9019 (set_attr "length" "26")])
9021 (define_expand "sym2DTPOFF"
9022 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
9026 (define_expand "symDTPOFF2reg"
9027 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
9031 rtx dtpoffsym, insn;
9032 rtx t = (!can_create_pseudo_p ()
9034 : gen_reg_rtx (GET_MODE (operands[0])));
9036 dtpoffsym = gen_sym2DTPOFF (operands[1]);
9037 PUT_MODE (dtpoffsym, Pmode);
9038 emit_move_insn (t, dtpoffsym);
9039 insn = emit_move_insn (operands[0],
9040 gen_rtx_PLUS (Pmode, t, operands[2]));
9044 (define_expand "sym2GOTTPOFF"
9045 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
9049 (define_insn "tls_initial_exec"
9050 [(set (match_operand:SI 0 "register_operand" "=&r")
9051 (unspec:SI [(match_operand:SI 1 "" "")]
9053 (use (reg:SI GBR_REG))
9054 (use (reg:SI PIC_REG))
9055 (clobber (reg:SI R0_REG))]
9061 \\tstc\\tgbr,%0\\n\\
9062 \\tmov.l\\t@(r0,r12),r0\\n\\
9066 1:\\t.long\\t%a1\\n\\
9069 [(set_attr "type" "tls_load")
9070 (set_attr "length" "16")])
9072 (define_expand "sym2TPOFF"
9073 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
9077 (define_expand "symTPOFF2reg"
9078 [(match_operand 0 "" "") (match_operand 1 "" "")]
9084 tpoffsym = gen_sym2TPOFF (operands[1]);
9085 PUT_MODE (tpoffsym, Pmode);
9086 insn = emit_move_insn (operands[0], tpoffsym);
9090 (define_insn "load_gbr"
9091 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
9092 (use (reg:SI GBR_REG))]
9095 [(set_attr "type" "tls_load")])
9097 ;; case instruction for switch statements.
9099 ;; Operand 0 is index
9100 ;; operand 1 is the minimum bound
9101 ;; operand 2 is the maximum bound - minimum bound + 1
9102 ;; operand 3 is CODE_LABEL for the table;
9103 ;; operand 4 is the CODE_LABEL to go to if index out of range.
9105 (define_expand "casesi"
9106 [(match_operand:SI 0 "arith_reg_operand" "")
9107 (match_operand:SI 1 "arith_reg_operand" "")
9108 (match_operand:SI 2 "arith_reg_operand" "")
9109 (match_operand 3 "" "") (match_operand 4 "" "")]
9113 rtx reg = gen_reg_rtx (SImode);
9114 rtx reg2 = gen_reg_rtx (SImode);
9117 rtx reg = gen_reg_rtx (DImode);
9118 rtx reg2 = gen_reg_rtx (DImode);
9119 rtx reg3 = gen_reg_rtx (Pmode);
9120 rtx reg4 = gen_reg_rtx (Pmode);
9121 rtx reg5 = gen_reg_rtx (Pmode);
9124 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9125 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9126 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9128 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9129 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9130 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9131 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9132 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9133 (Pmode, operands[3])));
9134 /* Messy: can we subreg to clean this up? */
9135 if (Pmode == DImode)
9136 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9138 load = gen_casesi_load_media (reg4,
9139 gen_rtx_SUBREG (DImode, reg3, 0),
9141 PUT_MODE (SET_SRC (load), Pmode);
9143 /* ??? The following add could be eliminated if we used ptrel. */
9144 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9145 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9149 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9150 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9151 /* If optimizing, casesi_worker depends on the mode of the instruction
9152 before label it 'uses' - operands[3]. */
9153 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9155 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9157 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9159 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9160 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9161 operands[3], but to lab. We will fix this up in
9162 machine_dependent_reorg. */
9167 (define_expand "casesi_0"
9168 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9169 (set (match_dup 4) (minus:SI (match_dup 4)
9170 (match_operand:SI 1 "arith_operand" "")))
9172 (gtu:SI (match_dup 4)
9173 (match_operand:SI 2 "arith_reg_operand" "")))
9175 (if_then_else (ne (reg:SI T_REG)
9177 (label_ref (match_operand 3 "" ""))
9182 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9183 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9184 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9186 (define_insn "casesi_worker_0"
9187 [(set (match_operand:SI 0 "register_operand" "=r,r")
9188 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9189 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9190 (clobber (match_scratch:SI 3 "=X,1"))
9191 (clobber (match_scratch:SI 4 "=&z,z"))]
9196 [(set (match_operand:SI 0 "register_operand" "")
9197 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9198 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9199 (clobber (match_scratch:SI 3 ""))
9200 (clobber (match_scratch:SI 4 ""))]
9201 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9202 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9203 (parallel [(set (match_dup 0)
9204 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9205 (label_ref (match_dup 2))] UNSPEC_CASESI))
9206 (clobber (match_dup 3))])
9207 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9208 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9211 [(set (match_operand:SI 0 "register_operand" "")
9212 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9213 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9214 (clobber (match_scratch:SI 3 ""))
9215 (clobber (match_scratch:SI 4 ""))]
9216 "TARGET_SH2 && reload_completed"
9217 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9218 (parallel [(set (match_dup 0)
9219 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9220 (label_ref (match_dup 2))] UNSPEC_CASESI))
9221 (clobber (match_dup 3))])]
9222 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9224 (define_insn "casesi_worker_1"
9225 [(set (match_operand:SI 0 "register_operand" "=r,r")
9226 (unspec:SI [(reg:SI R0_REG)
9227 (match_operand:SI 1 "register_operand" "0,r")
9228 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9229 (clobber (match_scratch:SI 3 "=X,1"))]
9233 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9235 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9237 switch (GET_MODE (diff_vec))
9240 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9242 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9244 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9245 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9246 return \"mov.b @(r0,%1),%0\";
9251 [(set_attr "length" "4")])
9253 (define_insn "casesi_worker_2"
9254 [(set (match_operand:SI 0 "register_operand" "=r,r")
9255 (unspec:SI [(reg:SI R0_REG)
9256 (match_operand:SI 1 "register_operand" "0,r")
9257 (label_ref (match_operand 2 "" ""))
9258 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9259 (clobber (match_operand:SI 4 "" "=X,1"))]
9260 "TARGET_SH2 && reload_completed && flag_pic"
9263 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9266 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9268 switch (GET_MODE (diff_vec))
9271 output_asm_insn (\"shll2 %1\", operands);
9272 load = \"mov.l @(r0,%1),%0\"; break;
9274 output_asm_insn (\"add %1,%1\", operands);
9275 load = \"mov.w @(r0,%1),%0\"; break;
9277 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9278 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9280 load = \"mov.b @(r0,%1),%0\";
9285 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9288 [(set_attr "length" "8")])
9290 (define_insn "casesi_shift_media"
9291 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9292 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9293 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9298 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9300 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9302 switch (GET_MODE (diff_vec))
9305 return \"shlli %1, 2, %0\";
9307 return \"shlli %1, 1, %0\";
9309 if (rtx_equal_p (operands[0], operands[1]))
9311 return \"add %1, r63, %0\";
9316 [(set_attr "type" "arith_media")])
9318 (define_insn "casesi_load_media"
9319 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9320 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9321 (match_operand:DI 2 "arith_reg_operand" "r")
9322 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9326 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9328 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9330 switch (GET_MODE (diff_vec))
9333 return \"ldx.l %1, %2, %0\";
9336 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9337 return \"ldx.uw %1, %2, %0\";
9339 return \"ldx.w %1, %2, %0\";
9341 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9342 return \"ldx.ub %1, %2, %0\";
9343 return \"ldx.b %1, %2, %0\";
9348 [(set_attr "type" "load_media")])
9350 (define_expand "return"
9352 "reload_completed && ! sh_need_epilogue ()"
9357 emit_jump_insn (gen_return_media ());
9361 if (TARGET_SHCOMPACT
9362 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9364 emit_jump_insn (gen_shcompact_return_tramp ());
9369 (define_insn "*return_i"
9371 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9372 && (crtl->args.info.call_cookie
9373 & CALL_COOKIE_RET_TRAMP (1)))
9375 && lookup_attribute (\"trap_exit\",
9376 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9379 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9380 && !current_function_interrupt)
9385 [(set_attr "type" "return")
9386 (set_attr "needs_delay_slot" "yes")])
9388 ;; trapa has no delay slot.
9389 (define_insn "*return_trapa"
9391 "TARGET_SH1 && !TARGET_SHCOMPACT
9392 && reload_completed"
9394 [(set_attr "type" "return")])
9396 (define_expand "shcompact_return_tramp"
9399 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9402 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9404 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9405 emit_jump_insn (gen_shcompact_return_tramp_i ());
9409 (define_insn "shcompact_return_tramp_i"
9410 [(parallel [(return) (use (reg:SI R0_REG))])]
9412 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9414 [(set_attr "type" "jump_ind")
9415 (set_attr "needs_delay_slot" "yes")])
9417 (define_insn "return_media_i"
9418 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9419 "TARGET_SHMEDIA && reload_completed"
9421 [(set_attr "type" "jump_media")])
9423 (define_insn "return_media_rte"
9425 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9427 [(set_attr "type" "jump_media")])
9429 (define_expand "return_media"
9431 "TARGET_SHMEDIA && reload_completed"
9434 int tr_regno = sh_media_register_for_return ();
9437 if (current_function_interrupt)
9439 emit_jump_insn (gen_return_media_rte ());
9444 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9446 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9448 tr = gen_rtx_REG (Pmode, tr_regno);
9449 emit_move_insn (tr, r18);
9452 tr = gen_rtx_REG (Pmode, tr_regno);
9454 emit_jump_insn (gen_return_media_i (tr));
9458 (define_insn "shcompact_preserve_incoming_args"
9459 [(set (match_operand:SI 0 "register_operand" "+r")
9460 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9463 [(set_attr "length" "0")])
9465 (define_insn "shcompact_incoming_args"
9466 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9467 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9468 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9469 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9470 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9471 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9472 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9473 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9474 (set (mem:BLK (reg:SI MACL_REG))
9475 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9476 (use (reg:SI R0_REG))
9477 (clobber (reg:SI R0_REG))
9478 (clobber (reg:SI MACL_REG))
9479 (clobber (reg:SI MACH_REG))
9480 (clobber (reg:SI PR_REG))]
9483 [(set_attr "needs_delay_slot" "yes")])
9485 (define_insn "shmedia_save_restore_regs_compact"
9486 [(set (reg:SI SP_REG)
9487 (plus:SI (reg:SI SP_REG)
9488 (match_operand:SI 0 "immediate_operand" "i")))
9489 (use (reg:SI R0_REG))
9490 (clobber (reg:SI PR_REG))]
9492 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9493 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9495 [(set_attr "needs_delay_slot" "yes")])
9497 (define_expand "prologue"
9500 "sh_expand_prologue (); DONE;")
9502 (define_expand "epilogue"
9507 sh_expand_epilogue (0);
9508 emit_jump_insn (gen_return ());
9512 (define_expand "eh_return"
9513 [(use (match_operand 0 "register_operand" ""))]
9516 rtx ra = operands[0];
9518 if (TARGET_SHMEDIA64)
9519 emit_insn (gen_eh_set_ra_di (ra));
9521 emit_insn (gen_eh_set_ra_si (ra));
9526 ;; Clobber the return address on the stack. We can't expand this
9527 ;; until we know where it will be put in the stack frame.
9529 (define_insn "eh_set_ra_si"
9530 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9532 (clobber (match_scratch:SI 1 "=&r"))]
9533 "! TARGET_SHMEDIA64"
9536 (define_insn "eh_set_ra_di"
9537 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9539 (clobber (match_scratch:DI 1 "=&r"))]
9544 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9546 (clobber (match_scratch 1 ""))]
9551 sh_set_return_address (operands[0], operands[1]);
9555 (define_insn "blockage"
9556 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9559 [(set_attr "length" "0")])
9561 ;; ------------------------------------------------------------------------
9563 ;; ------------------------------------------------------------------------
9566 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9567 (eq:SI (reg:SI T_REG) (const_int 1)))]
9570 [(set_attr "type" "arith")])
9572 ;; complements the T bit and stores the result in a register
9573 (define_insn "movrt"
9574 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9575 (if_then_else (eq:SI (reg:SI T_REG) (const_int 0))
9580 [(set_attr "type" "arith")])
9582 (define_expand "seq"
9583 [(set (match_operand:SI 0 "arith_reg_dest" "")
9592 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9593 if (sh_compare_op1 != const0_rtx)
9594 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9595 ? GET_MODE (sh_compare_op0)
9596 : GET_MODE (sh_compare_op1),
9598 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9600 if (GET_MODE (operands[0]) != SImode)
9601 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9603 switch (GET_MODE (sh_compare_op0))
9606 emit_insn (gen_cmpeqsi_media (operands[0],
9607 sh_compare_op0, sh_compare_op1));
9611 emit_insn (gen_cmpeqdi_media (operands[0],
9612 sh_compare_op0, sh_compare_op1));
9616 if (! TARGET_SHMEDIA_FPU)
9618 emit_insn (gen_cmpeqsf_media (operands[0],
9619 sh_compare_op0, sh_compare_op1));
9623 if (! TARGET_SHMEDIA_FPU)
9625 emit_insn (gen_cmpeqdf_media (operands[0],
9626 sh_compare_op0, sh_compare_op1));
9636 if (GET_MODE (operands[0]) != SImode)
9637 reg = (!can_create_pseudo_p ()
9638 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9639 : gen_reg_rtx (SImode));
9641 switch (GET_MODE (sh_compare_op0))
9644 emit_insn (gen_cmpeqsi_media (reg,
9645 sh_compare_op0, sh_compare_op1));
9649 emit_insn (gen_cmpeqdi_media (reg,
9650 sh_compare_op0, sh_compare_op1));
9654 if (! TARGET_SHMEDIA_FPU)
9656 emit_insn (gen_cmpeqsf_media (reg,
9657 sh_compare_op0, sh_compare_op1));
9661 if (! TARGET_SHMEDIA_FPU)
9663 emit_insn (gen_cmpeqdf_media (reg,
9664 sh_compare_op0, sh_compare_op1));
9671 if (GET_MODE (operands[0]) == DImode)
9672 emit_insn (gen_extendsidi2 (operands[0], reg));
9676 if (sh_expand_t_scc (EQ, operands[0]))
9678 if (! currently_expanding_to_rtl)
9680 operands[1] = prepare_scc_operands (EQ);
9683 (define_expand "slt"
9684 [(set (match_operand:SI 0 "arith_reg_operand" "")
9693 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9694 if (sh_compare_op1 != const0_rtx)
9695 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9696 ? GET_MODE (sh_compare_op0)
9697 : GET_MODE (sh_compare_op1),
9701 if (GET_MODE (operands[0]) != SImode)
9702 reg = (!can_create_pseudo_p ()
9703 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9704 : gen_reg_rtx (SImode));
9706 switch (GET_MODE (sh_compare_op0))
9709 emit_insn (gen_cmpgtsi_media (reg,
9710 sh_compare_op1, sh_compare_op0));
9714 emit_insn (gen_cmpgtdi_media (reg,
9715 sh_compare_op1, sh_compare_op0));
9719 if (! TARGET_SHMEDIA_FPU)
9721 emit_insn (gen_cmpgtsf_media (reg,
9722 sh_compare_op1, sh_compare_op0));
9726 if (! TARGET_SHMEDIA_FPU)
9728 emit_insn (gen_cmpgtdf_media (reg,
9729 sh_compare_op1, sh_compare_op0));
9736 if (GET_MODE (operands[0]) == DImode)
9737 emit_insn (gen_extendsidi2 (operands[0], reg));
9741 if (! currently_expanding_to_rtl)
9743 operands[1] = prepare_scc_operands (LT);
9746 (define_expand "sle"
9747 [(match_operand:SI 0 "arith_reg_operand" "")]
9751 rtx tmp = sh_compare_op0;
9757 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9758 if (sh_compare_op1 != const0_rtx)
9759 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9760 ? GET_MODE (sh_compare_op0)
9761 : GET_MODE (sh_compare_op1),
9765 if (GET_MODE (operands[0]) != SImode)
9766 reg = (!can_create_pseudo_p ()
9767 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9768 : gen_reg_rtx (SImode));
9770 switch (GET_MODE (sh_compare_op0))
9774 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9776 emit_insn (gen_cmpgtsi_media (tmp,
9777 sh_compare_op0, sh_compare_op1));
9778 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9784 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9786 emit_insn (gen_cmpgtdi_media (tmp,
9787 sh_compare_op0, sh_compare_op1));
9788 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9793 if (! TARGET_SHMEDIA_FPU)
9795 emit_insn (gen_cmpgesf_media (reg,
9796 sh_compare_op1, sh_compare_op0));
9800 if (! TARGET_SHMEDIA_FPU)
9802 emit_insn (gen_cmpgedf_media (reg,
9803 sh_compare_op1, sh_compare_op0));
9810 if (GET_MODE (operands[0]) == DImode)
9811 emit_insn (gen_extendsidi2 (operands[0], reg));
9816 sh_compare_op0 = sh_compare_op1;
9817 sh_compare_op1 = tmp;
9818 emit_insn (gen_sge (operands[0]));
9822 (define_expand "sgt"
9823 [(set (match_operand:SI 0 "arith_reg_operand" "")
9833 if (GET_MODE (operands[0]) != SImode)
9834 reg = (!can_create_pseudo_p () ?
9835 gen_rtx_SUBREG (SImode, operands[0], 0)
9836 : gen_reg_rtx (SImode));
9837 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9838 if (sh_compare_op1 != const0_rtx)
9839 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9840 ? GET_MODE (sh_compare_op0)
9841 : GET_MODE (sh_compare_op1),
9844 switch (GET_MODE (sh_compare_op0))
9847 emit_insn (gen_cmpgtsi_media (reg,
9848 sh_compare_op0, sh_compare_op1));
9852 emit_insn (gen_cmpgtdi_media (reg,
9853 sh_compare_op0, sh_compare_op1));
9857 if (! TARGET_SHMEDIA_FPU)
9859 emit_insn (gen_cmpgtsf_media (reg,
9860 sh_compare_op0, sh_compare_op1));
9864 if (! TARGET_SHMEDIA_FPU)
9866 emit_insn (gen_cmpgtdf_media (reg,
9867 sh_compare_op0, sh_compare_op1));
9874 if (GET_MODE (operands[0]) == DImode)
9875 emit_insn (gen_extendsidi2 (operands[0], reg));
9879 if (! currently_expanding_to_rtl)
9881 operands[1] = prepare_scc_operands (GT);
9884 (define_expand "sge"
9885 [(set (match_operand:SI 0 "arith_reg_operand" "")
9893 enum machine_mode mode = GET_MODE (sh_compare_op0);
9895 if ((mode) == VOIDmode)
9896 mode = GET_MODE (sh_compare_op1);
9898 if (GET_MODE (operands[0]) != SImode)
9899 reg = (!can_create_pseudo_p ()
9900 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9901 : gen_reg_rtx (SImode));
9902 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9903 if (sh_compare_op1 != const0_rtx)
9904 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9910 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9912 emit_insn (gen_cmpgtsi_media (tmp,
9913 sh_compare_op1, sh_compare_op0));
9914 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9920 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9922 emit_insn (gen_cmpgtdi_media (tmp,
9923 sh_compare_op1, sh_compare_op0));
9924 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9929 if (! TARGET_SHMEDIA_FPU)
9931 emit_insn (gen_cmpgesf_media (reg,
9932 sh_compare_op0, sh_compare_op1));
9936 if (! TARGET_SHMEDIA_FPU)
9938 emit_insn (gen_cmpgedf_media (reg,
9939 sh_compare_op0, sh_compare_op1));
9946 if (GET_MODE (operands[0]) == DImode)
9947 emit_insn (gen_extendsidi2 (operands[0], reg));
9952 if (! currently_expanding_to_rtl)
9954 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9958 rtx lab = gen_label_rtx ();
9959 prepare_scc_operands (EQ);
9960 emit_jump_insn (gen_branch_true (lab));
9961 prepare_scc_operands (GT);
9963 emit_insn (gen_movt (operands[0]));
9966 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9969 operands[1] = prepare_scc_operands (GE);
9972 (define_expand "sgtu"
9973 [(set (match_operand:SI 0 "arith_reg_operand" "")
9983 if (GET_MODE (operands[0]) == DImode)
9984 reg = (!can_create_pseudo_p ()
9985 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9986 : gen_reg_rtx (SImode));
9987 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9988 if (sh_compare_op1 != const0_rtx)
9989 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9990 ? GET_MODE (sh_compare_op0)
9991 : GET_MODE (sh_compare_op1),
9994 emit_insn (gen_cmpgtudi_media (reg,
9995 sh_compare_op0, sh_compare_op1));
9996 if (GET_MODE (operands[0]) == DImode)
9997 emit_insn (gen_extendsidi2 (operands[0], reg));
10001 if (! currently_expanding_to_rtl)
10003 operands[1] = prepare_scc_operands (GTU);
10006 (define_expand "sltu"
10007 [(set (match_operand:SI 0 "arith_reg_operand" "")
10012 if (TARGET_SHMEDIA)
10017 if (GET_MODE (operands[0]) == DImode)
10018 reg = (!can_create_pseudo_p ()
10019 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10020 : gen_reg_rtx (SImode));
10021 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10022 if (sh_compare_op1 != const0_rtx)
10023 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10024 ? GET_MODE (sh_compare_op0)
10025 : GET_MODE (sh_compare_op1),
10028 emit_insn (gen_cmpgtudi_media (reg,
10029 sh_compare_op1, sh_compare_op0));
10030 if (GET_MODE (operands[0]) == DImode)
10031 emit_insn (gen_extendsidi2 (operands[0], reg));
10035 if (! currently_expanding_to_rtl)
10037 operands[1] = prepare_scc_operands (LTU);
10040 (define_expand "sleu"
10041 [(set (match_operand:SI 0 "arith_reg_operand" "")
10046 if (TARGET_SHMEDIA)
10051 if (GET_MODE (operands[0]) != SImode)
10052 reg = (!can_create_pseudo_p ()
10053 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10054 : gen_reg_rtx (SImode));
10055 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10056 if (sh_compare_op1 != const0_rtx)
10057 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10058 ? GET_MODE (sh_compare_op0)
10059 : GET_MODE (sh_compare_op1),
10062 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10064 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
10065 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10066 if (GET_MODE (operands[0]) == DImode)
10067 emit_insn (gen_extendsidi2 (operands[0], reg));
10071 if (! currently_expanding_to_rtl)
10073 operands[1] = prepare_scc_operands (LEU);
10076 (define_expand "sgeu"
10077 [(set (match_operand:SI 0 "arith_reg_operand" "")
10082 if (TARGET_SHMEDIA)
10087 if (GET_MODE (operands[0]) != SImode)
10088 reg = (!can_create_pseudo_p ()
10089 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10090 : gen_reg_rtx (SImode));
10091 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10092 if (sh_compare_op1 != const0_rtx)
10093 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10094 ? GET_MODE (sh_compare_op0)
10095 : GET_MODE (sh_compare_op1),
10098 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
10100 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
10101 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10102 if (GET_MODE (operands[0]) == DImode)
10103 emit_insn (gen_extendsidi2 (operands[0], reg));
10108 if (! currently_expanding_to_rtl)
10110 operands[1] = prepare_scc_operands (GEU);
10113 ;; sne moves the complement of the T reg to DEST like this:
10117 ;; This is better than xoring compare result with 1 because it does
10118 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
10121 (define_expand "sne"
10122 [(set (match_dup 2) (const_int -1))
10123 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
10124 (neg:SI (plus:SI (match_dup 1)
10126 (set (reg:SI T_REG)
10127 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10132 if (TARGET_SHMEDIA)
10137 if (GET_MODE (operands[0]) != SImode)
10138 reg = (!can_create_pseudo_p ()
10139 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10140 : gen_reg_rtx (SImode));
10141 if (! TARGET_SHMEDIA_FPU
10142 && GET_MODE (sh_compare_op0) != DImode
10143 && GET_MODE (sh_compare_op0) != SImode)
10146 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10147 if (sh_compare_op1 != const0_rtx)
10148 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10149 ? GET_MODE (sh_compare_op0)
10150 : GET_MODE (sh_compare_op1),
10153 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10155 emit_insn (gen_seq (tmp));
10156 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10157 if (GET_MODE (operands[0]) == DImode)
10158 emit_insn (gen_extendsidi2 (operands[0], reg));
10163 if (sh_expand_t_scc (NE, operands[0]))
10165 if (! currently_expanding_to_rtl)
10167 operands[1] = prepare_scc_operands (EQ);
10168 operands[2] = gen_reg_rtx (SImode);
10171 (define_expand "sunordered"
10172 [(set (match_operand:SI 0 "arith_reg_operand" "")
10173 (unordered:SI (match_dup 1) (match_dup 2)))]
10174 "TARGET_SHMEDIA_FPU"
10177 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10178 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10181 ;; Use the same trick for FP sle / sge
10183 ;; Apart from the constant use and the T setting, this is like movt,
10184 ;; except that it uses the logically negated value of T, i.e.
10185 ;; operand[0] := T ? 0 : 1.
10186 (define_expand "movnegt"
10187 [(set (match_dup 2) (const_int -1))
10188 (parallel [(set (match_operand 0 "" "")
10189 (neg:SI (plus:SI (match_dup 1)
10191 (set (reg:SI T_REG)
10192 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10195 "operands[2] = gen_reg_rtx (SImode);")
10197 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10198 ;; This prevents a regression that occurred when we switched from xor to
10199 ;; mov/neg for sne.
10202 [(set (match_operand:SI 0 "arith_reg_dest" "")
10203 (plus:SI (reg:SI T_REG)
10206 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10207 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10210 ;; -------------------------------------------------------------------------
10211 ;; Instructions to cope with inline literal tables
10212 ;; -------------------------------------------------------------------------
10214 ; 2 byte integer in line
10216 (define_insn "consttable_2"
10217 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10218 (match_operand 1 "" "")]
10223 if (operands[1] != const0_rtx)
10224 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10227 [(set_attr "length" "2")
10228 (set_attr "in_delay_slot" "no")])
10230 ; 4 byte integer in line
10232 (define_insn "consttable_4"
10233 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10234 (match_operand 1 "" "")]
10239 if (operands[1] != const0_rtx)
10241 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10242 mark_symbol_refs_as_used (operands[0]);
10246 [(set_attr "length" "4")
10247 (set_attr "in_delay_slot" "no")])
10249 ; 8 byte integer in line
10251 (define_insn "consttable_8"
10252 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10253 (match_operand 1 "" "")]
10258 if (operands[1] != const0_rtx)
10259 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10262 [(set_attr "length" "8")
10263 (set_attr "in_delay_slot" "no")])
10265 ; 4 byte floating point
10267 (define_insn "consttable_sf"
10268 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10269 (match_operand 1 "" "")]
10274 if (operands[1] != const0_rtx)
10277 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10278 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10282 [(set_attr "length" "4")
10283 (set_attr "in_delay_slot" "no")])
10285 ; 8 byte floating point
10287 (define_insn "consttable_df"
10288 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10289 (match_operand 1 "" "")]
10294 if (operands[1] != const0_rtx)
10297 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10298 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10302 [(set_attr "length" "8")
10303 (set_attr "in_delay_slot" "no")])
10305 ;; Alignment is needed for some constant tables; it may also be added for
10306 ;; Instructions at the start of loops, or after unconditional branches.
10307 ;; ??? We would get more accurate lengths if we did instruction
10308 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10309 ;; here is too conservative.
10311 ; align to a two byte boundary
10313 (define_expand "align_2"
10314 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10318 ; align to a four byte boundary
10319 ;; align_4 and align_log are instructions for the starts of loops, or
10320 ;; after unconditional branches, which may take up extra room.
10322 (define_expand "align_4"
10323 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10327 ; align to a cache line boundary
10329 (define_insn "align_log"
10330 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10333 [(set_attr "length" "0")
10334 (set_attr "in_delay_slot" "no")])
10336 ; emitted at the end of the literal table, used to emit the
10337 ; 32bit branch labels if needed.
10339 (define_insn "consttable_end"
10340 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10342 "* return output_jump_label_table ();"
10343 [(set_attr "in_delay_slot" "no")])
10345 ; emitted at the end of the window in the literal table.
10347 (define_insn "consttable_window_end"
10348 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10351 [(set_attr "length" "0")
10352 (set_attr "in_delay_slot" "no")])
10354 ;; -------------------------------------------------------------------------
10356 ;; -------------------------------------------------------------------------
10358 ;; String/block move insn.
10360 (define_expand "movmemsi"
10361 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10362 (mem:BLK (match_operand:BLK 1 "" "")))
10363 (use (match_operand:SI 2 "nonmemory_operand" ""))
10364 (use (match_operand:SI 3 "immediate_operand" ""))
10365 (clobber (reg:SI PR_REG))
10366 (clobber (reg:SI R4_REG))
10367 (clobber (reg:SI R5_REG))
10368 (clobber (reg:SI R0_REG))])]
10369 "TARGET_SH1 && ! TARGET_SH5"
10372 if(expand_block_move (operands))
10377 (define_insn "block_move_real"
10378 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10379 (mem:BLK (reg:SI R5_REG)))
10380 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10381 (clobber (reg:SI PR_REG))
10382 (clobber (reg:SI R0_REG))])]
10383 "TARGET_SH1 && ! TARGET_HARD_SH4"
10385 [(set_attr "type" "sfunc")
10386 (set_attr "needs_delay_slot" "yes")])
10388 (define_insn "block_lump_real"
10389 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10390 (mem:BLK (reg:SI R5_REG)))
10391 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10392 (use (reg:SI R6_REG))
10393 (clobber (reg:SI PR_REG))
10394 (clobber (reg:SI T_REG))
10395 (clobber (reg:SI R4_REG))
10396 (clobber (reg:SI R5_REG))
10397 (clobber (reg:SI R6_REG))
10398 (clobber (reg:SI R0_REG))])]
10399 "TARGET_SH1 && ! TARGET_HARD_SH4"
10401 [(set_attr "type" "sfunc")
10402 (set_attr "needs_delay_slot" "yes")])
10404 (define_insn "block_move_real_i4"
10405 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10406 (mem:BLK (reg:SI R5_REG)))
10407 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10408 (clobber (reg:SI PR_REG))
10409 (clobber (reg:SI R0_REG))
10410 (clobber (reg:SI R1_REG))
10411 (clobber (reg:SI R2_REG))])]
10414 [(set_attr "type" "sfunc")
10415 (set_attr "needs_delay_slot" "yes")])
10417 (define_insn "block_lump_real_i4"
10418 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10419 (mem:BLK (reg:SI R5_REG)))
10420 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10421 (use (reg:SI R6_REG))
10422 (clobber (reg:SI PR_REG))
10423 (clobber (reg:SI T_REG))
10424 (clobber (reg:SI R4_REG))
10425 (clobber (reg:SI R5_REG))
10426 (clobber (reg:SI R6_REG))
10427 (clobber (reg:SI R0_REG))
10428 (clobber (reg:SI R1_REG))
10429 (clobber (reg:SI R2_REG))
10430 (clobber (reg:SI R3_REG))])]
10433 [(set_attr "type" "sfunc")
10434 (set_attr "needs_delay_slot" "yes")])
10436 ;; -------------------------------------------------------------------------
10437 ;; Floating point instructions.
10438 ;; -------------------------------------------------------------------------
10440 ;; ??? All patterns should have a type attribute.
10442 (define_expand "movpsi"
10443 [(set (match_operand:PSI 0 "register_operand" "")
10444 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10445 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10448 ;; The c / m alternative is a fake to guide reload to load directly into
10449 ;; fpscr, since reload doesn't know how to use post-increment.
10450 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10451 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10452 ;; predicate after reload.
10453 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10454 ;; like a mac -> gpr move.
10455 (define_insn "fpu_switch"
10456 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10457 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10459 && (! reload_completed
10460 || true_regnum (operands[0]) != FPSCR_REG
10461 || GET_CODE (operands[1]) != MEM
10462 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10464 ! precision stays the same
10473 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10474 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10477 [(set (reg:PSI FPSCR_REG)
10478 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10479 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10482 rtx fpscr, mem, new_insn;
10484 fpscr = SET_DEST (PATTERN (curr_insn));
10485 mem = SET_SRC (PATTERN (curr_insn));
10486 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10488 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10489 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10494 [(set (reg:PSI FPSCR_REG)
10495 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10496 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10497 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10500 rtx fpscr, mem, new_insn;
10502 fpscr = SET_DEST (PATTERN (curr_insn));
10503 mem = SET_SRC (PATTERN (curr_insn));
10504 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10506 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10507 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10509 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10510 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10514 ;; ??? This uses the fp unit, but has no type indicating that.
10515 ;; If we did that, this would either give a bogus latency or introduce
10516 ;; a bogus FIFO constraint.
10517 ;; Since this insn is currently only used for prologues/epilogues,
10518 ;; it is probably best to claim no function unit, which matches the
10519 ;; current setting.
10520 (define_insn "toggle_sz"
10521 [(set (reg:PSI FPSCR_REG)
10522 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10523 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10525 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10527 ;; There's no way we can use it today, since optimize mode switching
10528 ;; doesn't enable us to know from which mode we're switching to the
10529 ;; mode it requests, to tell whether we can use a relative mode switch
10530 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10532 (define_insn "toggle_pr"
10533 [(set (reg:PSI FPSCR_REG)
10534 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10535 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10537 [(set_attr "type" "fpscr_toggle")])
10539 (define_expand "addsf3"
10540 [(set (match_operand:SF 0 "arith_reg_operand" "")
10541 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10542 (match_operand:SF 2 "arith_reg_operand" "")))]
10543 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10548 expand_sf_binop (&gen_addsf3_i, operands);
10553 (define_insn "*addsf3_media"
10554 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10555 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10556 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10557 "TARGET_SHMEDIA_FPU"
10558 "fadd.s %1, %2, %0"
10559 [(set_attr "type" "fparith_media")])
10561 (define_insn_and_split "unary_sf_op"
10562 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10567 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10568 (match_operator:SF 2 "unary_float_operator"
10569 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10570 (parallel [(match_operand 4
10571 "const_int_operand" "n")]))]))
10572 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10573 "TARGET_SHMEDIA_FPU"
10575 "TARGET_SHMEDIA_FPU && reload_completed"
10576 [(set (match_dup 5) (match_dup 6))]
10579 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10580 rtx op1 = gen_rtx_REG (SFmode,
10581 (true_regnum (operands[1])
10582 + (INTVAL (operands[4]) ^ endian)));
10584 operands[7] = gen_rtx_REG (SFmode,
10585 (true_regnum (operands[0])
10586 + (INTVAL (operands[3]) ^ endian)));
10587 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10589 [(set_attr "type" "fparith_media")])
10591 (define_insn_and_split "binary_sf_op0"
10592 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10594 (match_operator:SF 3 "binary_float_operator"
10595 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10596 (parallel [(const_int 0)]))
10597 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10598 (parallel [(const_int 0)]))])
10601 (parallel [(const_int 1)]))))]
10602 "TARGET_SHMEDIA_FPU"
10604 "&& reload_completed"
10605 [(set (match_dup 4) (match_dup 5))]
10608 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10609 rtx op1 = gen_rtx_REG (SFmode,
10610 true_regnum (operands[1]) + endian);
10611 rtx op2 = gen_rtx_REG (SFmode,
10612 true_regnum (operands[2]) + endian);
10614 operands[4] = gen_rtx_REG (SFmode,
10615 true_regnum (operands[0]) + endian);
10616 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10618 [(set_attr "type" "fparith_media")])
10620 (define_insn_and_split "binary_sf_op1"
10621 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10625 (parallel [(const_int 0)]))
10626 (match_operator:SF 3 "binary_float_operator"
10627 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10628 (parallel [(const_int 1)]))
10629 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10630 (parallel [(const_int 1)]))])))]
10631 "TARGET_SHMEDIA_FPU"
10633 "&& reload_completed"
10634 [(set (match_dup 4) (match_dup 5))]
10637 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10638 rtx op1 = gen_rtx_REG (SFmode,
10639 true_regnum (operands[1]) + (1 ^ endian));
10640 rtx op2 = gen_rtx_REG (SFmode,
10641 true_regnum (operands[2]) + (1 ^ endian));
10643 operands[4] = gen_rtx_REG (SFmode,
10644 true_regnum (operands[0]) + (1 ^ endian));
10645 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10647 [(set_attr "type" "fparith_media")])
10649 (define_insn "addsf3_i"
10650 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10651 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10652 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10653 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10656 [(set_attr "type" "fp")
10657 (set_attr "fp_mode" "single")])
10659 (define_expand "subsf3"
10660 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10661 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10662 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10663 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10668 expand_sf_binop (&gen_subsf3_i, operands);
10673 (define_insn "*subsf3_media"
10674 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10676 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10677 "TARGET_SHMEDIA_FPU"
10678 "fsub.s %1, %2, %0"
10679 [(set_attr "type" "fparith_media")])
10681 (define_insn "subsf3_i"
10682 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10683 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10684 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10685 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10688 [(set_attr "type" "fp")
10689 (set_attr "fp_mode" "single")])
10691 (define_expand "mulsf3"
10692 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10693 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10694 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10695 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10698 (define_insn "*mulsf3_media"
10699 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10700 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10701 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10702 "TARGET_SHMEDIA_FPU"
10703 "fmul.s %1, %2, %0"
10704 [(set_attr "type" "fparith_media")])
10706 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10707 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10708 ;; we start out with a mulsf pattern that does not depend on fpscr.
10709 ;; This is split after combine to introduce the dependency, in order to
10710 ;; get mode switching and scheduling right.
10711 (define_insn_and_split "mulsf3_ie"
10712 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10713 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10714 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10717 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10721 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10722 get_fpscr_rtx ()));
10725 [(set_attr "type" "fp")])
10727 (define_insn "mulsf3_i4"
10728 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10729 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10730 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10731 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10734 [(set_attr "type" "fp")
10735 (set_attr "fp_mode" "single")])
10737 (define_insn "mac_media"
10738 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10739 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10740 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10741 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10742 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10743 "fmac.s %1, %2, %0"
10744 [(set_attr "type" "fparith_media")])
10746 (define_insn "*macsf3"
10747 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10748 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10749 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10750 (match_operand:SF 3 "arith_reg_operand" "0")))
10751 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10752 "TARGET_SH2E && TARGET_FMAC"
10754 [(set_attr "type" "fp")
10755 (set_attr "fp_mode" "single")])
10757 (define_expand "divsf3"
10758 [(set (match_operand:SF 0 "arith_reg_operand" "")
10759 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10760 (match_operand:SF 2 "arith_reg_operand" "")))]
10761 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10766 expand_sf_binop (&gen_divsf3_i, operands);
10771 (define_insn "*divsf3_media"
10772 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10773 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10774 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10775 "TARGET_SHMEDIA_FPU"
10776 "fdiv.s %1, %2, %0"
10777 [(set_attr "type" "fdiv_media")])
10779 (define_insn "divsf3_i"
10780 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10781 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10782 (match_operand:SF 2 "arith_reg_operand" "f")))
10783 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10786 [(set_attr "type" "fdiv")
10787 (set_attr "fp_mode" "single")])
10789 (define_insn "floatdisf2"
10790 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10791 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10792 "TARGET_SHMEDIA_FPU"
10794 [(set_attr "type" "fpconv_media")])
10796 (define_expand "floatsisf2"
10797 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10798 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10799 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10802 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10804 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10809 (define_insn "*floatsisf2_media"
10810 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10811 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10812 "TARGET_SHMEDIA_FPU"
10814 [(set_attr "type" "fpconv_media")])
10816 (define_insn "floatsisf2_i4"
10817 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10818 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10819 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10820 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10822 [(set_attr "type" "fp")
10823 (set_attr "fp_mode" "single")])
10825 (define_insn "*floatsisf2_ie"
10826 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10827 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10828 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10830 [(set_attr "type" "fp")])
10832 (define_insn "fix_truncsfdi2"
10833 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10834 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10835 "TARGET_SHMEDIA_FPU"
10837 [(set_attr "type" "fpconv_media")])
10839 (define_expand "fix_truncsfsi2"
10840 [(set (match_operand:SI 0 "fpul_operand" "=y")
10841 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10842 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10845 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10847 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10852 (define_insn "*fix_truncsfsi2_media"
10853 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10854 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10855 "TARGET_SHMEDIA_FPU"
10857 [(set_attr "type" "fpconv_media")])
10859 (define_insn "fix_truncsfsi2_i4"
10860 [(set (match_operand:SI 0 "fpul_operand" "=y")
10861 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10862 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10863 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10865 [(set_attr "type" "ftrc_s")
10866 (set_attr "fp_mode" "single")])
10868 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10869 ;; fix_truncsfsi2_i4.
10870 ;; (define_insn "fix_truncsfsi2_i4_2"
10871 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10872 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10873 ;; (use (reg:PSI FPSCR_REG))
10874 ;; (clobber (reg:SI FPUL_REG))]
10877 ;; [(set_attr "length" "4")
10878 ;; (set_attr "fp_mode" "single")])
10881 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10882 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10883 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10884 ;; (clobber (reg:SI FPUL_REG))]
10886 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10887 ;; (use (match_dup 2))])
10888 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10890 (define_insn "*fixsfsi"
10891 [(set (match_operand:SI 0 "fpul_operand" "=y")
10892 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10893 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10895 [(set_attr "type" "fp")])
10897 (define_insn "cmpgtsf_t"
10898 [(set (reg:SI T_REG)
10899 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10900 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10901 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10903 [(set_attr "type" "fp_cmp")
10904 (set_attr "fp_mode" "single")])
10906 (define_insn "cmpeqsf_t"
10907 [(set (reg:SI T_REG)
10908 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10909 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10910 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10912 [(set_attr "type" "fp_cmp")
10913 (set_attr "fp_mode" "single")])
10915 (define_insn "ieee_ccmpeqsf_t"
10916 [(set (reg:SI T_REG)
10917 (ior:SI (reg:SI T_REG)
10918 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10919 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10920 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10921 "* return output_ieee_ccmpeq (insn, operands);"
10922 [(set_attr "length" "4")])
10925 (define_insn "cmpgtsf_t_i4"
10926 [(set (reg:SI T_REG)
10927 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10928 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10929 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10930 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10932 [(set_attr "type" "fp_cmp")
10933 (set_attr "fp_mode" "single")])
10935 (define_insn "cmpeqsf_t_i4"
10936 [(set (reg:SI T_REG)
10937 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10938 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10939 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10940 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10942 [(set_attr "type" "fp_cmp")
10943 (set_attr "fp_mode" "single")])
10945 (define_insn "*ieee_ccmpeqsf_t_4"
10946 [(set (reg:SI T_REG)
10947 (ior:SI (reg:SI T_REG)
10948 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10949 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10950 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10951 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10952 "* return output_ieee_ccmpeq (insn, operands);"
10953 [(set_attr "length" "4")
10954 (set_attr "fp_mode" "single")])
10956 (define_insn "cmpeqsf_media"
10957 [(set (match_operand:SI 0 "register_operand" "=r")
10958 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10959 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10960 "TARGET_SHMEDIA_FPU"
10961 "fcmpeq.s %1, %2, %0"
10962 [(set_attr "type" "fcmp_media")])
10964 (define_insn "cmpgtsf_media"
10965 [(set (match_operand:SI 0 "register_operand" "=r")
10966 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10967 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10968 "TARGET_SHMEDIA_FPU"
10969 "fcmpgt.s %1, %2, %0"
10970 [(set_attr "type" "fcmp_media")])
10972 (define_insn "cmpgesf_media"
10973 [(set (match_operand:SI 0 "register_operand" "=r")
10974 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10975 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10976 "TARGET_SHMEDIA_FPU"
10977 "fcmpge.s %1, %2, %0"
10978 [(set_attr "type" "fcmp_media")])
10980 (define_insn "cmpunsf_media"
10981 [(set (match_operand:SI 0 "register_operand" "=r")
10982 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10983 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10984 "TARGET_SHMEDIA_FPU"
10985 "fcmpun.s %1, %2, %0"
10986 [(set_attr "type" "fcmp_media")])
10988 (define_expand "cmpsf"
10989 [(set (reg:SI T_REG)
10990 (compare (match_operand:SF 0 "arith_operand" "")
10991 (match_operand:SF 1 "arith_operand" "")))]
10992 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10995 sh_compare_op0 = operands[0];
10996 sh_compare_op1 = operands[1];
11000 (define_expand "negsf2"
11001 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11002 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11003 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11008 expand_sf_unop (&gen_negsf2_i, operands);
11013 (define_insn "*negsf2_media"
11014 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11015 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11016 "TARGET_SHMEDIA_FPU"
11018 [(set_attr "type" "fmove_media")])
11020 (define_insn "negsf2_i"
11021 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11022 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11023 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11026 [(set_attr "type" "fmove")
11027 (set_attr "fp_mode" "single")])
11029 (define_expand "sqrtsf2"
11030 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11031 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11032 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
11037 expand_sf_unop (&gen_sqrtsf2_i, operands);
11042 (define_insn "*sqrtsf2_media"
11043 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11044 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11045 "TARGET_SHMEDIA_FPU"
11047 [(set_attr "type" "fdiv_media")])
11049 (define_insn "sqrtsf2_i"
11050 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11051 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11052 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11055 [(set_attr "type" "fdiv")
11056 (set_attr "fp_mode" "single")])
11058 (define_insn "rsqrtsf2"
11059 [(set (match_operand:SF 0 "register_operand" "=f")
11060 (div:SF (match_operand:SF 1 "immediate_operand" "i")
11061 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
11062 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11063 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11064 && operands[1] == CONST1_RTX (SFmode)"
11066 [(set_attr "type" "fsrra")
11067 (set_attr "fp_mode" "single")])
11069 (define_insn "fsca"
11070 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11072 (unspec:SF [(mult:SF
11073 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
11074 (match_operand:SF 2 "immediate_operand" "i"))
11076 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
11078 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11079 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11080 && operands[2] == sh_fsca_int2sf ()"
11082 [(set_attr "type" "fsca")
11083 (set_attr "fp_mode" "single")])
11085 (define_expand "sinsf2"
11086 [(set (match_operand:SF 0 "nonimmediate_operand" "")
11087 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11089 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11092 rtx scaled = gen_reg_rtx (SFmode);
11093 rtx truncated = gen_reg_rtx (SImode);
11094 rtx fsca = gen_reg_rtx (V2SFmode);
11095 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11097 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11098 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11099 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11100 get_fpscr_rtx ()));
11101 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
11105 (define_expand "cossf2"
11106 [(set (match_operand:SF 0 "nonimmediate_operand" "")
11107 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11109 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11112 rtx scaled = gen_reg_rtx (SFmode);
11113 rtx truncated = gen_reg_rtx (SImode);
11114 rtx fsca = gen_reg_rtx (V2SFmode);
11115 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11117 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11118 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11119 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11120 get_fpscr_rtx ()));
11121 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
11125 (define_expand "sindf2"
11126 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11127 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11129 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11132 rtx scaled = gen_reg_rtx (DFmode);
11133 rtx truncated = gen_reg_rtx (SImode);
11134 rtx fsca = gen_reg_rtx (V2SFmode);
11135 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11136 rtx sfresult = gen_reg_rtx (SFmode);
11138 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11139 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11140 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11141 get_fpscr_rtx ()));
11142 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11143 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11147 (define_expand "cosdf2"
11148 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11149 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11151 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11154 rtx scaled = gen_reg_rtx (DFmode);
11155 rtx truncated = gen_reg_rtx (SImode);
11156 rtx fsca = gen_reg_rtx (V2SFmode);
11157 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11158 rtx sfresult = gen_reg_rtx (SFmode);
11160 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11161 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11162 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11163 get_fpscr_rtx ()));
11164 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11165 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11169 (define_expand "abssf2"
11170 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11171 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11172 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11177 expand_sf_unop (&gen_abssf2_i, operands);
11182 (define_insn "*abssf2_media"
11183 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11184 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11185 "TARGET_SHMEDIA_FPU"
11187 [(set_attr "type" "fmove_media")])
11189 (define_insn "abssf2_i"
11190 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11191 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11192 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11195 [(set_attr "type" "fmove")
11196 (set_attr "fp_mode" "single")])
11198 (define_expand "adddf3"
11199 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11200 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11201 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11202 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11205 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11207 expand_df_binop (&gen_adddf3_i, operands);
11212 (define_insn "*adddf3_media"
11213 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11214 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11215 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11216 "TARGET_SHMEDIA_FPU"
11217 "fadd.d %1, %2, %0"
11218 [(set_attr "type" "dfparith_media")])
11220 (define_insn "adddf3_i"
11221 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11222 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11223 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11224 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11225 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11227 [(set_attr "type" "dfp_arith")
11228 (set_attr "fp_mode" "double")])
11230 (define_expand "subdf3"
11231 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11232 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11233 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11234 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11237 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11239 expand_df_binop (&gen_subdf3_i, operands);
11244 (define_insn "*subdf3_media"
11245 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11246 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11247 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11248 "TARGET_SHMEDIA_FPU"
11249 "fsub.d %1, %2, %0"
11250 [(set_attr "type" "dfparith_media")])
11252 (define_insn "subdf3_i"
11253 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11254 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11255 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11256 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11257 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11259 [(set_attr "type" "dfp_arith")
11260 (set_attr "fp_mode" "double")])
11262 (define_expand "muldf3"
11263 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11264 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11265 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11266 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11269 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11271 expand_df_binop (&gen_muldf3_i, operands);
11276 (define_insn "*muldf3_media"
11277 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11278 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11279 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11280 "TARGET_SHMEDIA_FPU"
11281 "fmul.d %1, %2, %0"
11282 [(set_attr "type" "dfmul_media")])
11284 (define_insn "muldf3_i"
11285 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11286 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11287 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11288 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11289 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11291 [(set_attr "type" "dfp_mul")
11292 (set_attr "fp_mode" "double")])
11294 (define_expand "divdf3"
11295 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11296 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11297 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11298 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11301 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11303 expand_df_binop (&gen_divdf3_i, operands);
11308 (define_insn "*divdf3_media"
11309 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11310 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11311 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11312 "TARGET_SHMEDIA_FPU"
11313 "fdiv.d %1, %2, %0"
11314 [(set_attr "type" "dfdiv_media")])
11316 (define_insn "divdf3_i"
11317 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11318 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11319 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11320 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11321 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11323 [(set_attr "type" "dfdiv")
11324 (set_attr "fp_mode" "double")])
11326 (define_insn "floatdidf2"
11327 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11328 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11329 "TARGET_SHMEDIA_FPU"
11331 [(set_attr "type" "dfpconv_media")])
11333 (define_expand "floatsidf2"
11334 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11335 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11336 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11339 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11341 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11342 get_fpscr_rtx ()));
11347 (define_insn "*floatsidf2_media"
11348 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11349 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11350 "TARGET_SHMEDIA_FPU"
11352 [(set_attr "type" "dfpconv_media")])
11354 (define_insn "floatsidf2_i"
11355 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11356 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11357 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11360 [(set_attr "type" "dfp_conv")
11361 (set_attr "fp_mode" "double")])
11363 (define_insn "fix_truncdfdi2"
11364 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11365 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11366 "TARGET_SHMEDIA_FPU"
11368 [(set_attr "type" "dfpconv_media")])
11370 (define_expand "fix_truncdfsi2"
11371 [(set (match_operand:SI 0 "fpul_operand" "")
11372 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11373 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11376 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11378 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11379 get_fpscr_rtx ()));
11384 (define_insn "*fix_truncdfsi2_media"
11385 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11386 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11387 "TARGET_SHMEDIA_FPU"
11389 [(set_attr "type" "dfpconv_media")])
11391 (define_insn "fix_truncdfsi2_i"
11392 [(set (match_operand:SI 0 "fpul_operand" "=y")
11393 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11394 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11395 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11397 [(set_attr "type" "dfp_conv")
11398 (set_attr "dfp_comp" "no")
11399 (set_attr "fp_mode" "double")])
11401 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11402 ;; fix_truncdfsi2_i.
11403 ;; (define_insn "fix_truncdfsi2_i4"
11404 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11405 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11406 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11407 ;; (clobber (reg:SI FPUL_REG))]
11410 ;; [(set_attr "length" "4")
11411 ;; (set_attr "fp_mode" "double")])
11414 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11415 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11416 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11417 ;; (clobber (reg:SI FPUL_REG))]
11419 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11420 ;; (use (match_dup 2))])
11421 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11423 (define_insn "cmpgtdf_t"
11424 [(set (reg:SI T_REG)
11425 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11426 (match_operand:DF 1 "arith_reg_operand" "f")))
11427 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11428 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11430 [(set_attr "type" "dfp_cmp")
11431 (set_attr "fp_mode" "double")])
11433 (define_insn "cmpeqdf_t"
11434 [(set (reg:SI T_REG)
11435 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11436 (match_operand:DF 1 "arith_reg_operand" "f")))
11437 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11438 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11440 [(set_attr "type" "dfp_cmp")
11441 (set_attr "fp_mode" "double")])
11443 (define_insn "*ieee_ccmpeqdf_t"
11444 [(set (reg:SI T_REG)
11445 (ior:SI (reg:SI T_REG)
11446 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11447 (match_operand:DF 1 "arith_reg_operand" "f"))))
11448 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11449 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11450 "* return output_ieee_ccmpeq (insn, operands);"
11451 [(set_attr "length" "4")
11452 (set_attr "fp_mode" "double")])
11454 (define_insn "cmpeqdf_media"
11455 [(set (match_operand:SI 0 "register_operand" "=r")
11456 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11457 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11458 "TARGET_SHMEDIA_FPU"
11459 "fcmpeq.d %1,%2,%0"
11460 [(set_attr "type" "fcmp_media")])
11462 (define_insn "cmpgtdf_media"
11463 [(set (match_operand:SI 0 "register_operand" "=r")
11464 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11465 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11466 "TARGET_SHMEDIA_FPU"
11467 "fcmpgt.d %1,%2,%0"
11468 [(set_attr "type" "fcmp_media")])
11470 (define_insn "cmpgedf_media"
11471 [(set (match_operand:SI 0 "register_operand" "=r")
11472 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11473 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11474 "TARGET_SHMEDIA_FPU"
11475 "fcmpge.d %1,%2,%0"
11476 [(set_attr "type" "fcmp_media")])
11478 (define_insn "cmpundf_media"
11479 [(set (match_operand:SI 0 "register_operand" "=r")
11480 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11481 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11482 "TARGET_SHMEDIA_FPU"
11483 "fcmpun.d %1,%2,%0"
11484 [(set_attr "type" "fcmp_media")])
11486 (define_expand "cmpdf"
11487 [(set (reg:SI T_REG)
11488 (compare (match_operand:DF 0 "arith_operand" "")
11489 (match_operand:DF 1 "arith_operand" "")))]
11490 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11493 sh_compare_op0 = operands[0];
11494 sh_compare_op1 = operands[1];
11498 (define_expand "negdf2"
11499 [(set (match_operand:DF 0 "arith_reg_operand" "")
11500 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11501 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11504 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11506 expand_df_unop (&gen_negdf2_i, operands);
11511 (define_insn "*negdf2_media"
11512 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11513 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11514 "TARGET_SHMEDIA_FPU"
11516 [(set_attr "type" "fmove_media")])
11518 (define_insn "negdf2_i"
11519 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11520 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11521 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11522 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11524 [(set_attr "type" "fmove")
11525 (set_attr "fp_mode" "double")])
11527 (define_expand "sqrtdf2"
11528 [(set (match_operand:DF 0 "arith_reg_operand" "")
11529 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11530 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11533 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11535 expand_df_unop (&gen_sqrtdf2_i, operands);
11540 (define_insn "*sqrtdf2_media"
11541 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11542 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11543 "TARGET_SHMEDIA_FPU"
11545 [(set_attr "type" "dfdiv_media")])
11547 (define_insn "sqrtdf2_i"
11548 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11549 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11550 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11551 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11553 [(set_attr "type" "dfdiv")
11554 (set_attr "fp_mode" "double")])
11556 (define_expand "absdf2"
11557 [(set (match_operand:DF 0 "arith_reg_operand" "")
11558 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11559 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11562 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11564 expand_df_unop (&gen_absdf2_i, operands);
11569 (define_insn "*absdf2_media"
11570 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11571 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11572 "TARGET_SHMEDIA_FPU"
11574 [(set_attr "type" "fmove_media")])
11576 (define_insn "absdf2_i"
11577 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11578 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11579 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11580 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11582 [(set_attr "type" "fmove")
11583 (set_attr "fp_mode" "double")])
11585 (define_expand "extendsfdf2"
11586 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11587 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11588 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11591 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11593 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11594 get_fpscr_rtx ()));
11599 (define_insn "*extendsfdf2_media"
11600 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11601 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11602 "TARGET_SHMEDIA_FPU"
11604 [(set_attr "type" "dfpconv_media")])
11606 (define_insn "extendsfdf2_i4"
11607 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11608 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11609 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11610 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11612 [(set_attr "type" "fp")
11613 (set_attr "fp_mode" "double")])
11615 (define_expand "truncdfsf2"
11616 [(set (match_operand:SF 0 "fpul_operand" "")
11617 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11618 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11621 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11623 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11624 get_fpscr_rtx ()));
11629 (define_insn "*truncdfsf2_media"
11630 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11631 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11632 "TARGET_SHMEDIA_FPU"
11634 [(set_attr "type" "dfpconv_media")])
11636 (define_insn "truncdfsf2_i4"
11637 [(set (match_operand:SF 0 "fpul_operand" "=y")
11638 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11639 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11640 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11642 [(set_attr "type" "fp")
11643 (set_attr "fp_mode" "double")])
11645 ;; Bit field extract patterns. These give better code for packed bitfields,
11646 ;; because they allow auto-increment addresses to be generated.
11648 (define_expand "insv"
11649 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11650 (match_operand:SI 1 "immediate_operand" "")
11651 (match_operand:SI 2 "immediate_operand" ""))
11652 (match_operand:SI 3 "general_operand" ""))]
11653 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11656 rtx addr_target, orig_address, shift_reg, qi_val;
11657 HOST_WIDE_INT bitsize, size, v = 0;
11658 rtx x = operands[3];
11660 if (TARGET_SH2A && TARGET_BITOPS
11661 && (satisfies_constraint_Sbw (operands[0])
11662 || satisfies_constraint_Sbv (operands[0]))
11663 && satisfies_constraint_M (operands[1])
11664 && satisfies_constraint_K03 (operands[2]))
11666 if (satisfies_constraint_N (operands[3]))
11668 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11671 else if (satisfies_constraint_M (operands[3]))
11673 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11676 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11677 && satisfies_constraint_M (operands[1]))
11679 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11682 else if (REG_P (operands[3])
11683 && satisfies_constraint_M (operands[1]))
11685 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11686 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11690 /* ??? expmed doesn't care for non-register predicates. */
11691 if (! memory_operand (operands[0], VOIDmode)
11692 || ! immediate_operand (operands[1], VOIDmode)
11693 || ! immediate_operand (operands[2], VOIDmode)
11694 || ! general_operand (x, VOIDmode))
11696 /* If this isn't a 16 / 24 / 32 bit field, or if
11697 it doesn't start on a byte boundary, then fail. */
11698 bitsize = INTVAL (operands[1]);
11699 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11700 || (INTVAL (operands[2]) % 8) != 0)
11703 size = bitsize / 8;
11704 orig_address = XEXP (operands[0], 0);
11705 shift_reg = gen_reg_rtx (SImode);
11706 if (GET_CODE (x) == CONST_INT)
11709 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11713 emit_insn (gen_movsi (shift_reg, operands[3]));
11714 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11716 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11718 operands[0] = replace_equiv_address (operands[0], addr_target);
11719 emit_insn (gen_movqi (operands[0], qi_val));
11723 if (GET_CODE (x) == CONST_INT)
11725 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11728 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11729 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11731 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11732 emit_insn (gen_movqi (operands[0], qi_val));
11738 (define_insn "movua"
11739 [(set (match_operand:SI 0 "register_operand" "=z")
11740 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11744 [(set_attr "type" "movua")])
11746 ;; We shouldn't need this, but cse replaces increments with references
11747 ;; to other regs before flow has a chance to create post_inc
11748 ;; addressing modes, and only postreload's cse_move2add brings the
11749 ;; increments back to a usable form.
11751 [(set (match_operand:SI 0 "register_operand" "")
11752 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11753 (const_int 32) (const_int 0)))
11754 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11755 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11756 [(set (match_operand:SI 0 "register_operand" "")
11757 (sign_extract:SI (mem:SI (post_inc:SI
11758 (match_operand:SI 1 "register_operand" "")))
11759 (const_int 32) (const_int 0)))]
11762 (define_expand "extv"
11763 [(set (match_operand:SI 0 "register_operand" "")
11764 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11765 (match_operand 2 "const_int_operand" "")
11766 (match_operand 3 "const_int_operand" "")))]
11767 "TARGET_SH4A_ARCH || TARGET_SH2A"
11769 if (TARGET_SH2A && TARGET_BITOPS
11770 && (satisfies_constraint_Sbw (operands[1])
11771 || satisfies_constraint_Sbv (operands[1]))
11772 && satisfies_constraint_M (operands[2])
11773 && satisfies_constraint_K03 (operands[3]))
11775 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11776 if (REGNO (operands[0]) != T_REG)
11777 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11780 if (TARGET_SH4A_ARCH
11781 && INTVAL (operands[2]) == 32
11782 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11783 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11785 rtx src = adjust_address (operands[1], BLKmode, 0);
11786 set_mem_size (src, GEN_INT (4));
11787 emit_insn (gen_movua (operands[0], src));
11794 (define_expand "extzv"
11795 [(set (match_operand:SI 0 "register_operand" "")
11796 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11797 (match_operand 2 "const_int_operand" "")
11798 (match_operand 3 "const_int_operand" "")))]
11799 "TARGET_SH4A_ARCH || TARGET_SH2A"
11801 if (TARGET_SH2A && TARGET_BITOPS
11802 && (satisfies_constraint_Sbw (operands[1])
11803 || satisfies_constraint_Sbv (operands[1]))
11804 && satisfies_constraint_M (operands[2])
11805 && satisfies_constraint_K03 (operands[3]))
11807 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11808 if (REGNO (operands[0]) != T_REG)
11809 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11812 if (TARGET_SH4A_ARCH
11813 && INTVAL (operands[2]) == 32
11814 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11815 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11817 rtx src = adjust_address (operands[1], BLKmode, 0);
11818 set_mem_size (src, GEN_INT (4));
11819 emit_insn (gen_movua (operands[0], src));
11826 ;; SH2A instructions for bitwise operations.
11828 ;; Clear a bit in a memory location.
11829 (define_insn "bclr_m2a"
11830 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11832 (not:QI (ashift:QI (const_int 1)
11833 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11835 "TARGET_SH2A && TARGET_BITOPS"
11838 bclr.b\\t%1,@(0,%t0)"
11839 [(set_attr "length" "4,4")])
11841 (define_insn "bclrmem_m2a"
11842 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11843 (and:QI (match_dup 0)
11844 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11845 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11848 bclr.b\\t%W1,@(0,%t0)"
11849 [(set_attr "length" "4,4")])
11851 ;; Set a bit in a memory location.
11852 (define_insn "bset_m2a"
11853 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11855 (ashift:QI (const_int 1)
11856 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11858 "TARGET_SH2A && TARGET_BITOPS"
11861 bset.b\\t%1,@(0,%t0)"
11862 [(set_attr "length" "4,4")])
11864 (define_insn "bsetmem_m2a"
11865 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11866 (ior:QI (match_dup 0)
11867 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11868 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11871 bset.b\\t%V1,@(0,%t0)"
11872 [(set_attr "length" "4,4")])
11874 ;;; Transfer the contents of the T bit to a specified bit of memory.
11875 (define_insn "bst_m2a"
11876 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11877 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11879 (not:QI (ashift:QI (const_int 1)
11880 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11883 (ashift:QI (const_int 1) (match_dup 1))
11885 "TARGET_SH2A && TARGET_BITOPS"
11888 bst.b\\t%1,@(0,%t0)"
11889 [(set_attr "length" "4")])
11891 ;; Store a specified bit of memory in the T bit.
11892 (define_insn "bld_m2a"
11893 [(set (reg:SI T_REG)
11895 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11897 (match_operand 1 "const_int_operand" "K03,K03")))]
11898 "TARGET_SH2A && TARGET_BITOPS"
11901 bld.b\\t%1,@(0,%t0)"
11902 [(set_attr "length" "4,4")])
11904 ;; Store a specified bit of memory in the T bit.
11905 (define_insn "bldsign_m2a"
11906 [(set (reg:SI T_REG)
11908 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11910 (match_operand 1 "const_int_operand" "K03,K03")))]
11911 "TARGET_SH2A && TARGET_BITOPS"
11914 bld.b\\t%1,@(0,%t0)"
11915 [(set_attr "length" "4,4")])
11917 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11918 (define_insn "bld_reg"
11919 [(set (reg:SI T_REG)
11920 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11922 (match_operand 1 "const_int_operand" "K03")))]
11926 (define_insn "*bld_regqi"
11927 [(set (reg:SI T_REG)
11928 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11930 (match_operand 1 "const_int_operand" "K03")))]
11934 ;; Take logical and of a specified bit of memory with the T bit and
11935 ;; store its result in the T bit.
11936 (define_insn "band_m2a"
11937 [(set (reg:SI T_REG)
11938 (and:SI (reg:SI T_REG)
11940 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11942 (match_operand 1 "const_int_operand" "K03,K03"))))]
11943 "TARGET_SH2A && TARGET_BITOPS"
11946 band.b\\t%1,@(0,%t0)"
11947 [(set_attr "length" "4,4")])
11949 (define_insn "bandreg_m2a"
11950 [(set (match_operand:SI 0 "register_operand" "=r,r")
11951 (and:SI (zero_extract:SI
11952 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11954 (match_operand 2 "const_int_operand" "K03,K03"))
11955 (match_operand:SI 3 "register_operand" "r,r")))]
11956 "TARGET_SH2A && TARGET_BITOPS"
11958 band.b\\t%2,%1\;movt\\t%0
11959 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11960 [(set_attr "length" "6,6")])
11962 ;; Take logical or of a specified bit of memory with the T bit and
11963 ;; store its result in the T bit.
11964 (define_insn "bor_m2a"
11965 [(set (reg:SI T_REG)
11966 (ior:SI (reg:SI T_REG)
11968 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11970 (match_operand 1 "const_int_operand" "K03,K03"))))]
11971 "TARGET_SH2A && TARGET_BITOPS"
11974 bor.b\\t%1,@(0,%t0)"
11975 [(set_attr "length" "4,4")])
11977 (define_insn "borreg_m2a"
11978 [(set (match_operand:SI 0 "register_operand" "=r,r")
11979 (ior:SI (zero_extract:SI
11980 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11982 (match_operand 2 "const_int_operand" "K03,K03"))
11983 (match_operand:SI 3 "register_operand" "=r,r")))]
11984 "TARGET_SH2A && TARGET_BITOPS"
11986 bor.b\\t%2,%1\;movt\\t%0
11987 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11988 [(set_attr "length" "6,6")])
11990 ;; Take exclusive or of a specified bit of memory with the T bit and
11991 ;; store its result in the T bit.
11992 (define_insn "bxor_m2a"
11993 [(set (reg:SI T_REG)
11994 (xor:SI (reg:SI T_REG)
11996 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11998 (match_operand 1 "const_int_operand" "K03,K03"))))]
11999 "TARGET_SH2A && TARGET_BITOPS"
12002 bxor.b\\t%1,@(0,%t0)"
12003 [(set_attr "length" "4,4")])
12005 (define_insn "bxorreg_m2a"
12006 [(set (match_operand:SI 0 "register_operand" "=r,r")
12007 (xor:SI (zero_extract:SI
12008 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12010 (match_operand 2 "const_int_operand" "K03,K03"))
12011 (match_operand:SI 3 "register_operand" "=r,r")))]
12012 "TARGET_SH2A && TARGET_BITOPS"
12014 bxor.b\\t%2,%1\;movt\\t%0
12015 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
12016 [(set_attr "length" "6,6")])
12019 ;; -------------------------------------------------------------------------
12021 ;; -------------------------------------------------------------------------
12022 ;; This matches cases where the bit in a memory location is set.
12024 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12025 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12027 (ior:SI (match_dup 0)
12028 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
12030 (match_operand 3 "arith_reg_operand" "r,r"))]
12031 "TARGET_SH2A && TARGET_BITOPS
12032 && satisfies_constraint_Pso (operands[2])
12033 && REGNO (operands[0]) == REGNO (operands[3])"
12034 [(set (match_dup 1)
12035 (ior:QI (match_dup 1)
12039 ;; This matches cases where the bit in a memory location is cleared.
12041 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12042 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12044 (and:SI (match_dup 0)
12045 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
12047 (match_operand 3 "arith_reg_operand" "r,r"))]
12048 "TARGET_SH2A && TARGET_BITOPS
12049 && satisfies_constraint_Psz (operands[2])
12050 && REGNO (operands[0]) == REGNO (operands[3])"
12051 [(set (match_dup 1)
12052 (and:QI (match_dup 1)
12056 ;; This matches cases where a stack pointer increment at the start of the
12057 ;; epilogue combines with a stack slot read loading the return value.
12060 [(set (match_operand:SI 0 "arith_reg_operand" "")
12061 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
12062 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
12063 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
12066 ;; See the comment on the dt combiner pattern above.
12069 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12070 (plus:SI (match_dup 0)
12072 (set (reg:SI T_REG)
12073 (eq:SI (match_dup 0)
12078 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
12079 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
12080 ;; reload when the constant is too large for a reg+offset address.
12082 ;; ??? We would get much better code if this was done in reload. This would
12083 ;; require modifying find_reloads_address to recognize that if the constant
12084 ;; is out-of-range for an immediate add, then we get better code by reloading
12085 ;; the constant into a register than by reloading the sum into a register,
12086 ;; since the former is one instruction shorter if the address does not need
12087 ;; to be offsettable. Unfortunately this does not work, because there is
12088 ;; only one register, r0, that can be used as an index register. This register
12089 ;; is also the function return value register. So, if we try to force reload
12090 ;; to use double-reg addresses, then we end up with some instructions that
12091 ;; need to use r0 twice. The only way to fix this is to change the calling
12092 ;; convention so that r0 is not used to return values.
12095 [(set (match_operand:SI 0 "register_operand" "=r")
12096 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12097 (set (mem:SI (match_dup 0))
12098 (match_operand:SI 2 "general_movsrc_operand" ""))]
12099 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12100 "mov.l %2,@(%0,%1)")
12103 [(set (match_operand:SI 0 "register_operand" "=r")
12104 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12105 (set (match_operand:SI 2 "general_movdst_operand" "")
12106 (mem:SI (match_dup 0)))]
12107 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12108 "mov.l @(%0,%1),%2")
12111 [(set (match_operand:SI 0 "register_operand" "=r")
12112 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12113 (set (mem:HI (match_dup 0))
12114 (match_operand:HI 2 "general_movsrc_operand" ""))]
12115 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12116 "mov.w %2,@(%0,%1)")
12119 [(set (match_operand:SI 0 "register_operand" "=r")
12120 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12121 (set (match_operand:HI 2 "general_movdst_operand" "")
12122 (mem:HI (match_dup 0)))]
12123 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12124 "mov.w @(%0,%1),%2")
12127 [(set (match_operand:SI 0 "register_operand" "=r")
12128 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12129 (set (mem:QI (match_dup 0))
12130 (match_operand:QI 2 "general_movsrc_operand" ""))]
12131 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12132 "mov.b %2,@(%0,%1)")
12135 [(set (match_operand:SI 0 "register_operand" "=r")
12136 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12137 (set (match_operand:QI 2 "general_movdst_operand" "")
12138 (mem:QI (match_dup 0)))]
12139 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12140 "mov.b @(%0,%1),%2")
12143 [(set (match_operand:SI 0 "register_operand" "=r")
12144 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12145 (set (mem:SF (match_dup 0))
12146 (match_operand:SF 2 "general_movsrc_operand" ""))]
12147 "TARGET_SH1 && REGNO (operands[0]) == 0
12148 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12149 || (GET_CODE (operands[2]) == SUBREG
12150 && REGNO (SUBREG_REG (operands[2])) < 16))
12151 && reg_unused_after (operands[0], insn)"
12152 "mov.l %2,@(%0,%1)")
12155 [(set (match_operand:SI 0 "register_operand" "=r")
12156 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12157 (set (match_operand:SF 2 "general_movdst_operand" "")
12159 (mem:SF (match_dup 0)))]
12160 "TARGET_SH1 && REGNO (operands[0]) == 0
12161 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12162 || (GET_CODE (operands[2]) == SUBREG
12163 && REGNO (SUBREG_REG (operands[2])) < 16))
12164 && reg_unused_after (operands[0], insn)"
12165 "mov.l @(%0,%1),%2")
12168 [(set (match_operand:SI 0 "register_operand" "=r")
12169 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12170 (set (mem:SF (match_dup 0))
12171 (match_operand:SF 2 "general_movsrc_operand" ""))]
12172 "TARGET_SH2E && REGNO (operands[0]) == 0
12173 && ((GET_CODE (operands[2]) == REG
12174 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12175 || (GET_CODE (operands[2]) == SUBREG
12176 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12177 && reg_unused_after (operands[0], insn)"
12178 "fmov{.s|} %2,@(%0,%1)")
12181 [(set (match_operand:SI 0 "register_operand" "=r")
12182 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12183 (set (match_operand:SF 2 "general_movdst_operand" "")
12185 (mem:SF (match_dup 0)))]
12186 "TARGET_SH2E && REGNO (operands[0]) == 0
12187 && ((GET_CODE (operands[2]) == REG
12188 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12189 || (GET_CODE (operands[2]) == SUBREG
12190 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12191 && reg_unused_after (operands[0], insn)"
12192 "fmov{.s|} @(%0,%1),%2")
12194 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
12195 (define_insn "sp_switch_1"
12196 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
12200 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
12201 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
12202 return \"mov r0,r15\";
12204 [(set_attr "length" "10")])
12206 ;; Switch back to the original stack for interrupt functions with the
12207 ;; sp_switch attribute. */
12208 (define_insn "sp_switch_2"
12211 "mov.l @r15+,r15\;mov.l @r15+,r0"
12212 [(set_attr "length" "4")])
12214 ;; Integer vector moves
12216 (define_expand "movv8qi"
12217 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
12218 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
12220 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
12222 (define_insn "movv8qi_i"
12223 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
12224 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12226 && (register_operand (operands[0], V8QImode)
12227 || sh_register_operand (operands[1], V8QImode))"
12234 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12235 (set_attr "length" "4,4,16,4,4")])
12238 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
12239 (subreg:V8QI (const_int 0) 0))]
12241 [(set (match_dup 0)
12242 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
12243 (const_int 0) (const_int 0) (const_int 0)
12244 (const_int 0) (const_int 0)]))])
12247 [(set (match_operand 0 "arith_reg_dest" "")
12248 (match_operand 1 "sh_rep_vec" ""))]
12249 "TARGET_SHMEDIA && reload_completed
12250 && GET_MODE (operands[0]) == GET_MODE (operands[1])
12251 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
12252 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
12253 && (XVECEXP (operands[1], 0, 0) != const0_rtx
12254 || XVECEXP (operands[1], 0, 1) != const0_rtx)
12255 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
12256 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
12257 [(set (match_dup 0) (match_dup 1))
12261 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
12262 rtx elt1 = XVECEXP (operands[1], 0, 1);
12265 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
12269 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
12270 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
12272 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
12273 operands[1] = XVECEXP (operands[1], 0, 0);
12276 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
12278 = GEN_INT (TARGET_LITTLE_ENDIAN
12279 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
12280 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
12283 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
12285 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
12291 [(set (match_operand 0 "arith_reg_dest" "")
12292 (match_operand 1 "sh_const_vec" ""))]
12293 "TARGET_SHMEDIA && reload_completed
12294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
12295 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
12296 [(set (match_dup 0) (match_dup 1))]
12299 rtx v = operands[1];
12300 enum machine_mode new_mode
12301 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
12303 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
12305 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
12308 (define_expand "movv2hi"
12309 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
12310 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
12312 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
12314 (define_insn "movv2hi_i"
12315 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12316 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12318 && (register_operand (operands[0], V2HImode)
12319 || sh_register_operand (operands[1], V2HImode))"
12326 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12327 (set_attr "length" "4,4,16,4,4")
12328 (set (attr "highpart")
12329 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
12330 (const_string "user")]
12331 (const_string "ignore")))])
12333 (define_expand "movv4hi"
12334 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
12335 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
12337 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
12339 (define_insn "movv4hi_i"
12340 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12341 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12343 && (register_operand (operands[0], V4HImode)
12344 || sh_register_operand (operands[1], V4HImode))"
12351 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12352 (set_attr "length" "4,4,16,4,4")
12353 (set_attr "highpart" "depend")])
12355 (define_expand "movv2si"
12356 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
12357 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
12359 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
12361 (define_insn "movv2si_i"
12362 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
12363 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12365 && (register_operand (operands[0], V2SImode)
12366 || sh_register_operand (operands[1], V2SImode))"
12373 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12374 (set_attr "length" "4,4,16,4,4")
12375 (set_attr "highpart" "depend")])
12377 ;; Multimedia Intrinsics
12379 (define_insn "absv2si2"
12380 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12381 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
12384 [(set_attr "type" "mcmp_media")
12385 (set_attr "highpart" "depend")])
12387 (define_insn "absv4hi2"
12388 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12389 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
12392 [(set_attr "type" "mcmp_media")
12393 (set_attr "highpart" "depend")])
12395 (define_insn "addv2si3"
12396 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12397 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12398 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12400 "madd.l %1, %2, %0"
12401 [(set_attr "type" "arith_media")
12402 (set_attr "highpart" "depend")])
12404 (define_insn "addv4hi3"
12405 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12406 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12407 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12409 "madd.w %1, %2, %0"
12410 [(set_attr "type" "arith_media")
12411 (set_attr "highpart" "depend")])
12413 (define_insn_and_split "addv2hi3"
12414 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12415 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12416 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12423 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12424 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12425 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12426 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12427 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12429 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12430 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12433 [(set_attr "highpart" "must_split")])
12435 (define_insn "ssaddv2si3"
12436 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12437 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12438 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12440 "madds.l %1, %2, %0"
12441 [(set_attr "type" "mcmp_media")
12442 (set_attr "highpart" "depend")])
12444 (define_insn "usaddv8qi3"
12445 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12446 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12447 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12449 "madds.ub %1, %2, %0"
12450 [(set_attr "type" "mcmp_media")
12451 (set_attr "highpart" "depend")])
12453 (define_insn "ssaddv4hi3"
12454 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12455 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12456 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12458 "madds.w %1, %2, %0"
12459 [(set_attr "type" "mcmp_media")
12460 (set_attr "highpart" "depend")])
12462 (define_insn "negcmpeqv8qi"
12463 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12464 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12465 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12467 "mcmpeq.b %N1, %N2, %0"
12468 [(set_attr "type" "mcmp_media")
12469 (set_attr "highpart" "depend")])
12471 (define_insn "negcmpeqv2si"
12472 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12473 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12474 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12476 "mcmpeq.l %N1, %N2, %0"
12477 [(set_attr "type" "mcmp_media")
12478 (set_attr "highpart" "depend")])
12480 (define_insn "negcmpeqv4hi"
12481 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12482 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12483 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12485 "mcmpeq.w %N1, %N2, %0"
12486 [(set_attr "type" "mcmp_media")
12487 (set_attr "highpart" "depend")])
12489 (define_insn "negcmpgtuv8qi"
12490 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12491 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12492 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12494 "mcmpgt.ub %N1, %N2, %0"
12495 [(set_attr "type" "mcmp_media")
12496 (set_attr "highpart" "depend")])
12498 (define_insn "negcmpgtv2si"
12499 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12500 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12501 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12503 "mcmpgt.l %N1, %N2, %0"
12504 [(set_attr "type" "mcmp_media")
12505 (set_attr "highpart" "depend")])
12507 (define_insn "negcmpgtv4hi"
12508 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12509 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12510 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12512 "mcmpgt.w %N1, %N2, %0"
12513 [(set_attr "type" "mcmp_media")
12514 (set_attr "highpart" "depend")])
12516 (define_insn "mcmv"
12517 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12518 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12519 (match_operand:DI 2 "arith_reg_operand" "r"))
12520 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12521 (not:DI (match_dup 2)))))]
12524 [(set_attr "type" "arith_media")
12525 (set_attr "highpart" "depend")])
12527 (define_insn "mcnvs_lw"
12528 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12530 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12531 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12533 "mcnvs.lw %N1, %N2, %0"
12534 [(set_attr "type" "mcmp_media")])
12536 (define_insn "mcnvs_wb"
12537 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12539 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12540 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12542 "mcnvs.wb %N1, %N2, %0"
12543 [(set_attr "type" "mcmp_media")])
12545 (define_insn "mcnvs_wub"
12546 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12548 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12549 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12551 "mcnvs.wub %N1, %N2, %0"
12552 [(set_attr "type" "mcmp_media")])
12554 (define_insn "mextr_rl"
12555 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12556 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12557 (match_operand:HI 3 "mextr_bit_offset" "i"))
12558 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12559 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12560 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12563 static char templ[21];
12565 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12566 (int) INTVAL (operands[3]) >> 3);
12569 [(set_attr "type" "arith_media")])
12571 (define_insn "*mextr_lr"
12572 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12573 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12574 (match_operand:HI 3 "mextr_bit_offset" "i"))
12575 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12576 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12577 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12580 static char templ[21];
12582 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12583 (int) INTVAL (operands[4]) >> 3);
12586 [(set_attr "type" "arith_media")])
12588 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12589 ; vector then varies depending on endianness.
12590 (define_expand "mextr1"
12591 [(match_operand:DI 0 "arith_reg_dest" "")
12592 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12593 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12597 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12598 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12602 (define_expand "mextr2"
12603 [(match_operand:DI 0 "arith_reg_dest" "")
12604 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12605 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12609 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12610 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12614 (define_expand "mextr3"
12615 [(match_operand:DI 0 "arith_reg_dest" "")
12616 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12617 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12621 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12622 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12626 (define_expand "mextr4"
12627 [(match_operand:DI 0 "arith_reg_dest" "")
12628 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12629 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12633 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12634 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12638 (define_expand "mextr5"
12639 [(match_operand:DI 0 "arith_reg_dest" "")
12640 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12641 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12645 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12646 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12650 (define_expand "mextr6"
12651 [(match_operand:DI 0 "arith_reg_dest" "")
12652 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12653 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12657 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12658 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12662 (define_expand "mextr7"
12663 [(match_operand:DI 0 "arith_reg_dest" "")
12664 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12665 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12669 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12670 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12674 (define_expand "mmacfx_wl"
12675 [(match_operand:V2SI 0 "arith_reg_dest" "")
12676 (match_operand:V2HI 1 "extend_reg_operand" "")
12677 (match_operand:V2HI 2 "extend_reg_operand" "")
12678 (match_operand:V2SI 3 "arith_reg_operand" "")]
12682 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12683 operands[1], operands[2]));
12687 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12689 (define_insn "mmacfx_wl_i"
12690 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12692 (match_operand:V2SI 1 "arith_reg_operand" "0")
12697 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12698 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12701 "mmacfx.wl %2, %3, %0"
12702 [(set_attr "type" "mac_media")
12703 (set_attr "highpart" "depend")])
12705 (define_expand "mmacnfx_wl"
12706 [(match_operand:V2SI 0 "arith_reg_dest" "")
12707 (match_operand:V2HI 1 "extend_reg_operand" "")
12708 (match_operand:V2HI 2 "extend_reg_operand" "")
12709 (match_operand:V2SI 3 "arith_reg_operand" "")]
12713 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12714 operands[1], operands[2]));
12718 (define_insn "mmacnfx_wl_i"
12719 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12721 (match_operand:V2SI 1 "arith_reg_operand" "0")
12726 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12727 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12730 "mmacnfx.wl %2, %3, %0"
12731 [(set_attr "type" "mac_media")
12732 (set_attr "highpart" "depend")])
12734 (define_insn "mulv2si3"
12735 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12736 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12737 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12739 "mmul.l %1, %2, %0"
12740 [(set_attr "type" "d2mpy_media")
12741 (set_attr "highpart" "depend")])
12743 (define_insn "mulv4hi3"
12744 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12745 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12746 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12748 "mmul.w %1, %2, %0"
12749 [(set_attr "type" "dmpy_media")
12750 (set_attr "highpart" "depend")])
12752 (define_insn "mmulfx_l"
12753 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12757 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12758 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12761 "mmulfx.l %1, %2, %0"
12762 [(set_attr "type" "d2mpy_media")
12763 (set_attr "highpart" "depend")])
12765 (define_insn "mmulfx_w"
12766 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12770 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12771 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12774 "mmulfx.w %1, %2, %0"
12775 [(set_attr "type" "dmpy_media")
12776 (set_attr "highpart" "depend")])
12778 (define_insn "mmulfxrp_w"
12779 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12784 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12785 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12789 "mmulfxrp.w %1, %2, %0"
12790 [(set_attr "type" "dmpy_media")
12791 (set_attr "highpart" "depend")])
12794 (define_expand "mmulhi_wl"
12795 [(match_operand:V2SI 0 "arith_reg_dest" "")
12796 (match_operand:V4HI 1 "arith_reg_operand" "")
12797 (match_operand:V4HI 2 "arith_reg_operand" "")]
12801 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12802 (operands[0], operands[1], operands[2]));
12806 (define_expand "mmullo_wl"
12807 [(match_operand:V2SI 0 "arith_reg_dest" "")
12808 (match_operand:V4HI 1 "arith_reg_operand" "")
12809 (match_operand:V4HI 2 "arith_reg_operand" "")]
12813 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12814 (operands[0], operands[1], operands[2]));
12818 (define_insn "mmul23_wl"
12819 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12822 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12823 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12824 (parallel [(const_int 2) (const_int 3)])))]
12826 "* return (TARGET_LITTLE_ENDIAN
12827 ? \"mmulhi.wl %1, %2, %0\"
12828 : \"mmullo.wl %1, %2, %0\");"
12829 [(set_attr "type" "dmpy_media")
12830 (set (attr "highpart")
12831 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12832 (const_string "user")))])
12834 (define_insn "mmul01_wl"
12835 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12838 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12839 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12840 (parallel [(const_int 0) (const_int 1)])))]
12842 "* return (TARGET_LITTLE_ENDIAN
12843 ? \"mmullo.wl %1, %2, %0\"
12844 : \"mmulhi.wl %1, %2, %0\");"
12845 [(set_attr "type" "dmpy_media")
12846 (set (attr "highpart")
12847 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12848 (const_string "user")))])
12851 (define_expand "mmulsum_wq"
12852 [(match_operand:DI 0 "arith_reg_dest" "")
12853 (match_operand:V4HI 1 "arith_reg_operand" "")
12854 (match_operand:V4HI 2 "arith_reg_operand" "")
12855 (match_operand:DI 3 "arith_reg_operand" "")]
12859 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12860 operands[1], operands[2]));
12864 (define_insn "mmulsum_wq_i"
12865 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12866 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12871 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12872 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12873 (parallel [(const_int 0)]))
12874 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12875 (sign_extend:V4DI (match_dup 3)))
12876 (parallel [(const_int 1)])))
12878 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12879 (sign_extend:V4DI (match_dup 3)))
12880 (parallel [(const_int 2)]))
12881 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12882 (sign_extend:V4DI (match_dup 3)))
12883 (parallel [(const_int 3)]))))))]
12885 "mmulsum.wq %2, %3, %0"
12886 [(set_attr "type" "mac_media")])
12888 (define_expand "mperm_w"
12889 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12890 (match_operand:V4HI 1 "arith_reg_operand" "r")
12891 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12895 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12896 (operands[0], operands[1], operands[2]));
12900 ; This use of vec_select isn't exactly correct according to rtl.texi
12901 ; (because not constant), but it seems a straightforward extension.
12902 (define_insn "mperm_w_little"
12903 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12905 (match_operand:V4HI 1 "arith_reg_operand" "r")
12907 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12908 (const_int 2) (const_int 0))
12909 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12910 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12911 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12912 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12913 "mperm.w %1, %N2, %0"
12914 [(set_attr "type" "arith_media")])
12916 (define_insn "mperm_w_big"
12917 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12919 (match_operand:V4HI 1 "arith_reg_operand" "r")
12921 [(zero_extract:QI (not:QI (match_operand:QI 2
12922 "extend_reg_or_0_operand" "rZ"))
12923 (const_int 2) (const_int 0))
12924 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12925 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12926 (zero_extract:QI (not:QI (match_dup 2))
12927 (const_int 2) (const_int 6))])))]
12928 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12929 "mperm.w %1, %N2, %0"
12930 [(set_attr "type" "arith_media")])
12932 (define_insn "mperm_w0"
12933 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12934 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12935 "trunc_hi_operand" "r"))))]
12937 "mperm.w %1, r63, %0"
12938 [(set_attr "type" "arith_media")
12939 (set_attr "highpart" "ignore")])
12941 (define_expand "msad_ubq"
12942 [(match_operand:DI 0 "arith_reg_dest" "")
12943 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12944 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12945 (match_operand:DI 3 "arith_reg_operand" "")]
12949 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12950 operands[1], operands[2]));
12954 (define_insn "msad_ubq_i"
12955 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12960 (match_operand:DI 1 "arith_reg_operand" "0")
12961 (abs:DI (vec_select:DI
12964 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12966 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12967 (parallel [(const_int 0)]))))
12968 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12969 (zero_extend:V8DI (match_dup 3)))
12970 (parallel [(const_int 1)]))))
12972 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12973 (zero_extend:V8DI (match_dup 3)))
12974 (parallel [(const_int 2)])))
12975 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12976 (zero_extend:V8DI (match_dup 3)))
12977 (parallel [(const_int 3)])))))
12980 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12981 (zero_extend:V8DI (match_dup 3)))
12982 (parallel [(const_int 4)])))
12983 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12984 (zero_extend:V8DI (match_dup 3)))
12985 (parallel [(const_int 5)]))))
12987 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12988 (zero_extend:V8DI (match_dup 3)))
12989 (parallel [(const_int 6)])))
12990 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12991 (zero_extend:V8DI (match_dup 3)))
12992 (parallel [(const_int 7)])))))))]
12994 "msad.ubq %N2, %N3, %0"
12995 [(set_attr "type" "mac_media")])
12997 (define_insn "mshalds_l"
12998 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13001 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
13002 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13003 (const_int 31)))))]
13005 "mshalds.l %1, %2, %0"
13006 [(set_attr "type" "mcmp_media")
13007 (set_attr "highpart" "depend")])
13009 (define_insn "mshalds_w"
13010 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13013 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13014 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13015 (const_int 15)))))]
13017 "mshalds.w %1, %2, %0"
13018 [(set_attr "type" "mcmp_media")
13019 (set_attr "highpart" "depend")])
13021 (define_insn "ashrv2si3"
13022 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13023 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13024 (match_operand:DI 2 "arith_reg_operand" "r")))]
13026 "mshard.l %1, %2, %0"
13027 [(set_attr "type" "arith_media")
13028 (set_attr "highpart" "depend")])
13030 (define_insn "ashrv4hi3"
13031 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13032 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13033 (match_operand:DI 2 "arith_reg_operand" "r")))]
13035 "mshard.w %1, %2, %0"
13036 [(set_attr "type" "arith_media")
13037 (set_attr "highpart" "depend")])
13039 (define_insn "mshards_q"
13040 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
13042 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
13043 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
13045 "mshards.q %1, %N2, %0"
13046 [(set_attr "type" "mcmp_media")])
13048 (define_expand "mshfhi_b"
13049 [(match_operand:V8QI 0 "arith_reg_dest" "")
13050 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13051 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13055 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
13056 (operands[0], operands[1], operands[2]));
13060 (define_expand "mshflo_b"
13061 [(match_operand:V8QI 0 "arith_reg_dest" "")
13062 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13063 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13067 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
13068 (operands[0], operands[1], operands[2]));
13072 (define_insn "mshf4_b"
13074 (match_operand:V8QI 0 "arith_reg_dest" "=r")
13076 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13077 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13078 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
13079 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
13081 "* return (TARGET_LITTLE_ENDIAN
13082 ? \"mshfhi.b %N1, %N2, %0\"
13083 : \"mshflo.b %N1, %N2, %0\");"
13084 [(set_attr "type" "arith_media")
13085 (set (attr "highpart")
13086 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13087 (const_string "user")))])
13089 (define_insn "mshf0_b"
13091 (match_operand:V8QI 0 "arith_reg_dest" "=r")
13093 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13094 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13095 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
13096 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
13098 "* return (TARGET_LITTLE_ENDIAN
13099 ? \"mshflo.b %N1, %N2, %0\"
13100 : \"mshfhi.b %N1, %N2, %0\");"
13101 [(set_attr "type" "arith_media")
13102 (set (attr "highpart")
13103 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13104 (const_string "user")))])
13106 (define_expand "mshfhi_l"
13107 [(match_operand:V2SI 0 "arith_reg_dest" "")
13108 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13109 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13113 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
13114 (operands[0], operands[1], operands[2]));
13118 (define_expand "mshflo_l"
13119 [(match_operand:V2SI 0 "arith_reg_dest" "")
13120 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13121 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13125 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
13126 (operands[0], operands[1], operands[2]));
13130 (define_insn "mshf4_l"
13131 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13133 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13134 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13135 (parallel [(const_int 1) (const_int 3)])))]
13137 "* return (TARGET_LITTLE_ENDIAN
13138 ? \"mshfhi.l %N1, %N2, %0\"
13139 : \"mshflo.l %N1, %N2, %0\");"
13140 [(set_attr "type" "arith_media")
13141 (set (attr "highpart")
13142 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13143 (const_string "user")))])
13145 (define_insn "mshf0_l"
13146 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13148 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13149 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13150 (parallel [(const_int 0) (const_int 2)])))]
13152 "* return (TARGET_LITTLE_ENDIAN
13153 ? \"mshflo.l %N1, %N2, %0\"
13154 : \"mshfhi.l %N1, %N2, %0\");"
13155 [(set_attr "type" "arith_media")
13156 (set (attr "highpart")
13157 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13158 (const_string "user")))])
13160 (define_expand "mshfhi_w"
13161 [(match_operand:V4HI 0 "arith_reg_dest" "")
13162 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13163 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13167 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
13168 (operands[0], operands[1], operands[2]));
13172 (define_expand "mshflo_w"
13173 [(match_operand:V4HI 0 "arith_reg_dest" "")
13174 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13175 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13179 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
13180 (operands[0], operands[1], operands[2]));
13184 (define_insn "mshf4_w"
13185 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13187 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13188 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13189 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
13191 "* return (TARGET_LITTLE_ENDIAN
13192 ? \"mshfhi.w %N1, %N2, %0\"
13193 : \"mshflo.w %N1, %N2, %0\");"
13194 [(set_attr "type" "arith_media")
13195 (set (attr "highpart")
13196 (cond [(eq_attr "endian" "big") (const_string "ignore")]
13197 (const_string "user")))])
13199 (define_insn "mshf0_w"
13200 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13202 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13203 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13204 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
13206 "* return (TARGET_LITTLE_ENDIAN
13207 ? \"mshflo.w %N1, %N2, %0\"
13208 : \"mshfhi.w %N1, %N2, %0\");"
13209 [(set_attr "type" "arith_media")
13210 (set (attr "highpart")
13211 (cond [(eq_attr "endian" "little") (const_string "ignore")]
13212 (const_string "user")))])
13214 (define_insn "mshflo_w_x"
13215 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13217 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
13218 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
13219 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
13221 "mshflo.w %N1, %N2, %0"
13222 [(set_attr "type" "arith_media")
13223 (set_attr "highpart" "ignore")])
13225 /* These are useful to expand ANDs and as combiner patterns. */
13226 (define_insn_and_split "mshfhi_l_di"
13227 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
13228 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
13230 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
13231 (const_int -4294967296))))]
13234 mshfhi.l %N1, %N2, %0
13236 "TARGET_SHMEDIA && reload_completed
13237 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13238 [(set (match_dup 3) (match_dup 4))
13239 (set (match_dup 5) (match_dup 6))]
13242 operands[3] = gen_lowpart (SImode, operands[0]);
13243 operands[4] = gen_highpart (SImode, operands[1]);
13244 operands[5] = gen_highpart (SImode, operands[0]);
13245 operands[6] = gen_highpart (SImode, operands[2]);
13247 [(set_attr "type" "arith_media")])
13249 (define_insn "*mshfhi_l_di_rev"
13250 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13251 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13252 (const_int -4294967296))
13253 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13256 "mshfhi.l %N2, %N1, %0"
13257 [(set_attr "type" "arith_media")])
13260 [(set (match_operand:DI 0 "arith_reg_dest" "")
13261 (ior:DI (zero_extend:DI (match_operand:SI 1
13262 "extend_reg_or_0_operand" ""))
13263 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
13264 (const_int -4294967296))))
13265 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
13270 emit_insn (gen_ashldi3_media (operands[3],
13271 simplify_gen_subreg (DImode, operands[1],
13274 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
13278 (define_insn "mshflo_l_di"
13279 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13280 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13281 (const_int 4294967295))
13282 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13286 "mshflo.l %N1, %N2, %0"
13287 [(set_attr "type" "arith_media")
13288 (set_attr "highpart" "ignore")])
13290 (define_insn "*mshflo_l_di_rev"
13291 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13292 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13294 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13295 (const_int 4294967295))))]
13298 "mshflo.l %N2, %N1, %0"
13299 [(set_attr "type" "arith_media")
13300 (set_attr "highpart" "ignore")])
13302 ;; Combiner pattern for trampoline initialization.
13303 (define_insn_and_split "*double_shori"
13304 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13305 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
13307 (match_operand:DI 2 "const_int_operand" "n")))]
13309 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
13311 "rtx_equal_p (operands[0], operands[1])"
13315 HOST_WIDE_INT v = INTVAL (operands[2]);
13317 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
13318 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
13321 [(set_attr "highpart" "ignore")])
13324 (define_insn "*mshflo_l_di_x"
13325 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13326 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
13328 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13332 "mshflo.l %N1, %N2, %0"
13333 [(set_attr "type" "arith_media")
13334 (set_attr "highpart" "ignore")])
13336 (define_insn_and_split "concat_v2sf"
13337 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
13338 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
13339 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
13340 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
13344 mshflo.l %N1, %N2, %0
13347 "TARGET_SHMEDIA && reload_completed
13348 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13349 [(set (match_dup 3) (match_dup 1))
13350 (set (match_dup 4) (match_dup 2))]
13353 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
13354 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
13356 [(set_attr "type" "arith_media")
13357 (set_attr "highpart" "ignore")])
13359 (define_insn "*mshflo_l_di_x_rev"
13360 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13361 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13363 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
13366 "mshflo.l %N2, %N1, %0"
13367 [(set_attr "type" "arith_media")
13368 (set_attr "highpart" "ignore")])
13370 (define_insn "ashlv2si3"
13371 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13372 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13373 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13375 "mshlld.l %1, %2, %0"
13376 [(set_attr "type" "arith_media")
13377 (set_attr "highpart" "depend")])
13380 [(set (match_operand 0 "any_register_operand" "")
13381 (match_operator 3 "shift_operator"
13382 [(match_operand 1 "any_register_operand" "")
13383 (match_operand 2 "shift_count_reg_operand" "")]))]
13384 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
13385 [(set (match_dup 0) (match_dup 3))]
13388 rtx count = operands[2];
13389 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
13391 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
13392 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
13393 || GET_CODE (count) == TRUNCATE)
13394 count = XEXP (count, 0);
13395 inner_mode = GET_MODE (count);
13396 count = simplify_gen_subreg (outer_mode, count, inner_mode,
13397 subreg_lowpart_offset (outer_mode, inner_mode));
13398 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
13399 operands[1], count);
13402 (define_insn "ashlv4hi3"
13403 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13404 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13405 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13407 "mshlld.w %1, %2, %0"
13408 [(set_attr "type" "arith_media")
13409 (set_attr "highpart" "depend")])
13411 (define_insn "lshrv2si3"
13412 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13413 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13414 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13416 "mshlrd.l %1, %2, %0"
13417 [(set_attr "type" "arith_media")
13418 (set_attr "highpart" "depend")])
13420 (define_insn "lshrv4hi3"
13421 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13422 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13423 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13425 "mshlrd.w %1, %2, %0"
13426 [(set_attr "type" "arith_media")
13427 (set_attr "highpart" "depend")])
13429 (define_insn "subv2si3"
13430 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13431 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13432 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13434 "msub.l %N1, %2, %0"
13435 [(set_attr "type" "arith_media")
13436 (set_attr "highpart" "depend")])
13438 (define_insn "subv4hi3"
13439 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13440 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13441 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13443 "msub.w %N1, %2, %0"
13444 [(set_attr "type" "arith_media")
13445 (set_attr "highpart" "depend")])
13447 (define_insn_and_split "subv2hi3"
13448 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13449 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13450 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13457 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13458 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13459 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13460 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13461 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13463 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13464 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13467 [(set_attr "highpart" "must_split")])
13469 (define_insn "sssubv2si3"
13470 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13471 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13472 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13474 "msubs.l %N1, %2, %0"
13475 [(set_attr "type" "mcmp_media")
13476 (set_attr "highpart" "depend")])
13478 (define_insn "ussubv8qi3"
13479 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13480 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13481 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13483 "msubs.ub %N1, %2, %0"
13484 [(set_attr "type" "mcmp_media")
13485 (set_attr "highpart" "depend")])
13487 (define_insn "sssubv4hi3"
13488 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13489 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13490 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13492 "msubs.w %N1, %2, %0"
13493 [(set_attr "type" "mcmp_media")
13494 (set_attr "highpart" "depend")])
13496 ;; Floating Point Intrinsics
13498 (define_insn "fcosa_s"
13499 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13500 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13504 [(set_attr "type" "atrans_media")])
13506 (define_insn "fsina_s"
13507 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13508 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13512 [(set_attr "type" "atrans_media")])
13514 (define_insn "fipr"
13515 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13516 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13517 "fp_arith_reg_operand" "f")
13518 (match_operand:V4SF 2
13519 "fp_arith_reg_operand" "f"))
13520 (parallel [(const_int 0)]))
13521 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13522 (parallel [(const_int 1)])))
13523 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13524 (parallel [(const_int 2)]))
13525 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13526 (parallel [(const_int 3)])))))]
13528 "fipr.s %1, %2, %0"
13529 [(set_attr "type" "fparith_media")])
13531 (define_insn "fsrra_s"
13532 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13533 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13537 [(set_attr "type" "atrans_media")])
13539 (define_insn "ftrv"
13540 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13544 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13545 (parallel [(const_int 0) (const_int 5)
13546 (const_int 10) (const_int 15)]))
13547 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13549 (vec_select:V4SF (match_dup 1)
13550 (parallel [(const_int 4) (const_int 9)
13551 (const_int 14) (const_int 3)]))
13552 (vec_select:V4SF (match_dup 2)
13553 (parallel [(const_int 1) (const_int 2)
13554 (const_int 3) (const_int 0)]))))
13557 (vec_select:V4SF (match_dup 1)
13558 (parallel [(const_int 8) (const_int 13)
13559 (const_int 2) (const_int 7)]))
13560 (vec_select:V4SF (match_dup 2)
13561 (parallel [(const_int 2) (const_int 3)
13562 (const_int 0) (const_int 1)])))
13564 (vec_select:V4SF (match_dup 1)
13565 (parallel [(const_int 12) (const_int 1)
13566 (const_int 6) (const_int 11)]))
13567 (vec_select:V4SF (match_dup 2)
13568 (parallel [(const_int 3) (const_int 0)
13569 (const_int 1) (const_int 2)]))))))]
13571 "ftrv.s %1, %2, %0"
13572 [(set_attr "type" "fparith_media")])
13574 (define_insn "ldhi_l"
13575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13577 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13580 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13584 [(set_attr "type" "load_media")])
13586 (define_insn "ldhi_q"
13587 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13589 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13592 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13596 [(set_attr "type" "load_media")])
13598 (define_insn_and_split "*ldhi_q_comb0"
13599 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13601 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13602 "register_operand" "r")
13603 (match_operand:SI 2
13604 "ua_offset" "I06"))
13607 (plus:SI (and:SI (match_dup 1) (const_int 7))
13610 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13614 "emit_insn (gen_ldhi_q (operands[0],
13615 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13619 (define_insn_and_split "*ldhi_q_comb1"
13620 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13622 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13623 "register_operand" "r")
13624 (match_operand:SI 2
13625 "ua_offset" "I06"))
13628 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13629 "ua_offset" "I06"))
13633 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13634 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13638 "emit_insn (gen_ldhi_q (operands[0],
13639 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13643 (define_insn "ldlo_l"
13644 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13646 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13648 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13649 (and:SI (match_dup 1) (const_int 3))))]
13652 [(set_attr "type" "load_media")])
13654 (define_insn "ldlo_q"
13655 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13657 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13659 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13660 (and:SI (match_dup 1) (const_int 7))))]
13663 [(set_attr "type" "load_media")])
13665 (define_insn_and_split "*ldlo_q_comb0"
13666 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13668 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13669 (match_operand:SI 2 "ua_offset" "I06"))
13671 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13672 (and:SI (match_dup 1) (const_int 7))))]
13673 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13677 "emit_insn (gen_ldlo_q (operands[0],
13678 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13681 (define_insn_and_split "*ldlo_q_comb1"
13682 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13684 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13685 (match_operand:SI 2 "ua_offset" "I06"))
13687 (minus:SI (const_int 8)
13688 (and:SI (plus:SI (match_dup 1)
13689 (match_operand:SI 3 "ua_offset" "I06"))
13691 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13692 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13693 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13697 "emit_insn (gen_ldlo_q (operands[0],
13698 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13701 (define_insn "sthi_l"
13702 [(set (zero_extract:SI
13703 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13706 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13708 (match_operand:SI 1 "arith_reg_operand" "r"))]
13711 [(set_attr "type" "ustore_media")])
13713 ;; All unaligned stores are considered to be 'narrow' because they typically
13714 ;; operate on less that a quadword, and when they operate on a full quadword,
13715 ;; the vanilla store high / store low sequence will cause a stall if not
13716 ;; scheduled apart.
13717 (define_insn "sthi_q"
13718 [(set (zero_extract:DI
13719 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13722 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13724 (match_operand:DI 1 "arith_reg_operand" "r"))]
13727 [(set_attr "type" "ustore_media")])
13729 (define_insn_and_split "*sthi_q_comb0"
13730 [(set (zero_extract:DI
13731 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13732 "register_operand" "r")
13733 (match_operand:SI 1 "ua_offset"
13737 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13739 (match_operand:DI 2 "arith_reg_operand" "r"))]
13740 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13744 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13748 (define_insn_and_split "*sthi_q_comb1"
13749 [(set (zero_extract:DI
13750 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13751 "register_operand" "r")
13752 (match_operand:SI 1 "ua_offset"
13756 (plus:SI (and:SI (plus:SI (match_dup 0)
13757 (match_operand:SI 2 "ua_offset" "I06"))
13761 (match_operand:DI 3 "arith_reg_operand" "r"))]
13762 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13763 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13767 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13771 ;; This is highpart user because the address is used as full 64 bit.
13772 (define_insn "stlo_l"
13773 [(set (zero_extract:SI
13774 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13776 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13777 (and:SI (match_dup 0) (const_int 3)))
13778 (match_operand:SI 1 "arith_reg_operand" "r"))]
13781 [(set_attr "type" "ustore_media")])
13783 (define_insn "stlo_q"
13784 [(set (zero_extract:DI
13785 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13787 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13788 (and:SI (match_dup 0) (const_int 7)))
13789 (match_operand:DI 1 "arith_reg_operand" "r"))]
13792 [(set_attr "type" "ustore_media")])
13794 (define_insn_and_split "*stlo_q_comb0"
13795 [(set (zero_extract:DI
13796 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13797 (match_operand:SI 1 "ua_offset" "I06"))
13799 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13800 (and:SI (match_dup 0) (const_int 7)))
13801 (match_operand:DI 2 "arith_reg_operand" "r"))]
13802 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13806 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13810 (define_insn_and_split "*stlo_q_comb1"
13811 [(set (zero_extract:DI
13812 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13813 (match_operand:SI 1 "ua_offset" "I06"))
13815 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13816 (match_operand:SI 2
13817 "ua_offset" "I06"))
13819 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13820 (match_operand:DI 3 "arith_reg_operand" "r"))]
13821 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13825 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13829 (define_insn "ldhi_l64"
13830 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13832 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13835 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13839 [(set_attr "type" "load_media")])
13841 (define_insn "ldhi_q64"
13842 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13844 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13847 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13851 [(set_attr "type" "load_media")])
13853 (define_insn "ldlo_l64"
13854 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13856 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13858 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13859 (and:DI (match_dup 1) (const_int 3))))]
13862 [(set_attr "type" "load_media")])
13864 (define_insn "ldlo_q64"
13865 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13867 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13869 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13870 (and:DI (match_dup 1) (const_int 7))))]
13873 [(set_attr "type" "load_media")])
13875 (define_insn "sthi_l64"
13876 [(set (zero_extract:SI
13877 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13880 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13882 (match_operand:SI 1 "arith_reg_operand" "r"))]
13885 [(set_attr "type" "ustore_media")])
13887 (define_insn "sthi_q64"
13888 [(set (zero_extract:DI
13889 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13892 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13894 (match_operand:DI 1 "arith_reg_operand" "r"))]
13897 [(set_attr "type" "ustore_media")])
13899 (define_insn "stlo_l64"
13900 [(set (zero_extract:SI
13901 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13903 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13904 (and:DI (match_dup 0) (const_int 3)))
13905 (match_operand:SI 1 "arith_reg_operand" "r"))]
13908 [(set_attr "type" "ustore_media")])
13910 (define_insn "stlo_q64"
13911 [(set (zero_extract:DI
13912 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13914 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13915 (and:DI (match_dup 0) (const_int 7)))
13916 (match_operand:DI 1 "arith_reg_operand" "r"))]
13919 [(set_attr "type" "ustore_media")])
13922 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13923 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13927 [(set_attr "type" "arith_media")])
13929 (define_insn "nsbsi"
13930 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13932 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13936 [(set_attr "type" "arith_media")])
13938 (define_insn "nsbdi"
13939 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13941 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13945 [(set_attr "type" "arith_media")])
13947 (define_expand "ffsdi2"
13948 [(set (match_operand:DI 0 "arith_reg_dest" "")
13949 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13953 rtx scratch = gen_reg_rtx (DImode);
13956 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13957 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13958 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13959 emit_insn (gen_nsbdi (scratch, scratch));
13960 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13961 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13962 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13963 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13968 (define_expand "ffssi2"
13969 [(set (match_operand:SI 0 "arith_reg_dest" "")
13970 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13974 rtx scratch = gen_reg_rtx (SImode);
13975 rtx discratch = gen_reg_rtx (DImode);
13978 emit_insn (gen_adddi3 (discratch,
13979 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13981 emit_insn (gen_andcdi3 (discratch,
13982 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13984 emit_insn (gen_nsbsi (scratch, discratch));
13985 last = emit_insn (gen_subsi3 (operands[0],
13986 force_reg (SImode, GEN_INT (63)), scratch));
13987 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13992 (define_insn "byterev"
13993 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13994 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13995 (parallel [(const_int 7) (const_int 6) (const_int 5)
13996 (const_int 4) (const_int 3) (const_int 2)
13997 (const_int 1) (const_int 0)])))]
14000 [(set_attr "type" "arith_media")])
14002 (define_insn "*prefetch_media"
14003 [(prefetch (match_operand:QI 0 "address_operand" "p")
14004 (match_operand:SI 1 "const_int_operand" "n")
14005 (match_operand:SI 2 "const_int_operand" "n"))]
14009 operands[0] = gen_rtx_MEM (QImode, operands[0]);
14010 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
14013 [(set_attr "type" "other")])
14015 (define_insn "*prefetch_i4"
14016 [(prefetch (match_operand:SI 0 "register_operand" "r")
14017 (match_operand:SI 1 "const_int_operand" "n")
14018 (match_operand:SI 2 "const_int_operand" "n"))]
14019 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
14022 return \"pref @%0\";
14024 [(set_attr "type" "other")])
14026 ;; In user mode, the "pref" instruction will raise a RADDERR exception
14027 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
14028 ;; implementation of __builtin_prefetch for VxWorks RTPs.
14029 (define_expand "prefetch"
14030 [(prefetch (match_operand 0 "address_operand" "p")
14031 (match_operand:SI 1 "const_int_operand" "n")
14032 (match_operand:SI 2 "const_int_operand" "n"))]
14033 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
14034 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
14037 if (GET_MODE (operands[0]) != Pmode
14038 || GET_CODE (operands[1]) != CONST_INT
14039 || GET_CODE (operands[2]) != CONST_INT)
14041 if (! TARGET_SHMEDIA)
14042 operands[0] = force_reg (Pmode, operands[0]);
14045 (define_insn "prefetch_m2a"
14046 [(prefetch (match_operand:SI 0 "register_operand" "r")
14047 (match_operand:SI 1 "const_int_operand" "n")
14048 (match_operand:SI 2 "const_int_operand" "n"))]
14051 [(set_attr "type" "other")])
14053 (define_insn "alloco_i"
14054 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
14055 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
14061 if (GET_CODE (operands[0]) == PLUS)
14063 xops[0] = XEXP (operands[0], 0);
14064 xops[1] = XEXP (operands[0], 1);
14068 xops[0] = operands[0];
14069 xops[1] = const0_rtx;
14071 output_asm_insn (\"alloco %0, %1\", xops);
14074 [(set_attr "type" "other")])
14077 [(set (match_operand 0 "any_register_operand" "")
14078 (match_operand 1 "" ""))]
14079 "TARGET_SHMEDIA && reload_completed"
14080 [(set (match_dup 0) (match_dup 1))]
14085 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
14090 ; Stack Protector Patterns
14092 (define_expand "stack_protect_set"
14093 [(set (match_operand 0 "memory_operand" "")
14094 (match_operand 1 "memory_operand" ""))]
14097 if (TARGET_SHMEDIA)
14099 if (TARGET_SHMEDIA64)
14100 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
14102 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
14105 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
14110 (define_insn "stack_protect_set_si"
14111 [(set (match_operand:SI 0 "memory_operand" "=m")
14112 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14113 (set (match_scratch:SI 2 "=&r") (const_int 0))]
14115 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
14116 [(set_attr "type" "other")
14117 (set_attr "length" "6")])
14119 (define_insn "stack_protect_set_si_media"
14120 [(set (match_operand:SI 0 "memory_operand" "=m")
14121 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14122 (set (match_scratch:SI 2 "=&r") (const_int 0))]
14124 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
14125 [(set_attr "type" "other")
14126 (set_attr "length" "12")])
14128 (define_insn "stack_protect_set_di_media"
14129 [(set (match_operand:DI 0 "memory_operand" "=m")
14130 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14131 (set (match_scratch:DI 2 "=&r") (const_int 0))]
14133 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
14134 [(set_attr "type" "other")
14135 (set_attr "length" "12")])
14137 (define_expand "stack_protect_test"
14138 [(match_operand 0 "memory_operand" "")
14139 (match_operand 1 "memory_operand" "")
14140 (match_operand 2 "" "")]
14143 if (TARGET_SHMEDIA)
14145 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
14147 if (TARGET_SHMEDIA64)
14148 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
14151 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
14154 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
14158 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
14159 emit_jump_insn (gen_branch_true (operands[2]));
14165 (define_insn "stack_protect_test_si"
14166 [(set (reg:SI T_REG)
14167 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
14168 (match_operand:SI 1 "memory_operand" "m")]
14170 (set (match_scratch:SI 2 "=&r") (const_int 0))
14171 (set (match_scratch:SI 3 "=&r") (const_int 0))]
14173 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
14174 [(set_attr "type" "other")
14175 (set_attr "length" "10")])
14177 (define_insn "stack_protect_test_si_media"
14178 [(set (match_operand:SI 0 "register_operand" "=&r")
14179 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
14180 (match_operand:SI 2 "memory_operand" "m")]
14182 (set (match_scratch:SI 3 "=&r") (const_int 0))]
14184 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14185 [(set_attr "type" "other")
14186 (set_attr "length" "16")])
14188 (define_insn "stack_protect_test_di_media"
14189 [(set (match_operand:DI 0 "register_operand" "=&r")
14190 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
14191 (match_operand:DI 2 "memory_operand" "m")]
14193 (set (match_scratch:DI 3 "=&r") (const_int 0))]
14195 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14196 [(set_attr "type" "other")
14197 (set_attr "length" "16")])