1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
157 ;; These are used with unspec_volatile.
163 (UNSPECV_WINDOW_END 10)
164 (UNSPECV_CONST_END 11)
165 (UNSPECV_EH_RETURN 12)
168 ;; -------------------------------------------------------------------------
170 ;; -------------------------------------------------------------------------
175 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
176 (const (symbol_ref "sh_cpu_attr")))
178 (define_attr "endian" "big,little"
179 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
180 (const_string "little") (const_string "big"))))
182 ;; Indicate if the default fpu mode is single precision.
183 (define_attr "fpu_single" "yes,no"
184 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
185 (const_string "yes") (const_string "no"))))
187 (define_attr "fmovd" "yes,no"
188 (const (if_then_else (symbol_ref "TARGET_FMOVD")
189 (const_string "yes") (const_string "no"))))
191 (define_attr "pipe_model" "sh1,sh4,sh5media"
193 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
194 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
195 (const_string "sh1"))))
197 ;; cbranch conditional branch instructions
198 ;; jump unconditional jumps
199 ;; arith ordinary arithmetic
200 ;; arith3 a compound insn that behaves similarly to a sequence of
201 ;; three insns of type arith
202 ;; arith3b like above, but might end with a redirected branch
204 ;; load_si Likewise, SImode variant for general register.
205 ;; fload Likewise, but load to fp register.
207 ;; fstore floating point register to memory
208 ;; move general purpose register to register
209 ;; movi8 8-bit immediate to general purpose register
210 ;; mt_group other sh4 mt instructions
211 ;; fmove register to register, floating point
212 ;; smpy word precision integer multiply
213 ;; dmpy longword or doublelongword precision integer multiply
215 ;; pload load of pr reg, which can't be put into delay slot of rts
216 ;; prset copy register to pr reg, ditto
217 ;; pstore store of pr reg, which can't be put into delay slot of jsr
218 ;; prget copy pr to register, ditto
219 ;; pcload pc relative load of constant value
220 ;; pcfload Likewise, but load to fp register.
221 ;; pcload_si Likewise, SImode variant for general register.
222 ;; rte return from exception
223 ;; sfunc special function call with known used registers
224 ;; call function call
226 ;; fpscr_toggle toggle a bit in the fpscr
227 ;; fdiv floating point divide (or square root)
228 ;; gp_fpul move from general purpose register to fpul
229 ;; fpul_gp move from fpul to general purpose register
230 ;; mac_gp move from mac[lh] to general purpose register
231 ;; gp_mac move from general purpose register to mac[lh]
232 ;; mac_mem move from mac[lh] to memory
233 ;; mem_mac move from memory to mac[lh]
234 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
235 ;; ftrc_s fix_truncsfsi2_i4
236 ;; dfdiv double precision floating point divide (or square root)
237 ;; cwb ic_invalidate_line_i
238 ;; movua SH4a unaligned load
239 ;; fsrra square root reciprocal approximate
240 ;; fsca sine and cosine approximate
241 ;; tls_load load TLS related address
242 ;; arith_media SHmedia arithmetic, logical, and shift instructions
243 ;; cbranch_media SHmedia conditional branch instructions
244 ;; cmp_media SHmedia compare instructions
245 ;; dfdiv_media SHmedia double precision divide and square root
246 ;; dfmul_media SHmedia double precision multiply instruction
247 ;; dfparith_media SHmedia double precision floating point arithmetic
248 ;; dfpconv_media SHmedia double precision floating point conversions
249 ;; dmpy_media SHmedia longword multiply
250 ;; fcmp_media SHmedia floating point compare instructions
251 ;; fdiv_media SHmedia single precision divide and square root
252 ;; fload_media SHmedia floating point register load instructions
253 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
254 ;; fparith_media SHmedia single precision floating point arithmetic
255 ;; fpconv_media SHmedia single precision floating point conversions
256 ;; fstore_media SHmedia floating point register store instructions
257 ;; gettr_media SHmedia gettr instruction
258 ;; invalidate_line_media SHmedia invalidate_line sequence
259 ;; jump_media SHmedia unconditional branch instructions
260 ;; load_media SHmedia general register load instructions
261 ;; pt_media SHmedia pt instruction (expanded by assembler)
262 ;; ptabs_media SHmedia ptabs instruction
263 ;; store_media SHmedia general register store instructions
264 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
265 ;; mac_media SHmedia mac-style fixed point operations
266 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
267 ;; atrans_media SHmedia approximate transcendental functions
268 ;; ustore_media SHmedia unaligned stores
269 ;; nil no-op move, will be deleted.
272 "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"
273 (const_string "other"))
275 ;; We define a new attribute namely "insn_class".We use
276 ;; this for the DFA based pipeline description.
278 ;; mt_group SH4 "mt" group instructions.
280 ;; ex_group SH4 "ex" group instructions.
282 ;; ls_group SH4 "ls" group instructions.
285 (define_attr "insn_class"
286 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
287 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
288 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
289 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
290 (eq_attr "type" "cbranch,jump") (const_string "br_group")
291 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
292 (const_string "fe_group")
293 (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")]
294 (const_string "none")))
295 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
296 ;; so these do not belong in an insn group, although they are modeled
297 ;; with their own define_insn_reservations.
299 ;; Indicate what precision must be selected in fpscr for this insn, if any.
301 (define_attr "fp_mode" "single,double,none" (const_string "none"))
303 ;; Indicate if the fpu mode is set by this instruction
304 ;; "unknown" must have the value as "none" in fp_mode, and means
305 ;; that the instruction/abi has left the processor in an unknown
307 ;; "none" means that nothing has changed and no mode is set.
308 ;; This attribute is only used for the Renesas ABI.
309 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
311 ; If a conditional branch destination is within -252..258 bytes away
312 ; from the instruction it can be 2 bytes long. Something in the
313 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
314 ; branches are initially assumed to be 16 bytes long.
315 ; In machine_dependent_reorg, we split all branches that are longer than
318 ;; The maximum range used for SImode constant pool entries is 1018. A final
319 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
320 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
321 ;; instruction around the pool table, 2 bytes of alignment before the table,
322 ;; and 30 bytes of alignment after the table. That gives a maximum total
323 ;; pool size of 1058 bytes.
324 ;; Worst case code/pool content size ratio is 1:2 (using asms).
325 ;; Thus, in the worst case, there is one instruction in front of a maximum
326 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
327 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
328 ;; If we have a forward branch, the initial table will be put after the
329 ;; unconditional branch.
331 ;; ??? We could do much better by keeping track of the actual pcloads within
332 ;; the branch range and in the pcload range in front of the branch range.
334 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
336 (define_attr "short_cbranch_p" "no,yes"
337 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
339 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
341 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
343 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
345 ] (const_string "no")))
347 (define_attr "med_branch_p" "no,yes"
348 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
351 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
356 ] (const_string "no")))
358 (define_attr "med_cbranch_p" "no,yes"
359 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
362 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
367 ] (const_string "no")))
369 (define_attr "braf_branch_p" "no,yes"
370 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
372 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
375 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
380 ] (const_string "no")))
382 (define_attr "braf_cbranch_p" "no,yes"
383 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
385 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
388 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
393 ] (const_string "no")))
395 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
396 ; For wider ranges, we need a combination of a code and a data part.
397 ; If we can get a scratch register for a long range jump, the code
398 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
399 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
400 ; long; otherwise, it must be 6 bytes long.
402 ; All other instructions are two bytes long by default.
404 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
405 ;; but getattrtab doesn't understand this.
406 (define_attr "length" ""
407 (cond [(eq_attr "type" "cbranch")
408 (cond [(eq_attr "short_cbranch_p" "yes")
410 (eq_attr "med_cbranch_p" "yes")
412 (eq_attr "braf_cbranch_p" "yes")
414 ;; ??? using pc is not computed transitively.
415 (ne (match_dup 0) (match_dup 0))
417 (ne (symbol_ref ("flag_pic")) (const_int 0))
420 (eq_attr "type" "jump")
421 (cond [(eq_attr "med_branch_p" "yes")
423 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
425 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
427 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
428 (symbol_ref "code_for_indirect_jump_scratch"))))
429 (cond [(eq_attr "braf_branch_p" "yes")
431 (eq (symbol_ref "flag_pic") (const_int 0))
433 (ne (symbol_ref "TARGET_SH2") (const_int 0))
434 (const_int 10)] (const_int 18))
435 (eq_attr "braf_branch_p" "yes")
437 ;; ??? using pc is not computed transitively.
438 (ne (match_dup 0) (match_dup 0))
440 (ne (symbol_ref ("flag_pic")) (const_int 0))
443 (eq_attr "type" "pt_media")
444 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
445 (const_int 20) (const_int 12))
446 (and (eq_attr "type" "jump_media")
447 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
449 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
453 ;; DFA descriptions for the pipelines
456 (include "shmedia.md")
459 (include "predicates.md")
460 (include "constraints.md")
462 ;; Definitions for filling delay slots
464 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
466 ;; ??? This should be (nil) instead of (const_int 0)
467 (define_attr "hit_stack" "yes,no"
468 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
471 (const_string "yes")))
473 (define_attr "interrupt_function" "no,yes"
474 (const (symbol_ref "current_function_interrupt")))
476 (define_attr "in_delay_slot" "yes,no"
477 (cond [(eq_attr "type" "cbranch") (const_string "no")
478 (eq_attr "type" "pcload,pcload_si") (const_string "no")
479 (eq_attr "needs_delay_slot" "yes") (const_string "no")
480 (eq_attr "length" "2") (const_string "yes")
481 ] (const_string "no")))
483 (define_attr "cond_delay_slot" "yes,no"
484 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
485 ] (const_string "no")))
487 (define_attr "is_sfunc" ""
488 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
490 (define_attr "is_mac_media" ""
491 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
493 (define_attr "branch_zero" "yes,no"
494 (cond [(eq_attr "type" "!cbranch") (const_string "no")
495 (ne (symbol_ref "(next_active_insn (insn)\
496 == (prev_active_insn\
497 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
498 && get_attr_length (next_active_insn (insn)) == 2")
500 (const_string "yes")]
501 (const_string "no")))
503 ;; SH4 Double-precision computation with double-precision result -
504 ;; the two halves are ready at different times.
505 (define_attr "dfp_comp" "yes,no"
506 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
507 (const_string "no")))
509 ;; Insns for which the latency of a preceding fp insn is decreased by one.
510 (define_attr "late_fp_use" "yes,no" (const_string "no"))
511 ;; And feeding insns for which this relevant.
512 (define_attr "any_fp_comp" "yes,no"
513 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
514 (const_string "yes")]
515 (const_string "no")))
517 (define_attr "any_int_load" "yes,no"
518 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
519 (const_string "yes")]
520 (const_string "no")))
522 (define_attr "highpart" "user, ignore, extend, depend, must_split"
523 (const_string "user"))
526 (eq_attr "needs_delay_slot" "yes")
527 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
529 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
530 ;; and thus we can't put a pop instruction in its delay slot.
531 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
532 ;; instruction can go in the delay slot.
534 ;; Since a normal return (rts) implicitly uses the PR register,
535 ;; we can't allow PR register loads in an rts delay slot.
538 (eq_attr "type" "return")
539 [(and (eq_attr "in_delay_slot" "yes")
540 (ior (and (eq_attr "interrupt_function" "no")
541 (eq_attr "type" "!pload,prset"))
542 (and (eq_attr "interrupt_function" "yes")
544 (ne (symbol_ref "TARGET_SH3") (const_int 0))
545 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
547 ;; Since a call implicitly uses the PR register, we can't allow
548 ;; a PR register store in a jsr delay slot.
551 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
552 [(and (eq_attr "in_delay_slot" "yes")
553 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
555 ;; Say that we have annulled true branches, since this gives smaller and
556 ;; faster code when branches are predicted as not taken.
558 ;; ??? The non-annulled condition should really be "in_delay_slot",
559 ;; but insns that can be filled in non-annulled get priority over insns
560 ;; that can only be filled in anulled.
563 (and (eq_attr "type" "cbranch")
564 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
565 ;; SH2e has a hardware bug that pretty much prohibits the use of
566 ;; annuled delay slots.
567 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
568 (not (eq_attr "cpu" "sh2e"))) (nil)])
570 ;; -------------------------------------------------------------------------
571 ;; SImode signed integer comparisons
572 ;; -------------------------------------------------------------------------
576 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
577 (match_operand:SI 1 "arith_operand" "K08,r"))
581 [(set_attr "type" "mt_group")])
583 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
584 ;; That would still allow reload to create cmpi instructions, but would
585 ;; perhaps allow forcing the constant into a register when that is better.
586 ;; Probably should use r0 for mem/imm compares, but force constant into a
587 ;; register for pseudo/imm compares.
589 (define_insn "cmpeqsi_t"
591 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
592 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
598 [(set_attr "type" "mt_group")])
600 (define_insn "cmpgtsi_t"
602 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
603 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
608 [(set_attr "type" "mt_group")])
610 (define_insn "cmpgesi_t"
612 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
613 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
618 [(set_attr "type" "mt_group")])
620 ;; -------------------------------------------------------------------------
621 ;; SImode compare and branch
622 ;; -------------------------------------------------------------------------
624 (define_expand "cbranchsi4"
626 (if_then_else (match_operator 0 "comparison_operator"
627 [(match_operand:SI 1 "arith_operand" "")
628 (match_operand:SI 2 "arith_operand" "")])
629 (label_ref (match_operand 3 "" ""))
631 (clobber (reg:SI T_REG))]
633 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
635 ;; -------------------------------------------------------------------------
636 ;; SImode unsigned integer comparisons
637 ;; -------------------------------------------------------------------------
639 (define_insn_and_split "cmpgeusi_t"
641 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
642 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
645 "&& operands[0] == CONST0_RTX (SImode)"
649 emit_insn (gen_sett ());
652 [(set_attr "type" "mt_group")])
654 (define_insn "cmpgtusi_t"
656 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
657 (match_operand:SI 1 "arith_reg_operand" "r")))]
660 [(set_attr "type" "mt_group")])
662 ;; We save the compare operands in the cmpxx patterns and use them when
663 ;; we generate the branch.
665 (define_expand "cmpsi"
667 (compare (match_operand:SI 0 "cmpsi_operand" "")
668 (match_operand:SI 1 "arith_operand" "")))]
669 "TARGET_SH1 || TARGET_SHMEDIA"
672 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
673 && GET_CODE (operands[1]) != CONST_INT)
674 operands[0] = copy_to_mode_reg (SImode, operands[0]);
675 sh_compare_op0 = operands[0];
676 sh_compare_op1 = operands[1];
680 ;; -------------------------------------------------------------------------
681 ;; DImode compare and branch
682 ;; -------------------------------------------------------------------------
685 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
686 ;; Therefore, we aim to have a set of three branches that go straight to the
687 ;; destination, i.e. only one of them is taken at any one time.
688 ;; This mechanism should also be slightly better for the sh4-200.
690 (define_expand "cbranchdi4"
692 (if_then_else (match_operator 0 "comparison_operator"
693 [(match_operand:DI 1 "arith_operand" "")
694 (match_operand:DI 2 "arith_operand" "")])
695 (label_ref (match_operand 3 "" ""))
697 (clobber (match_dup 4))
698 (clobber (reg:SI T_REG))]
702 enum rtx_code comparison;
704 if (TARGET_EXPAND_CBRANCHDI4)
706 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
709 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
710 if (comparison != GET_CODE (operands[0]))
712 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
713 operands[4] = gen_rtx_SCRATCH (SImode);
716 (define_insn_and_split "cbranchdi4_i"
718 (if_then_else (match_operator 0 "comparison_operator"
719 [(match_operand:DI 1 "arith_operand" "r,r")
720 (match_operand:DI 2 "arith_operand" "rN,i")])
721 (label_ref (match_operand 3 "" ""))
723 (clobber (match_scratch:SI 4 "=X,&r"))
724 (clobber (reg:SI T_REG))]
727 "&& reload_completed"
731 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
736 ;; -------------------------------------------------------------------------
737 ;; DImode signed integer comparisons
738 ;; -------------------------------------------------------------------------
742 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
743 (match_operand:DI 1 "arith_operand" "r"))
746 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
748 [(set_attr "length" "6")
749 (set_attr "type" "arith3b")])
751 (define_insn "cmpeqdi_t"
753 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
754 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
757 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
758 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
759 [(set_attr "length" "6")
760 (set_attr "type" "arith3b")])
764 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
765 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
766 ;; If we applied this split when not optimizing, it would only be
767 ;; applied during the machine-dependent reorg, when no new basic blocks
769 "TARGET_SH1 && reload_completed && optimize"
770 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
771 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
772 (label_ref (match_dup 6))
774 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
779 = gen_rtx_REG (SImode,
780 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
782 = (operands[1] == const0_rtx
784 : gen_rtx_REG (SImode,
785 true_regnum (operands[1])
786 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
787 operands[4] = gen_lowpart (SImode, operands[0]);
788 operands[5] = gen_lowpart (SImode, operands[1]);
789 operands[6] = gen_label_rtx ();
792 (define_insn "cmpgtdi_t"
794 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
795 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
798 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
799 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
800 [(set_attr "length" "8")
801 (set_attr "type" "arith3")])
803 (define_insn "cmpgedi_t"
805 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
806 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
809 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
811 [(set_attr "length" "8,2")
812 (set_attr "type" "arith3,mt_group")])
814 ;; -------------------------------------------------------------------------
815 ;; DImode unsigned integer comparisons
816 ;; -------------------------------------------------------------------------
818 (define_insn "cmpgeudi_t"
820 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
821 (match_operand:DI 1 "arith_reg_operand" "r")))]
823 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
824 [(set_attr "length" "8")
825 (set_attr "type" "arith3")])
827 (define_insn "cmpgtudi_t"
829 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
830 (match_operand:DI 1 "arith_reg_operand" "r")))]
832 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
833 [(set_attr "length" "8")
834 (set_attr "type" "arith3")])
836 (define_insn "cmpeqsi_media"
837 [(set (match_operand:SI 0 "register_operand" "=r")
838 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
839 (match_operand:SI 2 "cmp_operand" "Nr")))]
842 [(set_attr "type" "cmp_media")])
844 (define_insn "cmpeqdi_media"
845 [(set (match_operand:SI 0 "register_operand" "=r")
846 (eq:SI (match_operand:DI 1 "register_operand" "%r")
847 (match_operand:DI 2 "cmp_operand" "Nr")))]
850 [(set_attr "type" "cmp_media")])
852 (define_insn "cmpgtsi_media"
853 [(set (match_operand:SI 0 "register_operand" "=r")
854 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
855 (match_operand:SI 2 "cmp_operand" "rN")))]
858 [(set_attr "type" "cmp_media")])
860 (define_insn "cmpgtdi_media"
861 [(set (match_operand:SI 0 "register_operand" "=r")
862 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
863 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
866 [(set_attr "type" "cmp_media")])
868 (define_insn "cmpgtusi_media"
869 [(set (match_operand:SI 0 "register_operand" "=r")
870 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
871 (match_operand:SI 2 "cmp_operand" "rN")))]
873 "cmpgtu %N1, %N2, %0"
874 [(set_attr "type" "cmp_media")])
876 (define_insn "cmpgtudi_media"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
879 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
881 "cmpgtu %N1, %N2, %0"
882 [(set_attr "type" "cmp_media")])
884 ; These two patterns are for combine.
885 (define_insn "*cmpne0sisi_media"
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
890 [(set_attr "type" "cmp_media")])
892 ;; We save the compare operands in the cmpxx patterns and use them when
893 ;; we generate the branch.
895 (define_expand "cmpdi"
897 (compare (match_operand:DI 0 "arith_operand" "")
898 (match_operand:DI 1 "arith_operand" "")))]
899 "TARGET_SH2 || TARGET_SHMEDIA"
902 sh_compare_op0 = operands[0];
903 sh_compare_op1 = operands[1];
906 ;; -------------------------------------------------------------------------
907 ;; Conditional move instructions
908 ;; -------------------------------------------------------------------------
910 ;; The insn names may seem reversed, but note that cmveq performs the move
911 ;; if op1 == 0, and cmvne does it if op1 != 0.
913 (define_insn "movdicc_false"
914 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
915 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
917 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
918 (match_operand:DI 3 "arith_reg_operand" "0")))]
921 [(set_attr "type" "arith_media")])
923 (define_insn "movdicc_true"
924 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
925 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
927 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
928 (match_operand:DI 3 "arith_reg_operand" "0")))]
931 [(set_attr "type" "arith_media")])
934 [(set (match_operand:DI 0 "arith_reg_dest" "")
935 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
936 [(match_operand:DI 1 "arith_reg_operand" "")
938 (match_operand:DI 2 "arith_reg_dest" "")
940 (set (match_dup 2) (match_dup 0))]
941 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
943 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
946 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
947 VOIDmode, operands[1], CONST0_RTX (DImode));
951 [(set (match_operand:DI 0 "general_movdst_operand" "")
952 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
953 (set (match_operand:DI 2 "arith_reg_dest" "")
954 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
955 [(match_operand:DI 3 "arith_reg_operand" "")
959 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
961 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
964 (define_expand "movdicc"
965 [(set (match_operand:DI 0 "register_operand" "")
966 (if_then_else:DI (match_operand 1 "comparison_operator" "")
967 (match_operand:DI 2 "register_operand" "")
968 (match_operand:DI 3 "register_operand" "")))]
972 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
973 && GET_MODE (sh_compare_op0) == DImode
974 && sh_compare_op1 == const0_rtx)
975 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
976 sh_compare_op0, sh_compare_op1);
984 tmp = gen_reg_rtx (DImode);
986 switch (GET_CODE (operands[1]))
989 emit_insn (gen_seq (tmp));
990 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
994 emit_insn (gen_seq (tmp));
995 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
999 emit_insn (gen_sgt (tmp));
1000 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1004 emit_insn (gen_slt (tmp));
1005 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1009 emit_insn (gen_slt (tmp));
1010 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1014 emit_insn (gen_sgt (tmp));
1015 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1019 emit_insn (gen_sgtu (tmp));
1020 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1024 emit_insn (gen_sltu (tmp));
1025 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1029 emit_insn (gen_sltu (tmp));
1030 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1034 emit_insn (gen_sgtu (tmp));
1035 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1039 emit_insn (gen_sunordered (tmp));
1040 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1044 emit_insn (gen_sunordered (tmp));
1045 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1062 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1063 ;; SImode to DImode.
1064 (define_insn "movsicc_false"
1065 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1066 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1068 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1069 (match_operand:SI 3 "arith_reg_operand" "0")))]
1072 [(set_attr "type" "arith_media")])
1074 (define_insn "movsicc_true"
1075 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1076 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1078 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1079 (match_operand:SI 3 "arith_reg_operand" "0")))]
1082 [(set_attr "type" "arith_media")])
1085 [(set (match_operand:SI 0 "arith_reg_dest" "")
1086 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1087 [(match_operand:SI 1 "arith_reg_operand" "")
1089 (match_operand:SI 2 "arith_reg_dest" "")
1091 (set (match_dup 2) (match_dup 0))]
1092 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1094 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1097 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1098 VOIDmode, operands[1], CONST0_RTX (SImode));
1102 [(set (match_operand:SI 0 "general_movdst_operand" "")
1103 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1104 (set (match_operand:SI 2 "arith_reg_dest" "")
1105 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1106 [(match_operand:SI 3 "arith_reg_operand" "")
1110 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1111 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1113 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1116 replace_rtx (operands[4], operands[0], operands[1]);
1120 [(set (match_operand 0 "any_register_operand" "")
1121 (match_operand 1 "any_register_operand" ""))
1122 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1123 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1124 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1125 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1126 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1127 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1128 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1129 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1130 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1131 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1132 && (REGNO_REG_CLASS (REGNO (operands[0]))
1133 == REGNO_REG_CLASS (REGNO (operands[2])))
1134 && (REGNO_REG_CLASS (REGNO (operands[1]))
1135 == REGNO_REG_CLASS (REGNO (operands[0])))"
1136 [(set (match_dup 0) (match_dup 3))
1137 (set (match_dup 4) (match_dup 5))]
1141 rtx replacements[4];
1143 /* We want to replace occurrences of operands[0] with operands[1] and
1144 operands[2] with operands[0] in operands[4]/operands[5].
1145 Doing just two replace_rtx calls naively would result in the second
1146 replacement undoing all that the first did if operands[1] and operands[2]
1147 are identical, so we must do this simultaneously. */
1148 replacements[0] = operands[0];
1149 replacements[1] = operands[1];
1150 replacements[2] = operands[2];
1151 replacements[3] = operands[0];
1152 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1153 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1154 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1157 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1158 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1159 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1160 /* The operands array is aliased to recog_data.operand, which gets
1161 clobbered by extract_insn, so finish with it now. */
1162 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1163 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1164 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1165 always uses emit_insn. */
1166 /* Check that we don't violate matching constraints or earlyclobbers. */
1167 extract_insn (emit_insn (set1));
1168 if (! constrain_operands (1))
1170 extract_insn (emit (set2));
1171 if (! constrain_operands (1))
1175 tmp = replacements[0];
1176 replacements[0] = replacements[1];
1177 replacements[1] = tmp;
1178 tmp = replacements[2];
1179 replacements[2] = replacements[3];
1180 replacements[3] = tmp;
1181 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1182 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1183 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1189 ;; The register allocator is rather clumsy in handling multi-way conditional
1190 ;; moves, so allow the combiner to make them, and we split them up after
1192 (define_insn_and_split "*movsicc_umin"
1193 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1194 (umin:SI (if_then_else:SI
1195 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1197 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1198 (match_operand:SI 3 "register_operand" "0"))
1199 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1200 (clobber (match_scratch:SI 5 "=&r"))]
1201 "TARGET_SHMEDIA && no_new_pseudos"
1203 "TARGET_SHMEDIA && reload_completed"
1207 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1209 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1210 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1215 (define_insn "*movsicc_t_false"
1216 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1217 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1218 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1219 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1220 "TARGET_PRETEND_CMOVE
1221 && (arith_reg_operand (operands[1], SImode)
1222 || (immediate_operand (operands[1], SImode)
1223 && satisfies_constraint_I08 (operands[1])))"
1224 "bt 0f\;mov %1,%0\\n0:"
1225 [(set_attr "type" "mt_group,arith") ;; poor approximation
1226 (set_attr "length" "4")])
1228 (define_insn "*movsicc_t_true"
1229 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1230 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1231 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1232 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1233 "TARGET_PRETEND_CMOVE
1234 && (arith_reg_operand (operands[1], SImode)
1235 || (immediate_operand (operands[1], SImode)
1236 && satisfies_constraint_I08 (operands[1])))"
1237 "bf 0f\;mov %1,%0\\n0:"
1238 [(set_attr "type" "mt_group,arith") ;; poor approximation
1239 (set_attr "length" "4")])
1241 (define_expand "movsicc"
1242 [(set (match_operand:SI 0 "arith_reg_dest" "")
1243 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1244 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1245 (match_operand:SI 3 "arith_reg_operand" "")))]
1246 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1249 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1250 && GET_MODE (sh_compare_op0) == SImode
1252 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1253 && sh_compare_op1 == const0_rtx)
1254 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1255 sh_compare_op0, sh_compare_op1);
1256 else if (TARGET_PRETEND_CMOVE)
1258 enum rtx_code code = GET_CODE (operands[1]);
1259 enum rtx_code new_code = code;
1262 if (! currently_expanding_to_rtl)
1266 case LT: case LE: case LEU: case LTU:
1267 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1270 new_code = reverse_condition (code);
1272 case EQ: case GT: case GE: case GEU: case GTU:
1277 tmp = prepare_scc_operands (new_code);
1278 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1288 tmp = gen_reg_rtx (SImode);
1290 switch (GET_CODE (operands[1]))
1293 emit_insn (gen_seq (tmp));
1294 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1298 emit_insn (gen_seq (tmp));
1299 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1303 emit_insn (gen_sgt (tmp));
1304 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1308 emit_insn (gen_slt (tmp));
1309 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1313 emit_insn (gen_slt (tmp));
1314 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1318 emit_insn (gen_sgt (tmp));
1319 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1323 emit_insn (gen_sgtu (tmp));
1324 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1328 emit_insn (gen_sltu (tmp));
1329 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1333 emit_insn (gen_sltu (tmp));
1334 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1338 emit_insn (gen_sgtu (tmp));
1339 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1343 emit_insn (gen_sunordered (tmp));
1344 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1348 emit_insn (gen_sunordered (tmp));
1349 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1366 (define_expand "movqicc"
1367 [(set (match_operand:QI 0 "register_operand" "")
1368 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1369 (match_operand:QI 2 "register_operand" "")
1370 (match_operand:QI 3 "register_operand" "")))]
1374 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1375 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1376 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1377 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1381 ;; -------------------------------------------------------------------------
1382 ;; Addition instructions
1383 ;; -------------------------------------------------------------------------
1385 (define_expand "adddi3"
1386 [(set (match_operand:DI 0 "arith_reg_operand" "")
1387 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1388 (match_operand:DI 2 "arith_operand" "")))]
1394 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1396 operands[2] = force_reg (DImode, operands[2]);
1397 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1402 (define_insn "*adddi3_media"
1403 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1404 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1405 (match_operand:DI 2 "arith_operand" "r,I10")))]
1410 [(set_attr "type" "arith_media")])
1412 (define_insn "*adddisi3_media"
1413 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1414 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1415 (match_operand:DI 2 "arith_operand" "r,I10")))]
1420 [(set_attr "type" "arith_media")
1421 (set_attr "highpart" "ignore")])
1423 (define_insn "adddi3z_media"
1424 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1426 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1427 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1429 "addz.l %1, %N2, %0"
1430 [(set_attr "type" "arith_media")
1431 (set_attr "highpart" "ignore")])
1433 (define_insn "adddi3_compact"
1434 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1435 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1436 (match_operand:DI 2 "arith_reg_operand" "r")))
1437 (clobber (reg:SI T_REG))]
1440 [(set_attr "length" "6")])
1443 [(set (match_operand:DI 0 "arith_reg_dest" "")
1444 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1445 (match_operand:DI 2 "arith_reg_operand" "")))
1446 (clobber (reg:SI T_REG))]
1447 "TARGET_SH1 && reload_completed"
1451 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1452 high0 = gen_rtx_REG (SImode,
1453 true_regnum (operands[0])
1454 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1455 high2 = gen_rtx_REG (SImode,
1456 true_regnum (operands[2])
1457 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1458 emit_insn (gen_clrt ());
1459 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1460 emit_insn (gen_addc1 (high0, high0, high2));
1465 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1466 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1467 (match_operand:SI 2 "arith_reg_operand" "r"))
1470 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1473 [(set_attr "type" "arith")])
1475 (define_insn "addc1"
1476 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1477 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1478 (match_operand:SI 2 "arith_reg_operand" "r"))
1480 (clobber (reg:SI T_REG))]
1483 [(set_attr "type" "arith")])
1485 (define_expand "addsi3"
1486 [(set (match_operand:SI 0 "arith_reg_operand" "")
1487 (plus:SI (match_operand:SI 1 "arith_operand" "")
1488 (match_operand:SI 2 "arith_operand" "")))]
1493 operands[1] = force_reg (SImode, operands[1]);
1496 (define_insn "addsi3_media"
1497 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1498 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1499 (match_operand:SI 2 "arith_operand" "r,I10")))]
1504 [(set_attr "type" "arith_media")
1505 (set_attr "highpart" "ignore")])
1507 (define_insn "addsidi3_media"
1508 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1509 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1511 (match_operand:SI 2 "arith_operand"
1517 [(set_attr "type" "arith_media")
1518 (set_attr "highpart" "ignore")])
1520 (define_insn "*addsi3_compact"
1521 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1522 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1523 (match_operand:SI 2 "arith_operand" "rI08")))]
1526 [(set_attr "type" "arith")])
1528 ;; -------------------------------------------------------------------------
1529 ;; Subtraction instructions
1530 ;; -------------------------------------------------------------------------
1532 (define_expand "subdi3"
1533 [(set (match_operand:DI 0 "arith_reg_operand" "")
1534 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1535 (match_operand:DI 2 "arith_reg_operand" "")))]
1541 operands[1] = force_reg (DImode, operands[1]);
1542 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1547 (define_insn "*subdi3_media"
1548 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1549 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1550 (match_operand:DI 2 "arith_reg_operand" "r")))]
1553 [(set_attr "type" "arith_media")])
1555 (define_insn "subdisi3_media"
1556 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1557 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1558 (match_operand:DI 2 "arith_reg_operand" "r")))]
1561 [(set_attr "type" "arith_media")
1562 (set_attr "highpart" "ignore")])
1564 (define_insn "subdi3_compact"
1565 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1566 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1567 (match_operand:DI 2 "arith_reg_operand" "r")))
1568 (clobber (reg:SI T_REG))]
1571 [(set_attr "length" "6")])
1574 [(set (match_operand:DI 0 "arith_reg_dest" "")
1575 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1576 (match_operand:DI 2 "arith_reg_operand" "")))
1577 (clobber (reg:SI T_REG))]
1578 "TARGET_SH1 && reload_completed"
1582 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1583 high0 = gen_rtx_REG (SImode,
1584 true_regnum (operands[0])
1585 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1586 high2 = gen_rtx_REG (SImode,
1587 true_regnum (operands[2])
1588 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1589 emit_insn (gen_clrt ());
1590 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1591 emit_insn (gen_subc1 (high0, high0, high2));
1596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1597 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1598 (match_operand:SI 2 "arith_reg_operand" "r"))
1601 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1606 [(set_attr "type" "arith")])
1608 (define_insn "subc1"
1609 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1610 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1611 (match_operand:SI 2 "arith_reg_operand" "r"))
1613 (clobber (reg:SI T_REG))]
1616 [(set_attr "type" "arith")])
1618 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1619 ;; pattern for this case. This helps multimedia applications that compute
1620 ;; the sum of absolute differences.
1621 (define_insn "mov_neg_si_t"
1622 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1625 [(set_attr "type" "arith")])
1627 (define_insn "*subsi3_internal"
1628 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1629 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630 (match_operand:SI 2 "arith_reg_operand" "r")))]
1633 [(set_attr "type" "arith")])
1635 (define_insn_and_split "*subsi3_media"
1636 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1637 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1638 (match_operand:SI 2 "extend_reg_operand" "r")))]
1640 && (operands[1] != constm1_rtx
1641 || (GET_CODE (operands[2]) != TRUNCATE
1642 && GET_CODE (operands[2]) != SUBREG))"
1644 "operands[1] == constm1_rtx"
1645 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1647 [(set_attr "type" "arith_media")
1648 (set_attr "highpart" "ignore")])
1651 [(set (match_operand:SI 0 "arith_reg_dest" "")
1652 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1653 "general_extend_operand"
1655 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1656 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1657 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1661 [(set (match_operand:SI 0 "arith_reg_dest" "")
1662 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1663 "general_extend_operand"
1665 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1666 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1667 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1669 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1670 ;; will sometimes save one instruction. Otherwise we might get
1671 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1674 (define_expand "subsi3"
1675 [(set (match_operand:SI 0 "arith_reg_operand" "")
1676 (minus:SI (match_operand:SI 1 "arith_operand" "")
1677 (match_operand:SI 2 "arith_reg_operand" "")))]
1681 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1683 emit_insn (gen_negsi2 (operands[0], operands[2]));
1684 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1689 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1691 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1692 operands[1] = force_reg (SImode, operands[1]);
1696 ;; -------------------------------------------------------------------------
1697 ;; Division instructions
1698 ;; -------------------------------------------------------------------------
1700 ;; We take advantage of the library routines which don't clobber as many
1701 ;; registers as a normal function call would.
1703 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1704 ;; also has an effect on the register that holds the address of the sfunc.
1705 ;; To make this work, we have an extra dummy insn that shows the use
1706 ;; of this register for reorg.
1708 (define_insn "use_sfunc_addr"
1709 [(set (reg:SI PR_REG)
1710 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1711 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1713 [(set_attr "length" "0")])
1715 (define_insn "udivsi3_sh2a"
1716 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1717 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1718 (match_operand:SI 2 "arith_reg_operand" "z")))]
1721 [(set_attr "type" "arith")
1722 (set_attr "in_delay_slot" "no")])
1724 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1725 ;; hard register 0. If we used hard register 0, then the next instruction
1726 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1727 ;; gets allocated to a stack slot that needs its address reloaded, then
1728 ;; there is nothing to prevent reload from using r0 to reload the address.
1729 ;; This reload would clobber the value in r0 we are trying to store.
1730 ;; If we let reload allocate r0, then this problem can never happen.
1732 (define_insn "udivsi3_i1"
1733 [(set (match_operand:SI 0 "register_operand" "=z")
1734 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1735 (clobber (reg:SI T_REG))
1736 (clobber (reg:SI PR_REG))
1737 (clobber (reg:SI R4_REG))
1738 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1739 "TARGET_SH1 && ! TARGET_SH4"
1741 [(set_attr "type" "sfunc")
1742 (set_attr "needs_delay_slot" "yes")])
1744 ; Since shmedia-nofpu code could be linked against shcompact code, and
1745 ; the udivsi3 libcall has the same name, we must consider all registers
1746 ; clobbered that are in the union of the registers clobbered by the
1747 ; shmedia and the shcompact implementation. Note, if the shcompact
1748 ; implementation actually used shcompact code, we'd need to clobber
1749 ; also r23 and fr23.
1750 (define_insn "udivsi3_i1_media"
1751 [(set (match_operand:SI 0 "register_operand" "=z")
1752 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1753 (clobber (reg:SI T_MEDIA_REG))
1754 (clobber (reg:SI PR_MEDIA_REG))
1755 (clobber (reg:SI R20_REG))
1756 (clobber (reg:SI R21_REG))
1757 (clobber (reg:SI R22_REG))
1758 (clobber (reg:DI TR0_REG))
1759 (clobber (reg:DI TR1_REG))
1760 (clobber (reg:DI TR2_REG))
1761 (use (match_operand 1 "target_operand" "b"))]
1762 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1764 [(set_attr "type" "sfunc")
1765 (set_attr "needs_delay_slot" "yes")])
1767 (define_expand "udivsi3_i4_media"
1769 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1771 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1772 (set (match_dup 5) (float:DF (match_dup 3)))
1773 (set (match_dup 6) (float:DF (match_dup 4)))
1774 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1775 (set (match_dup 8) (fix:DI (match_dup 7)))
1776 (set (match_operand:SI 0 "register_operand" "")
1777 (truncate:SI (match_dup 8)))]
1778 "TARGET_SHMEDIA_FPU"
1781 operands[3] = gen_reg_rtx (DImode);
1782 operands[4] = gen_reg_rtx (DImode);
1783 operands[5] = gen_reg_rtx (DFmode);
1784 operands[6] = gen_reg_rtx (DFmode);
1785 operands[7] = gen_reg_rtx (DFmode);
1786 operands[8] = gen_reg_rtx (DImode);
1789 (define_insn "udivsi3_i4"
1790 [(set (match_operand:SI 0 "register_operand" "=y")
1791 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1792 (clobber (reg:SI T_REG))
1793 (clobber (reg:SI PR_REG))
1794 (clobber (reg:DF DR0_REG))
1795 (clobber (reg:DF DR2_REG))
1796 (clobber (reg:DF DR4_REG))
1797 (clobber (reg:SI R0_REG))
1798 (clobber (reg:SI R1_REG))
1799 (clobber (reg:SI R4_REG))
1800 (clobber (reg:SI R5_REG))
1801 (use (reg:PSI FPSCR_REG))
1802 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1803 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1805 [(set_attr "type" "sfunc")
1806 (set_attr "fp_mode" "double")
1807 (set_attr "needs_delay_slot" "yes")])
1809 (define_insn "udivsi3_i4_single"
1810 [(set (match_operand:SI 0 "register_operand" "=y")
1811 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1812 (clobber (reg:SI T_REG))
1813 (clobber (reg:SI PR_REG))
1814 (clobber (reg:DF DR0_REG))
1815 (clobber (reg:DF DR2_REG))
1816 (clobber (reg:DF DR4_REG))
1817 (clobber (reg:SI R0_REG))
1818 (clobber (reg:SI R1_REG))
1819 (clobber (reg:SI R4_REG))
1820 (clobber (reg:SI R5_REG))
1821 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1822 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1824 [(set_attr "type" "sfunc")
1825 (set_attr "needs_delay_slot" "yes")])
1827 (define_insn "udivsi3_i4_int"
1828 [(set (match_operand:SI 0 "register_operand" "=z")
1829 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1830 (clobber (reg:SI T_REG))
1831 (clobber (reg:SI R1_REG))
1832 (clobber (reg:SI PR_REG))
1833 (clobber (reg:SI MACH_REG))
1834 (clobber (reg:SI MACL_REG))
1835 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1838 [(set_attr "type" "sfunc")
1839 (set_attr "needs_delay_slot" "yes")])
1842 (define_expand "udivsi3"
1843 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1844 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1845 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1846 (parallel [(set (match_operand:SI 0 "register_operand" "")
1847 (udiv:SI (reg:SI R4_REG)
1849 (clobber (reg:SI T_REG))
1850 (clobber (reg:SI PR_REG))
1851 (clobber (reg:SI R4_REG))
1852 (use (match_dup 3))])]
1858 operands[3] = gen_reg_rtx (Pmode);
1859 /* Emit the move of the address to a pseudo outside of the libcall. */
1860 if (TARGET_DIVIDE_CALL_TABLE)
1862 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1863 that causes problems when the divide code is supposed to come from a
1864 separate library. Division by zero is undefined, so dividing 1 can be
1865 implemented by comparing with the divisor. */
1866 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1868 emit_insn (gen_cmpsi (operands[1], operands[2]));
1869 emit_insn (gen_sgeu (operands[0]));
1872 else if (operands[2] == const0_rtx)
1874 emit_move_insn (operands[0], operands[2]);
1877 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1878 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1880 else if (TARGET_DIVIDE_CALL_FP)
1882 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1883 if (TARGET_FPU_SINGLE)
1884 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1886 last = gen_udivsi3_i4 (operands[0], operands[3]);
1888 else if (TARGET_SHMEDIA_FPU)
1890 operands[1] = force_reg (SImode, operands[1]);
1891 operands[2] = force_reg (SImode, operands[2]);
1892 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1895 else if (TARGET_SH2A)
1897 operands[1] = force_reg (SImode, operands[1]);
1898 operands[2] = force_reg (SImode, operands[2]);
1899 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1902 else if (TARGET_SH5)
1904 function_symbol (operands[3],
1905 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1909 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1910 else if (TARGET_FPU_ANY)
1911 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1913 last = gen_udivsi3_i1 (operands[0], operands[3]);
1917 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1918 last = gen_udivsi3_i1 (operands[0], operands[3]);
1920 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1921 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1922 last = emit_insn (last);
1923 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1924 invariant code motion can move it. */
1925 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1926 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1930 (define_insn "divsi3_sh2a"
1931 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1932 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1933 (match_operand:SI 2 "arith_reg_operand" "z")))]
1936 [(set_attr "type" "arith")
1937 (set_attr "in_delay_slot" "no")])
1939 (define_insn "divsi3_i1"
1940 [(set (match_operand:SI 0 "register_operand" "=z")
1941 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942 (clobber (reg:SI T_REG))
1943 (clobber (reg:SI PR_REG))
1944 (clobber (reg:SI R1_REG))
1945 (clobber (reg:SI R2_REG))
1946 (clobber (reg:SI R3_REG))
1947 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1948 "TARGET_SH1 && ! TARGET_SH4"
1950 [(set_attr "type" "sfunc")
1951 (set_attr "needs_delay_slot" "yes")])
1953 (define_insn "divsi3_i1_media"
1954 [(set (match_operand:SI 0 "register_operand" "=z")
1955 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956 (clobber (reg:SI T_MEDIA_REG))
1957 (clobber (reg:SI PR_MEDIA_REG))
1958 (clobber (reg:SI R1_REG))
1959 (clobber (reg:SI R20_REG))
1960 (clobber (reg:SI R21_REG))
1961 (clobber (reg:SI TR0_REG))
1962 (use (match_operand 1 "target_operand" "b"))]
1963 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1965 [(set_attr "type" "sfunc")])
1967 (define_insn "divsi3_media_2"
1968 [(set (match_operand:SI 0 "register_operand" "=z")
1969 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970 (clobber (reg:SI T_MEDIA_REG))
1971 (clobber (reg:SI PR_MEDIA_REG))
1972 (clobber (reg:SI R1_REG))
1973 (clobber (reg:SI R21_REG))
1974 (clobber (reg:SI TR0_REG))
1975 (use (reg:SI R20_REG))
1976 (use (match_operand 1 "target_operand" "b"))]
1977 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1979 [(set_attr "type" "sfunc")])
1981 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1982 ;; hard reg clobbers and data dependencies that we need when we want
1983 ;; to rematerialize the division into a call.
1984 (define_insn_and_split "divsi_inv_call"
1985 [(set (match_operand:SI 0 "register_operand" "=r")
1986 (div:SI (match_operand:SI 1 "register_operand" "r")
1987 (match_operand:SI 2 "register_operand" "r")))
1988 (clobber (reg:SI R4_REG))
1989 (clobber (reg:SI R5_REG))
1990 (clobber (reg:SI T_MEDIA_REG))
1991 (clobber (reg:SI PR_MEDIA_REG))
1992 (clobber (reg:SI R1_REG))
1993 (clobber (reg:SI R21_REG))
1994 (clobber (reg:SI TR0_REG))
1995 (clobber (reg:SI R20_REG))
1996 (use (match_operand:SI 3 "register_operand" "r"))]
1999 "&& (high_life_started || reload_completed)"
2000 [(set (match_dup 0) (match_dup 3))]
2002 [(set_attr "highpart" "must_split")])
2004 ;; This is the combiner pattern for -mdiv=inv:call .
2005 (define_insn_and_split "*divsi_inv_call_combine"
2006 [(set (match_operand:SI 0 "register_operand" "=z")
2007 (div:SI (match_operand:SI 1 "register_operand" "r")
2008 (match_operand:SI 2 "register_operand" "r")))
2009 (clobber (reg:SI R4_REG))
2010 (clobber (reg:SI R5_REG))
2011 (clobber (reg:SI T_MEDIA_REG))
2012 (clobber (reg:SI PR_MEDIA_REG))
2013 (clobber (reg:SI R1_REG))
2014 (clobber (reg:SI R21_REG))
2015 (clobber (reg:SI TR0_REG))
2016 (clobber (reg:SI R20_REG))
2017 (use (unspec:SI [(match_dup 1)
2018 (match_operand:SI 3 "" "")
2019 (unspec:SI [(match_operand:SI 4 "" "")
2021 (match_operand:DI 5 "" "")]
2023 (match_operand:DI 6 "" "")
2026 UNSPEC_DIV_INV_M3))]
2029 "&& (high_life_started || reload_completed)"
2033 const char *name = sh_divsi3_libfunc;
2034 enum sh_function_kind kind = SFUNC_GOT;
2037 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2038 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2039 while (TARGET_DIVIDE_INV_CALL2)
2041 rtx x = operands[3];
2043 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2045 x = XVECEXP (x, 0, 0);
2046 name = \"__sdivsi3_2\";
2047 kind = SFUNC_STATIC;
2048 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2051 sym = function_symbol (NULL, name, kind);
2052 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2055 [(set_attr "highpart" "must_split")])
2057 (define_expand "divsi3_i4_media"
2058 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2059 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2060 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2061 (set (match_operand:SI 0 "register_operand" "=r")
2062 (fix:SI (match_dup 5)))]
2063 "TARGET_SHMEDIA_FPU"
2066 operands[3] = gen_reg_rtx (DFmode);
2067 operands[4] = gen_reg_rtx (DFmode);
2068 operands[5] = gen_reg_rtx (DFmode);
2071 (define_insn "divsi3_i4"
2072 [(set (match_operand:SI 0 "register_operand" "=y")
2073 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2074 (clobber (reg:SI PR_REG))
2075 (clobber (reg:DF DR0_REG))
2076 (clobber (reg:DF DR2_REG))
2077 (use (reg:PSI FPSCR_REG))
2078 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2079 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2081 [(set_attr "type" "sfunc")
2082 (set_attr "fp_mode" "double")
2083 (set_attr "needs_delay_slot" "yes")])
2085 (define_insn "divsi3_i4_single"
2086 [(set (match_operand:SI 0 "register_operand" "=y")
2087 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2088 (clobber (reg:SI PR_REG))
2089 (clobber (reg:DF DR0_REG))
2090 (clobber (reg:DF DR2_REG))
2091 (clobber (reg:SI R2_REG))
2092 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2095 [(set_attr "type" "sfunc")
2096 (set_attr "needs_delay_slot" "yes")])
2098 (define_insn "divsi3_i4_int"
2099 [(set (match_operand:SI 0 "register_operand" "=z")
2100 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2101 (clobber (reg:SI T_REG))
2102 (clobber (reg:SI PR_REG))
2103 (clobber (reg:SI R1_REG))
2104 (clobber (reg:SI MACH_REG))
2105 (clobber (reg:SI MACL_REG))
2106 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2109 [(set_attr "type" "sfunc")
2110 (set_attr "needs_delay_slot" "yes")])
2112 (define_expand "divsi3"
2113 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2114 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2115 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2116 (parallel [(set (match_operand:SI 0 "register_operand" "")
2117 (div:SI (reg:SI R4_REG)
2119 (clobber (reg:SI T_REG))
2120 (clobber (reg:SI PR_REG))
2121 (clobber (reg:SI R1_REG))
2122 (clobber (reg:SI R2_REG))
2123 (clobber (reg:SI R3_REG))
2124 (use (match_dup 3))])]
2130 operands[3] = gen_reg_rtx (Pmode);
2131 /* Emit the move of the address to a pseudo outside of the libcall. */
2132 if (TARGET_DIVIDE_CALL_TABLE)
2134 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2135 last = gen_divsi3_i4_int (operands[0], operands[3]);
2137 else if (TARGET_DIVIDE_CALL_FP)
2139 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2140 if (TARGET_FPU_SINGLE)
2141 last = gen_divsi3_i4_single (operands[0], operands[3]);
2143 last = gen_divsi3_i4 (operands[0], operands[3]);
2145 else if (TARGET_SH2A)
2147 operands[1] = force_reg (SImode, operands[1]);
2148 operands[2] = force_reg (SImode, operands[2]);
2149 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2152 else if (TARGET_DIVIDE_INV)
2154 rtx dividend = operands[1];
2155 rtx divisor = operands[2];
2157 rtx nsb_res = gen_reg_rtx (DImode);
2158 rtx norm64 = gen_reg_rtx (DImode);
2159 rtx tab_ix = gen_reg_rtx (DImode);
2160 rtx norm32 = gen_reg_rtx (SImode);
2161 rtx i92 = force_reg (DImode, GEN_INT (92));
2162 rtx scratch0a = gen_reg_rtx (DImode);
2163 rtx scratch0b = gen_reg_rtx (DImode);
2164 rtx inv0 = gen_reg_rtx (SImode);
2165 rtx scratch1a = gen_reg_rtx (DImode);
2166 rtx scratch1b = gen_reg_rtx (DImode);
2167 rtx shift = gen_reg_rtx (DImode);
2169 rtx inv1 = gen_reg_rtx (SImode);
2170 rtx scratch2a = gen_reg_rtx (DImode);
2171 rtx scratch2b = gen_reg_rtx (SImode);
2172 rtx inv2 = gen_reg_rtx (SImode);
2173 rtx scratch3a = gen_reg_rtx (DImode);
2174 rtx scratch3b = gen_reg_rtx (DImode);
2175 rtx scratch3c = gen_reg_rtx (DImode);
2176 rtx scratch3d = gen_reg_rtx (SImode);
2177 rtx scratch3e = gen_reg_rtx (DImode);
2178 rtx result = gen_reg_rtx (SImode);
2180 if (! arith_reg_or_0_operand (dividend, SImode))
2181 dividend = force_reg (SImode, dividend);
2182 if (! arith_reg_operand (divisor, SImode))
2183 divisor = force_reg (SImode, divisor);
2184 if (flag_pic && Pmode != DImode)
2186 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2187 tab_base = gen_datalabel_ref (tab_base);
2188 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2192 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2193 tab_base = gen_datalabel_ref (tab_base);
2194 tab_base = force_reg (DImode, tab_base);
2196 if (TARGET_DIVIDE_INV20U)
2197 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2199 i2p27 = GEN_INT (0);
2200 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2201 i43 = force_reg (DImode, GEN_INT (43));
2204 emit_insn (gen_nsbdi (nsb_res,
2205 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2206 emit_insn (gen_ashldi3_media (norm64,
2207 gen_rtx_SUBREG (DImode, divisor, 0),
2209 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2210 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2211 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2212 inv0, scratch0a, scratch0b,
2213 scratch1a, scratch1b));
2214 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2215 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2217 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2219 scratch3a, scratch3b, scratch3c,
2220 scratch2a, scratch2b, scratch3d, scratch3e));
2221 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2222 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2223 else if (TARGET_DIVIDE_INV_FP)
2224 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2225 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2226 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2227 gen_reg_rtx (DFmode)));
2229 emit_move_insn (operands[0], result);
2232 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2234 operands[1] = force_reg (SImode, operands[1]);
2235 operands[2] = force_reg (SImode, operands[2]);
2236 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2239 else if (TARGET_SH5)
2241 if (TARGET_DIVIDE_CALL2)
2243 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2244 tab_base = gen_datalabel_ref (tab_base);
2245 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2247 if (TARGET_FPU_ANY && TARGET_SH1)
2248 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2249 else if (TARGET_DIVIDE_CALL2)
2250 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2252 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2255 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2256 (operands[0], operands[3]));
2257 else if (TARGET_FPU_ANY)
2258 last = gen_divsi3_i4_single (operands[0], operands[3]);
2260 last = gen_divsi3_i1 (operands[0], operands[3]);
2264 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2265 last = gen_divsi3_i1 (operands[0], operands[3]);
2267 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2268 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2269 last = emit_insn (last);
2270 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2271 invariant code motion can move it. */
2272 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2273 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2277 ;; operands: scratch, tab_base, tab_ix
2278 ;; These are unspecs because we could generate an indexed addressing mode
2279 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2280 ;; confuse reload. See PR27117.
2282 (define_insn "divsi_inv_qitable"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2285 (match_operand:DI 2 "register_operand" "r")]
2286 UNSPEC_DIV_INV_TABLE)))]
2290 [(set_attr "type" "load_media")
2291 (set_attr "highpart" "user")])
2293 ;; operands: scratch, tab_base, tab_ix
2294 (define_insn "divsi_inv_hitable"
2295 [(set (match_operand:DI 0 "register_operand" "=r")
2296 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2297 (match_operand:DI 2 "register_operand" "r")]
2298 UNSPEC_DIV_INV_TABLE)))]
2302 [(set_attr "type" "load_media")
2303 (set_attr "highpart" "user")])
2305 ;; operands: inv0, tab_base, tab_ix, norm32
2306 ;; scratch equiv in sdivsi3_2: r19, r21
2307 (define_expand "divsi_inv_m0"
2308 [(set (match_operand:SI 0 "register_operand" "=r")
2309 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2310 (match_operand:DI 2 "register_operand" "r")
2311 (match_operand:SI 3 "register_operand" "r")]
2313 (clobber (match_operand:DI 4 "register_operand" "=r"))
2314 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2322 ldx.ub r20, r21, r19 // u0.8
2324 muls.l r25, r19, r19 // s2.38
2325 ldx.w r20, r21, r21 // s2.14
2326 shari r19, 24, r19 // truncate to s2.14
2327 sub r21, r19, r19 // some 11 bit inverse in s1.14
2330 rtx inv0 = operands[0];
2331 rtx tab_base = operands[1];
2332 rtx tab_ix = operands[2];
2333 rtx norm32 = operands[3];
2334 rtx scratch0 = operands[4];
2335 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2336 rtx scratch1 = operands[5];
2338 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2339 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2340 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2341 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2342 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2343 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2347 ;; operands: inv1, tab_base, tab_ix, norm32
2348 (define_insn_and_split "divsi_inv_m1"
2349 [(set (match_operand:SI 0 "register_operand" "=r")
2350 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2351 (match_operand:DI 2 "register_operand" "r")
2352 (match_operand:SI 3 "register_operand" "r")]
2354 (clobber (match_operand:SI 4 "register_operand" "=r"))
2355 (clobber (match_operand:DI 5 "register_operand" "=r"))
2356 (clobber (match_operand:DI 6 "register_operand" "=r"))
2357 (clobber (match_operand:DI 7 "register_operand" "=r"))
2358 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2366 muls.l r19, r19, r18 // u0.28
2367 muls.l r25, r18, r18 // s2.58
2368 shlli r19, 45, r0 // multiply by two and convert to s2.58
2370 shari r18, 28, r18 // some 18 bit inverse in s1.30
2373 rtx inv1 = operands[0];
2374 rtx tab_base = operands[1];
2375 rtx tab_ix = operands[2];
2376 rtx norm32 = operands[3];
2377 rtx inv0 = operands[4];
2378 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2379 rtx scratch0a = operands[5];
2380 rtx scratch0b = operands[6];
2381 rtx scratch0 = operands[7];
2382 rtx scratch1 = operands[8];
2383 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2385 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2386 scratch0a, scratch0b));
2387 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2388 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2389 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2390 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2391 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2395 ;; operands: inv2, norm32, inv1, i92
2396 (define_insn_and_split "divsi_inv_m2"
2397 [(set (match_operand:SI 0 "register_operand" "=r")
2398 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2399 (match_operand:SI 2 "register_operand" "r")
2400 (match_operand:DI 3 "register_operand" "r")]
2402 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2410 muls.l r18, r25, r0 // s2.60
2411 shari r0, 16, r0 // s-16.44
2413 muls.l r0, r18, r19 // s-16.74
2414 shari r19, 30, r19 // s-16.44
2416 rtx inv2 = operands[0];
2417 rtx norm32 = operands[1];
2418 rtx inv1 = operands[2];
2419 rtx i92 = operands[3];
2420 rtx scratch0 = operands[4];
2421 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2423 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2424 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2425 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2426 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2427 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2431 (define_insn_and_split "divsi_inv_m3"
2432 [(set (match_operand:SI 0 "register_operand" "=r")
2433 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2434 (match_operand:SI 2 "register_operand" "r")
2435 (match_operand:SI 3 "register_operand" "r")
2436 (match_operand:DI 4 "register_operand" "r")
2437 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2438 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2440 (clobber (match_operand:DI 7 "register_operand" "=r"))
2441 (clobber (match_operand:DI 8 "register_operand" "=r"))
2442 (clobber (match_operand:DI 9 "register_operand" "=r"))
2443 (clobber (match_operand:DI 10 "register_operand" "=r"))
2444 (clobber (match_operand:SI 11 "register_operand" "=r"))
2445 (clobber (match_operand:SI 12 "register_operand" "=r"))
2446 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2454 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2455 r0: scratch0 r19: scratch1 r21: scratch2
2457 muls.l r18, r4, r25 // s32.30
2458 muls.l r19, r4, r19 // s15.30
2460 shari r19, 14, r19 // s18.-14
2466 rtx result = operands[0];
2467 rtx dividend = operands[1];
2468 rtx inv1 = operands[2];
2469 rtx inv2 = operands[3];
2470 rtx shift = operands[4];
2471 rtx scratch0 = operands[7];
2472 rtx scratch1 = operands[8];
2473 rtx scratch2 = operands[9];
2475 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2476 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2477 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2478 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2479 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2480 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2481 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2485 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2486 ;; inv1: tab_base, tab_ix, norm32
2487 ;; inv2: norm32, inv1, i92
2488 (define_insn_and_split "divsi_inv_m1_3"
2489 [(set (match_operand:SI 0 "register_operand" "=r")
2490 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2491 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2492 (match_operand:DI 3 "register_operand" "r")
2493 (match_operand:SI 4 "register_operand" "r")]
2495 (unspec:SI [(match_dup 4)
2496 (unspec:SI [(match_dup 2)
2498 (match_dup 4)] UNSPEC_DIV_INV_M1)
2499 (match_operand:SI 5 "" "")]
2501 (match_operand:DI 6 "register_operand" "r")
2502 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2503 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2505 (clobber (match_operand:DI 9 "register_operand" "=r"))
2506 (clobber (match_operand:DI 10 "register_operand" "=r"))
2507 (clobber (match_operand:DI 11 "register_operand" "=r"))
2508 (clobber (match_operand:DI 12 "register_operand" "=r"))
2509 (clobber (match_operand:SI 13 "register_operand" "=r"))
2510 (clobber (match_operand:SI 14 "register_operand" "=r"))
2511 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2513 && (TARGET_DIVIDE_INV_MINLAT
2514 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2520 rtx result = operands[0];
2521 rtx dividend = operands[1];
2522 rtx tab_base = operands[2];
2523 rtx tab_ix = operands[3];
2524 rtx norm32 = operands[4];
2525 /* rtx i92 = operands[5]; */
2526 rtx shift = operands[6];
2527 rtx i2p27 = operands[7];
2528 rtx i43 = operands[8];
2529 rtx scratch0 = operands[9];
2530 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2531 rtx scratch1 = operands[10];
2532 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2533 rtx scratch2 = operands[11];
2534 rtx scratch3 = operands[12];
2535 rtx scratch4 = operands[13];
2536 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2537 rtx scratch5 = operands[14];
2538 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2539 rtx scratch6 = operands[15];
2541 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2542 scratch0, scratch1));
2543 /* inv0 == scratch4 */
2544 if (! TARGET_DIVIDE_INV20U)
2546 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2548 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2552 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2553 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2555 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2556 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2557 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2558 /* inv1 == scratch4 */
2560 if (TARGET_DIVIDE_INV_MINLAT)
2562 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2563 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2564 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2565 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2566 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2567 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2568 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2569 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2570 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2571 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2572 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2576 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2577 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2578 emit_insn (gen_nsbdi (scratch6,
2579 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2580 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2581 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2582 emit_insn (gen_divsi_inv20 (scratch2,
2583 norm32, scratch4, dividend,
2584 scratch6, scratch3, i43,
2585 /* scratch0 may be shared with i2p27. */
2586 scratch0, scratch1, scratch5,
2587 label, label, i2p27));
2589 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2590 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2594 (define_insn "divsi_inv20"
2595 [(set (match_operand:DI 0 "register_operand" "=&r")
2596 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2597 (match_operand:SI 2 "register_operand" "r")
2598 (match_operand:SI 3 "register_operand" "r")
2599 (match_operand:DI 4 "register_operand" "r")
2600 (match_operand:DI 5 "register_operand" "r")
2601 (match_operand:DI 6 "register_operand" "r")
2602 (match_operand:DI 12 "register_operand" "r")
2603 (match_operand 10 "target_operand" "b")
2604 (match_operand 11 "immediate_operand" "i")]
2606 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2607 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2608 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2610 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2613 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2614 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2615 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2616 %10 label (tr), %11 label (imm)
2618 muls.l inv1, norm32, scratch0 // s2.60
2619 muls.l inv1, dividend, result // s32.30
2620 xor i2p27, result_sign, round_scratch
2621 bge/u dividend_nsb, i43, tr.. (label)
2622 shari scratch0, 16, scratch0 // s-16.44
2623 muls.l sratch0_si, inv1, scratch0 // s-16.74
2624 sub result, round_scratch, result
2625 shari dividend, 14, scratch1 // s19.-14
2626 shari scratch0, 30, scratch0 // s-16.44
2627 muls.l scratch0, scratch1, round_scratch // s15.30
2629 sub result, round_scratch, result */
2631 int likely = TARGET_DIVIDE_INV20L;
2633 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2634 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2635 output_asm_insn (likely
2636 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2637 : \"bge/u\t%4, %6, %10\", operands);
2638 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2639 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2640 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2642 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2643 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2646 (define_insn_and_split "divsi_inv_fp"
2647 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2648 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2649 (match_operand:SI 2 "register_operand" "rf")))
2650 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2651 (clobber (match_operand:SI 4 "register_operand" "=r"))
2652 (clobber (match_operand:SI 5 "register_operand" "=r"))
2653 (clobber (match_operand:DF 6 "register_operand" "=r"))
2654 (clobber (match_operand:DF 7 "register_operand" "=r"))
2655 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2656 "TARGET_SHMEDIA_FPU"
2658 "&& (high_life_started || reload_completed)"
2659 [(set (match_dup 0) (match_dup 3))]
2661 [(set_attr "highpart" "must_split")])
2663 ;; If a matching group of divide-by-inverse instructions is in the same
2664 ;; basic block after gcse & loop optimizations, we want to transform them
2665 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2666 (define_insn_and_split "*divsi_inv_fp_combine"
2667 [(set (match_operand:SI 0 "register_operand" "=f")
2668 (div:SI (match_operand:SI 1 "register_operand" "f")
2669 (match_operand:SI 2 "register_operand" "f")))
2670 (use (unspec:SI [(match_dup 1)
2671 (match_operand:SI 3 "" "")
2672 (unspec:SI [(match_operand:SI 4 "" "")
2674 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2675 (match_operand:DI 6 "" "")
2677 (const_int 0)] UNSPEC_DIV_INV_M3))
2678 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2680 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2681 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2682 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2683 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2686 [(set (match_dup 9) (float:DF (match_dup 1)))
2687 (set (match_dup 10) (float:DF (match_dup 2)))
2688 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2690 (fix:SI (match_dup 11)))
2691 (set (match_dup 0) (match_dup 8))]
2694 if (! fp_arith_reg_operand (operands[1], SImode))
2696 emit_move_insn (operands[7], operands[1]);
2697 operands[1] = operands[7];
2699 if (! fp_arith_reg_operand (operands[2], SImode))
2701 emit_move_insn (operands[8], operands[2]);
2702 operands[2] = operands[8];
2705 [(set_attr "highpart" "must_split")])
2707 ;; -------------------------------------------------------------------------
2708 ;; Multiplication instructions
2709 ;; -------------------------------------------------------------------------
2711 (define_insn "umulhisi3_i"
2712 [(set (reg:SI MACL_REG)
2713 (mult:SI (zero_extend:SI
2714 (match_operand:HI 0 "arith_reg_operand" "r"))
2716 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2719 [(set_attr "type" "smpy")])
2721 (define_insn "mulhisi3_i"
2722 [(set (reg:SI MACL_REG)
2723 (mult:SI (sign_extend:SI
2724 (match_operand:HI 0 "arith_reg_operand" "r"))
2726 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2729 [(set_attr "type" "smpy")])
2731 (define_expand "mulhisi3"
2732 [(set (reg:SI MACL_REG)
2733 (mult:SI (sign_extend:SI
2734 (match_operand:HI 1 "arith_reg_operand" ""))
2736 (match_operand:HI 2 "arith_reg_operand" ""))))
2737 (set (match_operand:SI 0 "arith_reg_operand" "")
2744 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2745 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2746 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2747 invariant code motion can move it. */
2748 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2749 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2750 /* expand_binop can't find a suitable code in umul_widen_optab to
2751 make a REG_EQUAL note from, so make one here.
2752 See also smulsi3_highpart.
2753 ??? Alternatively, we could put this at the calling site of expand_binop,
2754 i.e. expand_expr. */
2755 set_unique_reg_note (last, REG_EQUAL,
2756 copy_rtx (SET_SRC (single_set (first))));
2761 (define_expand "umulhisi3"
2762 [(set (reg:SI MACL_REG)
2763 (mult:SI (zero_extend:SI
2764 (match_operand:HI 1 "arith_reg_operand" ""))
2766 (match_operand:HI 2 "arith_reg_operand" ""))))
2767 (set (match_operand:SI 0 "arith_reg_operand" "")
2774 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2775 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2776 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2777 invariant code motion can move it. */
2778 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2779 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2780 /* expand_binop can't find a suitable code in umul_widen_optab to
2781 make a REG_EQUAL note from, so make one here.
2782 See also smulsi3_highpart.
2783 ??? Alternatively, we could put this at the calling site of expand_binop,
2784 i.e. expand_expr. */
2785 set_unique_reg_note (last, REG_EQUAL,
2786 copy_rtx (SET_SRC (single_set (first))));
2791 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2792 ;; a call to a routine which clobbers known registers.
2795 [(set (match_operand:SI 1 "register_operand" "=z")
2796 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2797 (clobber (reg:SI MACL_REG))
2798 (clobber (reg:SI T_REG))
2799 (clobber (reg:SI PR_REG))
2800 (clobber (reg:SI R3_REG))
2801 (clobber (reg:SI R2_REG))
2802 (clobber (reg:SI R1_REG))
2803 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2806 [(set_attr "type" "sfunc")
2807 (set_attr "needs_delay_slot" "yes")])
2809 (define_expand "mulsi3_call"
2810 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2811 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2812 (parallel[(set (match_operand:SI 0 "register_operand" "")
2813 (mult:SI (reg:SI R4_REG)
2815 (clobber (reg:SI MACL_REG))
2816 (clobber (reg:SI T_REG))
2817 (clobber (reg:SI PR_REG))
2818 (clobber (reg:SI R3_REG))
2819 (clobber (reg:SI R2_REG))
2820 (clobber (reg:SI R1_REG))
2821 (use (match_operand:SI 3 "register_operand" ""))])]
2825 (define_insn "mul_r"
2826 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2827 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2828 (match_operand:SI 2 "arith_reg_operand" "z")))]
2831 [(set_attr "type" "dmpy")])
2833 (define_insn "mul_l"
2834 [(set (reg:SI MACL_REG)
2835 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2836 (match_operand:SI 1 "arith_reg_operand" "r")))]
2839 [(set_attr "type" "dmpy")])
2841 (define_expand "mulsi3"
2842 [(set (reg:SI MACL_REG)
2843 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2844 (match_operand:SI 2 "arith_reg_operand" "")))
2845 (set (match_operand:SI 0 "arith_reg_operand" "")
2854 /* The address must be set outside the libcall,
2855 since it goes into a pseudo. */
2856 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2857 rtx addr = force_reg (SImode, sym);
2858 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2861 last = emit_insn (insns);
2865 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2867 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2868 /* consec_sets_giv can only recognize the first insn that sets a
2869 giv as the giv insn. So we must tag this also with a REG_EQUAL
2871 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2873 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2874 invariant code motion can move it. */
2875 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2876 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2880 (define_insn "mulsidi3_i"
2881 [(set (reg:SI MACH_REG)
2885 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2886 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2888 (set (reg:SI MACL_REG)
2889 (mult:SI (match_dup 0)
2893 [(set_attr "type" "dmpy")])
2895 (define_expand "mulsidi3"
2896 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2897 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2898 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2899 "TARGET_SH2 || TARGET_SHMEDIA"
2904 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2910 (define_insn "mulsidi3_media"
2911 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2912 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2913 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2916 [(set_attr "type" "dmpy_media")
2917 (set_attr "highpart" "ignore")])
2919 (define_insn "mulsidi3_compact"
2920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2922 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2923 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2924 (clobber (reg:SI MACH_REG))
2925 (clobber (reg:SI MACL_REG))]
2930 [(set (match_operand:DI 0 "arith_reg_dest" "")
2932 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2933 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2934 (clobber (reg:SI MACH_REG))
2935 (clobber (reg:SI MACL_REG))]
2940 rtx low_dst = gen_lowpart (SImode, operands[0]);
2941 rtx high_dst = gen_highpart (SImode, operands[0]);
2943 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2945 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2946 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2947 /* We need something to tag the possible REG_EQUAL notes on to. */
2948 emit_move_insn (operands[0], operands[0]);
2952 (define_insn "umulsidi3_i"
2953 [(set (reg:SI MACH_REG)
2957 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2958 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2960 (set (reg:SI MACL_REG)
2961 (mult:SI (match_dup 0)
2965 [(set_attr "type" "dmpy")])
2967 (define_expand "umulsidi3"
2968 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2969 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2970 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2971 "TARGET_SH2 || TARGET_SHMEDIA"
2976 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2982 (define_insn "umulsidi3_media"
2983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2984 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2985 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2988 [(set_attr "type" "dmpy_media")
2989 (set_attr "highpart" "ignore")])
2991 (define_insn "umulsidi3_compact"
2992 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2994 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2995 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2996 (clobber (reg:SI MACH_REG))
2997 (clobber (reg:SI MACL_REG))]
3002 [(set (match_operand:DI 0 "arith_reg_dest" "")
3003 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3004 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3005 (clobber (reg:SI MACH_REG))
3006 (clobber (reg:SI MACL_REG))]
3011 rtx low_dst = gen_lowpart (SImode, operands[0]);
3012 rtx high_dst = gen_highpart (SImode, operands[0]);
3014 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3016 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3017 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3018 /* We need something to tag the possible REG_EQUAL notes on to. */
3019 emit_move_insn (operands[0], operands[0]);
3023 (define_insn "smulsi3_highpart_i"
3024 [(set (reg:SI MACH_REG)
3028 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3029 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3031 (clobber (reg:SI MACL_REG))]
3034 [(set_attr "type" "dmpy")])
3036 (define_expand "smulsi3_highpart"
3038 [(set (reg:SI MACH_REG)
3042 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3043 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3045 (clobber (reg:SI MACL_REG))])
3046 (set (match_operand:SI 0 "arith_reg_operand" "")
3053 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3054 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3055 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3056 invariant code motion can move it. */
3057 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3058 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3059 /* expand_binop can't find a suitable code in mul_highpart_optab to
3060 make a REG_EQUAL note from, so make one here.
3061 See also {,u}mulhisi.
3062 ??? Alternatively, we could put this at the calling site of expand_binop,
3063 i.e. expand_mult_highpart. */
3064 set_unique_reg_note (last, REG_EQUAL,
3065 copy_rtx (SET_SRC (single_set (first))));
3070 (define_insn "umulsi3_highpart_i"
3071 [(set (reg:SI MACH_REG)
3075 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3076 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3078 (clobber (reg:SI MACL_REG))]
3081 [(set_attr "type" "dmpy")])
3083 (define_expand "umulsi3_highpart"
3085 [(set (reg:SI MACH_REG)
3089 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3090 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3092 (clobber (reg:SI MACL_REG))])
3093 (set (match_operand:SI 0 "arith_reg_operand" "")
3100 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3101 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3102 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3103 invariant code motion can move it. */
3104 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3105 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3109 (define_insn_and_split "muldi3"
3110 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3111 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3112 (match_operand:DI 2 "arith_reg_operand" "r")))
3113 (clobber (match_scratch:DI 3 "=&r"))
3114 (clobber (match_scratch:DI 4 "=r"))]
3121 rtx op3_v2si, op2_v2si;
3123 op3_v2si = operands[3];
3124 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3126 op3_v2si = XEXP (op3_v2si, 0);
3127 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3129 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3130 op2_v2si = operands[2];
3131 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3133 op2_v2si = XEXP (op2_v2si, 0);
3134 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3136 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3137 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3138 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3139 emit_insn (gen_umulsidi3_media (operands[4],
3140 sh_gen_truncate (SImode, operands[1], 0),
3141 sh_gen_truncate (SImode, operands[2], 0)));
3142 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3143 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3144 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3145 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3150 ;; -------------------------------------------------------------------------
3151 ;; Logical operations
3152 ;; -------------------------------------------------------------------------
3154 (define_insn "*andsi3_compact"
3155 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3156 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3157 (match_operand:SI 2 "logical_operand" "r,K08")))]
3160 [(set_attr "type" "arith")])
3162 (define_insn "*andsi3_media"
3163 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3164 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3165 (match_operand:SI 2 "logical_operand" "r,I10")))]
3170 [(set_attr "type" "arith_media")])
3172 ;; If the constant is 255, then emit an extu.b instruction instead of an
3173 ;; and, since that will give better code.
3175 (define_expand "andsi3"
3176 [(set (match_operand:SI 0 "arith_reg_operand" "")
3177 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3178 (match_operand:SI 2 "logical_operand" "")))]
3183 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3185 emit_insn (gen_zero_extendqisi2 (operands[0],
3186 gen_lowpart (QImode, operands[1])));
3191 (define_insn_and_split "anddi3"
3192 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3193 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3194 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3201 && ! logical_operand (operands[2], DImode)"
3205 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3206 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3208 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3211 [(set_attr "type" "arith_media")])
3213 (define_insn "andcsi3"
3214 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3215 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3216 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3219 [(set_attr "type" "arith_media")])
3221 (define_insn "andcdi3"
3222 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3223 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3224 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3227 [(set_attr "type" "arith_media")])
3229 (define_expand "iorsi3"
3230 [(set (match_operand:SI 0 "arith_reg_operand" "")
3231 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3232 (match_operand:SI 2 "logical_operand" "")))]
3236 (define_insn "*iorsi3_compact"
3237 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3238 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3239 (match_operand:SI 2 "logical_operand" "r,K08")))]
3242 [(set_attr "type" "arith")])
3244 (define_insn "*iorsi3_media"
3245 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3246 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3247 (match_operand:SI 2 "logical_operand" "r,I10")))]
3252 [(set_attr "type" "arith_media")])
3254 (define_insn "iordi3"
3255 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3256 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3257 (match_operand:DI 2 "logical_operand" "r,I10")))]
3262 [(set_attr "type" "arith_media")])
3264 (define_insn_and_split "*logical_sidi3"
3265 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3266 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3267 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3268 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3271 "&& reload_completed"
3272 [(set (match_dup 0) (match_dup 3))]
3276 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3277 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3278 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3281 (define_insn_and_split "*logical_sidisi3"
3282 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3283 (truncate:SI (sign_extend:DI
3284 (match_operator:SI 3 "logical_operator"
3285 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3286 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3290 [(set (match_dup 0) (match_dup 3))])
3292 (define_insn_and_split "*logical_sidi3_2"
3293 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3294 (sign_extend:DI (truncate:SI (sign_extend:DI
3295 (match_operator:SI 3 "logical_operator"
3296 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3297 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3301 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3303 (define_expand "xorsi3"
3304 [(set (match_operand:SI 0 "arith_reg_operand" "")
3305 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3306 (match_operand:SI 2 "xor_operand" "")))]
3310 (define_insn "*xorsi3_compact"
3311 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3312 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3313 (match_operand:SI 2 "logical_operand" "K08,r")))]
3316 [(set_attr "type" "arith")])
3318 (define_insn "*xorsi3_media"
3319 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3320 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3321 (match_operand:SI 2 "xor_operand" "r,I06")))]
3326 [(set_attr "type" "arith_media")])
3328 (define_insn "xordi3"
3329 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3330 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3331 (match_operand:DI 2 "xor_operand" "r,I06")))]
3336 [(set_attr "type" "arith_media")])
3338 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3339 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3341 [(set (match_operand:DI 0 "arith_reg_dest" "")
3342 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3343 [(match_operand 1 "any_register_operand" "")
3344 (match_operand 2 "any_register_operand" "")])))]
3346 [(set (match_dup 5) (match_dup 4))
3347 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3350 enum machine_mode inmode = GET_MODE (operands[1]);
3353 if (GET_CODE (operands[0]) == SUBREG)
3355 offset = SUBREG_BYTE (operands[0]);
3356 operands[0] = SUBREG_REG (operands[0]);
3358 gcc_assert (GET_CODE (operands[0]) == REG);
3359 if (! TARGET_LITTLE_ENDIAN)
3360 offset += 8 - GET_MODE_SIZE (inmode);
3361 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3364 ;; -------------------------------------------------------------------------
3365 ;; Shifts and rotates
3366 ;; -------------------------------------------------------------------------
3368 (define_expand "rotldi3"
3369 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3370 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3371 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3373 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3375 (define_insn "rotldi3_mextr"
3376 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3377 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3378 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3382 static char templ[16];
3384 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3385 8 - (int) (INTVAL (operands[2]) >> 3));
3388 [(set_attr "type" "arith_media")])
3390 (define_expand "rotrdi3"
3391 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3392 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3393 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3395 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3397 (define_insn "rotrdi3_mextr"
3398 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3399 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3400 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3404 static char templ[16];
3406 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3409 [(set_attr "type" "arith_media")])
3412 [(set (match_operand:DI 0 "arith_reg_dest" "")
3413 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3414 "ua_address_operand" "")))
3415 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3417 (clobber (match_operand:DI 3 "register_operand" ""))]
3419 [(match_dup 4) (match_dup 5)]
3422 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3423 (operands[3], operands[1]));
3424 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3425 GEN_INT (56), GEN_INT (8));
3428 (define_insn "rotlsi3_1"
3429 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3430 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3433 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3436 [(set_attr "type" "arith")])
3438 (define_insn "rotlsi3_31"
3439 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3440 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3442 (clobber (reg:SI T_REG))]
3445 [(set_attr "type" "arith")])
3447 (define_insn "rotlsi3_16"
3448 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3449 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3453 [(set_attr "type" "arith")])
3455 (define_expand "rotlsi3"
3456 [(set (match_operand:SI 0 "arith_reg_dest" "")
3457 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3458 (match_operand:SI 2 "immediate_operand" "")))]
3462 static const char rot_tab[] = {
3463 000, 000, 000, 000, 000, 000, 010, 001,
3464 001, 001, 011, 013, 003, 003, 003, 003,
3465 003, 003, 003, 003, 003, 013, 012, 002,
3466 002, 002, 010, 000, 000, 000, 000, 000,
3471 if (GET_CODE (operands[2]) != CONST_INT)
3473 count = INTVAL (operands[2]);
3474 choice = rot_tab[count];
3475 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3481 emit_move_insn (operands[0], operands[1]);
3482 count -= (count & 16) * 2;
3485 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3492 parts[0] = gen_reg_rtx (SImode);
3493 parts[1] = gen_reg_rtx (SImode);
3494 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3495 emit_move_insn (parts[choice-1], operands[1]);
3496 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3497 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3498 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3499 count = (count & ~16) - 8;
3503 for (; count > 0; count--)
3504 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3505 for (; count < 0; count++)
3506 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3511 (define_insn "*rotlhi3_8"
3512 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3513 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3517 [(set_attr "type" "arith")])
3519 (define_expand "rotlhi3"
3520 [(set (match_operand:HI 0 "arith_reg_operand" "")
3521 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3522 (match_operand:HI 2 "immediate_operand" "")))]
3526 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3533 (define_insn "ashlsi3_sh2a"
3534 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3535 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3536 (match_operand:SI 2 "arith_reg_operand" "r")))]
3539 [(set_attr "type" "arith")
3540 (set_attr "length" "4")])
3542 ;; This pattern is used by init_expmed for computing the costs of shift
3545 (define_insn_and_split "ashlsi3_std"
3546 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3547 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3548 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3549 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3551 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3559 && GET_CODE (operands[2]) == CONST_INT
3560 && ! satisfies_constraint_P27 (operands[2])"
3561 [(set (match_dup 3) (match_dup 2))
3563 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3564 (clobber (match_dup 4))])]
3565 "operands[4] = gen_rtx_SCRATCH (SImode);"
3566 [(set_attr "length" "*,*,*,4")
3567 (set_attr "type" "dyn_shift,arith,arith,arith")])
3569 (define_insn "ashlhi3_k"
3570 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3571 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3572 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3573 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3577 [(set_attr "type" "arith")])
3579 (define_insn "ashlsi3_n"
3580 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3581 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3582 (match_operand:SI 2 "const_int_operand" "n")))
3583 (clobber (reg:SI T_REG))]
3584 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3586 [(set (attr "length")
3587 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3589 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3591 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3593 (const_string "8")))
3594 (set_attr "type" "arith")])
3597 [(set (match_operand:SI 0 "arith_reg_dest" "")
3598 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3599 (match_operand:SI 2 "const_int_operand" "")))
3600 (clobber (reg:SI T_REG))]
3601 "TARGET_SH1 && reload_completed"
3602 [(use (reg:SI R0_REG))]
3605 gen_shifty_op (ASHIFT, operands);
3609 (define_insn "ashlsi3_media"
3610 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3611 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3612 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3617 [(set_attr "type" "arith_media")
3618 (set_attr "highpart" "ignore")])
3620 (define_expand "ashlsi3"
3621 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3622 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3623 (match_operand:SI 2 "nonmemory_operand" "")))
3624 (clobber (reg:SI T_REG))])]
3630 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3633 if (GET_CODE (operands[2]) == CONST_INT
3634 && sh_dynamicalize_shift_p (operands[2]))
3635 operands[2] = force_reg (SImode, operands[2]);
3638 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3641 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3645 (define_insn "*ashlhi3_n"
3646 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3647 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3648 (match_operand:HI 2 "const_int_operand" "n")))
3649 (clobber (reg:SI T_REG))]
3652 [(set (attr "length")
3653 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3655 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3657 (const_string "6")))
3658 (set_attr "type" "arith")])
3660 (define_expand "ashlhi3"
3661 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3662 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3663 (match_operand:SI 2 "nonmemory_operand" "")))
3664 (clobber (reg:SI T_REG))])]
3668 if (GET_CODE (operands[2]) != CONST_INT)
3670 /* It may be possible to call gen_ashlhi3 directly with more generic
3671 operands. Make sure operands[1] is a HImode register here. */
3672 if (!arith_reg_operand (operands[1], HImode))
3673 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3677 [(set (match_operand:HI 0 "arith_reg_dest" "")
3678 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3679 (match_operand:HI 2 "const_int_operand" "")))
3680 (clobber (reg:SI T_REG))]
3681 "TARGET_SH1 && reload_completed"
3682 [(use (reg:SI R0_REG))]
3685 gen_shifty_hi_op (ASHIFT, operands);
3690 ; arithmetic shift right
3693 (define_insn "ashrsi3_sh2a"
3694 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3695 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3696 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3699 [(set_attr "type" "dyn_shift")
3700 (set_attr "length" "4")])
3702 (define_insn "ashrsi3_k"
3703 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3704 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3705 (match_operand:SI 2 "const_int_operand" "M")))
3706 (clobber (reg:SI T_REG))]
3707 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3709 [(set_attr "type" "arith")])
3711 ;; We can't do HImode right shifts correctly unless we start out with an
3712 ;; explicit zero / sign extension; doing that would result in worse overall
3713 ;; code, so just let the machine independent code widen the mode.
3714 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3717 ;; ??? This should be a define expand.
3719 (define_insn "ashrsi2_16"
3720 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3721 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3725 [(set_attr "length" "4")])
3728 [(set (match_operand:SI 0 "arith_reg_dest" "")
3729 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3732 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3733 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3734 "operands[2] = gen_lowpart (HImode, operands[0]);")
3736 ;; ??? This should be a define expand.
3738 (define_insn "ashrsi2_31"
3739 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3740 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3742 (clobber (reg:SI T_REG))]
3745 [(set_attr "length" "4")])
3748 [(set (match_operand:SI 0 "arith_reg_dest" "")
3749 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3751 (clobber (reg:SI T_REG))]
3756 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3757 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3762 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3764 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3766 && peep2_reg_dead_p (2, operands[0])
3767 && peep2_reg_dead_p (2, operands[1])"
3771 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3775 (define_insn "ashlsi_c"
3776 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3777 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3779 (lt:SI (match_dup 1) (const_int 0)))]
3782 [(set_attr "type" "arith")])
3784 (define_insn "*ashlsi_c_void"
3785 [(set (reg:SI T_REG)
3786 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3787 (clobber (match_scratch:SI 1 "=0"))]
3788 "TARGET_SH1 && cse_not_expected"
3790 [(set_attr "type" "arith")])
3792 (define_insn "ashrsi3_d"
3793 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3794 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3795 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3798 [(set_attr "type" "dyn_shift")])
3800 (define_insn "ashrsi3_n"
3801 [(set (reg:SI R4_REG)
3802 (ashiftrt:SI (reg:SI R4_REG)
3803 (match_operand:SI 0 "const_int_operand" "i")))
3804 (clobber (reg:SI T_REG))
3805 (clobber (reg:SI PR_REG))
3806 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3809 [(set_attr "type" "sfunc")
3810 (set_attr "needs_delay_slot" "yes")])
3812 (define_insn "ashrsi3_media"
3813 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3814 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3815 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3820 [(set_attr "type" "arith_media")
3821 (set_attr "highpart" "ignore")])
3823 (define_expand "ashrsi3"
3824 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3825 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3826 (match_operand:SI 2 "nonmemory_operand" "")))
3827 (clobber (reg:SI T_REG))])]
3833 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3836 if (expand_ashiftrt (operands))
3842 ;; logical shift right
3844 (define_insn "lshrsi3_sh2a"
3845 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3846 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3847 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3850 [(set_attr "type" "dyn_shift")
3851 (set_attr "length" "4")])
3853 (define_insn "lshrsi3_d"
3854 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3855 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3856 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3859 [(set_attr "type" "dyn_shift")])
3861 ;; Only the single bit shift clobbers the T bit.
3863 (define_insn "lshrsi3_m"
3864 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3865 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3866 (match_operand:SI 2 "const_int_operand" "M")))
3867 (clobber (reg:SI T_REG))]
3868 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3870 [(set_attr "type" "arith")])
3872 (define_insn "lshrsi3_k"
3873 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3874 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3875 (match_operand:SI 2 "const_int_operand" "P27")))]
3876 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3877 && ! satisfies_constraint_M (operands[2])"
3879 [(set_attr "type" "arith")])
3881 (define_insn "lshrsi3_n"
3882 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3883 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3884 (match_operand:SI 2 "const_int_operand" "n")))
3885 (clobber (reg:SI T_REG))]
3886 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3888 [(set (attr "length")
3889 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3891 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3893 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3895 (const_string "8")))
3896 (set_attr "type" "arith")])
3899 [(set (match_operand:SI 0 "arith_reg_dest" "")
3900 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3901 (match_operand:SI 2 "const_int_operand" "")))
3902 (clobber (reg:SI T_REG))]
3903 "TARGET_SH1 && reload_completed"
3904 [(use (reg:SI R0_REG))]
3907 gen_shifty_op (LSHIFTRT, operands);
3911 (define_insn "lshrsi3_media"
3912 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3913 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3914 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3919 [(set_attr "type" "arith_media")
3920 (set_attr "highpart" "ignore")])
3922 (define_expand "lshrsi3"
3923 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3924 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3925 (match_operand:SI 2 "nonmemory_operand" "")))
3926 (clobber (reg:SI T_REG))])]
3932 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3935 if (GET_CODE (operands[2]) == CONST_INT
3936 && sh_dynamicalize_shift_p (operands[2]))
3937 operands[2] = force_reg (SImode, operands[2]);
3938 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3940 rtx count = copy_to_mode_reg (SImode, operands[2]);
3941 emit_insn (gen_negsi2 (count, count));
3942 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3945 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3949 ;; ??? This should be a define expand.
3951 (define_insn "ashldi3_k"
3952 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3953 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3955 (clobber (reg:SI T_REG))]
3957 "shll %R0\;rotcl %S0"
3958 [(set_attr "length" "4")
3959 (set_attr "type" "arith")])
3961 (define_insn "ashldi3_media"
3962 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3963 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3964 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3969 [(set_attr "type" "arith_media")])
3971 (define_insn "*ashldisi3_media"
3972 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3973 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3974 (match_operand:DI 2 "const_int_operand" "n")))]
3975 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3976 "shlli.l %1, %2, %0"
3977 [(set_attr "type" "arith_media")
3978 (set_attr "highpart" "ignore")])
3980 (define_expand "ashldi3"
3981 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3982 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3983 (match_operand:DI 2 "immediate_operand" "")))
3984 (clobber (reg:SI T_REG))])]
3990 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3993 if (GET_CODE (operands[2]) != CONST_INT
3994 || INTVAL (operands[2]) != 1)
3998 ;; ??? This should be a define expand.
4000 (define_insn "lshrdi3_k"
4001 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4002 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4004 (clobber (reg:SI T_REG))]
4006 "shlr %S0\;rotcr %R0"
4007 [(set_attr "length" "4")
4008 (set_attr "type" "arith")])
4010 (define_insn "lshrdi3_media"
4011 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4012 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4013 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4015 && (arith_reg_dest (operands[0], DImode)
4016 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4020 [(set_attr "type" "arith_media")])
4022 (define_insn "*lshrdisi3_media"
4023 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4024 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4025 (match_operand:DI 2 "const_int_operand" "n")))]
4026 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4027 "shlri.l %1, %2, %0"
4028 [(set_attr "type" "arith_media")
4029 (set_attr "highpart" "ignore")])
4031 (define_expand "lshrdi3"
4032 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034 (match_operand:DI 2 "immediate_operand" "")))
4035 (clobber (reg:SI T_REG))])]
4041 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4044 if (GET_CODE (operands[2]) != CONST_INT
4045 || INTVAL (operands[2]) != 1)
4049 ;; ??? This should be a define expand.
4051 (define_insn "ashrdi3_k"
4052 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4053 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4055 (clobber (reg:SI T_REG))]
4057 "shar %S0\;rotcr %R0"
4058 [(set_attr "length" "4")
4059 (set_attr "type" "arith")])
4061 (define_insn "ashrdi3_media"
4062 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4063 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4064 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4066 && (arith_reg_dest (operands[0], DImode)
4067 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4071 [(set_attr "type" "arith_media")])
4073 (define_insn "*ashrdisi3_media"
4074 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4075 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4076 (match_operand:DI 2 "const_int_operand" "n")))]
4077 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4078 "shari.l %1, %2, %0"
4079 [(set_attr "type" "arith_media")
4080 (set_attr "highpart" "ignore")])
4082 (define_insn "ashrdisi3_media_high"
4083 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4085 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4086 (match_operand:DI 2 "const_int_operand" "n"))))]
4087 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4089 [(set_attr "type" "arith_media")])
4091 (define_insn "ashrdisi3_media_opaque"
4092 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4093 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4094 (match_operand:DI 2 "const_int_operand" "n")]
4098 [(set_attr "type" "arith_media")])
4100 (define_expand "ashrdi3"
4101 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4102 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4103 (match_operand:DI 2 "immediate_operand" "")))
4104 (clobber (reg:SI T_REG))])]
4110 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4113 if (GET_CODE (operands[2]) != CONST_INT
4114 || INTVAL (operands[2]) != 1)
4118 ;; combined left/right shift
4121 [(set (match_operand:SI 0 "register_operand" "")
4122 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4123 (match_operand:SI 2 "const_int_operand" ""))
4124 (match_operand:SI 3 "const_int_operand" "")))]
4125 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4126 [(use (reg:SI R0_REG))]
4127 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4131 [(set (match_operand:SI 0 "register_operand" "")
4132 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4133 (match_operand:SI 2 "const_int_operand" ""))
4134 (match_operand:SI 3 "const_int_operand" "")))
4135 (clobber (reg:SI T_REG))]
4136 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4137 [(use (reg:SI R0_REG))]
4138 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4142 [(set (match_operand:SI 0 "register_operand" "=r")
4143 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4144 (match_operand:SI 2 "const_int_operand" "n"))
4145 (match_operand:SI 3 "const_int_operand" "n")))
4146 (clobber (reg:SI T_REG))]
4147 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4149 [(set (attr "length")
4150 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4152 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4154 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4156 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4158 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4160 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4162 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4163 (const_string "16")]
4164 (const_string "18")))
4165 (set_attr "type" "arith")])
4168 [(set (match_operand:SI 0 "register_operand" "=z")
4169 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4170 (match_operand:SI 2 "const_int_operand" "n"))
4171 (match_operand:SI 3 "const_int_operand" "n")))
4172 (clobber (reg:SI T_REG))]
4173 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4175 [(set (attr "length")
4176 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4178 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4180 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4182 (const_string "10")))
4183 (set_attr "type" "arith")])
4185 ;; shift left / and combination with a scratch register: The combine pass
4186 ;; does not accept the individual instructions, even though they are
4187 ;; cheap. But it needs a precise description so that it is usable after
4189 (define_insn "and_shl_scratch"
4190 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4194 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4195 (match_operand:SI 2 "const_int_operand" "N,n"))
4196 (match_operand:SI 3 "" "0,r"))
4197 (match_operand:SI 4 "const_int_operand" "n,n"))
4198 (match_operand:SI 5 "const_int_operand" "n,n")))
4199 (clobber (reg:SI T_REG))]
4202 [(set (attr "length")
4203 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4205 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4207 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4209 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4210 (const_string "10")]
4211 (const_string "12")))
4212 (set_attr "type" "arith")])
4215 [(set (match_operand:SI 0 "register_operand" "")
4219 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4220 (match_operand:SI 2 "const_int_operand" ""))
4221 (match_operand:SI 3 "register_operand" ""))
4222 (match_operand:SI 4 "const_int_operand" ""))
4223 (match_operand:SI 5 "const_int_operand" "")))
4224 (clobber (reg:SI T_REG))]
4226 [(use (reg:SI R0_REG))]
4229 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4231 if (INTVAL (operands[2]))
4233 gen_shifty_op (LSHIFTRT, operands);
4235 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4236 operands[2] = operands[4];
4237 gen_shifty_op (ASHIFT, operands);
4238 if (INTVAL (operands[5]))
4240 operands[2] = operands[5];
4241 gen_shifty_op (LSHIFTRT, operands);
4246 ;; signed left/right shift combination.
4248 [(set (match_operand:SI 0 "register_operand" "")
4250 (ashift:SI (match_operand:SI 1 "register_operand" "")
4251 (match_operand:SI 2 "const_int_operand" ""))
4252 (match_operand:SI 3 "const_int_operand" "")
4254 (clobber (reg:SI T_REG))]
4256 [(use (reg:SI R0_REG))]
4257 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4260 (define_insn "shl_sext_ext"
4261 [(set (match_operand:SI 0 "register_operand" "=r")
4263 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4264 (match_operand:SI 2 "const_int_operand" "n"))
4265 (match_operand:SI 3 "const_int_operand" "n")
4267 (clobber (reg:SI T_REG))]
4268 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4270 [(set (attr "length")
4271 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4273 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4275 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4277 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4279 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4281 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4283 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4285 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4286 (const_string "16")]
4287 (const_string "18")))
4288 (set_attr "type" "arith")])
4290 (define_insn "shl_sext_sub"
4291 [(set (match_operand:SI 0 "register_operand" "=z")
4293 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4294 (match_operand:SI 2 "const_int_operand" "n"))
4295 (match_operand:SI 3 "const_int_operand" "n")
4297 (clobber (reg:SI T_REG))]
4298 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4300 [(set (attr "length")
4301 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4303 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4305 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4307 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4308 (const_string "12")]
4309 (const_string "14")))
4310 (set_attr "type" "arith")])
4312 ;; These patterns are found in expansions of DImode shifts by 16, and
4313 ;; allow the xtrct instruction to be generated from C source.
4315 (define_insn "xtrct_left"
4316 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4317 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4319 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4323 [(set_attr "type" "arith")])
4325 (define_insn "xtrct_right"
4326 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4327 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4329 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4333 [(set_attr "type" "arith")])
4335 ;; -------------------------------------------------------------------------
4337 ;; -------------------------------------------------------------------------
4340 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4341 (neg:SI (plus:SI (reg:SI T_REG)
4342 (match_operand:SI 1 "arith_reg_operand" "r"))))
4344 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4348 [(set_attr "type" "arith")])
4350 (define_insn "*negdi_media"
4351 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4352 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4355 [(set_attr "type" "arith_media")])
4357 (define_expand "negdi2"
4358 [(set (match_operand:DI 0 "arith_reg_operand" "")
4359 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4365 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4366 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4368 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4369 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4371 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4372 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4374 emit_insn (gen_clrt ());
4375 emit_insn (gen_negc (low_dst, low_src));
4376 emit_insn (gen_negc (high_dst, high_src));
4381 (define_insn "negsi2"
4382 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4386 [(set_attr "type" "arith")])
4388 (define_insn "one_cmplsi2"
4389 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4390 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4393 [(set_attr "type" "arith")])
4395 (define_expand "one_cmpldi2"
4396 [(set (match_operand:DI 0 "arith_reg_dest" "")
4397 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4399 "TARGET_SHMEDIA" "")
4401 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4402 This can be used as some kind of conditional execution, which is useful
4405 [(set (match_operand:SI 0 "arith_reg_dest" "")
4406 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4407 (match_operand:SI 1 "arith_reg_operand" ""))
4411 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4412 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4416 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4417 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4418 (match_operand:SI 1 "arith_reg_operand" "0")
4419 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4421 "bf 0f\;neg %2,%0\\n0:"
4422 [(set_attr "type" "arith") ;; poor approximation
4423 (set_attr "length" "4")])
4426 ;; -------------------------------------------------------------------------
4427 ;; Zero extension instructions
4428 ;; -------------------------------------------------------------------------
4430 (define_insn "zero_extendsidi2"
4431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4432 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4434 "addz.l %1, r63, %0"
4435 [(set_attr "type" "arith_media")
4436 (set_attr "highpart" "extend")])
4438 (define_insn "zero_extendhidi2"
4439 [(set (match_operand:DI 0 "register_operand" "=r,r")
4440 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4445 [(set_attr "type" "*,load_media")
4446 (set (attr "highpart")
4447 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4448 (const_string "user")]
4449 (const_string "ignore")))])
4452 [(set (match_operand:DI 0 "register_operand" "")
4453 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4454 "TARGET_SHMEDIA && reload_completed"
4455 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4456 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4459 if (GET_CODE (operands[1]) == TRUNCATE)
4460 operands[1] = XEXP (operands[1], 0);
4463 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4464 ;; reload the entire truncate expression.
4465 (define_insn_and_split "*loaddi_trunc"
4466 [(set (match_operand 0 "any_register_operand" "=r")
4467 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4468 "TARGET_SHMEDIA && reload_completed"
4470 "TARGET_SHMEDIA && reload_completed"
4471 [(set (match_dup 0) (match_dup 1))]
4472 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4474 (define_insn "zero_extendqidi2"
4475 [(set (match_operand:DI 0 "register_operand" "=r,r")
4476 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4481 [(set_attr "type" "arith_media,load_media")
4482 (set (attr "highpart")
4483 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4484 (const_string "user")]
4485 (const_string "ignore")))])
4487 (define_expand "zero_extendhisi2"
4488 [(set (match_operand:SI 0 "arith_reg_operand" "")
4489 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4493 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4494 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4497 (define_insn "*zero_extendhisi2_compact"
4498 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4499 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4502 [(set_attr "type" "arith")])
4504 (define_insn "*zero_extendhisi2_media"
4505 [(set (match_operand:SI 0 "register_operand" "=r,r")
4506 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4511 [(set_attr "type" "arith_media,load_media")
4512 (set (attr "highpart")
4513 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4514 (const_string "user")]
4515 (const_string "ignore")))])
4518 [(set (match_operand:SI 0 "register_operand" "")
4519 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4520 "TARGET_SHMEDIA && reload_completed"
4521 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4522 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4525 rtx op1 = operands[1];
4527 if (GET_CODE (op1) == TRUNCATE)
4528 op1 = XEXP (op1, 0);
4530 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4531 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4534 (define_expand "zero_extendqisi2"
4535 [(set (match_operand:SI 0 "arith_reg_operand" "")
4536 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4540 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4541 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4544 (define_insn "*zero_extendqisi2_compact"
4545 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4546 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4549 [(set_attr "type" "arith")])
4551 (define_insn "*zero_extendqisi2_media"
4552 [(set (match_operand:SI 0 "register_operand" "=r,r")
4553 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4558 [(set_attr "type" "arith_media,load_media")
4559 (set (attr "highpart")
4560 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4561 (const_string "user")]
4562 (const_string "ignore")))])
4564 (define_insn "zero_extendqihi2"
4565 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4566 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4569 [(set_attr "type" "arith")])
4571 ;; -------------------------------------------------------------------------
4572 ;; Sign extension instructions
4573 ;; -------------------------------------------------------------------------
4575 ;; ??? This should be a define expand.
4576 ;; ??? Or perhaps it should be dropped?
4578 ;; convert_move generates good code for SH[1-4].
4579 (define_insn "extendsidi2"
4580 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4581 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4587 [(set_attr "type" "arith_media,load_media,fpconv_media")
4588 (set (attr "highpart")
4589 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4590 (const_string "user")]
4591 (const_string "extend")))])
4593 (define_insn "extendhidi2"
4594 [(set (match_operand:DI 0 "register_operand" "=r,r")
4595 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4600 [(set_attr "type" "*,load_media")
4601 (set (attr "highpart")
4602 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4603 (const_string "user")]
4604 (const_string "ignore")))])
4607 [(set (match_operand:DI 0 "register_operand" "")
4608 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4609 "TARGET_SHMEDIA && reload_completed"
4610 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4611 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4614 if (GET_CODE (operands[1]) == TRUNCATE)
4615 operands[1] = XEXP (operands[1], 0);
4618 (define_insn "extendqidi2"
4619 [(set (match_operand:DI 0 "register_operand" "=r,r")
4620 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4625 [(set_attr "type" "*,load_media")
4626 (set (attr "highpart")
4627 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4628 (const_string "user")]
4629 (const_string "ignore")))])
4632 [(set (match_operand:DI 0 "register_operand" "")
4633 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4634 "TARGET_SHMEDIA && reload_completed"
4635 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4636 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4639 if (GET_CODE (operands[1]) == TRUNCATE)
4640 operands[1] = XEXP (operands[1], 0);
4643 (define_expand "extendhisi2"
4644 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4645 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4649 (define_insn "*extendhisi2_compact"
4650 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4651 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4656 [(set_attr "type" "arith,load")])
4658 (define_insn "*extendhisi2_media"
4659 [(set (match_operand:SI 0 "register_operand" "=r,r")
4660 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4665 [(set_attr "type" "arith_media,load_media")
4666 (set (attr "highpart")
4667 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4668 (const_string "user")]
4669 (const_string "ignore")))])
4672 [(set (match_operand:SI 0 "register_operand" "")
4673 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4674 "TARGET_SHMEDIA && reload_completed"
4675 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4676 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4679 rtx op1 = operands[1];
4680 if (GET_CODE (op1) == TRUNCATE)
4681 op1 = XEXP (op1, 0);
4683 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4684 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4687 (define_expand "extendqisi2"
4688 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4689 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4693 (define_insn "*extendqisi2_compact"
4694 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4695 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4700 [(set_attr "type" "arith,load")])
4702 (define_insn "*extendqisi2_media"
4703 [(set (match_operand:SI 0 "register_operand" "=r,r")
4704 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4709 [(set_attr "type" "arith_media,load_media")
4710 (set (attr "highpart")
4711 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712 (const_string "user")]
4713 (const_string "ignore")))])
4716 [(set (match_operand:SI 0 "register_operand" "")
4717 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4718 "TARGET_SHMEDIA && reload_completed"
4719 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4720 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4723 rtx op1 = operands[1];
4724 if (GET_CODE (op1) == TRUNCATE)
4725 op1 = XEXP (op1, 0);
4727 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4728 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4731 (define_insn "extendqihi2"
4732 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4733 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4738 [(set_attr "type" "arith,load")])
4740 /* It would seem useful to combine the truncXi patterns into the movXi
4741 patterns, but unary operators are ignored when matching constraints,
4742 so we need separate patterns. */
4743 (define_insn "truncdisi2"
4744 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4745 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4754 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4755 (set (attr "highpart")
4756 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4757 (const_string "user")]
4758 (const_string "extend")))])
4760 (define_insn "truncdihi2"
4761 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4762 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4765 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4767 [(set_attr "type" "arith_media,store_media")
4768 (set_attr "length" "8,4")
4769 (set (attr "highpart")
4770 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4771 (const_string "user")]
4772 (const_string "extend")))])
4774 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4775 ; Because we use zero extension, we can't provide signed QImode compares
4776 ; using a simple compare or conditional branch insn.
4777 (define_insn "truncdiqi2"
4778 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4779 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4784 [(set_attr "type" "arith_media,store")
4785 (set (attr "highpart")
4786 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4787 (const_string "user")]
4788 (const_string "extend")))])
4789 ;; -------------------------------------------------------------------------
4790 ;; Move instructions
4791 ;; -------------------------------------------------------------------------
4793 ;; define push and pop so it is easy for sh.c
4794 ;; We can't use push and pop on SHcompact because the stack must always
4795 ;; be 8-byte aligned.
4797 (define_expand "push"
4798 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4799 (match_operand:SI 0 "register_operand" "r,l,x"))]
4800 "TARGET_SH1 && ! TARGET_SH5"
4803 (define_expand "pop"
4804 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4805 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4806 "TARGET_SH1 && ! TARGET_SH5"
4809 (define_expand "push_e"
4810 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4811 (match_operand:SF 0 "" ""))
4812 (use (reg:PSI FPSCR_REG))
4813 (clobber (scratch:SI))])]
4814 "TARGET_SH1 && ! TARGET_SH5"
4817 (define_insn "push_fpul"
4818 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4819 "TARGET_SH2E && ! TARGET_SH5"
4821 [(set_attr "type" "fstore")
4822 (set_attr "late_fp_use" "yes")
4823 (set_attr "hit_stack" "yes")])
4825 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4827 (define_expand "push_4"
4828 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4829 (match_operand:DF 0 "" ""))
4830 (use (reg:PSI FPSCR_REG))
4831 (clobber (scratch:SI))])]
4832 "TARGET_SH1 && ! TARGET_SH5"
4835 (define_expand "pop_e"
4836 [(parallel [(set (match_operand:SF 0 "" "")
4837 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4838 (use (reg:PSI FPSCR_REG))
4839 (clobber (scratch:SI))])]
4840 "TARGET_SH1 && ! TARGET_SH5"
4843 (define_insn "pop_fpul"
4844 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4845 "TARGET_SH2E && ! TARGET_SH5"
4847 [(set_attr "type" "load")
4848 (set_attr "hit_stack" "yes")])
4850 (define_expand "pop_4"
4851 [(parallel [(set (match_operand:DF 0 "" "")
4852 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4853 (use (reg:PSI FPSCR_REG))
4854 (clobber (scratch:SI))])]
4855 "TARGET_SH1 && ! TARGET_SH5"
4858 (define_expand "push_fpscr"
4863 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4864 gen_rtx_PRE_DEC (Pmode,
4865 stack_pointer_rtx)),
4867 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4871 (define_expand "pop_fpscr"
4876 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4877 gen_frame_mem (PSImode,
4878 gen_rtx_POST_INC (Pmode,
4879 stack_pointer_rtx))));
4880 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4884 ;; These two patterns can happen as the result of optimization, when
4885 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4886 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4889 [(set (reg:SI T_REG) (const_int 0))]
4894 [(set (reg:SI T_REG) (const_int 1))]
4898 ;; t/r must come after r/r, lest reload will try to reload stuff like
4899 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4900 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4901 (define_insn "movsi_i"
4902 [(set (match_operand:SI 0 "general_movdst_operand"
4903 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4904 (match_operand:SI 1 "general_movsrc_operand"
4905 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4909 && (register_operand (operands[0], SImode)
4910 || register_operand (operands[1], SImode))"
4928 [(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")
4929 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4931 ;; t/r must come after r/r, lest reload will try to reload stuff like
4932 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4933 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4934 ;; will require a reload.
4935 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4936 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4937 (define_insn "movsi_ie"
4938 [(set (match_operand:SI 0 "general_movdst_operand"
4939 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4940 (match_operand:SI 1 "general_movsrc_operand"
4941 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4942 "(TARGET_SH2E || TARGET_SH2A)
4943 && (register_operand (operands[0], SImode)
4944 || register_operand (operands[1], SImode))"
4970 ! move optimized away"
4971 [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4972 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4973 (set_attr_alternative "length"
4980 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4981 (const_int 4) (const_int 2))
4986 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4987 (const_int 4) (const_int 2))
5004 (define_insn "movsi_i_lowpart"
5005 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5006 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5008 && (register_operand (operands[0], SImode)
5009 || register_operand (operands[1], SImode))"
5020 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5022 (define_insn_and_split "load_ra"
5023 [(set (match_operand:SI 0 "general_movdst_operand" "")
5024 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5027 "&& ! currently_expanding_to_rtl"
5028 [(set (match_dup 0) (match_dup 1))]
5031 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5032 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5035 ;; The '?'s in the following constraints may not reflect the time taken
5036 ;; to perform the move. They are there to discourage the use of floating-
5037 ;; point registers for storing integer values.
5038 (define_insn "*movsi_media"
5039 [(set (match_operand:SI 0 "general_movdst_operand"
5040 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5041 (match_operand:SI 1 "general_movsrc_operand"
5042 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5044 && (register_operand (operands[0], SImode)
5045 || sh_register_operand (operands[1], SImode)
5046 || GET_CODE (operands[1]) == TRUNCATE)"
5061 [(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")
5062 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5063 (set (attr "highpart")
5064 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5065 (const_string "user")]
5066 (const_string "ignore")))])
5068 (define_insn "*movsi_media_nofpu"
5069 [(set (match_operand:SI 0 "general_movdst_operand"
5070 "=r,r,r,r,m,*b,r,*b")
5071 (match_operand:SI 1 "general_movsrc_operand"
5072 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5074 && (register_operand (operands[0], SImode)
5075 || sh_register_operand (operands[1], SImode)
5076 || GET_CODE (operands[1]) == TRUNCATE)"
5086 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5087 (set_attr "length" "4,4,8,4,4,4,4,12")
5088 (set (attr "highpart")
5089 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5090 (const_string "user")]
5091 (const_string "ignore")))])
5093 (define_expand "movsi_const"
5094 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5095 (const:SI (sign_extend:SI
5098 (match_operand:DI 1 "immediate_operand" "s")
5101 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5104 (truncate:HI (match_dup 1))))))]
5105 "TARGET_SHMEDIA && reload_completed
5106 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5109 if (GET_CODE (operands[1]) == LABEL_REF
5110 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5111 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5112 else if (GOTOFF_P (operands[1]))
5114 rtx unspec = XEXP (operands[1], 0);
5116 if (! UNSPEC_GOTOFF_P (unspec))
5118 unspec = XEXP (unspec, 0);
5119 if (! UNSPEC_GOTOFF_P (unspec))
5122 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5123 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5124 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5128 (define_expand "movsi_const_16bit"
5129 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5130 (const:SI (sign_extend:SI
5132 (match_operand:DI 1 "immediate_operand" "s")))))]
5133 "TARGET_SHMEDIA && flag_pic && reload_completed
5134 && GET_CODE (operands[1]) == SYMBOL_REF"
5138 [(set (match_operand:SI 0 "arith_reg_dest" "")
5139 (match_operand:SI 1 "immediate_operand" ""))]
5140 "TARGET_SHMEDIA && reload_completed
5141 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5145 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5147 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5153 [(set (match_operand:SI 0 "register_operand" "")
5154 (match_operand:SI 1 "immediate_operand" ""))]
5155 "TARGET_SHMEDIA && reload_completed
5156 && ((GET_CODE (operands[1]) == CONST_INT
5157 && ! satisfies_constraint_I16 (operands[1]))
5158 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5159 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5161 (define_expand "movsi"
5162 [(set (match_operand:SI 0 "general_movdst_operand" "")
5163 (match_operand:SI 1 "general_movsrc_operand" ""))]
5165 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5167 (define_expand "ic_invalidate_line"
5168 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5169 (match_dup 1)] UNSPEC_ICACHE)
5170 (clobber (scratch:SI))])]
5171 "TARGET_HARD_SH4 || TARGET_SH5"
5176 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5179 else if (TARGET_SHCOMPACT)
5181 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5182 operands[1] = force_reg (Pmode, operands[1]);
5183 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5186 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5188 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5191 operands[0] = force_reg (Pmode, operands[0]);
5192 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5196 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5197 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5198 ;; the requirement *1*00 for associative address writes. The alignment of
5199 ;; %0 implies that its least significant bit is cleared,
5200 ;; thus we clear the V bit of a matching entry if there is one.
5201 (define_insn "ic_invalidate_line_i"
5202 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5203 (match_operand:SI 1 "register_operand" "r")]
5205 (clobber (match_scratch:SI 2 "=&r"))]
5207 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5208 [(set_attr "length" "8")
5209 (set_attr "type" "cwb")])
5211 (define_insn "ic_invalidate_line_sh4a"
5212 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5214 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5215 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5216 [(set_attr "length" "16")
5217 (set_attr "type" "cwb")])
5219 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5220 ;; an add in the code that calculates the address.
5221 (define_insn "ic_invalidate_line_media"
5222 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5225 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5226 [(set_attr "length" "16")
5227 (set_attr "type" "invalidate_line_media")])
5229 (define_insn "ic_invalidate_line_compact"
5230 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5231 (match_operand:SI 1 "register_operand" "r")]
5233 (clobber (reg:SI PR_REG))]
5236 [(set_attr "type" "sfunc")
5237 (set_attr "needs_delay_slot" "yes")])
5239 (define_expand "initialize_trampoline"
5240 [(match_operand:SI 0 "" "")
5241 (match_operand:SI 1 "" "")
5242 (match_operand:SI 2 "" "")]
5248 tramp = force_reg (Pmode, operands[0]);
5249 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5251 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5252 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5254 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5258 (define_insn "initialize_trampoline_compact"
5259 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5260 (match_operand:SI 1 "register_operand" "r")
5261 (reg:SI R2_REG) (reg:SI R3_REG)]
5264 (clobber (reg:SI PR_REG))]
5267 [(set_attr "type" "sfunc")
5268 (set_attr "needs_delay_slot" "yes")])
5270 (define_insn "movqi_i"
5271 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5272 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5274 && (arith_reg_operand (operands[0], QImode)
5275 || arith_reg_operand (operands[1], QImode))"
5284 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5286 (define_insn "*movqi_media"
5287 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5288 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5290 && (arith_reg_operand (operands[0], QImode)
5291 || extend_reg_or_0_operand (operands[1], QImode))"
5297 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5298 (set (attr "highpart")
5299 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5300 (const_string "user")]
5301 (const_string "ignore")))])
5303 (define_expand "movqi"
5304 [(set (match_operand:QI 0 "general_operand" "")
5305 (match_operand:QI 1 "general_operand" ""))]
5307 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5309 (define_expand "reload_inqi"
5310 [(set (match_operand:SI 2 "" "=&r")
5311 (match_operand:QI 1 "inqhi_operand" ""))
5312 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5313 (truncate:QI (match_dup 3)))]
5317 rtx inner = XEXP (operands[1], 0);
5318 int regno = REGNO (inner);
5320 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5321 operands[1] = gen_rtx_REG (SImode, regno);
5322 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5325 /* When storing r0, we have to avoid reg+reg addressing. */
5326 (define_insn "movhi_i"
5327 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5328 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5330 && (arith_reg_operand (operands[0], HImode)
5331 || arith_reg_operand (operands[1], HImode))
5332 && (GET_CODE (operands[0]) != MEM
5333 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5334 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5335 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5345 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5347 (define_insn "*movhi_media"
5348 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5349 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5351 && (arith_reg_operand (operands[0], HImode)
5352 || arith_reg_or_0_operand (operands[1], HImode))"
5359 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5360 (set (attr "highpart")
5361 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5362 (const_string "user")]
5363 (const_string "ignore")))])
5366 [(set (match_operand:HI 0 "register_operand" "")
5367 (match_operand:HI 1 "immediate_operand" ""))]
5368 "TARGET_SHMEDIA && reload_completed
5369 && ! satisfies_constraint_I16 (operands[1])"
5370 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5372 (define_expand "movhi"
5373 [(set (match_operand:HI 0 "general_movdst_operand" "")
5374 (match_operand:HI 1 "general_movsrc_operand" ""))]
5376 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5378 (define_expand "reload_inhi"
5379 [(set (match_operand:SI 2 "" "=&r")
5380 (match_operand:HI 1 "inqhi_operand" ""))
5381 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5382 (truncate:HI (match_dup 3)))]
5386 rtx inner = XEXP (operands[1], 0);
5387 int regno = REGNO (inner);
5389 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5390 operands[1] = gen_rtx_REG (SImode, regno);
5391 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5394 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5395 ;; compiled with -m2 -ml -O3 -funroll-loops
5396 (define_insn "*movdi_i"
5397 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5398 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5400 && (arith_reg_operand (operands[0], DImode)
5401 || arith_reg_operand (operands[1], DImode))"
5402 "* return output_movedouble (insn, operands, DImode);"
5403 [(set_attr "length" "4")
5404 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5406 ;; If the output is a register and the input is memory or a register, we have
5407 ;; to be careful and see which word needs to be loaded first.
5410 [(set (match_operand:DI 0 "general_movdst_operand" "")
5411 (match_operand:DI 1 "general_movsrc_operand" ""))]
5412 "TARGET_SH1 && reload_completed"
5413 [(set (match_dup 2) (match_dup 3))
5414 (set (match_dup 4) (match_dup 5))]
5419 if ((GET_CODE (operands[0]) == MEM
5420 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5421 || (GET_CODE (operands[1]) == MEM
5422 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5425 switch (GET_CODE (operands[0]))
5428 regno = REGNO (operands[0]);
5431 regno = subreg_regno (operands[0]);
5441 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5443 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5444 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5445 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5446 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5450 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5451 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5452 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5453 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5456 if (operands[2] == 0 || operands[3] == 0
5457 || operands[4] == 0 || operands[5] == 0)
5461 ;; The '?'s in the following constraints may not reflect the time taken
5462 ;; to perform the move. They are there to discourage the use of floating-
5463 ;; point registers for storing integer values.
5464 (define_insn "*movdi_media"
5465 [(set (match_operand:DI 0 "general_movdst_operand"
5466 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5467 (match_operand:DI 1 "general_movsrc_operand"
5468 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5470 && (register_operand (operands[0], DImode)
5471 || sh_register_operand (operands[1], DImode))"
5486 [(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")
5487 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5489 (define_insn "*movdi_media_nofpu"
5490 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5491 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5493 && (register_operand (operands[0], DImode)
5494 || sh_register_operand (operands[1], DImode))"
5504 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5505 (set_attr "length" "4,4,16,4,4,4,4,*")])
5507 (define_insn "*movdi_media_I16"
5508 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5509 (match_operand:DI 1 "const_int_operand" "I16"))]
5510 "TARGET_SHMEDIA && reload_completed"
5512 [(set_attr "type" "arith_media")
5513 (set_attr "length" "4")])
5516 [(set (match_operand:DI 0 "arith_reg_dest" "")
5517 (match_operand:DI 1 "immediate_operand" ""))]
5518 "TARGET_SHMEDIA && reload_completed
5519 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5520 [(set (match_dup 0) (match_dup 1))]
5525 if (TARGET_SHMEDIA64)
5526 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5528 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5530 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5535 (define_expand "movdi_const"
5536 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5537 (const:DI (sign_extend:DI
5540 (match_operand:DI 1 "immediate_operand" "s")
5543 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5549 (const_int 32)))))))
5551 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5557 (const_int 16)))))))
5559 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5564 "TARGET_SHMEDIA64 && reload_completed
5565 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5568 sh_mark_label (operands[1], 4);
5571 (define_expand "movdi_const_32bit"
5572 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5573 (const:DI (sign_extend:DI
5576 (match_operand:DI 1 "immediate_operand" "s")
5579 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5584 "TARGET_SHMEDIA32 && reload_completed
5585 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5588 sh_mark_label (operands[1], 2);
5591 (define_expand "movdi_const_16bit"
5592 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5593 (const:DI (sign_extend:DI
5595 (match_operand:DI 1 "immediate_operand" "s")))))]
5596 "TARGET_SHMEDIA && flag_pic && reload_completed
5597 && GET_CODE (operands[1]) == SYMBOL_REF"
5601 [(set (match_operand:DI 0 "ext_dest_operand" "")
5602 (match_operand:DI 1 "immediate_operand" ""))]
5603 "TARGET_SHMEDIA && reload_completed
5604 && GET_CODE (operands[1]) == CONST_INT
5605 && ! satisfies_constraint_I16 (operands[1])"
5606 [(set (match_dup 0) (match_dup 2))
5610 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5611 unsigned HOST_WIDE_INT low = val;
5612 unsigned HOST_WIDE_INT high = val;
5613 unsigned HOST_WIDE_INT sign;
5614 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5616 /* Zero-extend the 16 least-significant bits. */
5619 /* Arithmetic shift right the word by 16 bits. */
5621 if (GET_CODE (operands[0]) == SUBREG
5622 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5631 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5637 /* If we can't generate the constant with a two-insn movi / shori
5638 sequence, try some other strategies. */
5639 if (! CONST_OK_FOR_I16 (high))
5641 /* Try constant load / left shift. We know VAL != 0. */
5642 val2 = val ^ (val-1);
5645 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5647 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5648 || (! CONST_OK_FOR_I16 (high >> 16)
5649 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5651 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5652 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5653 GEN_INT (trailing_zeroes));
5657 /* Try constant load / right shift. */
5658 val2 = (val >> 15) + 1;
5659 if (val2 == (val2 & -val2))
5661 int shift = 49 - exact_log2 (val2);
5663 val2 = trunc_int_for_mode (val << shift, DImode);
5664 if (CONST_OK_FOR_I16 (val2))
5666 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5672 val2 = val & 0xffff;
5673 if ((val >> 16 & 0xffff) == val2
5674 && (val >> 32 & 0xffff) == val2
5675 && (val >> 48 & 0xffff) == val2)
5677 val2 = (HOST_WIDE_INT) val >> 48;
5678 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5679 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5682 /* Try movi / mshflo.l */
5683 val2 = (HOST_WIDE_INT) val >> 32;
5684 if (val2 == ((unsigned HOST_WIDE_INT)
5685 trunc_int_for_mode (val, SImode)))
5687 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5691 /* Try movi / mshflo.l w/ r63. */
5692 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5693 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5695 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5701 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5704 operands[2] = GEN_INT (val2);
5708 [(set (match_operand:DI 0 "ext_dest_operand" "")
5709 (match_operand:DI 1 "immediate_operand" ""))]
5710 "TARGET_SHMEDIA && reload_completed
5711 && GET_CODE (operands[1]) == CONST_DOUBLE"
5712 [(set (match_dup 0) (match_dup 2))
5714 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5717 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5718 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5719 unsigned HOST_WIDE_INT val = low;
5720 unsigned HOST_WIDE_INT sign;
5722 /* Zero-extend the 16 least-significant bits. */
5724 operands[1] = GEN_INT (val);
5726 /* Arithmetic shift right the double-word by 16 bits. */
5728 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5731 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5735 /* This will only be true if high is a sign-extension of low, i.e.,
5736 it must be either 0 or (unsigned)-1, and be zero iff the
5737 most-significant bit of low is set. */
5738 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5739 operands[2] = GEN_INT (low);
5741 operands[2] = immed_double_const (low, high, DImode);
5744 (define_insn "shori_media"
5745 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5746 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5748 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5749 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5753 [(set_attr "type" "arith_media,*")])
5755 (define_insn "*shori_media_si"
5756 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5757 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5759 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5763 (define_expand "movdi"
5764 [(set (match_operand:DI 0 "general_movdst_operand" "")
5765 (match_operand:DI 1 "general_movsrc_operand" ""))]
5767 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5769 (define_insn "movdf_media"
5770 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5771 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5773 && (register_operand (operands[0], DFmode)
5774 || sh_register_operand (operands[1], DFmode))"
5785 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5787 (define_insn "movdf_media_nofpu"
5788 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5789 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5791 && (register_operand (operands[0], DFmode)
5792 || sh_register_operand (operands[1], DFmode))"
5798 [(set_attr "type" "arith_media,*,load_media,store_media")])
5801 [(set (match_operand:DF 0 "arith_reg_dest" "")
5802 (match_operand:DF 1 "immediate_operand" ""))]
5803 "TARGET_SHMEDIA && reload_completed"
5804 [(set (match_dup 3) (match_dup 2))]
5807 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5809 REAL_VALUE_TYPE value;
5811 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5812 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5814 if (HOST_BITS_PER_WIDE_INT >= 64)
5815 operands[2] = immed_double_const ((unsigned long) values[endian]
5816 | ((HOST_WIDE_INT) values[1 - endian]
5820 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5821 operands[2] = immed_double_const (values[endian], values[1 - endian],
5825 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5828 ;; ??? This should be a define expand.
5830 (define_insn "movdf_k"
5831 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5832 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5834 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5835 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5836 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5837 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5838 && (arith_reg_operand (operands[0], DFmode)
5839 || arith_reg_operand (operands[1], DFmode))"
5840 "* return output_movedouble (insn, operands, DFmode);"
5841 [(set_attr "length" "4")
5842 (set_attr "type" "move,pcload,load,store")])
5844 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5845 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5846 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5847 ;; the d/m/c/X alternative, which is split later into single-precision
5848 ;; instructions. And when not optimizing, no splits are done before fixing
5849 ;; up pcloads, so we need usable length information for that.
5850 (define_insn "movdf_i4"
5851 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5852 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5853 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5854 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5855 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5856 && (arith_reg_operand (operands[0], DFmode)
5857 || arith_reg_operand (operands[1], DFmode))"
5869 [(set_attr_alternative "length"
5870 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5872 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5873 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5874 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5876 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5877 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5878 ;; increment or decrement r15 explicitly.
5880 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5881 (const_int 10) (const_int 8))
5883 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5884 (const_int 10) (const_int 8))])
5885 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5886 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5887 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5888 (const_string "double")
5889 (const_string "none")))])
5891 ;; Moving DFmode between fp/general registers through memory
5892 ;; (the top of the stack) is faster than moving through fpul even for
5893 ;; little endian. Because the type of an instruction is important for its
5894 ;; scheduling, it is beneficial to split these operations, rather than
5895 ;; emitting them in one single chunk, even if this will expose a stack
5896 ;; use that will prevent scheduling of other stack accesses beyond this
5899 [(set (match_operand:DF 0 "register_operand" "")
5900 (match_operand:DF 1 "register_operand" ""))
5901 (use (match_operand:PSI 2 "fpscr_operand" ""))
5902 (clobber (match_scratch:SI 3 "=X"))]
5903 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5904 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5910 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5912 emit_move_insn (stack_pointer_rtx,
5913 plus_constant (stack_pointer_rtx, -8));
5914 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5917 tos = gen_tmp_stack_mem (DFmode,
5918 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5919 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5920 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5921 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5922 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5923 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5925 tos = gen_tmp_stack_mem (DFmode,
5926 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5927 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5928 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5929 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5931 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5935 ;; local-alloc sometimes allocates scratch registers even when not required,
5936 ;; so we must be prepared to handle these.
5938 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5940 [(set (match_operand:DF 0 "general_movdst_operand" "")
5941 (match_operand:DF 1 "general_movsrc_operand" ""))
5942 (use (match_operand:PSI 2 "fpscr_operand" ""))
5943 (clobber (match_scratch:SI 3 ""))]
5944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5946 && true_regnum (operands[0]) < 16
5947 && true_regnum (operands[1]) < 16"
5948 [(set (match_dup 0) (match_dup 1))]
5951 /* If this was a reg <-> mem operation with base + index reg addressing,
5952 we have to handle this in a special way. */
5953 rtx mem = operands[0];
5955 if (! memory_operand (mem, DFmode))
5960 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5961 mem = SUBREG_REG (mem);
5962 if (GET_CODE (mem) == MEM)
5964 rtx addr = XEXP (mem, 0);
5965 if (GET_CODE (addr) == PLUS
5966 && GET_CODE (XEXP (addr, 0)) == REG
5967 && GET_CODE (XEXP (addr, 1)) == REG)
5970 rtx reg0 = gen_rtx_REG (Pmode, 0);
5971 rtx regop = operands[store_p], word0 ,word1;
5973 if (GET_CODE (regop) == SUBREG)
5974 alter_subreg (®op);
5975 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5979 mem = copy_rtx (mem);
5980 PUT_MODE (mem, SImode);
5981 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5982 alter_subreg (&word0);
5983 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5984 alter_subreg (&word1);
5985 if (store_p || ! refers_to_regno_p (REGNO (word0),
5986 REGNO (word0) + 1, addr, 0))
5989 ? gen_movsi_ie (mem, word0)
5990 : gen_movsi_ie (word0, mem));
5991 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5992 mem = copy_rtx (mem);
5994 ? gen_movsi_ie (mem, word1)
5995 : gen_movsi_ie (word1, mem));
5996 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6000 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6001 emit_insn (gen_movsi_ie (word1, mem));
6002 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6003 mem = copy_rtx (mem);
6004 emit_insn (gen_movsi_ie (word0, mem));
6011 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6013 [(set (match_operand:DF 0 "register_operand" "")
6014 (match_operand:DF 1 "memory_operand" ""))
6015 (use (match_operand:PSI 2 "fpscr_operand" ""))
6016 (clobber (reg:SI R0_REG))]
6017 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6018 [(parallel [(set (match_dup 0) (match_dup 1))
6020 (clobber (scratch:SI))])]
6023 (define_expand "reload_indf__frn"
6024 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6025 (match_operand:DF 1 "immediate_operand" "FQ"))
6026 (use (reg:PSI FPSCR_REG))
6027 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6031 (define_expand "reload_outdf__RnFRm"
6032 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6033 (match_operand:DF 1 "register_operand" "af,r"))
6034 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6038 ;; Simplify no-op moves.
6040 [(set (match_operand:SF 0 "register_operand" "")
6041 (match_operand:SF 1 "register_operand" ""))
6042 (use (match_operand:PSI 2 "fpscr_operand" ""))
6043 (clobber (match_scratch:SI 3 ""))]
6044 "TARGET_SH2E && reload_completed
6045 && true_regnum (operands[0]) == true_regnum (operands[1])"
6046 [(set (match_dup 0) (match_dup 0))]
6049 ;; fmovd substitute post-reload splits
6051 [(set (match_operand:DF 0 "register_operand" "")
6052 (match_operand:DF 1 "register_operand" ""))
6053 (use (match_operand:PSI 2 "fpscr_operand" ""))
6054 (clobber (match_scratch:SI 3 ""))]
6055 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6056 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6057 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6061 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6062 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6063 gen_rtx_REG (SFmode, src), operands[2]));
6064 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6065 gen_rtx_REG (SFmode, src + 1), operands[2]));
6070 [(set (match_operand:DF 0 "register_operand" "")
6071 (mem:DF (match_operand:SI 1 "register_operand" "")))
6072 (use (match_operand:PSI 2 "fpscr_operand" ""))
6073 (clobber (match_scratch:SI 3 ""))]
6074 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6075 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6076 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6080 int regno = true_regnum (operands[0]);
6082 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6084 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6085 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6086 regno + !! TARGET_LITTLE_ENDIAN),
6087 mem2, operands[2]));
6088 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6089 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6090 regno + ! TARGET_LITTLE_ENDIAN),
6091 change_address (mem, SFmode, NULL_RTX),
6097 [(set (match_operand:DF 0 "register_operand" "")
6098 (match_operand:DF 1 "memory_operand" ""))
6099 (use (match_operand:PSI 2 "fpscr_operand" ""))
6100 (clobber (match_scratch:SI 3 ""))]
6101 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6102 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6106 int regno = true_regnum (operands[0]);
6107 rtx addr, insn, adjust = NULL_RTX;
6108 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6109 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6110 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6112 operands[1] = copy_rtx (mem2);
6113 addr = XEXP (mem2, 0);
6114 if (GET_CODE (addr) != POST_INC)
6116 /* If we have to modify the stack pointer, the value that we have
6117 read with post-increment might be modified by an interrupt,
6118 so write it back. */
6119 if (REGNO (addr) == STACK_POINTER_REGNUM)
6120 adjust = gen_push_e (reg0);
6122 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6123 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6125 addr = XEXP (addr, 0);
6126 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6127 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6128 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6132 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6137 [(set (match_operand:DF 0 "memory_operand" "")
6138 (match_operand:DF 1 "register_operand" ""))
6139 (use (match_operand:PSI 2 "fpscr_operand" ""))
6140 (clobber (match_scratch:SI 3 ""))]
6141 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6142 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6146 int regno = true_regnum (operands[1]);
6147 rtx insn, addr, adjust = NULL_RTX;
6149 operands[0] = copy_rtx (operands[0]);
6150 PUT_MODE (operands[0], SFmode);
6151 insn = emit_insn (gen_movsf_ie (operands[0],
6152 gen_rtx_REG (SFmode,
6153 regno + ! TARGET_LITTLE_ENDIAN),
6155 operands[0] = copy_rtx (operands[0]);
6156 addr = XEXP (operands[0], 0);
6157 if (GET_CODE (addr) != PRE_DEC)
6159 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6160 emit_insn_before (adjust, insn);
6161 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6163 addr = XEXP (addr, 0);
6165 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6166 insn = emit_insn (gen_movsf_ie (operands[0],
6167 gen_rtx_REG (SFmode,
6168 regno + !! TARGET_LITTLE_ENDIAN),
6170 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6174 ;; If the output is a register and the input is memory or a register, we have
6175 ;; to be careful and see which word needs to be loaded first.
6178 [(set (match_operand:DF 0 "general_movdst_operand" "")
6179 (match_operand:DF 1 "general_movsrc_operand" ""))]
6180 "TARGET_SH1 && reload_completed"
6181 [(set (match_dup 2) (match_dup 3))
6182 (set (match_dup 4) (match_dup 5))]
6187 if ((GET_CODE (operands[0]) == MEM
6188 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6189 || (GET_CODE (operands[1]) == MEM
6190 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6193 switch (GET_CODE (operands[0]))
6196 regno = REGNO (operands[0]);
6199 regno = subreg_regno (operands[0]);
6209 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6211 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6212 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6213 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6214 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6218 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6219 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6220 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6221 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6224 if (operands[2] == 0 || operands[3] == 0
6225 || operands[4] == 0 || operands[5] == 0)
6229 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6230 ;; used only once, let combine add in the index again.
6233 [(set (match_operand:SI 0 "register_operand" "")
6234 (match_operand:SI 1 "" ""))
6235 (clobber (match_operand 2 "register_operand" ""))]
6236 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6237 && ALLOW_INDEXED_ADDRESS"
6238 [(use (reg:SI R0_REG))]
6241 rtx addr, reg, const_int;
6243 if (GET_CODE (operands[1]) != MEM)
6245 addr = XEXP (operands[1], 0);
6246 if (GET_CODE (addr) != PLUS)
6248 reg = XEXP (addr, 0);
6249 const_int = XEXP (addr, 1);
6250 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6251 && GET_CODE (const_int) == CONST_INT))
6253 emit_move_insn (operands[2], const_int);
6254 emit_move_insn (operands[0],
6255 change_address (operands[1], VOIDmode,
6256 gen_rtx_PLUS (SImode, reg, operands[2])));
6261 [(set (match_operand:SI 1 "" "")
6262 (match_operand:SI 0 "register_operand" ""))
6263 (clobber (match_operand 2 "register_operand" ""))]
6264 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6265 && ALLOW_INDEXED_ADDRESS"
6266 [(use (reg:SI R0_REG))]
6269 rtx addr, reg, const_int;
6271 if (GET_CODE (operands[1]) != MEM)
6273 addr = XEXP (operands[1], 0);
6274 if (GET_CODE (addr) != PLUS)
6276 reg = XEXP (addr, 0);
6277 const_int = XEXP (addr, 1);
6278 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6279 && GET_CODE (const_int) == CONST_INT))
6281 emit_move_insn (operands[2], const_int);
6282 emit_move_insn (change_address (operands[1], VOIDmode,
6283 gen_rtx_PLUS (SImode, reg, operands[2])),
6288 (define_expand "movdf"
6289 [(set (match_operand:DF 0 "general_movdst_operand" "")
6290 (match_operand:DF 1 "general_movsrc_operand" ""))]
6294 if (prepare_move_operands (operands, DFmode)) DONE;
6297 if (TARGET_SHMEDIA_FPU)
6298 emit_insn (gen_movdf_media (operands[0], operands[1]));
6300 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6303 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6305 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6310 ;;This is incompatible with the way gcc uses subregs.
6311 ;;(define_insn "movv2sf_i"
6312 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6313 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6314 ;; "TARGET_SHMEDIA_FPU
6315 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6316 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6320 ;; fst%M0.p %m0, %1"
6321 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6323 (define_insn_and_split "movv2sf_i"
6324 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6325 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6326 "TARGET_SHMEDIA_FPU"
6328 "TARGET_SHMEDIA_FPU && reload_completed"
6329 [(set (match_dup 0) (match_dup 1))]
6332 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6333 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6336 (define_expand "movv2sf"
6337 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6338 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6339 "TARGET_SHMEDIA_FPU"
6342 if (prepare_move_operands (operands, V2SFmode))
6346 (define_expand "addv2sf3"
6347 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6348 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6349 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6350 "TARGET_SHMEDIA_FPU"
6353 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6357 (define_expand "subv2sf3"
6358 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6359 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6360 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6361 "TARGET_SHMEDIA_FPU"
6364 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6368 (define_expand "mulv2sf3"
6369 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6370 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6371 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6372 "TARGET_SHMEDIA_FPU"
6375 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6379 (define_expand "divv2sf3"
6380 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6381 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6382 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6383 "TARGET_SHMEDIA_FPU"
6386 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6390 (define_insn_and_split "*movv4sf_i"
6391 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6392 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6393 "TARGET_SHMEDIA_FPU"
6395 "&& reload_completed"
6401 for (i = 0; i < 4/2; i++)
6405 if (GET_CODE (operands[0]) == MEM)
6406 x = adjust_address (operands[0], V2SFmode,
6407 i * GET_MODE_SIZE (V2SFmode));
6409 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6411 if (GET_CODE (operands[1]) == MEM)
6412 y = adjust_address (operands[1], V2SFmode,
6413 i * GET_MODE_SIZE (V2SFmode));
6415 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6417 emit_insn (gen_movv2sf_i (x, y));
6422 [(set_attr "length" "8")])
6424 (define_expand "movv4sf"
6425 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6426 (match_operand:V4SF 1 "general_operand" ""))]
6427 "TARGET_SHMEDIA_FPU"
6430 if (prepare_move_operands (operands, V4SFmode))
6434 (define_insn_and_split "*movv16sf_i"
6435 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6436 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6437 "TARGET_SHMEDIA_FPU"
6439 "&& reload_completed"
6445 for (i = 0; i < 16/2; i++)
6449 if (GET_CODE (operands[0]) == MEM)
6450 x = adjust_address (operands[0], V2SFmode,
6451 i * GET_MODE_SIZE (V2SFmode));
6454 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6458 if (GET_CODE (operands[1]) == MEM)
6459 y = adjust_address (operands[1], V2SFmode,
6460 i * GET_MODE_SIZE (V2SFmode));
6463 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6467 emit_insn (gen_movv2sf_i (x, y));
6472 [(set_attr "length" "32")])
6474 (define_expand "movv16sf"
6475 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6476 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6477 "TARGET_SHMEDIA_FPU"
6480 if (prepare_move_operands (operands, V16SFmode))
6484 (define_insn "movsf_media"
6485 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6486 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6488 && (register_operand (operands[0], SFmode)
6489 || sh_register_operand (operands[1], SFmode))"
6500 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6501 (set (attr "highpart")
6502 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6503 (const_string "user")]
6504 (const_string "ignore")))])
6506 (define_insn "movsf_media_nofpu"
6507 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6508 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6510 && (register_operand (operands[0], SFmode)
6511 || sh_register_operand (operands[1], SFmode))"
6517 [(set_attr "type" "arith_media,*,load_media,store_media")
6518 (set (attr "highpart")
6519 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6520 (const_string "user")]
6521 (const_string "ignore")))])
6524 [(set (match_operand:SF 0 "arith_reg_dest" "")
6525 (match_operand:SF 1 "immediate_operand" ""))]
6526 "TARGET_SHMEDIA && reload_completed
6527 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6528 [(set (match_dup 3) (match_dup 2))]
6532 REAL_VALUE_TYPE value;
6534 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6535 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6536 operands[2] = GEN_INT (values);
6538 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6541 (define_insn "movsf_i"
6542 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6543 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6546 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6547 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6548 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6549 && (arith_reg_operand (operands[0], SFmode)
6550 || arith_reg_operand (operands[1], SFmode))"
6559 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6561 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6562 ;; update_flow_info would not know where to put REG_EQUAL notes
6563 ;; when the destination changes mode.
6564 (define_insn "movsf_ie"
6565 [(set (match_operand:SF 0 "general_movdst_operand"
6566 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6567 (match_operand:SF 1 "general_movsrc_operand"
6568 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6569 (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"))
6570 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6573 && (arith_reg_operand (operands[0], SFmode)
6574 || arith_reg_operand (operands[1], SFmode)
6575 || arith_reg_operand (operands[3], SImode)
6576 || (fpul_operand (operands[0], SFmode)
6577 && memory_operand (operands[1], SFmode)
6578 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6579 || (fpul_operand (operands[1], SFmode)
6580 && memory_operand (operands[0], SFmode)
6581 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6601 ! move optimized away"
6602 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6603 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6604 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6605 (set_attr_alternative "length"
6612 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613 (const_int 4) (const_int 2))
6615 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6616 (const_int 4) (const_int 2))
6629 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6630 (const_string "single")
6631 (const_string "none")))])
6634 [(set (match_operand:SF 0 "register_operand" "")
6635 (match_operand:SF 1 "register_operand" ""))
6636 (use (match_operand:PSI 2 "fpscr_operand" ""))
6637 (clobber (reg:SI FPUL_REG))]
6639 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641 (clobber (scratch:SI))])
6642 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644 (clobber (scratch:SI))])]
6647 (define_expand "movsf"
6648 [(set (match_operand:SF 0 "general_movdst_operand" "")
6649 (match_operand:SF 1 "general_movsrc_operand" ""))]
6653 if (prepare_move_operands (operands, SFmode))
6657 if (TARGET_SHMEDIA_FPU)
6658 emit_insn (gen_movsf_media (operands[0], operands[1]));
6660 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6665 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6670 (define_insn "mov_nop"
6671 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6674 [(set_attr "length" "0")
6675 (set_attr "type" "nil")])
6677 (define_expand "reload_insf__frn"
6678 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6679 (match_operand:SF 1 "immediate_operand" "FQ"))
6680 (use (reg:PSI FPSCR_REG))
6681 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6685 (define_expand "reload_insi__i_fpul"
6686 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6687 (match_operand:SI 1 "immediate_operand" "i"))
6688 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6692 (define_expand "ptabs"
6693 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6697 if (!TARGET_PT_FIXED)
6699 rtx eq = operands[1];
6701 /* ??? For canonical RTL we really should remove any CONST from EQ
6702 before wrapping it in the AND, and finally wrap the EQ into a
6703 const if is constant. However, for reload we must expose the
6704 input register or symbolic constant, and we can't have
6705 different insn structures outside of the operands for different
6706 alternatives of the same pattern. */
6707 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6710 = (gen_rtx_IF_THEN_ELSE
6713 gen_rtx_MEM (PDImode, operands[1]),
6714 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6715 PDImode, operands[1])));
6719 ;; expanded by ptabs expander.
6720 (define_insn "*extendsipdi_media"
6721 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6722 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6726 (mem:PDI (match_dup 1))
6727 (sign_extend:PDI (match_dup 1))))]
6728 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6732 [(set_attr "type" "ptabs_media,pt_media")
6733 (set_attr "length" "4,*")])
6735 (define_insn "*truncdipdi_media"
6736 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6737 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6741 (mem:PDI (match_dup 1))
6742 (truncate:PDI (match_dup 1))))]
6743 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6747 [(set_attr "type" "ptabs_media,pt_media")
6748 (set_attr "length" "4,*")])
6750 (define_insn "*movsi_y"
6751 [(set (match_operand:SI 0 "register_operand" "=y,y")
6752 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6753 (clobber (match_scratch:SI 2 "=&z,r"))]
6755 && (reload_in_progress || reload_completed)"
6757 [(set_attr "length" "4")
6758 (set_attr "type" "pcload,move")])
6761 [(set (match_operand:SI 0 "register_operand" "")
6762 (match_operand:SI 1 "immediate_operand" ""))
6763 (clobber (match_operand:SI 2 "register_operand" ""))]
6765 [(set (match_dup 2) (match_dup 1))
6766 (set (match_dup 0) (match_dup 2))]
6770 [(set (match_operand:SI 0 "register_operand" "")
6771 (match_operand:SI 1 "memory_operand" ""))
6772 (clobber (reg:SI R0_REG))]
6774 [(set (match_dup 0) (match_dup 1))]
6777 ;; ------------------------------------------------------------------------
6778 ;; Define the real conditional branch instructions.
6779 ;; ------------------------------------------------------------------------
6781 (define_insn "branch_true"
6782 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6783 (label_ref (match_operand 0 "" ""))
6786 "* return output_branch (1, insn, operands);"
6787 [(set_attr "type" "cbranch")])
6789 (define_insn "branch_false"
6790 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6791 (label_ref (match_operand 0 "" ""))
6794 "* return output_branch (0, insn, operands);"
6795 [(set_attr "type" "cbranch")])
6797 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6798 ;; which destination is too far away.
6799 ;; The const_int_operand is distinct for each branch target; it avoids
6800 ;; unwanted matches with redundant_insn.
6801 (define_insn "block_branch_redirect"
6802 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6805 [(set_attr "length" "0")])
6807 ;; This one has the additional purpose to record a possible scratch register
6808 ;; for the following branch.
6809 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6810 ;; because the insn then might be deemed dead and deleted. And we can't
6811 ;; make the use in the jump insn explicit because that would disable
6812 ;; delay slot scheduling from the target.
6813 (define_insn "indirect_jump_scratch"
6814 [(set (match_operand:SI 0 "register_operand" "=r")
6815 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6816 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6819 [(set_attr "length" "0")])
6821 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6822 ;; being pulled into the delay slot of a condbranch that has been made to
6823 ;; jump around the unconditional jump because it was out of range.
6824 (define_insn "stuff_delay_slot"
6826 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6827 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6830 [(set_attr "length" "0")
6831 (set_attr "cond_delay_slot" "yes")])
6833 ;; Conditional branch insns
6835 (define_expand "beq_media"
6837 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6838 (match_operand:DI 2 "arith_operand" "r,I06"))
6839 (match_operand 0 "" "")
6842 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6844 (define_insn "*beq_media_i"
6846 (if_then_else (match_operator 3 "equality_comparison_operator"
6847 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6848 (match_operand:DI 2 "arith_operand" "r,I06")])
6849 (match_operand 0 "target_operand" "b,b")
6854 b%o3i%' %1, %2, %0%>"
6855 [(set_attr "type" "cbranch_media")])
6857 (define_insn "*beq_media_i32"
6859 (if_then_else (match_operator 3 "equality_comparison_operator"
6860 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6861 (match_operand:SI 2 "arith_operand" "r,I06")])
6862 (match_operand 0 "target_operand" "b,b")
6867 b%o3i%' %1, %2, %0%>"
6868 [(set_attr "type" "cbranch_media")])
6870 (define_expand "bne_media"
6872 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6873 (match_operand:DI 2 "arith_operand" "r,I06"))
6874 (match_operand 0 "" "")
6877 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6879 (define_expand "bgt_media"
6881 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6882 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6883 (match_operand 0 "" "")
6886 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6888 (define_expand "bge_media"
6890 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6891 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6892 (match_operand 0 "" "")
6895 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6897 (define_expand "bgtu_media"
6899 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6900 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6901 (match_operand 0 "" "")
6904 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6906 (define_expand "bgeu_media"
6908 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6909 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6910 (match_operand 0 "" "")
6913 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6915 (define_insn "*bgt_media_i"
6917 (if_then_else (match_operator 3 "greater_comparison_operator"
6918 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6919 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6920 (match_operand 0 "target_operand" "b")
6923 "b%o3%' %N1, %N2, %0%>"
6924 [(set_attr "type" "cbranch_media")])
6926 (define_insn "*bgt_media_i32"
6928 (if_then_else (match_operator 3 "greater_comparison_operator"
6929 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6930 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6931 (match_operand 0 "target_operand" "b")
6934 "b%o3%' %N1, %N2, %0%>"
6935 [(set_attr "type" "cbranch_media")])
6937 ;; These are only needed to make invert_jump() happy - otherwise, jump
6938 ;; optimization will be silently disabled.
6939 (define_insn "*blt_media_i"
6941 (if_then_else (match_operator 3 "less_comparison_operator"
6942 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6943 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6944 (match_operand 0 "target_operand" "b")
6947 "b%o3%' %N2, %N1, %0%>"
6948 [(set_attr "type" "cbranch_media")])
6950 (define_insn "*blt_media_i32"
6952 (if_then_else (match_operator 3 "less_comparison_operator"
6953 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6954 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6955 (match_operand 0 "target_operand" "b")
6958 "b%o3%' %N2, %N1, %0%>"
6959 [(set_attr "type" "cbranch_media")])
6961 (define_expand "beq"
6963 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6964 (label_ref (match_operand 0 "" ""))
6971 enum machine_mode mode = GET_MODE (sh_compare_op0);
6973 if (mode != DImode && mode != SImode)
6975 rtx tmp = gen_reg_rtx (DImode);
6977 emit_insn (gen_seq (tmp));
6978 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6982 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6983 if (CONSTANT_P (sh_compare_op1)
6984 && (! satisfies_constraint_I06 (sh_compare_op1)))
6985 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6986 emit_jump_insn (gen_beq_media (operands[0],
6987 sh_compare_op0, sh_compare_op1));
6991 from_compare (operands, EQ);
6994 (define_expand "bne"
6996 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6997 (label_ref (match_operand 0 "" ""))
7004 enum machine_mode mode = GET_MODE (sh_compare_op0);
7006 if (mode != DImode && mode != SImode)
7008 rtx tmp = gen_reg_rtx (DImode);
7010 emit_insn (gen_seq (tmp));
7011 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7015 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7016 if (CONSTANT_P (sh_compare_op1)
7017 && (! satisfies_constraint_I06 (sh_compare_op1)))
7018 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7019 emit_jump_insn (gen_bne_media (operands[0],
7020 sh_compare_op0, sh_compare_op1));
7024 from_compare (operands, EQ);
7027 (define_expand "bgt"
7029 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7030 (label_ref (match_operand 0 "" ""))
7037 enum machine_mode mode = GET_MODE (sh_compare_op0);
7039 if (mode != DImode && mode != SImode)
7041 rtx tmp = gen_reg_rtx (DImode);
7043 emit_insn (gen_sgt (tmp));
7044 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7048 if (sh_compare_op0 != const0_rtx)
7049 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7050 if (sh_compare_op1 != const0_rtx)
7051 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7052 emit_jump_insn (gen_bgt_media (operands[0],
7053 sh_compare_op0, sh_compare_op1));
7057 from_compare (operands, GT);
7060 (define_expand "blt"
7062 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7063 (label_ref (match_operand 0 "" ""))
7070 enum machine_mode mode = GET_MODE (sh_compare_op0);
7072 if (mode != DImode && mode != SImode)
7074 rtx tmp = gen_reg_rtx (DImode);
7076 emit_insn (gen_slt (tmp));
7077 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7081 if (sh_compare_op0 != const0_rtx)
7082 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7083 if (sh_compare_op1 != const0_rtx)
7084 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7085 emit_jump_insn (gen_bgt_media (operands[0],
7086 sh_compare_op1, sh_compare_op0));
7090 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7092 rtx tmp = sh_compare_op0;
7093 sh_compare_op0 = sh_compare_op1;
7094 sh_compare_op1 = tmp;
7095 emit_insn (gen_bgt (operands[0]));
7098 from_compare (operands, GE);
7101 (define_expand "ble"
7103 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7104 (label_ref (match_operand 0 "" ""))
7111 enum machine_mode mode = GET_MODE (sh_compare_op0);
7113 if (mode != DImode && mode != SImode)
7115 rtx tmp = gen_reg_rtx (DImode);
7117 emit_insn (gen_sle (tmp));
7118 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7122 if (sh_compare_op0 != const0_rtx)
7123 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7124 if (sh_compare_op1 != const0_rtx)
7125 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7126 emit_jump_insn (gen_bge_media (operands[0],
7127 sh_compare_op1, sh_compare_op0));
7133 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7135 rtx tmp = sh_compare_op0;
7136 sh_compare_op0 = sh_compare_op1;
7137 sh_compare_op1 = tmp;
7138 emit_insn (gen_bge (operands[0]));
7141 from_compare (operands, GT);
7144 (define_expand "bge"
7146 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7147 (label_ref (match_operand 0 "" ""))
7154 enum machine_mode mode = GET_MODE (sh_compare_op0);
7156 if (mode != DImode && mode != SImode)
7158 rtx tmp = gen_reg_rtx (DImode);
7160 emit_insn (gen_sge (tmp));
7161 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7165 if (sh_compare_op0 != const0_rtx)
7166 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7167 if (sh_compare_op1 != const0_rtx)
7168 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7169 emit_jump_insn (gen_bge_media (operands[0],
7170 sh_compare_op0, sh_compare_op1));
7176 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7178 rtx tmp = sh_compare_op0;
7179 sh_compare_op0 = sh_compare_op1;
7180 sh_compare_op1 = tmp;
7181 emit_insn (gen_ble (operands[0]));
7184 from_compare (operands, GE);
7187 (define_expand "bgtu"
7189 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7190 (label_ref (match_operand 0 "" ""))
7197 enum machine_mode mode = GET_MODE (sh_compare_op0);
7199 if (sh_compare_op0 != const0_rtx)
7200 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7201 if (sh_compare_op1 != const0_rtx)
7202 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7203 emit_jump_insn (gen_bgtu_media (operands[0],
7204 sh_compare_op0, sh_compare_op1));
7208 from_compare (operands, GTU);
7211 (define_expand "bltu"
7213 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7214 (label_ref (match_operand 0 "" ""))
7221 enum machine_mode mode = GET_MODE (sh_compare_op0);
7223 if (sh_compare_op0 != const0_rtx)
7224 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7225 if (sh_compare_op1 != const0_rtx)
7226 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7227 emit_jump_insn (gen_bgtu_media (operands[0],
7228 sh_compare_op1, sh_compare_op0));
7232 from_compare (operands, GEU);
7235 (define_expand "bgeu"
7237 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7238 (label_ref (match_operand 0 "" ""))
7245 enum machine_mode mode = GET_MODE (sh_compare_op0);
7247 if (sh_compare_op0 != const0_rtx)
7248 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7249 if (sh_compare_op1 != const0_rtx)
7250 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7251 emit_jump_insn (gen_bgeu_media (operands[0],
7252 sh_compare_op0, sh_compare_op1));
7256 from_compare (operands, GEU);
7259 (define_expand "bleu"
7261 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7262 (label_ref (match_operand 0 "" ""))
7269 enum machine_mode mode = GET_MODE (sh_compare_op0);
7271 if (sh_compare_op0 != const0_rtx)
7272 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7273 if (sh_compare_op1 != const0_rtx)
7274 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7275 emit_jump_insn (gen_bgeu_media (operands[0],
7276 sh_compare_op1, sh_compare_op0));
7280 from_compare (operands, GTU);
7283 (define_expand "bunordered"
7284 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7286 (if_then_else (ne (match_dup 1) (const_int 0))
7287 (match_operand 0 "" "")
7292 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7293 operands[1] = gen_reg_rtx (SImode);
7294 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7295 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7298 ;; combiner splitter for test-and-branch on single bit in register. This
7299 ;; is endian dependent because the non-paradoxical subreg looks different
7304 (match_operator 3 "equality_comparison_operator"
7305 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7306 "extend_reg_operand" "")
7310 "const_int_operand" "")) 0)
7312 (match_operand 0 "target_operand" "")
7314 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7315 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7316 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7317 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7321 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7322 operands[6] = (GET_CODE (operands[3]) == EQ
7323 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7324 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7327 ; operand 0 is the loop count pseudo register
7328 ; operand 1 is the number of loop iterations or 0 if it is unknown
7329 ; operand 2 is the maximum number of loop iterations
7330 ; operand 3 is the number of levels of enclosed loops
7331 ; operand 4 is the label to jump to at the top of the loop
7333 (define_expand "doloop_end"
7334 [(parallel [(set (pc) (if_then_else
7335 (ne:SI (match_operand:SI 0 "" "")
7337 (label_ref (match_operand 4 "" ""))
7340 (plus:SI (match_dup 0) (const_int -1)))
7341 (clobber (reg:SI T_REG))])]
7345 if (GET_MODE (operands[0]) != SImode)
7350 (define_insn_and_split "doloop_end_split"
7352 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7354 (label_ref (match_operand 1 "" ""))
7357 (plus (match_dup 0) (const_int -1)))
7358 (clobber (reg:SI T_REG))]
7362 [(parallel [(set (reg:SI T_REG)
7363 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7365 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7366 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7367 (label_ref (match_operand 1 "" ""))
7370 [(set_attr "type" "cbranch")])
7373 ;; ------------------------------------------------------------------------
7374 ;; Jump and linkage insns
7375 ;; ------------------------------------------------------------------------
7377 (define_insn "jump_compact"
7379 (label_ref (match_operand 0 "" "")))]
7383 /* The length is 16 if the delay slot is unfilled. */
7384 if (get_attr_length(insn) > 4)
7385 return output_far_jump(insn, operands[0]);
7387 return \"bra %l0%#\";
7389 [(set_attr "type" "jump")
7390 (set_attr "needs_delay_slot" "yes")])
7392 ;; ??? It would be much saner to explicitly use the scratch register
7393 ;; in the jump insn, and have indirect_jump_scratch only set it,
7394 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7395 ;; from the target then, as it uses simplejump_p.
7396 ;;(define_insn "jump_compact_far"
7398 ;; (label_ref (match_operand 0 "" "")))
7399 ;; (use (match_operand 1 "register_operand" "r")]
7401 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7402 ;; [(set_attr "type" "jump")
7403 ;; (set_attr "needs_delay_slot" "yes")])
7405 (define_insn "jump_media"
7407 (match_operand 0 "target_operand" "b"))]
7410 [(set_attr "type" "jump_media")])
7412 (define_expand "jump"
7414 (label_ref (match_operand 0 "" "")))]
7419 emit_jump_insn (gen_jump_compact (operands[0]));
7420 else if (TARGET_SHMEDIA)
7422 if (reload_in_progress || reload_completed)
7424 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7430 (define_insn "force_mode_for_call"
7431 [(use (reg:PSI FPSCR_REG))]
7434 [(set_attr "length" "0")
7435 (set (attr "fp_mode")
7436 (if_then_else (eq_attr "fpu_single" "yes")
7437 (const_string "single") (const_string "double")))])
7439 (define_insn "calli"
7440 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7441 (match_operand 1 "" ""))
7442 (use (reg:PSI FPSCR_REG))
7443 (clobber (reg:SI PR_REG))]
7446 [(set_attr "type" "call")
7447 (set (attr "fp_mode")
7448 (if_then_else (eq_attr "fpu_single" "yes")
7449 (const_string "single") (const_string "double")))
7450 (set_attr "needs_delay_slot" "yes")
7451 (set_attr "fp_set" "unknown")])
7453 ;; This is a pc-rel call, using bsrf, for use with PIC.
7455 (define_insn "calli_pcrel"
7456 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7457 (match_operand 1 "" ""))
7458 (use (reg:PSI FPSCR_REG))
7459 (use (reg:SI PIC_REG))
7460 (use (match_operand 2 "" ""))
7461 (clobber (reg:SI PR_REG))]
7464 [(set_attr "type" "call")
7465 (set (attr "fp_mode")
7466 (if_then_else (eq_attr "fpu_single" "yes")
7467 (const_string "single") (const_string "double")))
7468 (set_attr "needs_delay_slot" "yes")
7469 (set_attr "fp_set" "unknown")])
7471 (define_insn_and_split "call_pcrel"
7472 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7473 (match_operand 1 "" ""))
7474 (use (reg:PSI FPSCR_REG))
7475 (use (reg:SI PIC_REG))
7476 (clobber (reg:SI PR_REG))
7477 (clobber (match_scratch:SI 2 "=r"))]
7484 rtx lab = PATTERN (gen_call_site ());
7486 if (SYMBOL_REF_LOCAL_P (operands[0]))
7487 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7489 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7490 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7493 [(set_attr "type" "call")
7494 (set (attr "fp_mode")
7495 (if_then_else (eq_attr "fpu_single" "yes")
7496 (const_string "single") (const_string "double")))
7497 (set_attr "needs_delay_slot" "yes")
7498 (set_attr "fp_set" "unknown")])
7500 (define_insn "call_compact"
7501 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7502 (match_operand 1 "" ""))
7503 (match_operand 2 "immediate_operand" "n")
7504 (use (reg:SI R0_REG))
7505 (use (reg:SI R1_REG))
7506 (use (reg:PSI FPSCR_REG))
7507 (clobber (reg:SI PR_REG))]
7508 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7510 [(set_attr "type" "call")
7511 (set (attr "fp_mode")
7512 (if_then_else (eq_attr "fpu_single" "yes")
7513 (const_string "single") (const_string "double")))
7514 (set_attr "needs_delay_slot" "yes")])
7516 (define_insn "call_compact_rettramp"
7517 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7518 (match_operand 1 "" ""))
7519 (match_operand 2 "immediate_operand" "n")
7520 (use (reg:SI R0_REG))
7521 (use (reg:SI R1_REG))
7522 (use (reg:PSI FPSCR_REG))
7523 (clobber (reg:SI R10_REG))
7524 (clobber (reg:SI PR_REG))]
7525 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7527 [(set_attr "type" "call")
7528 (set (attr "fp_mode")
7529 (if_then_else (eq_attr "fpu_single" "yes")
7530 (const_string "single") (const_string "double")))
7531 (set_attr "needs_delay_slot" "yes")])
7533 (define_insn "call_media"
7534 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7535 (match_operand 1 "" ""))
7536 (clobber (reg:DI PR_MEDIA_REG))]
7539 [(set_attr "type" "jump_media")])
7541 (define_insn "call_valuei"
7542 [(set (match_operand 0 "" "=rf")
7543 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7544 (match_operand 2 "" "")))
7545 (use (reg:PSI FPSCR_REG))
7546 (clobber (reg:SI PR_REG))]
7549 [(set_attr "type" "call")
7550 (set (attr "fp_mode")
7551 (if_then_else (eq_attr "fpu_single" "yes")
7552 (const_string "single") (const_string "double")))
7553 (set_attr "needs_delay_slot" "yes")
7554 (set_attr "fp_set" "unknown")])
7556 (define_insn "call_valuei_pcrel"
7557 [(set (match_operand 0 "" "=rf")
7558 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7559 (match_operand 2 "" "")))
7560 (use (reg:PSI FPSCR_REG))
7561 (use (reg:SI PIC_REG))
7562 (use (match_operand 3 "" ""))
7563 (clobber (reg:SI PR_REG))]
7566 [(set_attr "type" "call")
7567 (set (attr "fp_mode")
7568 (if_then_else (eq_attr "fpu_single" "yes")
7569 (const_string "single") (const_string "double")))
7570 (set_attr "needs_delay_slot" "yes")
7571 (set_attr "fp_set" "unknown")])
7573 (define_insn_and_split "call_value_pcrel"
7574 [(set (match_operand 0 "" "=rf")
7575 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7576 (match_operand 2 "" "")))
7577 (use (reg:PSI FPSCR_REG))
7578 (use (reg:SI PIC_REG))
7579 (clobber (reg:SI PR_REG))
7580 (clobber (match_scratch:SI 3 "=r"))]
7587 rtx lab = PATTERN (gen_call_site ());
7589 if (SYMBOL_REF_LOCAL_P (operands[1]))
7590 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7592 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7593 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7594 operands[2], copy_rtx (lab)));
7597 [(set_attr "type" "call")
7598 (set (attr "fp_mode")
7599 (if_then_else (eq_attr "fpu_single" "yes")
7600 (const_string "single") (const_string "double")))
7601 (set_attr "needs_delay_slot" "yes")
7602 (set_attr "fp_set" "unknown")])
7604 (define_insn "call_value_compact"
7605 [(set (match_operand 0 "" "=rf")
7606 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7607 (match_operand 2 "" "")))
7608 (match_operand 3 "immediate_operand" "n")
7609 (use (reg:SI R0_REG))
7610 (use (reg:SI R1_REG))
7611 (use (reg:PSI FPSCR_REG))
7612 (clobber (reg:SI PR_REG))]
7613 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7615 [(set_attr "type" "call")
7616 (set (attr "fp_mode")
7617 (if_then_else (eq_attr "fpu_single" "yes")
7618 (const_string "single") (const_string "double")))
7619 (set_attr "needs_delay_slot" "yes")])
7621 (define_insn "call_value_compact_rettramp"
7622 [(set (match_operand 0 "" "=rf")
7623 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7624 (match_operand 2 "" "")))
7625 (match_operand 3 "immediate_operand" "n")
7626 (use (reg:SI R0_REG))
7627 (use (reg:SI R1_REG))
7628 (use (reg:PSI FPSCR_REG))
7629 (clobber (reg:SI R10_REG))
7630 (clobber (reg:SI PR_REG))]
7631 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7633 [(set_attr "type" "call")
7634 (set (attr "fp_mode")
7635 (if_then_else (eq_attr "fpu_single" "yes")
7636 (const_string "single") (const_string "double")))
7637 (set_attr "needs_delay_slot" "yes")])
7639 (define_insn "call_value_media"
7640 [(set (match_operand 0 "" "=rf")
7641 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7642 (match_operand 2 "" "")))
7643 (clobber (reg:DI PR_MEDIA_REG))]
7646 [(set_attr "type" "jump_media")])
7648 (define_expand "call"
7649 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7650 (match_operand 1 "" ""))
7651 (match_operand 2 "" "")
7652 (use (reg:PSI FPSCR_REG))
7653 (clobber (reg:SI PR_REG))])]
7659 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7660 emit_call_insn (gen_call_media (operands[0], operands[1]));
7663 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7665 rtx cookie_rtx = operands[2];
7666 long cookie = INTVAL (cookie_rtx);
7667 rtx func = XEXP (operands[0], 0);
7672 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7674 rtx reg = gen_reg_rtx (Pmode);
7676 emit_insn (gen_symGOTPLT2reg (reg, func));
7680 func = legitimize_pic_address (func, Pmode, 0);
7683 r0 = gen_rtx_REG (SImode, R0_REG);
7684 r1 = gen_rtx_REG (SImode, R1_REG);
7686 /* Since such a call function may use all call-clobbered
7687 registers, we force a mode switch earlier, so that we don't
7688 run out of registers when adjusting fpscr for the call. */
7689 emit_insn (gen_force_mode_for_call ());
7692 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7694 operands[0] = force_reg (SImode, operands[0]);
7696 emit_move_insn (r0, func);
7697 emit_move_insn (r1, cookie_rtx);
7699 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7700 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7703 emit_call_insn (gen_call_compact (operands[0], operands[1],
7708 else if (TARGET_SHCOMPACT && flag_pic
7709 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7710 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7712 rtx reg = gen_reg_rtx (Pmode);
7714 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7715 XEXP (operands[0], 0) = reg;
7717 if (flag_pic && TARGET_SH2
7718 && GET_CODE (operands[0]) == MEM
7719 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7721 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7726 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7727 operands[1] = operands[2];
7730 emit_call_insn (gen_calli (operands[0], operands[1]));
7734 (define_insn "call_pop_compact"
7735 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7736 (match_operand 1 "" ""))
7737 (match_operand 2 "immediate_operand" "n")
7738 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7739 (match_operand 3 "immediate_operand" "n")))
7740 (use (reg:SI R0_REG))
7741 (use (reg:SI R1_REG))
7742 (use (reg:PSI FPSCR_REG))
7743 (clobber (reg:SI PR_REG))]
7744 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7746 [(set_attr "type" "call")
7747 (set (attr "fp_mode")
7748 (if_then_else (eq_attr "fpu_single" "yes")
7749 (const_string "single") (const_string "double")))
7750 (set_attr "needs_delay_slot" "yes")])
7752 (define_insn "call_pop_compact_rettramp"
7753 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7754 (match_operand 1 "" ""))
7755 (match_operand 2 "immediate_operand" "n")
7756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7757 (match_operand 3 "immediate_operand" "n")))
7758 (use (reg:SI R0_REG))
7759 (use (reg:SI R1_REG))
7760 (use (reg:PSI FPSCR_REG))
7761 (clobber (reg:SI R10_REG))
7762 (clobber (reg:SI PR_REG))]
7763 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7765 [(set_attr "type" "call")
7766 (set (attr "fp_mode")
7767 (if_then_else (eq_attr "fpu_single" "yes")
7768 (const_string "single") (const_string "double")))
7769 (set_attr "needs_delay_slot" "yes")])
7771 (define_expand "call_pop"
7772 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773 (match_operand 1 "" ""))
7774 (match_operand 2 "" "")
7775 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7776 (match_operand 3 "" "")))])]
7785 gcc_assert (operands[2] && INTVAL (operands[2]));
7786 cookie_rtx = operands[2];
7787 cookie = INTVAL (cookie_rtx);
7788 func = XEXP (operands[0], 0);
7792 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7794 rtx reg = gen_reg_rtx (Pmode);
7795 emit_insn (gen_symGOTPLT2reg (reg, func));
7799 func = legitimize_pic_address (func, Pmode, 0);
7802 r0 = gen_rtx_REG (SImode, R0_REG);
7803 r1 = gen_rtx_REG (SImode, R1_REG);
7805 /* Since such a call function may use all call-clobbered
7806 registers, we force a mode switch earlier, so that we don't
7807 run out of registers when adjusting fpscr for the call. */
7808 emit_insn (gen_force_mode_for_call ());
7810 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7812 operands[0] = force_reg (SImode, operands[0]);
7814 emit_move_insn (r0, func);
7815 emit_move_insn (r1, cookie_rtx);
7817 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7818 emit_call_insn (gen_call_pop_compact_rettramp
7819 (operands[0], operands[1], operands[2], operands[3]));
7821 emit_call_insn (gen_call_pop_compact
7822 (operands[0], operands[1], operands[2], operands[3]));
7827 (define_expand "call_value"
7828 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7829 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7830 (match_operand 2 "" "")))
7831 (match_operand 3 "" "")
7832 (use (reg:PSI FPSCR_REG))
7833 (clobber (reg:SI PR_REG))])]
7839 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7840 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7844 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7846 rtx cookie_rtx = operands[3];
7847 long cookie = INTVAL (cookie_rtx);
7848 rtx func = XEXP (operands[1], 0);
7853 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7855 rtx reg = gen_reg_rtx (Pmode);
7857 emit_insn (gen_symGOTPLT2reg (reg, func));
7861 func = legitimize_pic_address (func, Pmode, 0);
7864 r0 = gen_rtx_REG (SImode, R0_REG);
7865 r1 = gen_rtx_REG (SImode, R1_REG);
7867 /* Since such a call function may use all call-clobbered
7868 registers, we force a mode switch earlier, so that we don't
7869 run out of registers when adjusting fpscr for the call. */
7870 emit_insn (gen_force_mode_for_call ());
7873 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7875 operands[1] = force_reg (SImode, operands[1]);
7877 emit_move_insn (r0, func);
7878 emit_move_insn (r1, cookie_rtx);
7880 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7881 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7886 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7887 operands[2], operands[3]));
7891 else if (TARGET_SHCOMPACT && flag_pic
7892 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7893 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7895 rtx reg = gen_reg_rtx (Pmode);
7897 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7898 XEXP (operands[1], 0) = reg;
7900 if (flag_pic && TARGET_SH2
7901 && GET_CODE (operands[1]) == MEM
7902 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7904 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7909 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7911 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7915 (define_insn "sibcalli"
7916 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7917 (match_operand 1 "" ""))
7918 (use (reg:PSI FPSCR_REG))
7922 [(set_attr "needs_delay_slot" "yes")
7923 (set (attr "fp_mode")
7924 (if_then_else (eq_attr "fpu_single" "yes")
7925 (const_string "single") (const_string "double")))
7926 (set_attr "type" "jump_ind")])
7928 (define_insn "sibcalli_pcrel"
7929 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7930 (match_operand 1 "" ""))
7931 (use (match_operand 2 "" ""))
7932 (use (reg:PSI FPSCR_REG))
7936 [(set_attr "needs_delay_slot" "yes")
7937 (set (attr "fp_mode")
7938 (if_then_else (eq_attr "fpu_single" "yes")
7939 (const_string "single") (const_string "double")))
7940 (set_attr "type" "jump_ind")])
7942 ;; This uses an unspec to describe that the symbol_ref is very close.
7943 (define_insn "sibcalli_thunk"
7944 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7946 (match_operand 1 "" ""))
7947 (use (reg:PSI FPSCR_REG))
7951 [(set_attr "needs_delay_slot" "yes")
7952 (set (attr "fp_mode")
7953 (if_then_else (eq_attr "fpu_single" "yes")
7954 (const_string "single") (const_string "double")))
7955 (set_attr "type" "jump")
7956 (set_attr "length" "2")])
7958 (define_insn_and_split "sibcall_pcrel"
7959 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7960 (match_operand 1 "" ""))
7961 (use (reg:PSI FPSCR_REG))
7962 (clobber (match_scratch:SI 2 "=k"))
7970 rtx lab = PATTERN (gen_call_site ());
7973 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7974 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7976 SIBLING_CALL_P (call_insn) = 1;
7979 [(set_attr "needs_delay_slot" "yes")
7980 (set (attr "fp_mode")
7981 (if_then_else (eq_attr "fpu_single" "yes")
7982 (const_string "single") (const_string "double")))
7983 (set_attr "type" "jump_ind")])
7985 (define_insn "sibcall_compact"
7986 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7987 (match_operand 1 "" ""))
7989 (use (match_operand:SI 2 "register_operand" "z,x"))
7990 (use (reg:SI R1_REG))
7991 (use (reg:PSI FPSCR_REG))
7992 ;; We want to make sure the `x' above will only match MACH_REG
7993 ;; because sibcall_epilogue may clobber MACL_REG.
7994 (clobber (reg:SI MACL_REG))]
7998 jmp @%0\\n sts %2, r0"
7999 [(set_attr "needs_delay_slot" "yes,no")
8000 (set_attr "length" "2,4")
8001 (set (attr "fp_mode") (const_string "single"))
8002 (set_attr "type" "jump_ind")])
8004 (define_insn "sibcall_media"
8005 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8006 (match_operand 1 "" ""))
8007 (use (reg:SI PR_MEDIA_REG))
8011 [(set_attr "type" "jump_media")])
8013 (define_expand "sibcall"
8015 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8016 (match_operand 1 "" ""))
8017 (match_operand 2 "" "")
8018 (use (reg:PSI FPSCR_REG))
8025 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8026 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8029 else if (TARGET_SHCOMPACT && operands[2]
8030 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8032 rtx cookie_rtx = operands[2];
8033 long cookie = INTVAL (cookie_rtx);
8034 rtx func = XEXP (operands[0], 0);
8039 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8041 rtx reg = gen_reg_rtx (Pmode);
8043 emit_insn (gen_symGOT2reg (reg, func));
8047 func = legitimize_pic_address (func, Pmode, 0);
8050 /* FIXME: if we could tell whether all argument registers are
8051 already taken, we could decide whether to force the use of
8052 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8053 simple way to tell. We could use the CALL_COOKIE, but we
8054 can't currently tell a register used for regular argument
8055 passing from one that is unused. If we leave it up to reload
8056 to decide which register to use, it seems to always choose
8057 R0_REG, which leaves no available registers in SIBCALL_REGS
8058 to hold the address of the trampoline. */
8059 mach = gen_rtx_REG (SImode, MACH_REG);
8060 r1 = gen_rtx_REG (SImode, R1_REG);
8062 /* Since such a call function may use all call-clobbered
8063 registers, we force a mode switch earlier, so that we don't
8064 run out of registers when adjusting fpscr for the call. */
8065 emit_insn (gen_force_mode_for_call ());
8068 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8070 operands[0] = force_reg (SImode, operands[0]);
8072 /* We don't need a return trampoline, since the callee will
8073 return directly to the upper caller. */
8074 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8076 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8077 cookie_rtx = GEN_INT (cookie);
8080 emit_move_insn (mach, func);
8081 emit_move_insn (r1, cookie_rtx);
8083 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8086 else if (TARGET_SHCOMPACT && flag_pic
8087 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8088 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8090 rtx reg = gen_reg_rtx (Pmode);
8092 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8093 XEXP (operands[0], 0) = reg;
8095 if (flag_pic && TARGET_SH2
8096 && GET_CODE (operands[0]) == MEM
8097 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8098 /* The PLT needs the PIC register, but the epilogue would have
8099 to restore it, so we can only use PC-relative PIC calls for
8100 static functions. */
8101 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8103 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8107 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8109 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8113 (define_insn "sibcall_valuei"
8114 [(set (match_operand 0 "" "=rf")
8115 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8116 (match_operand 2 "" "")))
8117 (use (reg:PSI FPSCR_REG))
8121 [(set_attr "needs_delay_slot" "yes")
8122 (set (attr "fp_mode")
8123 (if_then_else (eq_attr "fpu_single" "yes")
8124 (const_string "single") (const_string "double")))
8125 (set_attr "type" "jump_ind")])
8127 (define_insn "sibcall_valuei_pcrel"
8128 [(set (match_operand 0 "" "=rf")
8129 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8130 (match_operand 2 "" "")))
8131 (use (match_operand 3 "" ""))
8132 (use (reg:PSI FPSCR_REG))
8136 [(set_attr "needs_delay_slot" "yes")
8137 (set (attr "fp_mode")
8138 (if_then_else (eq_attr "fpu_single" "yes")
8139 (const_string "single") (const_string "double")))
8140 (set_attr "type" "jump_ind")])
8142 (define_insn_and_split "sibcall_value_pcrel"
8143 [(set (match_operand 0 "" "=rf")
8144 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8145 (match_operand 2 "" "")))
8146 (use (reg:PSI FPSCR_REG))
8147 (clobber (match_scratch:SI 3 "=k"))
8155 rtx lab = PATTERN (gen_call_site ());
8158 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8159 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8163 SIBLING_CALL_P (call_insn) = 1;
8166 [(set_attr "needs_delay_slot" "yes")
8167 (set (attr "fp_mode")
8168 (if_then_else (eq_attr "fpu_single" "yes")
8169 (const_string "single") (const_string "double")))
8170 (set_attr "type" "jump_ind")])
8172 (define_insn "sibcall_value_compact"
8173 [(set (match_operand 0 "" "=rf,rf")
8174 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8175 (match_operand 2 "" "")))
8177 (use (match_operand:SI 3 "register_operand" "z,x"))
8178 (use (reg:SI R1_REG))
8179 (use (reg:PSI FPSCR_REG))
8180 ;; We want to make sure the `x' above will only match MACH_REG
8181 ;; because sibcall_epilogue may clobber MACL_REG.
8182 (clobber (reg:SI MACL_REG))]
8186 jmp @%1\\n sts %3, r0"
8187 [(set_attr "needs_delay_slot" "yes,no")
8188 (set_attr "length" "2,4")
8189 (set (attr "fp_mode") (const_string "single"))
8190 (set_attr "type" "jump_ind")])
8192 (define_insn "sibcall_value_media"
8193 [(set (match_operand 0 "" "=rf")
8194 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8195 (match_operand 2 "" "")))
8196 (use (reg:SI PR_MEDIA_REG))
8200 [(set_attr "type" "jump_media")])
8202 (define_expand "sibcall_value"
8204 [(set (match_operand 0 "arith_reg_operand" "")
8205 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8206 (match_operand 2 "" "")))
8207 (match_operand 3 "" "")
8208 (use (reg:PSI FPSCR_REG))
8215 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8216 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8220 else if (TARGET_SHCOMPACT && operands[3]
8221 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8223 rtx cookie_rtx = operands[3];
8224 long cookie = INTVAL (cookie_rtx);
8225 rtx func = XEXP (operands[1], 0);
8230 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8232 rtx reg = gen_reg_rtx (Pmode);
8234 emit_insn (gen_symGOT2reg (reg, func));
8238 func = legitimize_pic_address (func, Pmode, 0);
8241 /* FIXME: if we could tell whether all argument registers are
8242 already taken, we could decide whether to force the use of
8243 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8244 simple way to tell. We could use the CALL_COOKIE, but we
8245 can't currently tell a register used for regular argument
8246 passing from one that is unused. If we leave it up to reload
8247 to decide which register to use, it seems to always choose
8248 R0_REG, which leaves no available registers in SIBCALL_REGS
8249 to hold the address of the trampoline. */
8250 mach = gen_rtx_REG (SImode, MACH_REG);
8251 r1 = gen_rtx_REG (SImode, R1_REG);
8253 /* Since such a call function may use all call-clobbered
8254 registers, we force a mode switch earlier, so that we don't
8255 run out of registers when adjusting fpscr for the call. */
8256 emit_insn (gen_force_mode_for_call ());
8259 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8261 operands[1] = force_reg (SImode, operands[1]);
8263 /* We don't need a return trampoline, since the callee will
8264 return directly to the upper caller. */
8265 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8267 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8268 cookie_rtx = GEN_INT (cookie);
8271 emit_move_insn (mach, func);
8272 emit_move_insn (r1, cookie_rtx);
8274 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8275 operands[2], mach));
8278 else if (TARGET_SHCOMPACT && flag_pic
8279 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8280 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8282 rtx reg = gen_reg_rtx (Pmode);
8284 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8285 XEXP (operands[1], 0) = reg;
8287 if (flag_pic && TARGET_SH2
8288 && GET_CODE (operands[1]) == MEM
8289 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8290 /* The PLT needs the PIC register, but the epilogue would have
8291 to restore it, so we can only use PC-relative PIC calls for
8292 static functions. */
8293 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8295 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8296 XEXP (operands[1], 0),
8301 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8303 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8307 (define_insn "call_value_pop_compact"
8308 [(set (match_operand 0 "" "=rf")
8309 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8310 (match_operand 2 "" "")))
8311 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8312 (match_operand 4 "immediate_operand" "n")))
8313 (match_operand 3 "immediate_operand" "n")
8314 (use (reg:SI R0_REG))
8315 (use (reg:SI R1_REG))
8316 (use (reg:PSI FPSCR_REG))
8317 (clobber (reg:SI PR_REG))]
8318 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8320 [(set_attr "type" "call")
8321 (set (attr "fp_mode")
8322 (if_then_else (eq_attr "fpu_single" "yes")
8323 (const_string "single") (const_string "double")))
8324 (set_attr "needs_delay_slot" "yes")])
8326 (define_insn "call_value_pop_compact_rettramp"
8327 [(set (match_operand 0 "" "=rf")
8328 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8329 (match_operand 2 "" "")))
8330 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8331 (match_operand 4 "immediate_operand" "n")))
8332 (match_operand 3 "immediate_operand" "n")
8333 (use (reg:SI R0_REG))
8334 (use (reg:SI R1_REG))
8335 (use (reg:PSI FPSCR_REG))
8336 (clobber (reg:SI R10_REG))
8337 (clobber (reg:SI PR_REG))]
8338 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8340 [(set_attr "type" "call")
8341 (set (attr "fp_mode")
8342 (if_then_else (eq_attr "fpu_single" "yes")
8343 (const_string "single") (const_string "double")))
8344 (set_attr "needs_delay_slot" "yes")])
8346 (define_expand "call_value_pop"
8347 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8348 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8349 (match_operand 2 "" "")))
8350 (match_operand 3 "" "")
8351 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8352 (match_operand 4 "" "")))])]
8361 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8362 cookie_rtx = operands[3];
8363 cookie = INTVAL (cookie_rtx);
8364 func = XEXP (operands[1], 0);
8368 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8370 rtx reg = gen_reg_rtx (Pmode);
8372 emit_insn (gen_symGOTPLT2reg (reg, func));
8376 func = legitimize_pic_address (func, Pmode, 0);
8379 r0 = gen_rtx_REG (SImode, R0_REG);
8380 r1 = gen_rtx_REG (SImode, R1_REG);
8382 /* Since such a call function may use all call-clobbered
8383 registers, we force a mode switch earlier, so that we don't
8384 run out of registers when adjusting fpscr for the call. */
8385 emit_insn (gen_force_mode_for_call ());
8387 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8389 operands[1] = force_reg (SImode, operands[1]);
8391 emit_move_insn (r0, func);
8392 emit_move_insn (r1, cookie_rtx);
8394 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8395 emit_call_insn (gen_call_value_pop_compact_rettramp
8396 (operands[0], operands[1], operands[2],
8397 operands[3], operands[4]));
8399 emit_call_insn (gen_call_value_pop_compact
8400 (operands[0], operands[1], operands[2],
8401 operands[3], operands[4]));
8406 (define_expand "sibcall_epilogue"
8411 sh_expand_epilogue (1);
8412 if (TARGET_SHCOMPACT)
8416 /* If epilogue clobbers r0, preserve it in macl. */
8417 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8418 if ((set = single_set (insn))
8419 && GET_CODE (SET_DEST (set)) == REG
8420 && REGNO (SET_DEST (set)) == R0_REG)
8422 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8423 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8425 /* We can't tell at this point whether the sibcall is a
8426 sibcall_compact and, if it is, whether it uses r0 or
8427 mach as operand 2, so let the instructions that
8428 preserve r0 be optimized away if r0 turns out to be
8430 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8431 emit_move_insn (r0, tmp);
8438 (define_insn "indirect_jump_compact"
8440 (match_operand:SI 0 "arith_reg_operand" "r"))]
8443 [(set_attr "needs_delay_slot" "yes")
8444 (set_attr "type" "jump_ind")])
8446 (define_expand "indirect_jump"
8448 (match_operand 0 "register_operand" ""))]
8452 if (GET_MODE (operands[0]) != Pmode)
8453 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8456 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8457 ;; which can be present in structured code from indirect jumps which can not
8458 ;; be present in structured code. This allows -fprofile-arcs to work.
8460 ;; For SH1 processors.
8461 (define_insn "casesi_jump_1"
8463 (match_operand:SI 0 "register_operand" "r"))
8464 (use (label_ref (match_operand 1 "" "")))]
8467 [(set_attr "needs_delay_slot" "yes")
8468 (set_attr "type" "jump_ind")])
8470 ;; For all later processors.
8471 (define_insn "casesi_jump_2"
8472 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8473 (label_ref (match_operand 1 "" ""))))
8474 (use (label_ref (match_operand 2 "" "")))]
8476 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8478 [(set_attr "needs_delay_slot" "yes")
8479 (set_attr "type" "jump_ind")])
8481 (define_insn "casesi_jump_media"
8482 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8483 (use (label_ref (match_operand 1 "" "")))]
8486 [(set_attr "type" "jump_media")])
8488 ;; Call subroutine returning any type.
8489 ;; ??? This probably doesn't work.
8491 (define_expand "untyped_call"
8492 [(parallel [(call (match_operand 0 "" "")
8494 (match_operand 1 "" "")
8495 (match_operand 2 "" "")])]
8496 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8501 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8503 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8505 rtx set = XVECEXP (operands[2], 0, i);
8506 emit_move_insn (SET_DEST (set), SET_SRC (set));
8509 /* The optimizer does not know that the call sets the function value
8510 registers we stored in the result block. We avoid problems by
8511 claiming that all hard registers are used and clobbered at this
8513 emit_insn (gen_blockage ());
8518 ;; ------------------------------------------------------------------------
8520 ;; ------------------------------------------------------------------------
8523 [(set (reg:SI T_REG)
8524 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8525 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8528 [(set_attr "type" "arith")])
8535 ;; Load address of a label. This is only generated by the casesi expand,
8536 ;; and by machine_dependent_reorg (fixing up fp moves).
8537 ;; This must use unspec, because this only works for labels that are
8541 [(set (reg:SI R0_REG)
8542 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8545 [(set_attr "in_delay_slot" "no")
8546 (set_attr "type" "arith")])
8548 ;; machine_dependent_reorg will make this a `mova'.
8549 (define_insn "mova_const"
8550 [(set (reg:SI R0_REG)
8551 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8554 [(set_attr "in_delay_slot" "no")
8555 (set_attr "type" "arith")])
8557 (define_expand "GOTaddr2picreg"
8558 [(set (reg:SI R0_REG)
8559 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8561 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8562 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8565 if (TARGET_VXWORKS_RTP)
8567 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8568 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8569 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8573 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8574 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8578 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8579 rtx pic = operands[0];
8580 rtx lab = PATTERN (gen_call_site ());
8583 equiv = operands[1];
8584 operands[1] = gen_rtx_MINUS (Pmode,
8588 gen_rtx_MINUS (Pmode,
8589 gen_rtx_CONST (Pmode,
8592 operands[1] = gen_sym2PIC (operands[1]);
8593 PUT_MODE (operands[1], Pmode);
8595 if (Pmode == SImode)
8597 emit_insn (gen_movsi_const (pic, operands[1]));
8598 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8602 emit_insn (gen_movdi_const (pic, operands[1]));
8603 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8606 insn = emit_move_insn (operands[0], tr);
8608 set_unique_reg_note (insn, REG_EQUAL, equiv);
8615 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8618 (define_expand "vxworks_picreg"
8619 [(set (reg:SI PIC_REG)
8620 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8621 (set (reg:SI R0_REG)
8622 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8623 (set (reg:SI PIC_REG)
8624 (mem:SI (reg:SI PIC_REG)))
8625 (set (reg:SI PIC_REG)
8626 (mem:SI (plus:SI (reg:SI PIC_REG)
8628 "TARGET_VXWORKS_RTP")
8631 [(set (match_operand 0 "target_reg_operand" "=b")
8632 (const (unspec [(match_operand 1 "" "Csy")]
8633 UNSPEC_DATALABEL)))]
8634 "TARGET_SHMEDIA && flag_pic
8635 && satisfies_constraint_Csy (operands[1])"
8636 "ptb/u datalabel %1, %0"
8637 [(set_attr "type" "ptabs_media")
8638 (set_attr "length" "*")])
8640 (define_insn "ptrel_si"
8641 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8642 (plus:SI (match_operand:SI 1 "register_operand" "r")
8644 (match_operand:SI 2 "" "")]
8646 "%O2: ptrel/u %1, %0"
8647 [(set_attr "type" "ptabs_media")])
8649 (define_insn "ptrel_di"
8650 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8651 (plus:DI (match_operand:DI 1 "register_operand" "r")
8653 (match_operand:DI 2 "" "")]
8655 "%O2: ptrel/u %1, %0"
8656 [(set_attr "type" "ptabs_media")])
8658 (define_expand "builtin_setjmp_receiver"
8659 [(match_operand 0 "" "")]
8663 emit_insn (gen_GOTaddr2picreg ());
8667 (define_expand "call_site"
8668 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8672 static HOST_WIDE_INT i = 0;
8673 operands[0] = GEN_INT (i);
8677 (define_expand "sym_label2reg"
8678 [(set (match_operand:SI 0 "" "")
8681 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8684 (match_operand:SI 2 "" "")
8688 (define_expand "symGOT_load"
8689 [(set (match_dup 2) (match_operand 1 "" ""))
8690 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8691 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8697 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8698 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8702 rtx reg = operands[2];
8704 if (Pmode == DImode)
8707 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8709 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8714 emit_insn (gen_movsi_const (reg, operands[1]));
8716 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8720 emit_move_insn (operands[2], operands[1]);
8722 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8724 gen_rtx_REG (Pmode, PIC_REG)));
8726 /* When stack protector inserts codes after the result is set to
8727 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8728 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8729 when rX is a GOT address for the guard symbol. Ugly but doesn't
8730 matter because this is a rare situation. */
8732 && flag_stack_protect
8733 && GET_CODE (operands[1]) == CONST
8734 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8735 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8736 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8737 \"__stack_chk_guard\") == 0)
8738 emit_insn (gen_blockage ());
8740 /* N.B. This is not constant for a GOTPLT relocation. */
8741 mem = gen_rtx_MEM (Pmode, operands[3]);
8742 MEM_NOTRAP_P (mem) = 1;
8743 /* ??? Should we have a special alias set for the GOT? */
8744 insn = emit_move_insn (operands[0], mem);
8746 set_unique_reg_note (insn, REG_EQUAL,
8747 XVECEXP (XEXP (operands[1], 0), 0, 0));
8752 (define_expand "sym2GOT"
8753 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8757 (define_expand "symGOT2reg"
8758 [(match_operand 0 "" "") (match_operand 1 "" "")]
8764 gotsym = gen_sym2GOT (operands[1]);
8765 PUT_MODE (gotsym, Pmode);
8766 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8768 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8773 (define_expand "symGOTPLT2reg"
8774 [(match_operand 0 "" "") (match_operand 1 "" "")]
8778 rtx pltsym = gen_rtx_CONST (Pmode,
8779 gen_rtx_UNSPEC (Pmode,
8780 gen_rtvec (1, operands[1]),
8782 emit_insn (gen_symGOT_load (operands[0], pltsym));
8786 (define_expand "sym2GOTOFF"
8787 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8791 (define_expand "symGOTOFF2reg"
8792 [(match_operand 0 "" "") (match_operand 1 "" "")]
8796 rtx gotoffsym, insn;
8797 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8799 gotoffsym = gen_sym2GOTOFF (operands[1]);
8800 PUT_MODE (gotoffsym, Pmode);
8801 emit_move_insn (t, gotoffsym);
8802 insn = emit_move_insn (operands[0],
8803 gen_rtx_PLUS (Pmode, t,
8804 gen_rtx_REG (Pmode, PIC_REG)));
8806 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8811 (define_expand "symPLT_label2reg"
8812 [(set (match_operand:SI 0 "" "")
8815 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8819 (match_operand:SI 2 "" "")
8821 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8822 ;; Even though the PIC register is not really used by the call
8823 ;; sequence in which this is expanded, the PLT code assumes the PIC
8824 ;; register is set, so we must not skip its initialization. Since
8825 ;; we only use this expand as part of calling sequences, and never
8826 ;; to take the address of a function, this is the best point to
8827 ;; insert the (use). Using the PLT to take the address of a
8828 ;; function would be wrong, not only because the PLT entry could
8829 ;; then be called from a function that doesn't initialize the PIC
8830 ;; register to the proper GOT, but also because pointers to the
8831 ;; same function might not compare equal, should they be set by
8832 ;; different shared libraries.
8833 (use (reg:SI PIC_REG))]
8837 (define_expand "sym2PIC"
8838 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8842 ;; TLS code generation.
8843 ;; ??? this should be a define_insn_and_split
8844 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8845 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8848 (define_insn "tls_global_dynamic"
8849 [(set (match_operand:SI 0 "register_operand" "=&z")
8850 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8853 (use (reg:PSI FPSCR_REG))
8854 (use (reg:SI PIC_REG))
8855 (clobber (reg:SI PR_REG))
8856 (clobber (scratch:SI))]
8862 \\tmova\\t2f,r0\\n\\
8863 \\tmov.l\\t2f,r1\\n\\
8866 \\tadd\\tr12,r4\\n\\
8870 1:\\t.long\\t%a1@TLSGD\\n\\
8871 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8874 [(set_attr "type" "tls_load")
8875 (set_attr "length" "26")])
8877 (define_insn "tls_local_dynamic"
8878 [(set (match_operand:SI 0 "register_operand" "=&z")
8879 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8882 (use (reg:PSI FPSCR_REG))
8883 (use (reg:SI PIC_REG))
8884 (clobber (reg:SI PR_REG))
8885 (clobber (scratch:SI))]
8891 \\tmova\\t2f,r0\\n\\
8892 \\tmov.l\\t2f,r1\\n\\
8895 \\tadd\\tr12,r4\\n\\
8899 1:\\t.long\\t%a1@TLSLDM\\n\\
8900 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8903 [(set_attr "type" "tls_load")
8904 (set_attr "length" "26")])
8906 (define_expand "sym2DTPOFF"
8907 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8911 (define_expand "symDTPOFF2reg"
8912 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8916 rtx dtpoffsym, insn;
8917 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8919 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8920 PUT_MODE (dtpoffsym, Pmode);
8921 emit_move_insn (t, dtpoffsym);
8922 insn = emit_move_insn (operands[0],
8923 gen_rtx_PLUS (Pmode, t, operands[2]));
8927 (define_expand "sym2GOTTPOFF"
8928 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8932 (define_insn "tls_initial_exec"
8933 [(set (match_operand:SI 0 "register_operand" "=&r")
8934 (unspec:SI [(match_operand:SI 1 "" "")]
8936 (use (reg:SI GBR_REG))
8937 (use (reg:SI PIC_REG))
8938 (clobber (reg:SI R0_REG))]
8944 \\tstc\\tgbr,%0\\n\\
8945 \\tmov.l\\t@(r0,r12),r0\\n\\
8949 1:\\t.long\\t%a1\\n\\
8952 [(set_attr "type" "tls_load")
8953 (set_attr "length" "16")])
8955 (define_expand "sym2TPOFF"
8956 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8960 (define_expand "symTPOFF2reg"
8961 [(match_operand 0 "" "") (match_operand 1 "" "")]
8967 tpoffsym = gen_sym2TPOFF (operands[1]);
8968 PUT_MODE (tpoffsym, Pmode);
8969 insn = emit_move_insn (operands[0], tpoffsym);
8973 (define_insn "load_gbr"
8974 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8975 (use (reg:SI GBR_REG))]
8978 [(set_attr "type" "tls_load")])
8980 ;; case instruction for switch statements.
8982 ;; Operand 0 is index
8983 ;; operand 1 is the minimum bound
8984 ;; operand 2 is the maximum bound - minimum bound + 1
8985 ;; operand 3 is CODE_LABEL for the table;
8986 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8988 (define_expand "casesi"
8989 [(match_operand:SI 0 "arith_reg_operand" "")
8990 (match_operand:SI 1 "arith_reg_operand" "")
8991 (match_operand:SI 2 "arith_reg_operand" "")
8992 (match_operand 3 "" "") (match_operand 4 "" "")]
8996 rtx reg = gen_reg_rtx (SImode);
8997 rtx reg2 = gen_reg_rtx (SImode);
9000 rtx reg = gen_reg_rtx (DImode);
9001 rtx reg2 = gen_reg_rtx (DImode);
9002 rtx reg3 = gen_reg_rtx (Pmode);
9003 rtx reg4 = gen_reg_rtx (Pmode);
9004 rtx reg5 = gen_reg_rtx (Pmode);
9007 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9008 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9009 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9011 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9012 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9013 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9014 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9015 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9016 (Pmode, operands[3])));
9017 /* Messy: can we subreg to clean this up? */
9018 if (Pmode == DImode)
9019 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9021 load = gen_casesi_load_media (reg4,
9022 gen_rtx_SUBREG (DImode, reg3, 0),
9024 PUT_MODE (SET_SRC (load), Pmode);
9026 /* ??? The following add could be eliminated if we used ptrel. */
9027 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9028 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9032 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9033 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9034 /* If optimizing, casesi_worker depends on the mode of the instruction
9035 before label it 'uses' - operands[3]. */
9036 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9038 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9040 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9042 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9043 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9044 operands[3], but to lab. We will fix this up in
9045 machine_dependent_reorg. */
9050 (define_expand "casesi_0"
9051 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9052 (set (match_dup 4) (minus:SI (match_dup 4)
9053 (match_operand:SI 1 "arith_operand" "")))
9055 (gtu:SI (match_dup 4)
9056 (match_operand:SI 2 "arith_reg_operand" "")))
9058 (if_then_else (ne (reg:SI T_REG)
9060 (label_ref (match_operand 3 "" ""))
9065 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9066 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9067 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9069 (define_insn "casesi_worker_0"
9070 [(set (match_operand:SI 0 "register_operand" "=r,r")
9071 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9072 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9073 (clobber (match_scratch:SI 3 "=X,1"))
9074 (clobber (match_scratch:SI 4 "=&z,z"))]
9079 [(set (match_operand:SI 0 "register_operand" "")
9080 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9081 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9082 (clobber (match_scratch:SI 3 ""))
9083 (clobber (match_scratch:SI 4 ""))]
9084 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9085 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9086 (parallel [(set (match_dup 0)
9087 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9088 (label_ref (match_dup 2))] UNSPEC_CASESI))
9089 (clobber (match_dup 3))])
9090 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9091 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9094 [(set (match_operand:SI 0 "register_operand" "")
9095 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9096 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9097 (clobber (match_scratch:SI 3 ""))
9098 (clobber (match_scratch:SI 4 ""))]
9099 "TARGET_SH2 && reload_completed"
9100 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9101 (parallel [(set (match_dup 0)
9102 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9103 (label_ref (match_dup 2))] UNSPEC_CASESI))
9104 (clobber (match_dup 3))])]
9105 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9107 (define_insn "casesi_worker_1"
9108 [(set (match_operand:SI 0 "register_operand" "=r,r")
9109 (unspec:SI [(reg:SI R0_REG)
9110 (match_operand:SI 1 "register_operand" "0,r")
9111 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9112 (clobber (match_scratch:SI 3 "=X,1"))]
9116 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9118 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9120 switch (GET_MODE (diff_vec))
9123 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9125 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9127 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9128 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9129 return \"mov.b @(r0,%1),%0\";
9134 [(set_attr "length" "4")])
9136 (define_insn "casesi_worker_2"
9137 [(set (match_operand:SI 0 "register_operand" "=r,r")
9138 (unspec:SI [(reg:SI R0_REG)
9139 (match_operand:SI 1 "register_operand" "0,r")
9140 (label_ref (match_operand 2 "" ""))
9141 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9142 (clobber (match_operand:SI 4 "" "=X,1"))]
9143 "TARGET_SH2 && reload_completed && flag_pic"
9146 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9149 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9151 switch (GET_MODE (diff_vec))
9154 output_asm_insn (\"shll2 %1\", operands);
9155 load = \"mov.l @(r0,%1),%0\"; break;
9157 output_asm_insn (\"add %1,%1\", operands);
9158 load = \"mov.w @(r0,%1),%0\"; break;
9160 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9161 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9163 load = \"mov.b @(r0,%1),%0\";
9168 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9171 [(set_attr "length" "8")])
9173 (define_insn "casesi_shift_media"
9174 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9175 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9176 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9181 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9183 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9185 switch (GET_MODE (diff_vec))
9188 return \"shlli %1, 2, %0\";
9190 return \"shlli %1, 1, %0\";
9192 if (rtx_equal_p (operands[0], operands[1]))
9194 return \"add %1, r63, %0\";
9199 [(set_attr "type" "arith_media")])
9201 (define_insn "casesi_load_media"
9202 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9203 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9204 (match_operand:DI 2 "arith_reg_operand" "r")
9205 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9209 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9211 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9213 switch (GET_MODE (diff_vec))
9216 return \"ldx.l %1, %2, %0\";
9219 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9220 return \"ldx.uw %1, %2, %0\";
9222 return \"ldx.w %1, %2, %0\";
9224 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9225 return \"ldx.ub %1, %2, %0\";
9226 return \"ldx.b %1, %2, %0\";
9231 [(set_attr "type" "load_media")])
9233 (define_expand "return"
9235 "reload_completed && ! sh_need_epilogue ()"
9240 emit_jump_insn (gen_return_media ());
9244 if (TARGET_SHCOMPACT
9245 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9247 emit_jump_insn (gen_shcompact_return_tramp ());
9252 (define_insn "*return_i"
9254 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9255 && (current_function_args_info.call_cookie
9256 & CALL_COOKIE_RET_TRAMP (1)))
9258 && lookup_attribute (\"trap_exit\",
9259 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9261 [(set_attr "type" "return")
9262 (set_attr "needs_delay_slot" "yes")])
9264 ;; trapa has no delay slot.
9265 (define_insn "*return_trapa"
9267 "TARGET_SH1 && !TARGET_SHCOMPACT
9268 && reload_completed"
9270 [(set_attr "type" "return")])
9272 (define_expand "shcompact_return_tramp"
9275 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9278 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9280 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9281 emit_jump_insn (gen_shcompact_return_tramp_i ());
9285 (define_insn "shcompact_return_tramp_i"
9286 [(parallel [(return) (use (reg:SI R0_REG))])]
9288 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9290 [(set_attr "type" "jump_ind")
9291 (set_attr "needs_delay_slot" "yes")])
9293 (define_insn "return_media_i"
9294 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9295 "TARGET_SHMEDIA && reload_completed"
9297 [(set_attr "type" "jump_media")])
9299 (define_insn "return_media_rte"
9301 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9303 [(set_attr "type" "jump_media")])
9305 (define_expand "return_media"
9307 "TARGET_SHMEDIA && reload_completed"
9310 int tr_regno = sh_media_register_for_return ();
9313 if (current_function_interrupt)
9315 emit_jump_insn (gen_return_media_rte ());
9320 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9322 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9324 tr = gen_rtx_REG (Pmode, tr_regno);
9325 emit_move_insn (tr, r18);
9328 tr = gen_rtx_REG (Pmode, tr_regno);
9330 emit_jump_insn (gen_return_media_i (tr));
9334 (define_insn "shcompact_preserve_incoming_args"
9335 [(set (match_operand:SI 0 "register_operand" "+r")
9336 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9339 [(set_attr "length" "0")])
9341 (define_insn "shcompact_incoming_args"
9342 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9343 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9344 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9345 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9346 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9347 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9349 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9350 (set (mem:BLK (reg:SI MACL_REG))
9351 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9352 (use (reg:SI R0_REG))
9353 (clobber (reg:SI R0_REG))
9354 (clobber (reg:SI MACL_REG))
9355 (clobber (reg:SI MACH_REG))
9356 (clobber (reg:SI PR_REG))]
9359 [(set_attr "needs_delay_slot" "yes")])
9361 (define_insn "shmedia_save_restore_regs_compact"
9362 [(set (reg:SI SP_REG)
9363 (plus:SI (reg:SI SP_REG)
9364 (match_operand:SI 0 "immediate_operand" "i")))
9365 (use (reg:SI R0_REG))
9366 (clobber (reg:SI PR_REG))]
9368 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9369 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9371 [(set_attr "needs_delay_slot" "yes")])
9373 (define_expand "prologue"
9376 "sh_expand_prologue (); DONE;")
9378 (define_expand "epilogue"
9383 sh_expand_epilogue (0);
9384 emit_jump_insn (gen_return ());
9388 (define_expand "eh_return"
9389 [(use (match_operand 0 "register_operand" ""))]
9392 rtx ra = operands[0];
9394 if (TARGET_SHMEDIA64)
9395 emit_insn (gen_eh_set_ra_di (ra));
9397 emit_insn (gen_eh_set_ra_si (ra));
9402 ;; Clobber the return address on the stack. We can't expand this
9403 ;; until we know where it will be put in the stack frame.
9405 (define_insn "eh_set_ra_si"
9406 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9408 (clobber (match_scratch:SI 1 "=&r"))]
9409 "! TARGET_SHMEDIA64"
9412 (define_insn "eh_set_ra_di"
9413 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9415 (clobber (match_scratch:DI 1 "=&r"))]
9420 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9422 (clobber (match_scratch 1 ""))]
9427 sh_set_return_address (operands[0], operands[1]);
9431 (define_insn "blockage"
9432 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9435 [(set_attr "length" "0")])
9437 ;; ------------------------------------------------------------------------
9439 ;; ------------------------------------------------------------------------
9442 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9443 (eq:SI (reg:SI T_REG) (const_int 1)))]
9446 [(set_attr "type" "arith")])
9448 (define_expand "seq"
9449 [(set (match_operand:SI 0 "arith_reg_dest" "")
9458 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9459 if (sh_compare_op1 != const0_rtx)
9460 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9461 ? GET_MODE (sh_compare_op0)
9462 : GET_MODE (sh_compare_op1),
9464 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9466 if (GET_MODE (operands[0]) != SImode)
9467 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9469 switch (GET_MODE (sh_compare_op0))
9472 emit_insn (gen_cmpeqsi_media (operands[0],
9473 sh_compare_op0, sh_compare_op1));
9477 emit_insn (gen_cmpeqdi_media (operands[0],
9478 sh_compare_op0, sh_compare_op1));
9482 if (! TARGET_SHMEDIA_FPU)
9484 emit_insn (gen_cmpeqsf_media (operands[0],
9485 sh_compare_op0, sh_compare_op1));
9489 if (! TARGET_SHMEDIA_FPU)
9491 emit_insn (gen_cmpeqdf_media (operands[0],
9492 sh_compare_op0, sh_compare_op1));
9502 if (GET_MODE (operands[0]) != SImode)
9503 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9504 : gen_reg_rtx (SImode);
9506 switch (GET_MODE (sh_compare_op0))
9509 emit_insn (gen_cmpeqsi_media (reg,
9510 sh_compare_op0, sh_compare_op1));
9514 emit_insn (gen_cmpeqdi_media (reg,
9515 sh_compare_op0, sh_compare_op1));
9519 if (! TARGET_SHMEDIA_FPU)
9521 emit_insn (gen_cmpeqsf_media (reg,
9522 sh_compare_op0, sh_compare_op1));
9526 if (! TARGET_SHMEDIA_FPU)
9528 emit_insn (gen_cmpeqdf_media (reg,
9529 sh_compare_op0, sh_compare_op1));
9536 if (GET_MODE (operands[0]) == DImode)
9537 emit_insn (gen_extendsidi2 (operands[0], reg));
9541 if (sh_expand_t_scc (EQ, operands[0]))
9543 if (! currently_expanding_to_rtl)
9545 operands[1] = prepare_scc_operands (EQ);
9548 (define_expand "slt"
9549 [(set (match_operand:SI 0 "arith_reg_operand" "")
9558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9559 if (sh_compare_op1 != const0_rtx)
9560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9561 ? GET_MODE (sh_compare_op0)
9562 : GET_MODE (sh_compare_op1),
9566 if (GET_MODE (operands[0]) != SImode)
9567 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9568 : gen_reg_rtx (SImode);
9570 switch (GET_MODE (sh_compare_op0))
9573 emit_insn (gen_cmpgtsi_media (reg,
9574 sh_compare_op1, sh_compare_op0));
9578 emit_insn (gen_cmpgtdi_media (reg,
9579 sh_compare_op1, sh_compare_op0));
9583 if (! TARGET_SHMEDIA_FPU)
9585 emit_insn (gen_cmpgtsf_media (reg,
9586 sh_compare_op1, sh_compare_op0));
9590 if (! TARGET_SHMEDIA_FPU)
9592 emit_insn (gen_cmpgtdf_media (reg,
9593 sh_compare_op1, sh_compare_op0));
9600 if (GET_MODE (operands[0]) == DImode)
9601 emit_insn (gen_extendsidi2 (operands[0], reg));
9605 if (! currently_expanding_to_rtl)
9607 operands[1] = prepare_scc_operands (LT);
9610 (define_expand "sle"
9611 [(match_operand:SI 0 "arith_reg_operand" "")]
9615 rtx tmp = sh_compare_op0;
9621 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9622 if (sh_compare_op1 != const0_rtx)
9623 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9624 ? GET_MODE (sh_compare_op0)
9625 : GET_MODE (sh_compare_op1),
9629 if (GET_MODE (operands[0]) != SImode)
9630 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9631 : gen_reg_rtx (SImode);
9633 switch (GET_MODE (sh_compare_op0))
9637 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9639 emit_insn (gen_cmpgtsi_media (tmp,
9640 sh_compare_op0, sh_compare_op1));
9641 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9647 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9649 emit_insn (gen_cmpgtdi_media (tmp,
9650 sh_compare_op0, sh_compare_op1));
9651 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9656 if (! TARGET_SHMEDIA_FPU)
9658 emit_insn (gen_cmpgesf_media (reg,
9659 sh_compare_op1, sh_compare_op0));
9663 if (! TARGET_SHMEDIA_FPU)
9665 emit_insn (gen_cmpgedf_media (reg,
9666 sh_compare_op1, sh_compare_op0));
9673 if (GET_MODE (operands[0]) == DImode)
9674 emit_insn (gen_extendsidi2 (operands[0], reg));
9679 sh_compare_op0 = sh_compare_op1;
9680 sh_compare_op1 = tmp;
9681 emit_insn (gen_sge (operands[0]));
9685 (define_expand "sgt"
9686 [(set (match_operand:SI 0 "arith_reg_operand" "")
9696 if (GET_MODE (operands[0]) != SImode)
9697 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9698 : gen_reg_rtx (SImode);
9699 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9700 if (sh_compare_op1 != const0_rtx)
9701 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9702 ? GET_MODE (sh_compare_op0)
9703 : GET_MODE (sh_compare_op1),
9706 switch (GET_MODE (sh_compare_op0))
9709 emit_insn (gen_cmpgtsi_media (reg,
9710 sh_compare_op0, sh_compare_op1));
9714 emit_insn (gen_cmpgtdi_media (reg,
9715 sh_compare_op0, sh_compare_op1));
9719 if (! TARGET_SHMEDIA_FPU)
9721 emit_insn (gen_cmpgtsf_media (reg,
9722 sh_compare_op0, sh_compare_op1));
9726 if (! TARGET_SHMEDIA_FPU)
9728 emit_insn (gen_cmpgtdf_media (reg,
9729 sh_compare_op0, sh_compare_op1));
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 (GT);
9746 (define_expand "sge"
9747 [(set (match_operand:SI 0 "arith_reg_operand" "")
9755 enum machine_mode mode = GET_MODE (sh_compare_op0);
9757 if ((mode) == VOIDmode)
9758 mode = GET_MODE (sh_compare_op1);
9760 if (GET_MODE (operands[0]) != SImode)
9761 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9762 : gen_reg_rtx (SImode);
9763 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9764 if (sh_compare_op1 != const0_rtx)
9765 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9771 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9773 emit_insn (gen_cmpgtsi_media (tmp,
9774 sh_compare_op1, sh_compare_op0));
9775 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9781 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9783 emit_insn (gen_cmpgtdi_media (tmp,
9784 sh_compare_op1, sh_compare_op0));
9785 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9790 if (! TARGET_SHMEDIA_FPU)
9792 emit_insn (gen_cmpgesf_media (reg,
9793 sh_compare_op0, sh_compare_op1));
9797 if (! TARGET_SHMEDIA_FPU)
9799 emit_insn (gen_cmpgedf_media (reg,
9800 sh_compare_op0, sh_compare_op1));
9807 if (GET_MODE (operands[0]) == DImode)
9808 emit_insn (gen_extendsidi2 (operands[0], reg));
9813 if (! currently_expanding_to_rtl)
9815 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9819 rtx lab = gen_label_rtx ();
9820 prepare_scc_operands (EQ);
9821 emit_jump_insn (gen_branch_true (lab));
9822 prepare_scc_operands (GT);
9824 emit_insn (gen_movt (operands[0]));
9827 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9830 operands[1] = prepare_scc_operands (GE);
9833 (define_expand "sgtu"
9834 [(set (match_operand:SI 0 "arith_reg_operand" "")
9844 if (GET_MODE (operands[0]) == DImode)
9845 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9846 : gen_reg_rtx (SImode);
9847 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9848 if (sh_compare_op1 != const0_rtx)
9849 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9850 ? GET_MODE (sh_compare_op0)
9851 : GET_MODE (sh_compare_op1),
9854 emit_insn (gen_cmpgtudi_media (reg,
9855 sh_compare_op0, sh_compare_op1));
9856 if (GET_MODE (operands[0]) == DImode)
9857 emit_insn (gen_extendsidi2 (operands[0], reg));
9861 if (! currently_expanding_to_rtl)
9863 operands[1] = prepare_scc_operands (GTU);
9866 (define_expand "sltu"
9867 [(set (match_operand:SI 0 "arith_reg_operand" "")
9877 if (GET_MODE (operands[0]) == DImode)
9878 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9879 : gen_reg_rtx (SImode);
9880 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9881 if (sh_compare_op1 != const0_rtx)
9882 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9883 ? GET_MODE (sh_compare_op0)
9884 : GET_MODE (sh_compare_op1),
9887 emit_insn (gen_cmpgtudi_media (reg,
9888 sh_compare_op1, sh_compare_op0));
9889 if (GET_MODE (operands[0]) == DImode)
9890 emit_insn (gen_extendsidi2 (operands[0], reg));
9894 if (! currently_expanding_to_rtl)
9896 operands[1] = prepare_scc_operands (LTU);
9899 (define_expand "sleu"
9900 [(set (match_operand:SI 0 "arith_reg_operand" "")
9910 if (GET_MODE (operands[0]) != SImode)
9911 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9912 : gen_reg_rtx (SImode);
9913 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9914 if (sh_compare_op1 != const0_rtx)
9915 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9916 ? GET_MODE (sh_compare_op0)
9917 : GET_MODE (sh_compare_op1),
9920 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9922 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9923 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9924 if (GET_MODE (operands[0]) == DImode)
9925 emit_insn (gen_extendsidi2 (operands[0], reg));
9929 if (! currently_expanding_to_rtl)
9931 operands[1] = prepare_scc_operands (LEU);
9934 (define_expand "sgeu"
9935 [(set (match_operand:SI 0 "arith_reg_operand" "")
9945 if (GET_MODE (operands[0]) != SImode)
9946 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9947 : gen_reg_rtx (SImode);
9948 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9949 if (sh_compare_op1 != const0_rtx)
9950 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9951 ? GET_MODE (sh_compare_op0)
9952 : GET_MODE (sh_compare_op1),
9955 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9957 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9958 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9959 if (GET_MODE (operands[0]) == DImode)
9960 emit_insn (gen_extendsidi2 (operands[0], reg));
9965 if (! currently_expanding_to_rtl)
9967 operands[1] = prepare_scc_operands (GEU);
9970 ;; sne moves the complement of the T reg to DEST like this:
9974 ;; This is better than xoring compare result with 1 because it does
9975 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9978 (define_expand "sne"
9979 [(set (match_dup 2) (const_int -1))
9980 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9981 (neg:SI (plus:SI (match_dup 1)
9984 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9994 if (GET_MODE (operands[0]) != SImode)
9995 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9996 : gen_reg_rtx (SImode);
9997 if (! TARGET_SHMEDIA_FPU
9998 && GET_MODE (sh_compare_op0) != DImode
9999 && GET_MODE (sh_compare_op0) != SImode)
10002 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10003 if (sh_compare_op1 != const0_rtx)
10004 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10005 ? GET_MODE (sh_compare_op0)
10006 : GET_MODE (sh_compare_op1),
10009 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
10011 emit_insn (gen_seq (tmp));
10012 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10013 if (GET_MODE (operands[0]) == DImode)
10014 emit_insn (gen_extendsidi2 (operands[0], reg));
10019 if (sh_expand_t_scc (NE, operands[0]))
10021 if (! currently_expanding_to_rtl)
10023 operands[1] = prepare_scc_operands (EQ);
10024 operands[2] = gen_reg_rtx (SImode);
10027 (define_expand "sunordered"
10028 [(set (match_operand:SI 0 "arith_reg_operand" "")
10029 (unordered:SI (match_dup 1) (match_dup 2)))]
10030 "TARGET_SHMEDIA_FPU"
10033 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10034 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10037 ;; Use the same trick for FP sle / sge
10039 ;; Apart from the constant use and the T setting, this is like movt,
10040 ;; except that it uses the logically negated value of T, i.e.
10041 ;; operand[0] := T ? 0 : 1.
10042 (define_expand "movnegt"
10043 [(set (match_dup 2) (const_int -1))
10044 (parallel [(set (match_operand 0 "" "")
10045 (neg:SI (plus:SI (match_dup 1)
10047 (set (reg:SI T_REG)
10048 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10051 "operands[2] = gen_reg_rtx (SImode);")
10053 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10054 ;; This prevents a regression that occurred when we switched from xor to
10055 ;; mov/neg for sne.
10058 [(set (match_operand:SI 0 "arith_reg_dest" "")
10059 (plus:SI (reg:SI T_REG)
10062 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10063 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10066 ;; -------------------------------------------------------------------------
10067 ;; Instructions to cope with inline literal tables
10068 ;; -------------------------------------------------------------------------
10070 ; 2 byte integer in line
10072 (define_insn "consttable_2"
10073 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10074 (match_operand 1 "" "")]
10079 if (operands[1] != const0_rtx)
10080 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10083 [(set_attr "length" "2")
10084 (set_attr "in_delay_slot" "no")])
10086 ; 4 byte integer in line
10088 (define_insn "consttable_4"
10089 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10090 (match_operand 1 "" "")]
10095 if (operands[1] != const0_rtx)
10096 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10099 [(set_attr "length" "4")
10100 (set_attr "in_delay_slot" "no")])
10102 ; 8 byte integer in line
10104 (define_insn "consttable_8"
10105 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10106 (match_operand 1 "" "")]
10111 if (operands[1] != const0_rtx)
10112 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10115 [(set_attr "length" "8")
10116 (set_attr "in_delay_slot" "no")])
10118 ; 4 byte floating point
10120 (define_insn "consttable_sf"
10121 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10122 (match_operand 1 "" "")]
10127 if (operands[1] != const0_rtx)
10130 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10131 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10135 [(set_attr "length" "4")
10136 (set_attr "in_delay_slot" "no")])
10138 ; 8 byte floating point
10140 (define_insn "consttable_df"
10141 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10142 (match_operand 1 "" "")]
10147 if (operands[1] != const0_rtx)
10150 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10151 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10155 [(set_attr "length" "8")
10156 (set_attr "in_delay_slot" "no")])
10158 ;; Alignment is needed for some constant tables; it may also be added for
10159 ;; Instructions at the start of loops, or after unconditional branches.
10160 ;; ??? We would get more accurate lengths if we did instruction
10161 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10162 ;; here is too conservative.
10164 ; align to a two byte boundary
10166 (define_expand "align_2"
10167 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10171 ; align to a four byte boundary
10172 ;; align_4 and align_log are instructions for the starts of loops, or
10173 ;; after unconditional branches, which may take up extra room.
10175 (define_expand "align_4"
10176 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10180 ; align to a cache line boundary
10182 (define_insn "align_log"
10183 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10186 [(set_attr "length" "0")
10187 (set_attr "in_delay_slot" "no")])
10189 ; emitted at the end of the literal table, used to emit the
10190 ; 32bit branch labels if needed.
10192 (define_insn "consttable_end"
10193 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10195 "* return output_jump_label_table ();"
10196 [(set_attr "in_delay_slot" "no")])
10198 ; emitted at the end of the window in the literal table.
10200 (define_insn "consttable_window_end"
10201 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10204 [(set_attr "length" "0")
10205 (set_attr "in_delay_slot" "no")])
10207 ;; -------------------------------------------------------------------------
10209 ;; -------------------------------------------------------------------------
10211 ;; String/block move insn.
10213 (define_expand "movmemsi"
10214 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10215 (mem:BLK (match_operand:BLK 1 "" "")))
10216 (use (match_operand:SI 2 "nonmemory_operand" ""))
10217 (use (match_operand:SI 3 "immediate_operand" ""))
10218 (clobber (reg:SI PR_REG))
10219 (clobber (reg:SI R4_REG))
10220 (clobber (reg:SI R5_REG))
10221 (clobber (reg:SI R0_REG))])]
10222 "TARGET_SH1 && ! TARGET_SH5"
10225 if(expand_block_move (operands))
10230 (define_insn "block_move_real"
10231 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10232 (mem:BLK (reg:SI R5_REG)))
10233 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10234 (clobber (reg:SI PR_REG))
10235 (clobber (reg:SI R0_REG))])]
10236 "TARGET_SH1 && ! TARGET_HARD_SH4"
10238 [(set_attr "type" "sfunc")
10239 (set_attr "needs_delay_slot" "yes")])
10241 (define_insn "block_lump_real"
10242 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10243 (mem:BLK (reg:SI R5_REG)))
10244 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10245 (use (reg:SI R6_REG))
10246 (clobber (reg:SI PR_REG))
10247 (clobber (reg:SI T_REG))
10248 (clobber (reg:SI R4_REG))
10249 (clobber (reg:SI R5_REG))
10250 (clobber (reg:SI R6_REG))
10251 (clobber (reg:SI R0_REG))])]
10252 "TARGET_SH1 && ! TARGET_HARD_SH4"
10254 [(set_attr "type" "sfunc")
10255 (set_attr "needs_delay_slot" "yes")])
10257 (define_insn "block_move_real_i4"
10258 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10259 (mem:BLK (reg:SI R5_REG)))
10260 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10261 (clobber (reg:SI PR_REG))
10262 (clobber (reg:SI R0_REG))
10263 (clobber (reg:SI R1_REG))
10264 (clobber (reg:SI R2_REG))])]
10267 [(set_attr "type" "sfunc")
10268 (set_attr "needs_delay_slot" "yes")])
10270 (define_insn "block_lump_real_i4"
10271 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10272 (mem:BLK (reg:SI R5_REG)))
10273 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10274 (use (reg:SI R6_REG))
10275 (clobber (reg:SI PR_REG))
10276 (clobber (reg:SI T_REG))
10277 (clobber (reg:SI R4_REG))
10278 (clobber (reg:SI R5_REG))
10279 (clobber (reg:SI R6_REG))
10280 (clobber (reg:SI R0_REG))
10281 (clobber (reg:SI R1_REG))
10282 (clobber (reg:SI R2_REG))
10283 (clobber (reg:SI R3_REG))])]
10286 [(set_attr "type" "sfunc")
10287 (set_attr "needs_delay_slot" "yes")])
10289 ;; -------------------------------------------------------------------------
10290 ;; Floating point instructions.
10291 ;; -------------------------------------------------------------------------
10293 ;; ??? All patterns should have a type attribute.
10295 (define_expand "movpsi"
10296 [(set (match_operand:PSI 0 "register_operand" "")
10297 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10298 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10301 ;; The c / m alternative is a fake to guide reload to load directly into
10302 ;; fpscr, since reload doesn't know how to use post-increment.
10303 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10304 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10305 ;; predicate after reload.
10306 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10307 ;; like a mac -> gpr move.
10308 (define_insn "fpu_switch"
10309 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10310 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10312 && (! reload_completed
10313 || true_regnum (operands[0]) != FPSCR_REG
10314 || GET_CODE (operands[1]) != MEM
10315 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10317 ! precision stays the same
10326 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10327 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10330 [(set (reg:PSI FPSCR_REG)
10331 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10332 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10335 rtx fpscr, mem, new_insn;
10337 fpscr = SET_DEST (PATTERN (curr_insn));
10338 mem = SET_SRC (PATTERN (curr_insn));
10339 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10341 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10342 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10347 [(set (reg:PSI FPSCR_REG)
10348 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10349 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10350 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10353 rtx fpscr, mem, new_insn;
10355 fpscr = SET_DEST (PATTERN (curr_insn));
10356 mem = SET_SRC (PATTERN (curr_insn));
10357 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10359 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10360 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10362 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10363 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10367 ;; ??? This uses the fp unit, but has no type indicating that.
10368 ;; If we did that, this would either give a bogus latency or introduce
10369 ;; a bogus FIFO constraint.
10370 ;; Since this insn is currently only used for prologues/epilogues,
10371 ;; it is probably best to claim no function unit, which matches the
10372 ;; current setting.
10373 (define_insn "toggle_sz"
10374 [(set (reg:PSI FPSCR_REG)
10375 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10376 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10378 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10380 ;; There's no way we can use it today, since optimize mode switching
10381 ;; doesn't enable us to know from which mode we're switching to the
10382 ;; mode it requests, to tell whether we can use a relative mode switch
10383 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10385 (define_insn "toggle_pr"
10386 [(set (reg:PSI FPSCR_REG)
10387 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10388 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10390 [(set_attr "type" "fpscr_toggle")])
10392 (define_expand "addsf3"
10393 [(set (match_operand:SF 0 "arith_reg_operand" "")
10394 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10395 (match_operand:SF 2 "arith_reg_operand" "")))]
10396 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10401 expand_sf_binop (&gen_addsf3_i, operands);
10406 (define_insn "*addsf3_media"
10407 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10408 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10409 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10410 "TARGET_SHMEDIA_FPU"
10411 "fadd.s %1, %2, %0"
10412 [(set_attr "type" "fparith_media")])
10414 (define_insn_and_split "unary_sf_op"
10415 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10420 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10421 (match_operator:SF 2 "unary_float_operator"
10422 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10423 (parallel [(match_operand 4
10424 "const_int_operand" "n")]))]))
10425 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10426 "TARGET_SHMEDIA_FPU"
10428 "TARGET_SHMEDIA_FPU && reload_completed"
10429 [(set (match_dup 5) (match_dup 6))]
10432 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10433 rtx op1 = gen_rtx_REG (SFmode,
10434 (true_regnum (operands[1])
10435 + (INTVAL (operands[4]) ^ endian)));
10437 operands[7] = gen_rtx_REG (SFmode,
10438 (true_regnum (operands[0])
10439 + (INTVAL (operands[3]) ^ endian)));
10440 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10442 [(set_attr "type" "fparith_media")])
10444 (define_insn_and_split "binary_sf_op"
10445 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10450 (parallel [(match_operand 7 "const_int_operand" "n")]))
10451 (match_operator:SF 3 "binary_float_operator"
10452 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10453 (parallel [(match_operand 5
10454 "const_int_operand" "n")]))
10455 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10456 (parallel [(match_operand 6
10457 "const_int_operand" "n")]))]))
10458 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10459 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10461 "&& reload_completed"
10462 [(set (match_dup 8) (match_dup 9))]
10465 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10466 rtx op1 = gen_rtx_REG (SFmode,
10467 (true_regnum (operands[1])
10468 + (INTVAL (operands[5]) ^ endian)));
10469 rtx op2 = gen_rtx_REG (SFmode,
10470 (true_regnum (operands[2])
10471 + (INTVAL (operands[6]) ^ endian)));
10473 operands[8] = gen_rtx_REG (SFmode,
10474 (true_regnum (operands[0])
10475 + (INTVAL (operands[4]) ^ endian)));
10476 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10478 [(set_attr "type" "fparith_media")])
10480 (define_insn "addsf3_i"
10481 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10482 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10483 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10484 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10487 [(set_attr "type" "fp")
10488 (set_attr "fp_mode" "single")])
10490 (define_expand "subsf3"
10491 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10492 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10493 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10494 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10499 expand_sf_binop (&gen_subsf3_i, operands);
10504 (define_insn "*subsf3_media"
10505 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10506 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10507 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10508 "TARGET_SHMEDIA_FPU"
10509 "fsub.s %1, %2, %0"
10510 [(set_attr "type" "fparith_media")])
10512 (define_insn "subsf3_i"
10513 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10514 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10515 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10516 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10519 [(set_attr "type" "fp")
10520 (set_attr "fp_mode" "single")])
10522 (define_expand "mulsf3"
10523 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10524 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10525 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10526 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10529 (define_insn "*mulsf3_media"
10530 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10531 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10532 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10533 "TARGET_SHMEDIA_FPU"
10534 "fmul.s %1, %2, %0"
10535 [(set_attr "type" "fparith_media")])
10537 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10538 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10539 ;; we start out with a mulsf pattern that does not depend on fpscr.
10540 ;; This is split after combine to introduce the dependency, in order to
10541 ;; get mode switching and scheduling right.
10542 (define_insn_and_split "mulsf3_ie"
10543 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10544 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10545 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10548 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10552 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10553 get_fpscr_rtx ()));
10556 [(set_attr "type" "fp")])
10558 (define_insn "mulsf3_i4"
10559 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10560 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10561 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10562 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10565 [(set_attr "type" "fp")
10566 (set_attr "fp_mode" "single")])
10568 (define_insn "mac_media"
10569 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10570 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10571 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10572 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10573 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10574 "fmac.s %1, %2, %0"
10575 [(set_attr "type" "fparith_media")])
10577 (define_insn "*macsf3"
10578 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10580 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10581 (match_operand:SF 3 "arith_reg_operand" "0")))
10582 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10583 "TARGET_SH2E && TARGET_FMAC"
10585 [(set_attr "type" "fp")
10586 (set_attr "fp_mode" "single")])
10588 (define_expand "divsf3"
10589 [(set (match_operand:SF 0 "arith_reg_operand" "")
10590 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10591 (match_operand:SF 2 "arith_reg_operand" "")))]
10592 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10597 expand_sf_binop (&gen_divsf3_i, operands);
10602 (define_insn "*divsf3_media"
10603 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10604 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10605 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10606 "TARGET_SHMEDIA_FPU"
10607 "fdiv.s %1, %2, %0"
10608 [(set_attr "type" "fdiv_media")])
10610 (define_insn "divsf3_i"
10611 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10612 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10613 (match_operand:SF 2 "arith_reg_operand" "f")))
10614 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10617 [(set_attr "type" "fdiv")
10618 (set_attr "fp_mode" "single")])
10620 (define_insn "floatdisf2"
10621 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10622 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10623 "TARGET_SHMEDIA_FPU"
10625 [(set_attr "type" "fpconv_media")])
10627 (define_expand "floatsisf2"
10628 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10629 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10630 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10633 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10635 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10640 (define_insn "*floatsisf2_media"
10641 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10642 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10643 "TARGET_SHMEDIA_FPU"
10645 [(set_attr "type" "fpconv_media")])
10647 (define_insn "floatsisf2_i4"
10648 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10649 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10650 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10651 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10653 [(set_attr "type" "fp")
10654 (set_attr "fp_mode" "single")])
10656 (define_insn "*floatsisf2_ie"
10657 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10658 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10659 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10661 [(set_attr "type" "fp")])
10663 (define_insn "fix_truncsfdi2"
10664 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10665 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10666 "TARGET_SHMEDIA_FPU"
10668 [(set_attr "type" "fpconv_media")])
10670 (define_expand "fix_truncsfsi2"
10671 [(set (match_operand:SI 0 "fpul_operand" "=y")
10672 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10673 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10676 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10678 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10683 (define_insn "*fix_truncsfsi2_media"
10684 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10685 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10686 "TARGET_SHMEDIA_FPU"
10688 [(set_attr "type" "fpconv_media")])
10690 (define_insn "fix_truncsfsi2_i4"
10691 [(set (match_operand:SI 0 "fpul_operand" "=y")
10692 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10693 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10694 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10696 [(set_attr "type" "ftrc_s")
10697 (set_attr "fp_mode" "single")])
10699 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10700 ;; fix_truncsfsi2_i4.
10701 ;; (define_insn "fix_truncsfsi2_i4_2"
10702 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10703 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10704 ;; (use (reg:PSI FPSCR_REG))
10705 ;; (clobber (reg:SI FPUL_REG))]
10708 ;; [(set_attr "length" "4")
10709 ;; (set_attr "fp_mode" "single")])
10712 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10713 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10714 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10715 ;; (clobber (reg:SI FPUL_REG))]
10717 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10718 ;; (use (match_dup 2))])
10719 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10721 (define_insn "*fixsfsi"
10722 [(set (match_operand:SI 0 "fpul_operand" "=y")
10723 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10724 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10726 [(set_attr "type" "fp")])
10728 (define_insn "cmpgtsf_t"
10729 [(set (reg:SI T_REG)
10730 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10731 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10732 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10734 [(set_attr "type" "fp_cmp")
10735 (set_attr "fp_mode" "single")])
10737 (define_insn "cmpeqsf_t"
10738 [(set (reg:SI T_REG)
10739 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10740 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10741 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10743 [(set_attr "type" "fp_cmp")
10744 (set_attr "fp_mode" "single")])
10746 (define_insn "ieee_ccmpeqsf_t"
10747 [(set (reg:SI T_REG)
10748 (ior:SI (reg:SI T_REG)
10749 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10750 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10751 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10752 "* return output_ieee_ccmpeq (insn, operands);"
10753 [(set_attr "length" "4")])
10756 (define_insn "cmpgtsf_t_i4"
10757 [(set (reg:SI T_REG)
10758 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10759 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10760 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10761 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10763 [(set_attr "type" "fp_cmp")
10764 (set_attr "fp_mode" "single")])
10766 (define_insn "cmpeqsf_t_i4"
10767 [(set (reg:SI T_REG)
10768 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10769 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10770 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10771 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10773 [(set_attr "type" "fp_cmp")
10774 (set_attr "fp_mode" "single")])
10776 (define_insn "*ieee_ccmpeqsf_t_4"
10777 [(set (reg:SI T_REG)
10778 (ior:SI (reg:SI T_REG)
10779 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10780 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10781 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10782 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10783 "* return output_ieee_ccmpeq (insn, operands);"
10784 [(set_attr "length" "4")
10785 (set_attr "fp_mode" "single")])
10787 (define_insn "cmpeqsf_media"
10788 [(set (match_operand:SI 0 "register_operand" "=r")
10789 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10790 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10791 "TARGET_SHMEDIA_FPU"
10792 "fcmpeq.s %1, %2, %0"
10793 [(set_attr "type" "fcmp_media")])
10795 (define_insn "cmpgtsf_media"
10796 [(set (match_operand:SI 0 "register_operand" "=r")
10797 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10798 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10799 "TARGET_SHMEDIA_FPU"
10800 "fcmpgt.s %1, %2, %0"
10801 [(set_attr "type" "fcmp_media")])
10803 (define_insn "cmpgesf_media"
10804 [(set (match_operand:SI 0 "register_operand" "=r")
10805 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10806 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10807 "TARGET_SHMEDIA_FPU"
10808 "fcmpge.s %1, %2, %0"
10809 [(set_attr "type" "fcmp_media")])
10811 (define_insn "cmpunsf_media"
10812 [(set (match_operand:SI 0 "register_operand" "=r")
10813 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10814 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10815 "TARGET_SHMEDIA_FPU"
10816 "fcmpun.s %1, %2, %0"
10817 [(set_attr "type" "fcmp_media")])
10819 (define_expand "cmpsf"
10820 [(set (reg:SI T_REG)
10821 (compare (match_operand:SF 0 "arith_operand" "")
10822 (match_operand:SF 1 "arith_operand" "")))]
10823 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10826 sh_compare_op0 = operands[0];
10827 sh_compare_op1 = operands[1];
10831 (define_expand "negsf2"
10832 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10833 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10834 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10839 expand_sf_unop (&gen_negsf2_i, operands);
10844 (define_insn "*negsf2_media"
10845 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10846 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10847 "TARGET_SHMEDIA_FPU"
10849 [(set_attr "type" "fmove_media")])
10851 (define_insn "negsf2_i"
10852 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10853 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10854 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10857 [(set_attr "type" "fmove")
10858 (set_attr "fp_mode" "single")])
10860 (define_expand "sqrtsf2"
10861 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10862 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10863 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10868 expand_sf_unop (&gen_sqrtsf2_i, operands);
10873 (define_insn "*sqrtsf2_media"
10874 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10875 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10876 "TARGET_SHMEDIA_FPU"
10878 [(set_attr "type" "fdiv_media")])
10880 (define_insn "sqrtsf2_i"
10881 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10882 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10883 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10886 [(set_attr "type" "fdiv")
10887 (set_attr "fp_mode" "single")])
10889 (define_insn "rsqrtsf2"
10890 [(set (match_operand:SF 0 "register_operand" "=f")
10891 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10892 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10893 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10894 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10895 && operands[1] == CONST1_RTX (SFmode)"
10897 [(set_attr "type" "fsrra")
10898 (set_attr "fp_mode" "single")])
10900 (define_insn "fsca"
10901 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10903 (unspec:SF [(mult:SF
10904 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10905 (match_operand:SF 2 "immediate_operand" "i"))
10907 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10909 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10910 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10911 && operands[2] == sh_fsca_int2sf ()"
10913 [(set_attr "type" "fsca")
10914 (set_attr "fp_mode" "single")])
10916 (define_expand "sinsf2"
10917 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10918 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10920 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10923 rtx scaled = gen_reg_rtx (SFmode);
10924 rtx truncated = gen_reg_rtx (SImode);
10925 rtx fsca = gen_reg_rtx (V2SFmode);
10926 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10928 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10929 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10930 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10931 get_fpscr_rtx ()));
10932 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10936 (define_expand "cossf2"
10937 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10938 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10940 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10943 rtx scaled = gen_reg_rtx (SFmode);
10944 rtx truncated = gen_reg_rtx (SImode);
10945 rtx fsca = gen_reg_rtx (V2SFmode);
10946 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10948 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10949 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10950 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10951 get_fpscr_rtx ()));
10952 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10956 (define_expand "sindf2"
10957 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10958 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10960 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10963 rtx scaled = gen_reg_rtx (DFmode);
10964 rtx truncated = gen_reg_rtx (SImode);
10965 rtx fsca = gen_reg_rtx (V2SFmode);
10966 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10967 rtx sfresult = gen_reg_rtx (SFmode);
10969 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10970 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10971 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10972 get_fpscr_rtx ()));
10973 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10974 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10978 (define_expand "cosdf2"
10979 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10980 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10982 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10985 rtx scaled = gen_reg_rtx (DFmode);
10986 rtx truncated = gen_reg_rtx (SImode);
10987 rtx fsca = gen_reg_rtx (V2SFmode);
10988 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10989 rtx sfresult = gen_reg_rtx (SFmode);
10991 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10992 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10993 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10994 get_fpscr_rtx ()));
10995 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10996 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11000 (define_expand "abssf2"
11001 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11002 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11003 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11008 expand_sf_unop (&gen_abssf2_i, operands);
11013 (define_insn "*abssf2_media"
11014 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11015 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11016 "TARGET_SHMEDIA_FPU"
11018 [(set_attr "type" "fmove_media")])
11020 (define_insn "abssf2_i"
11021 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11022 (abs: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 "adddf3"
11030 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11031 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11032 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11033 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11036 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11038 expand_df_binop (&gen_adddf3_i, operands);
11043 (define_insn "*adddf3_media"
11044 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11045 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11046 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11047 "TARGET_SHMEDIA_FPU"
11048 "fadd.d %1, %2, %0"
11049 [(set_attr "type" "dfparith_media")])
11051 (define_insn "adddf3_i"
11052 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11053 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11054 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11055 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11056 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11058 [(set_attr "type" "dfp_arith")
11059 (set_attr "fp_mode" "double")])
11061 (define_expand "subdf3"
11062 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11063 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11064 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11065 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11068 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11070 expand_df_binop (&gen_subdf3_i, operands);
11075 (define_insn "*subdf3_media"
11076 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11077 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11078 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11079 "TARGET_SHMEDIA_FPU"
11080 "fsub.d %1, %2, %0"
11081 [(set_attr "type" "dfparith_media")])
11083 (define_insn "subdf3_i"
11084 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11085 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11086 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11087 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11088 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11090 [(set_attr "type" "dfp_arith")
11091 (set_attr "fp_mode" "double")])
11093 (define_expand "muldf3"
11094 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11095 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11096 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11097 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11100 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11102 expand_df_binop (&gen_muldf3_i, operands);
11107 (define_insn "*muldf3_media"
11108 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11109 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11110 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11111 "TARGET_SHMEDIA_FPU"
11112 "fmul.d %1, %2, %0"
11113 [(set_attr "type" "dfmul_media")])
11115 (define_insn "muldf3_i"
11116 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11117 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11118 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11119 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11120 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11122 [(set_attr "type" "dfp_mul")
11123 (set_attr "fp_mode" "double")])
11125 (define_expand "divdf3"
11126 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11127 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11128 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11129 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11132 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11134 expand_df_binop (&gen_divdf3_i, operands);
11139 (define_insn "*divdf3_media"
11140 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11141 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11142 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11143 "TARGET_SHMEDIA_FPU"
11144 "fdiv.d %1, %2, %0"
11145 [(set_attr "type" "dfdiv_media")])
11147 (define_insn "divdf3_i"
11148 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11149 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11150 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11151 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11152 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11154 [(set_attr "type" "dfdiv")
11155 (set_attr "fp_mode" "double")])
11157 (define_insn "floatdidf2"
11158 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11159 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11160 "TARGET_SHMEDIA_FPU"
11162 [(set_attr "type" "dfpconv_media")])
11164 (define_expand "floatsidf2"
11165 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11166 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11167 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11170 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11172 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11173 get_fpscr_rtx ()));
11178 (define_insn "*floatsidf2_media"
11179 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11180 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11181 "TARGET_SHMEDIA_FPU"
11183 [(set_attr "type" "dfpconv_media")])
11185 (define_insn "floatsidf2_i"
11186 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11187 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11188 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11189 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11191 [(set_attr "type" "dfp_conv")
11192 (set_attr "fp_mode" "double")])
11194 (define_insn "fix_truncdfdi2"
11195 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11196 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11197 "TARGET_SHMEDIA_FPU"
11199 [(set_attr "type" "dfpconv_media")])
11201 (define_expand "fix_truncdfsi2"
11202 [(set (match_operand:SI 0 "fpul_operand" "")
11203 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11204 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11207 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11209 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11210 get_fpscr_rtx ()));
11215 (define_insn "*fix_truncdfsi2_media"
11216 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11217 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11218 "TARGET_SHMEDIA_FPU"
11220 [(set_attr "type" "dfpconv_media")])
11222 (define_insn "fix_truncdfsi2_i"
11223 [(set (match_operand:SI 0 "fpul_operand" "=y")
11224 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11225 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11226 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11228 [(set_attr "type" "dfp_conv")
11229 (set_attr "dfp_comp" "no")
11230 (set_attr "fp_mode" "double")])
11232 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11233 ;; fix_truncdfsi2_i.
11234 ;; (define_insn "fix_truncdfsi2_i4"
11235 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11236 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11237 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11238 ;; (clobber (reg:SI FPUL_REG))]
11241 ;; [(set_attr "length" "4")
11242 ;; (set_attr "fp_mode" "double")])
11245 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11246 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11247 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11248 ;; (clobber (reg:SI FPUL_REG))]
11250 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11251 ;; (use (match_dup 2))])
11252 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11254 (define_insn "cmpgtdf_t"
11255 [(set (reg:SI T_REG)
11256 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11257 (match_operand:DF 1 "arith_reg_operand" "f")))
11258 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11259 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11261 [(set_attr "type" "dfp_cmp")
11262 (set_attr "fp_mode" "double")])
11264 (define_insn "cmpeqdf_t"
11265 [(set (reg:SI T_REG)
11266 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11267 (match_operand:DF 1 "arith_reg_operand" "f")))
11268 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11269 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11271 [(set_attr "type" "dfp_cmp")
11272 (set_attr "fp_mode" "double")])
11274 (define_insn "*ieee_ccmpeqdf_t"
11275 [(set (reg:SI T_REG)
11276 (ior:SI (reg:SI T_REG)
11277 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11278 (match_operand:DF 1 "arith_reg_operand" "f"))))
11279 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11280 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11281 "* return output_ieee_ccmpeq (insn, operands);"
11282 [(set_attr "length" "4")
11283 (set_attr "fp_mode" "double")])
11285 (define_insn "cmpeqdf_media"
11286 [(set (match_operand:SI 0 "register_operand" "=r")
11287 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11288 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11289 "TARGET_SHMEDIA_FPU"
11290 "fcmpeq.d %1,%2,%0"
11291 [(set_attr "type" "fcmp_media")])
11293 (define_insn "cmpgtdf_media"
11294 [(set (match_operand:SI 0 "register_operand" "=r")
11295 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11296 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11297 "TARGET_SHMEDIA_FPU"
11298 "fcmpgt.d %1,%2,%0"
11299 [(set_attr "type" "fcmp_media")])
11301 (define_insn "cmpgedf_media"
11302 [(set (match_operand:SI 0 "register_operand" "=r")
11303 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11304 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11305 "TARGET_SHMEDIA_FPU"
11306 "fcmpge.d %1,%2,%0"
11307 [(set_attr "type" "fcmp_media")])
11309 (define_insn "cmpundf_media"
11310 [(set (match_operand:SI 0 "register_operand" "=r")
11311 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11312 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11313 "TARGET_SHMEDIA_FPU"
11314 "fcmpun.d %1,%2,%0"
11315 [(set_attr "type" "fcmp_media")])
11317 (define_expand "cmpdf"
11318 [(set (reg:SI T_REG)
11319 (compare (match_operand:DF 0 "arith_operand" "")
11320 (match_operand:DF 1 "arith_operand" "")))]
11321 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11324 sh_compare_op0 = operands[0];
11325 sh_compare_op1 = operands[1];
11329 (define_expand "negdf2"
11330 [(set (match_operand:DF 0 "arith_reg_operand" "")
11331 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11332 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11335 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11337 expand_df_unop (&gen_negdf2_i, operands);
11342 (define_insn "*negdf2_media"
11343 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11344 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11345 "TARGET_SHMEDIA_FPU"
11347 [(set_attr "type" "fmove_media")])
11349 (define_insn "negdf2_i"
11350 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11351 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11352 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11353 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11355 [(set_attr "type" "fmove")
11356 (set_attr "fp_mode" "double")])
11358 (define_expand "sqrtdf2"
11359 [(set (match_operand:DF 0 "arith_reg_operand" "")
11360 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11361 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11364 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11366 expand_df_unop (&gen_sqrtdf2_i, operands);
11371 (define_insn "*sqrtdf2_media"
11372 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11373 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11374 "TARGET_SHMEDIA_FPU"
11376 [(set_attr "type" "dfdiv_media")])
11378 (define_insn "sqrtdf2_i"
11379 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11380 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11381 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11382 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11384 [(set_attr "type" "dfdiv")
11385 (set_attr "fp_mode" "double")])
11387 (define_expand "absdf2"
11388 [(set (match_operand:DF 0 "arith_reg_operand" "")
11389 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11390 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11393 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11395 expand_df_unop (&gen_absdf2_i, operands);
11400 (define_insn "*absdf2_media"
11401 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11402 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11403 "TARGET_SHMEDIA_FPU"
11405 [(set_attr "type" "fmove_media")])
11407 (define_insn "absdf2_i"
11408 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11409 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11410 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11411 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11413 [(set_attr "type" "fmove")
11414 (set_attr "fp_mode" "double")])
11416 (define_expand "extendsfdf2"
11417 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11418 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11419 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11422 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11424 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11425 get_fpscr_rtx ()));
11430 (define_insn "*extendsfdf2_media"
11431 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11432 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11433 "TARGET_SHMEDIA_FPU"
11435 [(set_attr "type" "dfpconv_media")])
11437 (define_insn "extendsfdf2_i4"
11438 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11439 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11440 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11441 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11443 [(set_attr "type" "fp")
11444 (set_attr "fp_mode" "double")])
11446 (define_expand "truncdfsf2"
11447 [(set (match_operand:SF 0 "fpul_operand" "")
11448 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11449 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11452 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11454 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11455 get_fpscr_rtx ()));
11460 (define_insn "*truncdfsf2_media"
11461 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11462 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11463 "TARGET_SHMEDIA_FPU"
11465 [(set_attr "type" "dfpconv_media")])
11467 (define_insn "truncdfsf2_i4"
11468 [(set (match_operand:SF 0 "fpul_operand" "=y")
11469 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11470 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11471 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11473 [(set_attr "type" "fp")
11474 (set_attr "fp_mode" "double")])
11476 ;; Bit field extract patterns. These give better code for packed bitfields,
11477 ;; because they allow auto-increment addresses to be generated.
11479 (define_expand "insv"
11480 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11481 (match_operand:SI 1 "immediate_operand" "")
11482 (match_operand:SI 2 "immediate_operand" ""))
11483 (match_operand:SI 3 "general_operand" ""))]
11484 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11487 rtx addr_target, orig_address, shift_reg, qi_val;
11488 HOST_WIDE_INT bitsize, size, v = 0;
11489 rtx x = operands[3];
11491 /* ??? expmed doesn't care for non-register predicates. */
11492 if (! memory_operand (operands[0], VOIDmode)
11493 || ! immediate_operand (operands[1], VOIDmode)
11494 || ! immediate_operand (operands[2], VOIDmode)
11495 || ! general_operand (x, VOIDmode))
11497 /* If this isn't a 16 / 24 / 32 bit field, or if
11498 it doesn't start on a byte boundary, then fail. */
11499 bitsize = INTVAL (operands[1]);
11500 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11501 || (INTVAL (operands[2]) % 8) != 0)
11504 size = bitsize / 8;
11505 orig_address = XEXP (operands[0], 0);
11506 shift_reg = gen_reg_rtx (SImode);
11507 if (GET_CODE (x) == CONST_INT)
11510 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11514 emit_insn (gen_movsi (shift_reg, operands[3]));
11515 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11517 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11519 operands[0] = replace_equiv_address (operands[0], addr_target);
11520 emit_insn (gen_movqi (operands[0], qi_val));
11524 if (GET_CODE (x) == CONST_INT)
11526 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11529 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11530 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11532 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11533 emit_insn (gen_movqi (operands[0], qi_val));
11539 (define_insn "movua"
11540 [(set (match_operand:SI 0 "register_operand" "=z")
11541 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11545 [(set_attr "type" "movua")])
11547 ;; We shouldn't need this, but cse replaces increments with references
11548 ;; to other regs before flow has a chance to create post_inc
11549 ;; addressing modes, and only postreload's cse_move2add brings the
11550 ;; increments back to a usable form.
11552 [(set (match_operand:SI 0 "register_operand" "")
11553 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11554 (const_int 32) (const_int 0)))
11555 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11556 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11557 [(set (match_operand:SI 0 "register_operand" "")
11558 (sign_extract:SI (mem:SI (post_inc:SI
11559 (match_operand:SI 1 "register_operand" "")))
11560 (const_int 32) (const_int 0)))]
11563 (define_expand "extv"
11564 [(set (match_operand:SI 0 "register_operand" "")
11565 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11566 (match_operand 2 "const_int_operand" "")
11567 (match_operand 3 "const_int_operand" "")))]
11570 if (TARGET_SH4A_ARCH
11571 && INTVAL (operands[2]) == 32
11572 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11573 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11575 rtx src = adjust_address (operands[1], BLKmode, 0);
11576 set_mem_size (src, GEN_INT (4));
11577 emit_insn (gen_movua (operands[0], src));
11584 (define_expand "extzv"
11585 [(set (match_operand:SI 0 "register_operand" "")
11586 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11587 (match_operand 2 "const_int_operand" "")
11588 (match_operand 3 "const_int_operand" "")))]
11591 if (TARGET_SH4A_ARCH
11592 && INTVAL (operands[2]) == 32
11593 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11594 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11596 rtx src = adjust_address (operands[1], BLKmode, 0);
11597 set_mem_size (src, GEN_INT (4));
11598 emit_insn (gen_movua (operands[0], src));
11606 ;; -------------------------------------------------------------------------
11608 ;; -------------------------------------------------------------------------
11610 ;; This matches cases where a stack pointer increment at the start of the
11611 ;; epilogue combines with a stack slot read loading the return value.
11614 [(set (match_operand:SI 0 "arith_reg_operand" "")
11615 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11616 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11617 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11620 ;; See the comment on the dt combiner pattern above.
11623 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11624 (plus:SI (match_dup 0)
11626 (set (reg:SI T_REG)
11627 (eq:SI (match_dup 0)
11632 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11633 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11634 ;; reload when the constant is too large for a reg+offset address.
11636 ;; ??? We would get much better code if this was done in reload. This would
11637 ;; require modifying find_reloads_address to recognize that if the constant
11638 ;; is out-of-range for an immediate add, then we get better code by reloading
11639 ;; the constant into a register than by reloading the sum into a register,
11640 ;; since the former is one instruction shorter if the address does not need
11641 ;; to be offsettable. Unfortunately this does not work, because there is
11642 ;; only one register, r0, that can be used as an index register. This register
11643 ;; is also the function return value register. So, if we try to force reload
11644 ;; to use double-reg addresses, then we end up with some instructions that
11645 ;; need to use r0 twice. The only way to fix this is to change the calling
11646 ;; convention so that r0 is not used to return values.
11649 [(set (match_operand:SI 0 "register_operand" "=r")
11650 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11651 (set (mem:SI (match_dup 0))
11652 (match_operand:SI 2 "general_movsrc_operand" ""))]
11653 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11654 "mov.l %2,@(%0,%1)")
11657 [(set (match_operand:SI 0 "register_operand" "=r")
11658 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11659 (set (match_operand:SI 2 "general_movdst_operand" "")
11660 (mem:SI (match_dup 0)))]
11661 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11662 "mov.l @(%0,%1),%2")
11665 [(set (match_operand:SI 0 "register_operand" "=r")
11666 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11667 (set (mem:HI (match_dup 0))
11668 (match_operand:HI 2 "general_movsrc_operand" ""))]
11669 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11670 "mov.w %2,@(%0,%1)")
11673 [(set (match_operand:SI 0 "register_operand" "=r")
11674 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11675 (set (match_operand:HI 2 "general_movdst_operand" "")
11676 (mem:HI (match_dup 0)))]
11677 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11678 "mov.w @(%0,%1),%2")
11681 [(set (match_operand:SI 0 "register_operand" "=r")
11682 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11683 (set (mem:QI (match_dup 0))
11684 (match_operand:QI 2 "general_movsrc_operand" ""))]
11685 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11686 "mov.b %2,@(%0,%1)")
11689 [(set (match_operand:SI 0 "register_operand" "=r")
11690 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11691 (set (match_operand:QI 2 "general_movdst_operand" "")
11692 (mem:QI (match_dup 0)))]
11693 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11694 "mov.b @(%0,%1),%2")
11697 [(set (match_operand:SI 0 "register_operand" "=r")
11698 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11699 (set (mem:SF (match_dup 0))
11700 (match_operand:SF 2 "general_movsrc_operand" ""))]
11701 "TARGET_SH1 && REGNO (operands[0]) == 0
11702 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11703 || (GET_CODE (operands[2]) == SUBREG
11704 && REGNO (SUBREG_REG (operands[2])) < 16))
11705 && reg_unused_after (operands[0], insn)"
11706 "mov.l %2,@(%0,%1)")
11709 [(set (match_operand:SI 0 "register_operand" "=r")
11710 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11711 (set (match_operand:SF 2 "general_movdst_operand" "")
11713 (mem:SF (match_dup 0)))]
11714 "TARGET_SH1 && REGNO (operands[0]) == 0
11715 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11716 || (GET_CODE (operands[2]) == SUBREG
11717 && REGNO (SUBREG_REG (operands[2])) < 16))
11718 && reg_unused_after (operands[0], insn)"
11719 "mov.l @(%0,%1),%2")
11722 [(set (match_operand:SI 0 "register_operand" "=r")
11723 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11724 (set (mem:SF (match_dup 0))
11725 (match_operand:SF 2 "general_movsrc_operand" ""))]
11726 "TARGET_SH2E && REGNO (operands[0]) == 0
11727 && ((GET_CODE (operands[2]) == REG
11728 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11729 || (GET_CODE (operands[2]) == SUBREG
11730 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11731 && reg_unused_after (operands[0], insn)"
11732 "fmov{.s|} %2,@(%0,%1)")
11735 [(set (match_operand:SI 0 "register_operand" "=r")
11736 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11737 (set (match_operand:SF 2 "general_movdst_operand" "")
11739 (mem:SF (match_dup 0)))]
11740 "TARGET_SH2E && REGNO (operands[0]) == 0
11741 && ((GET_CODE (operands[2]) == REG
11742 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11743 || (GET_CODE (operands[2]) == SUBREG
11744 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11745 && reg_unused_after (operands[0], insn)"
11746 "fmov{.s|} @(%0,%1),%2")
11748 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11749 (define_insn "sp_switch_1"
11750 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11754 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11755 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11756 return \"mov r0,r15\";
11758 [(set_attr "length" "10")])
11760 ;; Switch back to the original stack for interrupt functions with the
11761 ;; sp_switch attribute. */
11762 (define_insn "sp_switch_2"
11765 "mov.l @r15+,r15\;mov.l @r15+,r0"
11766 [(set_attr "length" "4")])
11768 ;; Integer vector moves
11770 (define_expand "movv8qi"
11771 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11772 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11774 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11776 (define_insn "movv8qi_i"
11777 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11778 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11780 && (register_operand (operands[0], V8QImode)
11781 || sh_register_operand (operands[1], V8QImode))"
11788 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11789 (set_attr "length" "4,4,16,4,4")])
11792 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11793 (subreg:V8QI (const_int 0) 0))]
11795 [(set (match_dup 0)
11796 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11797 (const_int 0) (const_int 0) (const_int 0)
11798 (const_int 0) (const_int 0)]))])
11801 [(set (match_operand 0 "arith_reg_dest" "")
11802 (match_operand 1 "sh_rep_vec" ""))]
11803 "TARGET_SHMEDIA && reload_completed
11804 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11805 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11806 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11807 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11808 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11809 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11810 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11811 [(set (match_dup 0) (match_dup 1))
11815 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11816 rtx elt1 = XVECEXP (operands[1], 0, 1);
11819 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11823 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11824 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11826 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11827 operands[1] = XVECEXP (operands[1], 0, 0);
11830 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11832 = GEN_INT (TARGET_LITTLE_ENDIAN
11833 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11834 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11837 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11839 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11845 [(set (match_operand 0 "arith_reg_dest" "")
11846 (match_operand 1 "sh_const_vec" ""))]
11847 "TARGET_SHMEDIA && reload_completed
11848 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11849 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11850 [(set (match_dup 0) (match_dup 1))]
11853 rtx v = operands[1];
11854 enum machine_mode new_mode
11855 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11857 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11859 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11862 (define_expand "movv2hi"
11863 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11864 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11866 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11868 (define_insn "movv2hi_i"
11869 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11870 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11872 && (register_operand (operands[0], V2HImode)
11873 || sh_register_operand (operands[1], V2HImode))"
11880 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11881 (set_attr "length" "4,4,16,4,4")
11882 (set (attr "highpart")
11883 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11884 (const_string "user")]
11885 (const_string "ignore")))])
11887 (define_expand "movv4hi"
11888 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11889 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11891 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11893 (define_insn "movv4hi_i"
11894 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11895 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11897 && (register_operand (operands[0], V4HImode)
11898 || sh_register_operand (operands[1], V4HImode))"
11905 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11906 (set_attr "length" "4,4,16,4,4")
11907 (set_attr "highpart" "depend")])
11909 (define_expand "movv2si"
11910 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11911 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11913 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11915 (define_insn "movv2si_i"
11916 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11917 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11919 && (register_operand (operands[0], V2SImode)
11920 || sh_register_operand (operands[1], V2SImode))"
11927 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11928 (set_attr "length" "4,4,16,4,4")
11929 (set_attr "highpart" "depend")])
11931 ;; Multimedia Intrinsics
11933 (define_insn "absv2si2"
11934 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11935 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11938 [(set_attr "type" "mcmp_media")
11939 (set_attr "highpart" "depend")])
11941 (define_insn "absv4hi2"
11942 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11943 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11946 [(set_attr "type" "mcmp_media")
11947 (set_attr "highpart" "depend")])
11949 (define_insn "addv2si3"
11950 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11951 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11952 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11954 "madd.l %1, %2, %0"
11955 [(set_attr "type" "arith_media")
11956 (set_attr "highpart" "depend")])
11958 (define_insn "addv4hi3"
11959 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11960 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11961 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11963 "madd.w %1, %2, %0"
11964 [(set_attr "type" "arith_media")
11965 (set_attr "highpart" "depend")])
11967 (define_insn_and_split "addv2hi3"
11968 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11969 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11970 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11977 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11978 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11979 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11980 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11981 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11983 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11984 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11987 [(set_attr "highpart" "must_split")])
11989 (define_insn "ssaddv2si3"
11990 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11991 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11992 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11994 "madds.l %1, %2, %0"
11995 [(set_attr "type" "mcmp_media")
11996 (set_attr "highpart" "depend")])
11998 (define_insn "usaddv8qi3"
11999 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12000 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12001 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12003 "madds.ub %1, %2, %0"
12004 [(set_attr "type" "mcmp_media")
12005 (set_attr "highpart" "depend")])
12007 (define_insn "ssaddv4hi3"
12008 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12009 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12010 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12012 "madds.w %1, %2, %0"
12013 [(set_attr "type" "mcmp_media")
12014 (set_attr "highpart" "depend")])
12016 (define_insn "negcmpeqv8qi"
12017 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12018 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12019 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12021 "mcmpeq.b %N1, %N2, %0"
12022 [(set_attr "type" "mcmp_media")
12023 (set_attr "highpart" "depend")])
12025 (define_insn "negcmpeqv2si"
12026 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12027 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12028 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12030 "mcmpeq.l %N1, %N2, %0"
12031 [(set_attr "type" "mcmp_media")
12032 (set_attr "highpart" "depend")])
12034 (define_insn "negcmpeqv4hi"
12035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12036 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12037 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12039 "mcmpeq.w %N1, %N2, %0"
12040 [(set_attr "type" "mcmp_media")
12041 (set_attr "highpart" "depend")])
12043 (define_insn "negcmpgtuv8qi"
12044 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12045 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12046 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12048 "mcmpgt.ub %N1, %N2, %0"
12049 [(set_attr "type" "mcmp_media")
12050 (set_attr "highpart" "depend")])
12052 (define_insn "negcmpgtv2si"
12053 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12054 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12055 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12057 "mcmpgt.l %N1, %N2, %0"
12058 [(set_attr "type" "mcmp_media")
12059 (set_attr "highpart" "depend")])
12061 (define_insn "negcmpgtv4hi"
12062 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12063 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12064 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12066 "mcmpgt.w %N1, %N2, %0"
12067 [(set_attr "type" "mcmp_media")
12068 (set_attr "highpart" "depend")])
12070 (define_insn "mcmv"
12071 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12072 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12073 (match_operand:DI 2 "arith_reg_operand" "r"))
12074 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12075 (not:DI (match_dup 2)))))]
12078 [(set_attr "type" "arith_media")
12079 (set_attr "highpart" "depend")])
12081 (define_insn "mcnvs_lw"
12082 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12084 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12085 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12087 "mcnvs.lw %N1, %N2, %0"
12088 [(set_attr "type" "mcmp_media")])
12090 (define_insn "mcnvs_wb"
12091 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12093 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12094 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12096 "mcnvs.wb %N1, %N2, %0"
12097 [(set_attr "type" "mcmp_media")])
12099 (define_insn "mcnvs_wub"
12100 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12102 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12103 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12105 "mcnvs.wub %N1, %N2, %0"
12106 [(set_attr "type" "mcmp_media")])
12108 (define_insn "mextr_rl"
12109 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12110 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12111 (match_operand:HI 3 "mextr_bit_offset" "i"))
12112 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12113 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12114 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12117 static char templ[21];
12119 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12120 (int) INTVAL (operands[3]) >> 3);
12123 [(set_attr "type" "arith_media")])
12125 (define_insn "*mextr_lr"
12126 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12127 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12128 (match_operand:HI 3 "mextr_bit_offset" "i"))
12129 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12130 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12131 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12134 static char templ[21];
12136 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12137 (int) INTVAL (operands[4]) >> 3);
12140 [(set_attr "type" "arith_media")])
12142 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12143 ; vector then varies depending on endianness.
12144 (define_expand "mextr1"
12145 [(match_operand:DI 0 "arith_reg_dest" "")
12146 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12147 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12151 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12152 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12156 (define_expand "mextr2"
12157 [(match_operand:DI 0 "arith_reg_dest" "")
12158 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12159 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12163 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12164 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12168 (define_expand "mextr3"
12169 [(match_operand:DI 0 "arith_reg_dest" "")
12170 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12171 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12175 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12176 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12180 (define_expand "mextr4"
12181 [(match_operand:DI 0 "arith_reg_dest" "")
12182 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12183 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12187 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12188 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12192 (define_expand "mextr5"
12193 [(match_operand:DI 0 "arith_reg_dest" "")
12194 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12195 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12199 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12200 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12204 (define_expand "mextr6"
12205 [(match_operand:DI 0 "arith_reg_dest" "")
12206 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12207 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12211 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12212 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12216 (define_expand "mextr7"
12217 [(match_operand:DI 0 "arith_reg_dest" "")
12218 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12219 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12223 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12224 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12228 (define_expand "mmacfx_wl"
12229 [(match_operand:V2SI 0 "arith_reg_dest" "")
12230 (match_operand:V2HI 1 "extend_reg_operand" "")
12231 (match_operand:V2HI 2 "extend_reg_operand" "")
12232 (match_operand:V2SI 3 "arith_reg_operand" "")]
12236 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12237 operands[1], operands[2]));
12241 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12243 (define_insn "mmacfx_wl_i"
12244 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12246 (match_operand:V2SI 1 "arith_reg_operand" "0")
12251 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12252 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12255 "mmacfx.wl %2, %3, %0"
12256 [(set_attr "type" "mac_media")
12257 (set_attr "highpart" "depend")])
12259 (define_expand "mmacnfx_wl"
12260 [(match_operand:V2SI 0 "arith_reg_dest" "")
12261 (match_operand:V2HI 1 "extend_reg_operand" "")
12262 (match_operand:V2HI 2 "extend_reg_operand" "")
12263 (match_operand:V2SI 3 "arith_reg_operand" "")]
12267 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12268 operands[1], operands[2]));
12272 (define_insn "mmacnfx_wl_i"
12273 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12275 (match_operand:V2SI 1 "arith_reg_operand" "0")
12280 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12281 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12284 "mmacnfx.wl %2, %3, %0"
12285 [(set_attr "type" "mac_media")
12286 (set_attr "highpart" "depend")])
12288 (define_insn "mulv2si3"
12289 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12290 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12291 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12293 "mmul.l %1, %2, %0"
12294 [(set_attr "type" "d2mpy_media")
12295 (set_attr "highpart" "depend")])
12297 (define_insn "mulv4hi3"
12298 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12299 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12300 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12302 "mmul.w %1, %2, %0"
12303 [(set_attr "type" "dmpy_media")
12304 (set_attr "highpart" "depend")])
12306 (define_insn "mmulfx_l"
12307 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12311 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12312 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12315 "mmulfx.l %1, %2, %0"
12316 [(set_attr "type" "d2mpy_media")
12317 (set_attr "highpart" "depend")])
12319 (define_insn "mmulfx_w"
12320 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12324 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12325 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12328 "mmulfx.w %1, %2, %0"
12329 [(set_attr "type" "dmpy_media")
12330 (set_attr "highpart" "depend")])
12332 (define_insn "mmulfxrp_w"
12333 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12338 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12339 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12343 "mmulfxrp.w %1, %2, %0"
12344 [(set_attr "type" "dmpy_media")
12345 (set_attr "highpart" "depend")])
12348 (define_expand "mmulhi_wl"
12349 [(match_operand:V2SI 0 "arith_reg_dest" "")
12350 (match_operand:V4HI 1 "arith_reg_operand" "")
12351 (match_operand:V4HI 2 "arith_reg_operand" "")]
12355 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12356 (operands[0], operands[1], operands[2]));
12360 (define_expand "mmullo_wl"
12361 [(match_operand:V2SI 0 "arith_reg_dest" "")
12362 (match_operand:V4HI 1 "arith_reg_operand" "")
12363 (match_operand:V4HI 2 "arith_reg_operand" "")]
12367 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12368 (operands[0], operands[1], operands[2]));
12372 (define_insn "mmul23_wl"
12373 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12376 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12377 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12378 (parallel [(const_int 2) (const_int 3)])))]
12380 "* return (TARGET_LITTLE_ENDIAN
12381 ? \"mmulhi.wl %1, %2, %0\"
12382 : \"mmullo.wl %1, %2, %0\");"
12383 [(set_attr "type" "dmpy_media")
12384 (set (attr "highpart")
12385 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12386 (const_string "user")))])
12388 (define_insn "mmul01_wl"
12389 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12392 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12393 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12394 (parallel [(const_int 0) (const_int 1)])))]
12396 "* return (TARGET_LITTLE_ENDIAN
12397 ? \"mmullo.wl %1, %2, %0\"
12398 : \"mmulhi.wl %1, %2, %0\");"
12399 [(set_attr "type" "dmpy_media")
12400 (set (attr "highpart")
12401 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12402 (const_string "user")))])
12405 (define_expand "mmulsum_wq"
12406 [(match_operand:DI 0 "arith_reg_dest" "")
12407 (match_operand:V4HI 1 "arith_reg_operand" "")
12408 (match_operand:V4HI 2 "arith_reg_operand" "")
12409 (match_operand:DI 3 "arith_reg_operand" "")]
12413 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12414 operands[1], operands[2]));
12418 (define_insn "mmulsum_wq_i"
12419 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12420 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12425 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12426 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12427 (parallel [(const_int 0)]))
12428 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12429 (sign_extend:V4DI (match_dup 3)))
12430 (parallel [(const_int 1)])))
12432 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12433 (sign_extend:V4DI (match_dup 3)))
12434 (parallel [(const_int 2)]))
12435 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12436 (sign_extend:V4DI (match_dup 3)))
12437 (parallel [(const_int 3)]))))))]
12439 "mmulsum.wq %2, %3, %0"
12440 [(set_attr "type" "mac_media")])
12442 (define_expand "mperm_w"
12443 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12444 (match_operand:V4HI 1 "arith_reg_operand" "r")
12445 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12449 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12450 (operands[0], operands[1], operands[2]));
12454 ; This use of vec_select isn't exactly correct according to rtl.texi
12455 ; (because not constant), but it seems a straightforward extension.
12456 (define_insn "mperm_w_little"
12457 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12459 (match_operand:V4HI 1 "arith_reg_operand" "r")
12461 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12462 (const_int 2) (const_int 0))
12463 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12464 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12465 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12466 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12467 "mperm.w %1, %N2, %0"
12468 [(set_attr "type" "arith_media")])
12470 (define_insn "mperm_w_big"
12471 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12473 (match_operand:V4HI 1 "arith_reg_operand" "r")
12475 [(zero_extract:QI (not:QI (match_operand:QI 2
12476 "extend_reg_or_0_operand" "rZ"))
12477 (const_int 2) (const_int 0))
12478 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12479 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12480 (zero_extract:QI (not:QI (match_dup 2))
12481 (const_int 2) (const_int 6))])))]
12482 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12483 "mperm.w %1, %N2, %0"
12484 [(set_attr "type" "arith_media")])
12486 (define_insn "mperm_w0"
12487 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12488 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12489 "trunc_hi_operand" "r"))))]
12491 "mperm.w %1, r63, %0"
12492 [(set_attr "type" "arith_media")
12493 (set_attr "highpart" "ignore")])
12495 (define_expand "msad_ubq"
12496 [(match_operand:DI 0 "arith_reg_dest" "")
12497 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12498 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12499 (match_operand:DI 3 "arith_reg_operand" "")]
12503 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12504 operands[1], operands[2]));
12508 (define_insn "msad_ubq_i"
12509 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12514 (match_operand:DI 1 "arith_reg_operand" "0")
12515 (abs:DI (vec_select:DI
12518 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12520 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12521 (parallel [(const_int 0)]))))
12522 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12523 (zero_extend:V8DI (match_dup 3)))
12524 (parallel [(const_int 1)]))))
12526 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12527 (zero_extend:V8DI (match_dup 3)))
12528 (parallel [(const_int 2)])))
12529 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12530 (zero_extend:V8DI (match_dup 3)))
12531 (parallel [(const_int 3)])))))
12534 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12535 (zero_extend:V8DI (match_dup 3)))
12536 (parallel [(const_int 4)])))
12537 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12538 (zero_extend:V8DI (match_dup 3)))
12539 (parallel [(const_int 5)]))))
12541 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12542 (zero_extend:V8DI (match_dup 3)))
12543 (parallel [(const_int 6)])))
12544 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12545 (zero_extend:V8DI (match_dup 3)))
12546 (parallel [(const_int 7)])))))))]
12548 "msad.ubq %N2, %N3, %0"
12549 [(set_attr "type" "mac_media")])
12551 (define_insn "mshalds_l"
12552 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12555 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12556 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12557 (const_int 31)))))]
12559 "mshalds.l %1, %2, %0"
12560 [(set_attr "type" "mcmp_media")
12561 (set_attr "highpart" "depend")])
12563 (define_insn "mshalds_w"
12564 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12567 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12568 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12569 (const_int 15)))))]
12571 "mshalds.w %1, %2, %0"
12572 [(set_attr "type" "mcmp_media")
12573 (set_attr "highpart" "depend")])
12575 (define_insn "ashrv2si3"
12576 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12577 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12578 (match_operand:DI 2 "arith_reg_operand" "r")))]
12580 "mshard.l %1, %2, %0"
12581 [(set_attr "type" "arith_media")
12582 (set_attr "highpart" "depend")])
12584 (define_insn "ashrv4hi3"
12585 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12586 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12587 (match_operand:DI 2 "arith_reg_operand" "r")))]
12589 "mshard.w %1, %2, %0"
12590 [(set_attr "type" "arith_media")
12591 (set_attr "highpart" "depend")])
12593 (define_insn "mshards_q"
12594 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12596 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12597 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12599 "mshards.q %1, %N2, %0"
12600 [(set_attr "type" "mcmp_media")])
12602 (define_expand "mshfhi_b"
12603 [(match_operand:V8QI 0 "arith_reg_dest" "")
12604 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12605 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12609 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12610 (operands[0], operands[1], operands[2]));
12614 (define_expand "mshflo_b"
12615 [(match_operand:V8QI 0 "arith_reg_dest" "")
12616 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12617 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12621 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12622 (operands[0], operands[1], operands[2]));
12626 (define_insn "mshf4_b"
12628 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12630 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12631 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12632 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12633 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12635 "* return (TARGET_LITTLE_ENDIAN
12636 ? \"mshfhi.b %N1, %N2, %0\"
12637 : \"mshflo.b %N1, %N2, %0\");"
12638 [(set_attr "type" "arith_media")
12639 (set (attr "highpart")
12640 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12641 (const_string "user")))])
12643 (define_insn "mshf0_b"
12645 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12647 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12648 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12649 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12650 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12652 "* return (TARGET_LITTLE_ENDIAN
12653 ? \"mshflo.b %N1, %N2, %0\"
12654 : \"mshfhi.b %N1, %N2, %0\");"
12655 [(set_attr "type" "arith_media")
12656 (set (attr "highpart")
12657 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12658 (const_string "user")))])
12660 (define_expand "mshfhi_l"
12661 [(match_operand:V2SI 0 "arith_reg_dest" "")
12662 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12663 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12667 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12668 (operands[0], operands[1], operands[2]));
12672 (define_expand "mshflo_l"
12673 [(match_operand:V2SI 0 "arith_reg_dest" "")
12674 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12675 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12679 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12680 (operands[0], operands[1], operands[2]));
12684 (define_insn "mshf4_l"
12685 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12687 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12688 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12689 (parallel [(const_int 1) (const_int 3)])))]
12691 "* return (TARGET_LITTLE_ENDIAN
12692 ? \"mshfhi.l %N1, %N2, %0\"
12693 : \"mshflo.l %N1, %N2, %0\");"
12694 [(set_attr "type" "arith_media")
12695 (set (attr "highpart")
12696 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12697 (const_string "user")))])
12699 (define_insn "mshf0_l"
12700 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12702 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12703 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12704 (parallel [(const_int 0) (const_int 2)])))]
12706 "* return (TARGET_LITTLE_ENDIAN
12707 ? \"mshflo.l %N1, %N2, %0\"
12708 : \"mshfhi.l %N1, %N2, %0\");"
12709 [(set_attr "type" "arith_media")
12710 (set (attr "highpart")
12711 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12712 (const_string "user")))])
12714 (define_expand "mshfhi_w"
12715 [(match_operand:V4HI 0 "arith_reg_dest" "")
12716 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12717 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12721 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12722 (operands[0], operands[1], operands[2]));
12726 (define_expand "mshflo_w"
12727 [(match_operand:V4HI 0 "arith_reg_dest" "")
12728 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12729 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12733 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12734 (operands[0], operands[1], operands[2]));
12738 (define_insn "mshf4_w"
12739 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12741 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12742 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12743 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12745 "* return (TARGET_LITTLE_ENDIAN
12746 ? \"mshfhi.w %N1, %N2, %0\"
12747 : \"mshflo.w %N1, %N2, %0\");"
12748 [(set_attr "type" "arith_media")
12749 (set (attr "highpart")
12750 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12751 (const_string "user")))])
12753 (define_insn "mshf0_w"
12754 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12756 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12757 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12758 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12760 "* return (TARGET_LITTLE_ENDIAN
12761 ? \"mshflo.w %N1, %N2, %0\"
12762 : \"mshfhi.w %N1, %N2, %0\");"
12763 [(set_attr "type" "arith_media")
12764 (set (attr "highpart")
12765 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12766 (const_string "user")))])
12768 (define_insn "mshflo_w_x"
12769 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12771 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12772 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12773 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12775 "mshflo.w %N1, %N2, %0"
12776 [(set_attr "type" "arith_media")
12777 (set_attr "highpart" "ignore")])
12779 /* These are useful to expand ANDs and as combiner patterns. */
12780 (define_insn_and_split "mshfhi_l_di"
12781 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12782 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12784 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12785 (const_int -4294967296))))]
12788 mshfhi.l %N1, %N2, %0
12790 "TARGET_SHMEDIA && reload_completed
12791 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12792 [(set (match_dup 3) (match_dup 4))
12793 (set (match_dup 5) (match_dup 6))]
12796 operands[3] = gen_lowpart (SImode, operands[0]);
12797 operands[4] = gen_highpart (SImode, operands[1]);
12798 operands[5] = gen_highpart (SImode, operands[0]);
12799 operands[6] = gen_highpart (SImode, operands[2]);
12801 [(set_attr "type" "arith_media")])
12803 (define_insn "*mshfhi_l_di_rev"
12804 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12805 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12806 (const_int -4294967296))
12807 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12810 "mshfhi.l %N2, %N1, %0"
12811 [(set_attr "type" "arith_media")])
12814 [(set (match_operand:DI 0 "arith_reg_dest" "")
12815 (ior:DI (zero_extend:DI (match_operand:SI 1
12816 "extend_reg_or_0_operand" ""))
12817 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12818 (const_int -4294967296))))
12819 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12824 emit_insn (gen_ashldi3_media (operands[3],
12825 simplify_gen_subreg (DImode, operands[1],
12828 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12832 (define_insn "mshflo_l_di"
12833 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12834 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12835 (const_int 4294967295))
12836 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12840 "mshflo.l %N1, %N2, %0"
12841 [(set_attr "type" "arith_media")
12842 (set_attr "highpart" "ignore")])
12844 (define_insn "*mshflo_l_di_rev"
12845 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12846 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12848 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12849 (const_int 4294967295))))]
12852 "mshflo.l %N2, %N1, %0"
12853 [(set_attr "type" "arith_media")
12854 (set_attr "highpart" "ignore")])
12856 ;; Combiner pattern for trampoline initialization.
12857 (define_insn_and_split "*double_shori"
12858 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12859 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12861 (match_operand:DI 2 "const_int_operand" "n")))]
12863 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12865 "rtx_equal_p (operands[0], operands[1])"
12869 HOST_WIDE_INT v = INTVAL (operands[2]);
12871 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12872 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12875 [(set_attr "highpart" "ignore")])
12878 (define_insn "*mshflo_l_di_x"
12879 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12880 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12882 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12886 "mshflo.l %N1, %N2, %0"
12887 [(set_attr "type" "arith_media")
12888 (set_attr "highpart" "ignore")])
12890 (define_insn_and_split "concat_v2sf"
12891 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12892 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12893 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12894 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12898 mshflo.l %N1, %N2, %0
12901 "TARGET_SHMEDIA && reload_completed
12902 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12903 [(set (match_dup 3) (match_dup 1))
12904 (set (match_dup 4) (match_dup 2))]
12907 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12908 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12910 [(set_attr "type" "arith_media")
12911 (set_attr "highpart" "ignore")])
12913 (define_insn "*mshflo_l_di_x_rev"
12914 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12915 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12917 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12920 "mshflo.l %N2, %N1, %0"
12921 [(set_attr "type" "arith_media")
12922 (set_attr "highpart" "ignore")])
12924 (define_insn "ashlv2si3"
12925 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12926 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12927 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12929 "mshlld.l %1, %2, %0"
12930 [(set_attr "type" "arith_media")
12931 (set_attr "highpart" "depend")])
12934 [(set (match_operand 0 "any_register_operand" "")
12935 (match_operator 3 "shift_operator"
12936 [(match_operand 1 "any_register_operand" "")
12937 (match_operand 2 "shift_count_reg_operand" "")]))]
12938 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12939 [(set (match_dup 0) (match_dup 3))]
12942 rtx count = operands[2];
12943 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12945 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12946 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12947 || GET_CODE (count) == TRUNCATE)
12948 count = XEXP (count, 0);
12949 inner_mode = GET_MODE (count);
12950 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12951 subreg_lowpart_offset (outer_mode, inner_mode));
12952 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12953 operands[1], count);
12956 (define_insn "ashlv4hi3"
12957 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12958 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12959 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12961 "mshlld.w %1, %2, %0"
12962 [(set_attr "type" "arith_media")
12963 (set_attr "highpart" "depend")])
12965 (define_insn "lshrv2si3"
12966 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12967 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12968 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12970 "mshlrd.l %1, %2, %0"
12971 [(set_attr "type" "arith_media")
12972 (set_attr "highpart" "depend")])
12974 (define_insn "lshrv4hi3"
12975 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12976 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12977 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12979 "mshlrd.w %1, %2, %0"
12980 [(set_attr "type" "arith_media")
12981 (set_attr "highpart" "depend")])
12983 (define_insn "subv2si3"
12984 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12985 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12986 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12988 "msub.l %N1, %2, %0"
12989 [(set_attr "type" "arith_media")
12990 (set_attr "highpart" "depend")])
12992 (define_insn "subv4hi3"
12993 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12994 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12995 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12997 "msub.w %N1, %2, %0"
12998 [(set_attr "type" "arith_media")
12999 (set_attr "highpart" "depend")])
13001 (define_insn_and_split "subv2hi3"
13002 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13003 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13004 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13011 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13012 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13013 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13014 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13015 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13017 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13018 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13021 [(set_attr "highpart" "must_split")])
13023 (define_insn "sssubv2si3"
13024 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13025 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13026 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13028 "msubs.l %N1, %2, %0"
13029 [(set_attr "type" "mcmp_media")
13030 (set_attr "highpart" "depend")])
13032 (define_insn "ussubv8qi3"
13033 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13034 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13035 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13037 "msubs.ub %N1, %2, %0"
13038 [(set_attr "type" "mcmp_media")
13039 (set_attr "highpart" "depend")])
13041 (define_insn "sssubv4hi3"
13042 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13043 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13044 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13046 "msubs.w %N1, %2, %0"
13047 [(set_attr "type" "mcmp_media")
13048 (set_attr "highpart" "depend")])
13050 ;; Floating Point Intrinsics
13052 (define_insn "fcosa_s"
13053 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13054 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13058 [(set_attr "type" "atrans_media")])
13060 (define_insn "fsina_s"
13061 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13062 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13066 [(set_attr "type" "atrans_media")])
13068 (define_insn "fipr"
13069 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13070 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13071 "fp_arith_reg_operand" "f")
13072 (match_operand:V4SF 2
13073 "fp_arith_reg_operand" "f"))
13074 (parallel [(const_int 0)]))
13075 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13076 (parallel [(const_int 1)])))
13077 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13078 (parallel [(const_int 2)]))
13079 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13080 (parallel [(const_int 3)])))))]
13082 "fipr.s %1, %2, %0"
13083 [(set_attr "type" "fparith_media")])
13085 (define_insn "fsrra_s"
13086 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13087 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13091 [(set_attr "type" "atrans_media")])
13093 (define_insn "ftrv"
13094 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13098 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13099 (parallel [(const_int 0) (const_int 5)
13100 (const_int 10) (const_int 15)]))
13101 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13103 (vec_select:V4SF (match_dup 1)
13104 (parallel [(const_int 4) (const_int 9)
13105 (const_int 14) (const_int 3)]))
13106 (vec_select:V4SF (match_dup 2)
13107 (parallel [(const_int 1) (const_int 2)
13108 (const_int 3) (const_int 0)]))))
13111 (vec_select:V4SF (match_dup 1)
13112 (parallel [(const_int 8) (const_int 13)
13113 (const_int 2) (const_int 7)]))
13114 (vec_select:V4SF (match_dup 2)
13115 (parallel [(const_int 2) (const_int 3)
13116 (const_int 0) (const_int 1)])))
13118 (vec_select:V4SF (match_dup 1)
13119 (parallel [(const_int 12) (const_int 1)
13120 (const_int 6) (const_int 11)]))
13121 (vec_select:V4SF (match_dup 2)
13122 (parallel [(const_int 3) (const_int 0)
13123 (const_int 1) (const_int 2)]))))))]
13125 "ftrv.s %1, %2, %0"
13126 [(set_attr "type" "fparith_media")])
13128 (define_insn "ldhi_l"
13129 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13131 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13134 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13138 [(set_attr "type" "load_media")])
13140 (define_insn "ldhi_q"
13141 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13143 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13146 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13150 [(set_attr "type" "load_media")])
13152 (define_insn_and_split "*ldhi_q_comb0"
13153 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13155 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13156 "register_operand" "r")
13157 (match_operand:SI 2
13158 "ua_offset" "I06"))
13161 (plus:SI (and:SI (match_dup 1) (const_int 7))
13164 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13168 "emit_insn (gen_ldhi_q (operands[0],
13169 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13173 (define_insn_and_split "*ldhi_q_comb1"
13174 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13176 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13177 "register_operand" "r")
13178 (match_operand:SI 2
13179 "ua_offset" "I06"))
13182 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13183 "ua_offset" "I06"))
13187 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13188 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13192 "emit_insn (gen_ldhi_q (operands[0],
13193 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13197 (define_insn "ldlo_l"
13198 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13200 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13202 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13203 (and:SI (match_dup 1) (const_int 3))))]
13206 [(set_attr "type" "load_media")])
13208 (define_insn "ldlo_q"
13209 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13211 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13213 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13214 (and:SI (match_dup 1) (const_int 7))))]
13217 [(set_attr "type" "load_media")])
13219 (define_insn_and_split "*ldlo_q_comb0"
13220 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13222 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13223 (match_operand:SI 2 "ua_offset" "I06"))
13225 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13226 (and:SI (match_dup 1) (const_int 7))))]
13227 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13231 "emit_insn (gen_ldlo_q (operands[0],
13232 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13235 (define_insn_and_split "*ldlo_q_comb1"
13236 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13238 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13239 (match_operand:SI 2 "ua_offset" "I06"))
13241 (minus:SI (const_int 8)
13242 (and:SI (plus:SI (match_dup 1)
13243 (match_operand:SI 3 "ua_offset" "I06"))
13245 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13246 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13247 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13251 "emit_insn (gen_ldlo_q (operands[0],
13252 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13255 (define_insn "sthi_l"
13256 [(set (zero_extract:SI
13257 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13260 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13262 (match_operand:SI 1 "arith_reg_operand" "r"))]
13265 [(set_attr "type" "ustore_media")])
13267 ;; All unaligned stores are considered to be 'narrow' because they typically
13268 ;; operate on less that a quadword, and when they operate on a full quadword,
13269 ;; the vanilla store high / store low sequence will cause a stall if not
13270 ;; scheduled apart.
13271 (define_insn "sthi_q"
13272 [(set (zero_extract:DI
13273 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13276 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13278 (match_operand:DI 1 "arith_reg_operand" "r"))]
13281 [(set_attr "type" "ustore_media")])
13283 (define_insn_and_split "*sthi_q_comb0"
13284 [(set (zero_extract:DI
13285 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13286 "register_operand" "r")
13287 (match_operand:SI 1 "ua_offset"
13291 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13293 (match_operand:DI 2 "arith_reg_operand" "r"))]
13294 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13298 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13302 (define_insn_and_split "*sthi_q_comb1"
13303 [(set (zero_extract:DI
13304 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13305 "register_operand" "r")
13306 (match_operand:SI 1 "ua_offset"
13310 (plus:SI (and:SI (plus:SI (match_dup 0)
13311 (match_operand:SI 2 "ua_offset" "I06"))
13315 (match_operand:DI 3 "arith_reg_operand" "r"))]
13316 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13317 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13321 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13325 ;; This is highpart user because the address is used as full 64 bit.
13326 (define_insn "stlo_l"
13327 [(set (zero_extract:SI
13328 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13330 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13331 (and:SI (match_dup 0) (const_int 3)))
13332 (match_operand:SI 1 "arith_reg_operand" "r"))]
13335 [(set_attr "type" "ustore_media")])
13337 (define_insn "stlo_q"
13338 [(set (zero_extract:DI
13339 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13341 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13342 (and:SI (match_dup 0) (const_int 7)))
13343 (match_operand:DI 1 "arith_reg_operand" "r"))]
13346 [(set_attr "type" "ustore_media")])
13348 (define_insn_and_split "*stlo_q_comb0"
13349 [(set (zero_extract:DI
13350 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13351 (match_operand:SI 1 "ua_offset" "I06"))
13353 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13354 (and:SI (match_dup 0) (const_int 7)))
13355 (match_operand:DI 2 "arith_reg_operand" "r"))]
13356 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13360 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13364 (define_insn_and_split "*stlo_q_comb1"
13365 [(set (zero_extract:DI
13366 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13367 (match_operand:SI 1 "ua_offset" "I06"))
13369 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13370 (match_operand:SI 2
13371 "ua_offset" "I06"))
13373 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13374 (match_operand:DI 3 "arith_reg_operand" "r"))]
13375 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13379 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13383 (define_insn "ldhi_l64"
13384 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13386 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13389 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13393 [(set_attr "type" "load_media")])
13395 (define_insn "ldhi_q64"
13396 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13398 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13401 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13405 [(set_attr "type" "load_media")])
13407 (define_insn "ldlo_l64"
13408 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13410 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13412 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13413 (and:DI (match_dup 1) (const_int 3))))]
13416 [(set_attr "type" "load_media")])
13418 (define_insn "ldlo_q64"
13419 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13421 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13423 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13424 (and:DI (match_dup 1) (const_int 7))))]
13427 [(set_attr "type" "load_media")])
13429 (define_insn "sthi_l64"
13430 [(set (zero_extract:SI
13431 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13434 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13436 (match_operand:SI 1 "arith_reg_operand" "r"))]
13439 [(set_attr "type" "ustore_media")])
13441 (define_insn "sthi_q64"
13442 [(set (zero_extract:DI
13443 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13446 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13448 (match_operand:DI 1 "arith_reg_operand" "r"))]
13451 [(set_attr "type" "ustore_media")])
13453 (define_insn "stlo_l64"
13454 [(set (zero_extract:SI
13455 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13457 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13458 (and:DI (match_dup 0) (const_int 3)))
13459 (match_operand:SI 1 "arith_reg_operand" "r"))]
13462 [(set_attr "type" "ustore_media")])
13464 (define_insn "stlo_q64"
13465 [(set (zero_extract:DI
13466 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13468 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13469 (and:DI (match_dup 0) (const_int 7)))
13470 (match_operand:DI 1 "arith_reg_operand" "r"))]
13473 [(set_attr "type" "ustore_media")])
13476 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13477 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13481 [(set_attr "type" "arith_media")])
13483 (define_insn "nsbsi"
13484 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13486 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13490 [(set_attr "type" "arith_media")])
13492 (define_insn "nsbdi"
13493 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13495 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13499 [(set_attr "type" "arith_media")])
13501 (define_expand "ffsdi2"
13502 [(set (match_operand:DI 0 "arith_reg_dest" "")
13503 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13507 rtx scratch = gen_reg_rtx (DImode);
13510 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13511 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13512 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13513 emit_insn (gen_nsbdi (scratch, scratch));
13514 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13515 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13516 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13517 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13522 (define_expand "ffssi2"
13523 [(set (match_operand:SI 0 "arith_reg_dest" "")
13524 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13528 rtx scratch = gen_reg_rtx (SImode);
13529 rtx discratch = gen_reg_rtx (DImode);
13532 emit_insn (gen_adddi3 (discratch,
13533 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13535 emit_insn (gen_andcdi3 (discratch,
13536 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13538 emit_insn (gen_nsbsi (scratch, discratch));
13539 last = emit_insn (gen_subsi3 (operands[0],
13540 force_reg (SImode, GEN_INT (63)), scratch));
13541 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13546 (define_insn "byterev"
13547 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13548 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13549 (parallel [(const_int 7) (const_int 6) (const_int 5)
13550 (const_int 4) (const_int 3) (const_int 2)
13551 (const_int 1) (const_int 0)])))]
13554 [(set_attr "type" "arith_media")])
13556 (define_insn "*prefetch_media"
13557 [(prefetch (match_operand:QI 0 "address_operand" "p")
13558 (match_operand:SI 1 "const_int_operand" "n")
13559 (match_operand:SI 2 "const_int_operand" "n"))]
13563 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13564 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13567 [(set_attr "type" "other")])
13569 (define_insn "*prefetch_i4"
13570 [(prefetch (match_operand:SI 0 "register_operand" "r")
13571 (match_operand:SI 1 "const_int_operand" "n")
13572 (match_operand:SI 2 "const_int_operand" "n"))]
13573 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13576 return \"pref @%0\";
13578 [(set_attr "type" "other")])
13580 (define_expand "prefetch"
13581 [(prefetch (match_operand 0 "address_operand" "p")
13582 (match_operand:SI 1 "const_int_operand" "n")
13583 (match_operand:SI 2 "const_int_operand" "n"))]
13584 "TARGET_HARD_SH4 || TARGET_SH5"
13587 if (GET_MODE (operands[0]) != Pmode
13588 || GET_CODE (operands[1]) != CONST_INT
13589 || GET_CODE (operands[2]) != CONST_INT)
13591 if (! TARGET_SHMEDIA)
13592 operands[0] = force_reg (Pmode, operands[0]);
13595 (define_insn "alloco_i"
13596 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13597 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13603 if (GET_CODE (operands[0]) == PLUS)
13605 xops[0] = XEXP (operands[0], 0);
13606 xops[1] = XEXP (operands[0], 1);
13610 xops[0] = operands[0];
13611 xops[1] = const0_rtx;
13613 output_asm_insn (\"alloco %0, %1\", xops);
13616 [(set_attr "type" "other")])
13619 [(set (match_operand 0 "any_register_operand" "")
13620 (match_operand 1 "" ""))]
13621 "TARGET_SHMEDIA && reload_completed"
13622 [(set (match_dup 0) (match_dup 1))]
13627 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13632 ; Stack Protector Patterns
13634 (define_expand "stack_protect_set"
13635 [(set (match_operand 0 "memory_operand" "")
13636 (match_operand 1 "memory_operand" ""))]
13639 if (TARGET_SHMEDIA)
13641 if (TARGET_SHMEDIA64)
13642 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13644 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13647 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13652 (define_insn "stack_protect_set_si"
13653 [(set (match_operand:SI 0 "memory_operand" "=m")
13654 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13655 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13657 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13658 [(set_attr "type" "other")
13659 (set_attr "length" "6")])
13661 (define_insn "stack_protect_set_si_media"
13662 [(set (match_operand:SI 0 "memory_operand" "=m")
13663 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13664 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13666 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13667 [(set_attr "type" "other")
13668 (set_attr "length" "12")])
13670 (define_insn "stack_protect_set_di_media"
13671 [(set (match_operand:DI 0 "memory_operand" "=m")
13672 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13673 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13675 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13676 [(set_attr "type" "other")
13677 (set_attr "length" "12")])
13679 (define_expand "stack_protect_test"
13680 [(match_operand 0 "memory_operand" "")
13681 (match_operand 1 "memory_operand" "")
13682 (match_operand 2 "" "")]
13685 if (TARGET_SHMEDIA)
13687 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13689 if (TARGET_SHMEDIA64)
13690 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13693 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13696 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13700 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13701 emit_jump_insn (gen_branch_true (operands[2]));
13707 (define_insn "stack_protect_test_si"
13708 [(set (reg:SI T_REG)
13709 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13710 (match_operand:SI 1 "memory_operand" "m")]
13712 (set (match_scratch:SI 2 "=&r") (const_int 0))
13713 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13715 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13716 [(set_attr "type" "other")
13717 (set_attr "length" "10")])
13719 (define_insn "stack_protect_test_si_media"
13720 [(set (match_operand:SI 0 "register_operand" "=&r")
13721 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13722 (match_operand:SI 2 "memory_operand" "m")]
13724 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13726 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13727 [(set_attr "type" "other")
13728 (set_attr "length" "16")])
13730 (define_insn "stack_protect_test_di_media"
13731 [(set (match_operand:DI 0 "register_operand" "=&r")
13732 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13733 (match_operand:DI 2 "memory_operand" "m")]
13735 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13737 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13738 [(set_attr "type" "other")
13739 (set_attr "length" "16")])