1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;; Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
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)
158 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160 (UNSPEC_EXTRACT_S16 43)
161 (UNSPEC_EXTRACT_U16 44)
163 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
166 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167 (UNSPEC_PCREL_SYMOFF 46)
169 ;; These are used with unspec_volatile.
175 (UNSPECV_WINDOW_END 10)
176 (UNSPECV_CONST_END 11)
177 (UNSPECV_EH_RETURN 12)
180 ;; -------------------------------------------------------------------------
182 ;; -------------------------------------------------------------------------
187 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188 (const (symbol_ref "sh_cpu_attr")))
190 (define_attr "endian" "big,little"
191 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192 (const_string "little") (const_string "big"))))
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197 (const_string "yes") (const_string "no"))))
199 (define_attr "fmovd" "yes,no"
200 (const (if_then_else (symbol_ref "TARGET_FMOVD")
201 (const_string "yes") (const_string "no"))))
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
205 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207 (const_string "sh1"))))
209 ;; cbranch conditional branch instructions
210 ;; jump unconditional jumps
211 ;; arith ordinary arithmetic
212 ;; arith3 a compound insn that behaves similarly to a sequence of
213 ;; three insns of type arith
214 ;; arith3b like above, but might end with a redirected branch
216 ;; load_si Likewise, SImode variant for general register.
217 ;; fload Likewise, but load to fp register.
219 ;; fstore floating point register to memory
220 ;; move general purpose register to register
221 ;; movi8 8-bit immediate to general purpose register
222 ;; mt_group other sh4 mt instructions
223 ;; fmove register to register, floating point
224 ;; smpy word precision integer multiply
225 ;; dmpy longword or doublelongword precision integer multiply
227 ;; pload load of pr reg, which can't be put into delay slot of rts
228 ;; prset copy register to pr reg, ditto
229 ;; pstore store of pr reg, which can't be put into delay slot of jsr
230 ;; prget copy pr to register, ditto
231 ;; pcload pc relative load of constant value
232 ;; pcfload Likewise, but load to fp register.
233 ;; pcload_si Likewise, SImode variant for general register.
234 ;; rte return from exception
235 ;; sfunc special function call with known used registers
236 ;; call function call
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv floating point divide (or square root)
240 ;; gp_fpul move from general purpose register to fpul
241 ;; fpul_gp move from fpul to general purpose register
242 ;; mac_gp move from mac[lh] to general purpose register
243 ;; gp_mac move from general purpose register to mac[lh]
244 ;; mac_mem move from mac[lh] to memory
245 ;; mem_mac move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s fix_truncsfsi2_i4
248 ;; dfdiv double precision floating point divide (or square root)
249 ;; cwb ic_invalidate_line_i
250 ;; movua SH4a unaligned load
251 ;; fsrra square root reciprocal approximate
252 ;; fsca sine and cosine approximate
253 ;; tls_load load TLS related address
254 ;; arith_media SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media SHmedia compare instructions
257 ;; dfdiv_media SHmedia double precision divide and square root
258 ;; dfmul_media SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media SHmedia longword multiply
262 ;; fcmp_media SHmedia floating point compare instructions
263 ;; fdiv_media SHmedia single precision divide and square root
264 ;; fload_media SHmedia floating point register load instructions
265 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media SHmedia unconditional branch instructions
272 ;; load_media SHmedia general register load instructions
273 ;; pt_media SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media SHmedia ptabs instruction
275 ;; store_media SHmedia general register store instructions
276 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media SHmedia mac-style fixed point operations
278 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil no-op move, will be deleted.
284 "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"
285 (const_string "other"))
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
290 ;; mt_group SH4 "mt" group instructions.
292 ;; ex_group SH4 "ex" group instructions.
294 ;; ls_group SH4 "ls" group instructions.
297 (define_attr "insn_class"
298 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302 (eq_attr "type" "cbranch,jump") (const_string "br_group")
303 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304 (const_string "fe_group")
305 (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")]
306 (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long. Something in the
325 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
330 ;; The maximum range used for SImode constant pool entries is 1018. A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table. That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
348 (define_attr "short_cbranch_p" "no,yes"
349 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
351 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
353 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
357 ] (const_string "no")))
359 (define_attr "med_branch_p" "no,yes"
360 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
363 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
368 ] (const_string "no")))
370 (define_attr "med_cbranch_p" "no,yes"
371 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
374 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
379 ] (const_string "no")))
381 (define_attr "braf_branch_p" "no,yes"
382 (cond [(match_test "! TARGET_SH2")
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
387 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
392 ] (const_string "no")))
394 (define_attr "braf_cbranch_p" "no,yes"
395 (cond [(match_test "! TARGET_SH2")
397 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
400 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
402 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
405 ] (const_string "no")))
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
414 ; All other instructions are two bytes long by default.
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419 (cond [(eq_attr "type" "cbranch")
420 (cond [(eq_attr "short_cbranch_p" "yes")
422 (eq_attr "med_cbranch_p" "yes")
424 (eq_attr "braf_cbranch_p" "yes")
426 ;; ??? using pc is not computed transitively.
427 (ne (match_dup 0) (match_dup 0))
429 (match_test "flag_pic")
432 (eq_attr "type" "jump")
433 (cond [(eq_attr "med_branch_p" "yes")
435 (and (match_test "prev_nonnote_insn (insn)")
436 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") (symbol_ref "INSN"))
437 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") (symbol_ref "code_for_indirect_jump_scratch"))))
438 (cond [(eq_attr "braf_branch_p" "yes")
440 (not (match_test "flag_pic"))
442 (match_test "TARGET_SH2")
443 (const_int 10)] (const_int 18))
444 (eq_attr "braf_branch_p" "yes")
446 ;; ??? using pc is not computed transitively.
447 (ne (match_dup 0) (match_dup 0))
449 (match_test "flag_pic")
452 (eq_attr "type" "pt_media")
453 (if_then_else (match_test "TARGET_SHMEDIA64")
454 (const_int 20) (const_int 12))
455 (and (eq_attr "type" "jump_media")
456 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
458 ] (if_then_else (match_test "TARGET_SHMEDIA")
462 ;; DFA descriptions for the pipelines
465 (include "shmedia.md")
468 (include "predicates.md")
469 (include "constraints.md")
471 ;; Definitions for filling delay slots
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475 (define_attr "banked" "yes,no"
476 (cond [(match_test "sh_loads_bankedreg_p (insn)")
477 (const_string "yes")]
478 (const_string "no")))
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
484 (const_string "yes")))
486 (define_attr "interrupt_function" "no,yes"
487 (const (symbol_ref "current_function_interrupt")))
489 (define_attr "in_delay_slot" "yes,no"
490 (cond [(eq_attr "type" "cbranch") (const_string "no")
491 (eq_attr "type" "pcload,pcload_si") (const_string "no")
492 (eq_attr "needs_delay_slot" "yes") (const_string "no")
493 (eq_attr "length" "2") (const_string "yes")
494 ] (const_string "no")))
496 (define_attr "cond_delay_slot" "yes,no"
497 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498 ] (const_string "no")))
500 (define_attr "is_sfunc" ""
501 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
503 (define_attr "is_mac_media" ""
504 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
506 (define_attr "branch_zero" "yes,no"
507 (cond [(eq_attr "type" "!cbranch") (const_string "no")
508 (ne (symbol_ref "(next_active_insn (insn)\
509 == (prev_active_insn\
510 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511 && get_attr_length (next_active_insn (insn)) == 2")
513 (const_string "yes")]
514 (const_string "no")))
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520 (const_string "no")))
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527 (const_string "yes")]
528 (const_string "no")))
530 (define_attr "any_int_load" "yes,no"
531 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532 (const_string "yes")]
533 (const_string "no")))
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536 (const_string "user"))
539 (eq_attr "needs_delay_slot" "yes")
540 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
551 (eq_attr "type" "return")
552 [(and (eq_attr "in_delay_slot" "yes")
553 (ior (and (eq_attr "interrupt_function" "no")
554 (eq_attr "type" "!pload,prset"))
555 (and (eq_attr "interrupt_function" "yes")
557 (not (match_test "TARGET_SH3"))
558 (eq_attr "hit_stack" "no")
559 (eq_attr "banked" "no"))))) (nil) (nil)])
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
565 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566 [(and (eq_attr "in_delay_slot" "yes")
567 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
577 (and (eq_attr "type" "cbranch")
578 (match_test "TARGET_SH2"))
579 ;; SH2e has a hardware bug that pretty much prohibits the use of
580 ;; annuled delay slots.
581 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582 (not (eq_attr "cpu" "sh2e"))) (nil)])
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
590 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
591 (match_operand:SI 1 "logical_operand" "K08,r"))
595 [(set_attr "type" "mt_group")])
597 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
598 ;; That would still allow reload to create cmpi instructions, but would
599 ;; perhaps allow forcing the constant into a register when that is better.
600 ;; Probably should use r0 for mem/imm compares, but force constant into a
601 ;; register for pseudo/imm compares.
603 (define_insn "cmpeqsi_t"
605 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
606 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
612 [(set_attr "type" "mt_group")])
614 (define_insn "cmpgtsi_t"
616 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
617 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
622 [(set_attr "type" "mt_group")])
624 (define_insn "cmpgesi_t"
626 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
627 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
632 [(set_attr "type" "mt_group")])
634 ;; -------------------------------------------------------------------------
635 ;; SImode compare and branch
636 ;; -------------------------------------------------------------------------
638 (define_expand "cbranchsi4"
640 (if_then_else (match_operator 0 "comparison_operator"
641 [(match_operand:SI 1 "arith_operand" "")
642 (match_operand:SI 2 "arith_operand" "")])
643 (label_ref (match_operand 3 "" ""))
645 (clobber (reg:SI T_REG))]
648 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
649 operands[2], operands[3]));
650 else if (TARGET_CBRANCHDI4)
651 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
653 sh_emit_compare_and_branch (operands, SImode);
656 ;; -------------------------------------------------------------------------
657 ;; SImode unsigned integer comparisons
658 ;; -------------------------------------------------------------------------
660 (define_insn_and_split "cmpgeusi_t"
662 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
666 "&& operands[1] == CONST0_RTX (SImode)"
670 emit_insn (gen_sett ());
673 [(set_attr "type" "mt_group")])
675 (define_insn "cmpgtusi_t"
677 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
678 (match_operand:SI 1 "arith_reg_operand" "r")))]
681 [(set_attr "type" "mt_group")])
684 ;; -------------------------------------------------------------------------
685 ;; DImode compare and branch
686 ;; -------------------------------------------------------------------------
689 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
690 ;; Therefore, we aim to have a set of three branches that go straight to the
691 ;; destination, i.e. only one of them is taken at any one time.
692 ;; This mechanism should also be slightly better for the sh4-200.
694 (define_expand "cbranchdi4"
696 (if_then_else (match_operator 0 "comparison_operator"
697 [(match_operand:DI 1 "arith_operand" "")
698 (match_operand:DI 2 "arith_operand" "")])
699 (label_ref (match_operand 3 "" ""))
701 (clobber (match_dup 4))
702 (clobber (reg:SI T_REG))]
703 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
706 enum rtx_code comparison;
710 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
711 operands[2], operands[3]));
715 else if (!TARGET_CBRANCHDI4)
717 sh_emit_compare_and_branch (operands, DImode);
723 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
726 comparison = prepare_cbranch_operands (operands, DImode,
727 LAST_AND_UNUSED_RTX_CODE);
728 if (comparison != GET_CODE (operands[0]))
730 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
731 operands[4] = gen_rtx_SCRATCH (SImode);
735 (define_insn_and_split "cbranchdi4_i"
737 (if_then_else (match_operator 0 "comparison_operator"
738 [(match_operand:DI 1 "arith_operand" "r,r")
739 (match_operand:DI 2 "arith_operand" "rN,I08")])
740 (label_ref (match_operand 3 "" ""))
742 (clobber (match_scratch:SI 4 "=X,&r"))
743 (clobber (reg:SI T_REG))]
746 "&& reload_completed"
750 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
755 ;; -------------------------------------------------------------------------
756 ;; DImode signed integer comparisons
757 ;; -------------------------------------------------------------------------
761 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
762 (match_operand:DI 1 "arith_operand" "r"))
765 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
767 [(set_attr "length" "6")
768 (set_attr "type" "arith3b")])
770 (define_insn "cmpeqdi_t"
772 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
776 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
777 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
778 [(set_attr "length" "6")
779 (set_attr "type" "arith3b")])
783 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
784 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
785 ;; If we applied this split when not optimizing, it would only be
786 ;; applied during the machine-dependent reorg, when no new basic blocks
788 "TARGET_SH1 && reload_completed && optimize"
789 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
790 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
791 (label_ref (match_dup 6))
793 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
798 = gen_rtx_REG (SImode,
799 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
801 = (operands[1] == const0_rtx
803 : gen_rtx_REG (SImode,
804 true_regnum (operands[1])
805 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
806 operands[4] = gen_lowpart (SImode, operands[0]);
807 operands[5] = gen_lowpart (SImode, operands[1]);
808 operands[6] = gen_label_rtx ();
811 (define_insn "cmpgtdi_t"
813 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
814 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
817 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
818 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
819 [(set_attr "length" "8")
820 (set_attr "type" "arith3")])
822 (define_insn "cmpgedi_t"
824 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
825 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
828 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
830 [(set_attr "length" "8,2")
831 (set_attr "type" "arith3,mt_group")])
833 ;; -------------------------------------------------------------------------
834 ;; DImode unsigned integer comparisons
835 ;; -------------------------------------------------------------------------
837 (define_insn "cmpgeudi_t"
839 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
840 (match_operand:DI 1 "arith_reg_operand" "r")))]
842 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
843 [(set_attr "length" "8")
844 (set_attr "type" "arith3")])
846 (define_insn "cmpgtudi_t"
848 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
849 (match_operand:DI 1 "arith_reg_operand" "r")))]
851 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
852 [(set_attr "length" "8")
853 (set_attr "type" "arith3")])
855 (define_insn "cmpeqsi_media"
856 [(set (match_operand:SI 0 "register_operand" "=r")
857 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
858 (match_operand:SI 2 "cmp_operand" "Nr")))]
861 [(set_attr "type" "cmp_media")])
863 (define_insn "cmpeqdi_media"
864 [(set (match_operand:SI 0 "register_operand" "=r")
865 (eq:SI (match_operand:DI 1 "register_operand" "%r")
866 (match_operand:DI 2 "cmp_operand" "Nr")))]
869 [(set_attr "type" "cmp_media")])
871 (define_insn "cmpgtsi_media"
872 [(set (match_operand:SI 0 "register_operand" "=r")
873 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
874 (match_operand:SI 2 "cmp_operand" "rN")))]
877 [(set_attr "type" "cmp_media")])
879 (define_insn "cmpgtdi_media"
880 [(set (match_operand:SI 0 "register_operand" "=r")
881 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
882 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
885 [(set_attr "type" "cmp_media")])
887 (define_insn "cmpgtusi_media"
888 [(set (match_operand:SI 0 "register_operand" "=r")
889 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
890 (match_operand:SI 2 "cmp_operand" "rN")))]
892 "cmpgtu %N1, %N2, %0"
893 [(set_attr "type" "cmp_media")])
895 (define_insn "cmpgtudi_media"
896 [(set (match_operand:SI 0 "register_operand" "=r")
897 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
898 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
900 "cmpgtu %N1, %N2, %0"
901 [(set_attr "type" "cmp_media")])
903 ; These two patterns are for combine.
904 (define_insn "*cmpne0sisi_media"
905 [(set (match_operand:SI 0 "register_operand" "=r")
906 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
909 [(set_attr "type" "cmp_media")])
911 ;; -------------------------------------------------------------------------
912 ;; Conditional move instructions
913 ;; -------------------------------------------------------------------------
915 ;; The insn names may seem reversed, but note that cmveq performs the move
916 ;; if op1 == 0, and cmvne does it if op1 != 0.
918 (define_insn "movdicc_false"
919 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
920 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
922 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
923 (match_operand:DI 3 "arith_reg_operand" "0")))]
926 [(set_attr "type" "arith_media")])
928 (define_insn "movdicc_true"
929 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
930 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
932 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
933 (match_operand:DI 3 "arith_reg_operand" "0")))]
936 [(set_attr "type" "arith_media")])
939 [(set (match_operand:DI 0 "arith_reg_dest" "")
940 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
941 [(match_operand:DI 1 "arith_reg_operand" "")
943 (match_operand:DI 2 "arith_reg_dest" "")
945 (set (match_dup 2) (match_dup 0))]
946 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
948 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
951 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
952 VOIDmode, operands[1], CONST0_RTX (DImode));
956 [(set (match_operand:DI 0 "general_movdst_operand" "")
957 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
958 (set (match_operand:DI 2 "arith_reg_dest" "")
959 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
960 [(match_operand:DI 3 "arith_reg_operand" "")
964 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
966 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
969 (define_expand "movdicc"
970 [(set (match_operand:DI 0 "register_operand" "")
971 (if_then_else:DI (match_operand 1 "comparison_operator" "")
972 (match_operand:DI 2 "register_operand" "")
973 (match_operand:DI 3 "register_operand" "")))]
977 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
978 && GET_MODE (XEXP (operands[1], 0)) == DImode
979 && XEXP (operands[1], 1) == const0_rtx)
983 if (!can_create_pseudo_p ())
986 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
987 GET_CODE (operands[1]),
988 XEXP (operands[1], 0),
989 XEXP (operands[1], 1));
995 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
997 (define_insn "movsicc_false"
998 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
999 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1001 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1002 (match_operand:SI 3 "arith_reg_operand" "0")))]
1005 [(set_attr "type" "arith_media")])
1007 (define_insn "movsicc_true"
1008 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1009 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1011 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1012 (match_operand:SI 3 "arith_reg_operand" "0")))]
1015 [(set_attr "type" "arith_media")])
1018 [(set (match_operand:SI 0 "arith_reg_dest" "")
1019 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1020 [(match_operand:SI 1 "arith_reg_operand" "")
1022 (match_operand:SI 2 "arith_reg_dest" "")
1024 (set (match_dup 2) (match_dup 0))]
1025 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1027 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1030 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1031 VOIDmode, operands[1], CONST0_RTX (SImode));
1035 [(set (match_operand:SI 0 "general_movdst_operand" "")
1036 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1037 (set (match_operand:SI 2 "arith_reg_dest" "")
1038 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1039 [(match_operand:SI 3 "arith_reg_operand" "")
1043 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1044 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1046 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1049 replace_rtx (operands[4], operands[0], operands[1]);
1053 [(set (match_operand 0 "any_register_operand" "")
1054 (match_operand 1 "any_register_operand" ""))
1055 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1056 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1057 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1058 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1059 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1060 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1061 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1062 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1063 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1064 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1065 && (REGNO_REG_CLASS (REGNO (operands[0]))
1066 == REGNO_REG_CLASS (REGNO (operands[2])))
1067 && (REGNO_REG_CLASS (REGNO (operands[1]))
1068 == REGNO_REG_CLASS (REGNO (operands[0])))"
1069 [(set (match_dup 0) (match_dup 3))
1070 (set (match_dup 4) (match_dup 5))]
1073 rtx set1, set2, insn2;
1074 rtx replacements[4];
1076 /* We want to replace occurrences of operands[0] with operands[1] and
1077 operands[2] with operands[0] in operands[4]/operands[5].
1078 Doing just two replace_rtx calls naively would result in the second
1079 replacement undoing all that the first did if operands[1] and operands[2]
1080 are identical, so we must do this simultaneously. */
1081 replacements[0] = operands[0];
1082 replacements[1] = operands[1];
1083 replacements[2] = operands[2];
1084 replacements[3] = operands[0];
1085 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1086 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1087 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1090 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1091 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1092 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1093 /* The operands array is aliased to recog_data.operand, which gets
1094 clobbered by extract_insn, so finish with it now. */
1095 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1096 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1097 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1098 always uses emit_insn. */
1099 /* Check that we don't violate matching constraints or earlyclobbers. */
1100 extract_insn (emit_insn (set1));
1101 if (! constrain_operands (1))
1103 insn2 = emit (set2);
1104 if (GET_CODE (insn2) == BARRIER)
1106 extract_insn (insn2);
1107 if (! constrain_operands (1))
1111 tmp = replacements[0];
1112 replacements[0] = replacements[1];
1113 replacements[1] = tmp;
1114 tmp = replacements[2];
1115 replacements[2] = replacements[3];
1116 replacements[3] = tmp;
1117 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1118 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1119 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1125 ;; The register allocator is rather clumsy in handling multi-way conditional
1126 ;; moves, so allow the combiner to make them, and we split them up after
1128 (define_insn_and_split "*movsicc_umin"
1129 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1130 (umin:SI (if_then_else:SI
1131 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1133 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1134 (match_operand:SI 3 "register_operand" "0"))
1135 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1136 (clobber (match_scratch:SI 5 "=&r"))]
1137 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1139 "TARGET_SHMEDIA && reload_completed"
1143 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1145 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1146 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1151 (define_insn "*movsicc_t_false"
1152 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1153 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1154 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1155 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1156 "TARGET_PRETEND_CMOVE
1157 && (arith_reg_operand (operands[1], SImode)
1158 || (immediate_operand (operands[1], SImode)
1159 && satisfies_constraint_I08 (operands[1])))"
1160 "bt 0f\;mov %1,%0\\n0:"
1161 [(set_attr "type" "mt_group,arith") ;; poor approximation
1162 (set_attr "length" "4")])
1164 (define_insn "*movsicc_t_true"
1165 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1166 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1167 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1168 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1169 "TARGET_PRETEND_CMOVE
1170 && (arith_reg_operand (operands[1], SImode)
1171 || (immediate_operand (operands[1], SImode)
1172 && satisfies_constraint_I08 (operands[1])))"
1173 "bf 0f\;mov %1,%0\\n0:"
1174 [(set_attr "type" "mt_group,arith") ;; poor approximation
1175 (set_attr "length" "4")])
1177 (define_expand "movsicc"
1178 [(set (match_operand:SI 0 "arith_reg_dest" "")
1179 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1180 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1181 (match_operand:SI 3 "arith_reg_operand" "")))]
1182 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1185 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1186 && GET_MODE (XEXP (operands[1], 0)) == SImode
1188 || (REG_P (XEXP (operands[1], 0))
1189 && REGNO (XEXP (operands[1], 0)) == T_REG))
1190 && XEXP (operands[1], 1) == const0_rtx)
1193 else if (TARGET_PRETEND_CMOVE)
1195 enum rtx_code code = GET_CODE (operands[1]);
1196 enum rtx_code new_code = code;
1197 rtx op0 = XEXP (operands[1], 0);
1198 rtx op1 = XEXP (operands[1], 1);
1200 if (! currently_expanding_to_rtl)
1204 case LT: case LE: case LEU: case LTU:
1205 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1208 new_code = reverse_condition (code);
1210 case EQ: case GT: case GE: case GEU: case GTU:
1215 sh_emit_scc_to_t (new_code, op0, op1);
1216 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1217 gen_rtx_REG (SImode, T_REG), const0_rtx);
1221 if (!can_create_pseudo_p ())
1224 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1225 GET_CODE (operands[1]),
1226 XEXP (operands[1], 0),
1227 XEXP (operands[1], 1));
1233 (define_expand "movqicc"
1234 [(set (match_operand:QI 0 "register_operand" "")
1235 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1236 (match_operand:QI 2 "register_operand" "")
1237 (match_operand:QI 3 "register_operand" "")))]
1241 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1242 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1243 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1244 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1248 ;; -------------------------------------------------------------------------
1249 ;; Addition instructions
1250 ;; -------------------------------------------------------------------------
1252 (define_expand "adddi3"
1253 [(set (match_operand:DI 0 "arith_reg_operand" "")
1254 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1255 (match_operand:DI 2 "arith_operand" "")))]
1261 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1263 operands[2] = force_reg (DImode, operands[2]);
1264 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1269 (define_insn "*adddi3_media"
1270 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1271 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1272 (match_operand:DI 2 "arith_operand" "r,I10")))]
1277 [(set_attr "type" "arith_media")])
1279 (define_insn "*adddisi3_media"
1280 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1281 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1282 (match_operand:DI 2 "arith_operand" "r,I10")))]
1287 [(set_attr "type" "arith_media")
1288 (set_attr "highpart" "ignore")])
1290 (define_insn "adddi3z_media"
1291 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1293 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1294 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1296 "addz.l %1, %N2, %0"
1297 [(set_attr "type" "arith_media")
1298 (set_attr "highpart" "ignore")])
1300 (define_insn "adddi3_compact"
1301 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1302 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1303 (match_operand:DI 2 "arith_reg_operand" "r")))
1304 (clobber (reg:SI T_REG))]
1307 [(set_attr "length" "6")])
1310 [(set (match_operand:DI 0 "arith_reg_dest" "")
1311 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1312 (match_operand:DI 2 "arith_reg_operand" "")))
1313 (clobber (reg:SI T_REG))]
1314 "TARGET_SH1 && reload_completed"
1318 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1319 high0 = gen_rtx_REG (SImode,
1320 true_regnum (operands[0])
1321 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1322 high2 = gen_rtx_REG (SImode,
1323 true_regnum (operands[2])
1324 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325 emit_insn (gen_clrt ());
1326 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1327 emit_insn (gen_addc1 (high0, high0, high2));
1332 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1333 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1334 (match_operand:SI 2 "arith_reg_operand" "r"))
1337 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1340 [(set_attr "type" "arith")])
1342 (define_insn "addc1"
1343 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1344 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1345 (match_operand:SI 2 "arith_reg_operand" "r"))
1347 (clobber (reg:SI T_REG))]
1350 [(set_attr "type" "arith")])
1352 (define_expand "addsi3"
1353 [(set (match_operand:SI 0 "arith_reg_operand" "")
1354 (plus:SI (match_operand:SI 1 "arith_operand" "")
1355 (match_operand:SI 2 "arith_operand" "")))]
1360 operands[1] = force_reg (SImode, operands[1]);
1363 (define_insn "addsi3_media"
1364 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1365 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1366 (match_operand:SI 2 "arith_operand" "r,I10")))]
1371 [(set_attr "type" "arith_media")
1372 (set_attr "highpart" "ignore")])
1374 (define_insn "addsidi3_media"
1375 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1376 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1378 (match_operand:SI 2 "arith_operand"
1384 [(set_attr "type" "arith_media")
1385 (set_attr "highpart" "ignore")])
1387 (define_insn "*addsi3_compact"
1388 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1389 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1390 (match_operand:SI 2 "arith_operand" "rI08")))]
1393 [(set_attr "type" "arith")])
1395 ;; -------------------------------------------------------------------------
1396 ;; Subtraction instructions
1397 ;; -------------------------------------------------------------------------
1399 (define_expand "subdi3"
1400 [(set (match_operand:DI 0 "arith_reg_operand" "")
1401 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1402 (match_operand:DI 2 "arith_reg_operand" "")))]
1408 operands[1] = force_reg (DImode, operands[1]);
1409 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1414 (define_insn "*subdi3_media"
1415 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1416 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1417 (match_operand:DI 2 "arith_reg_operand" "r")))]
1420 [(set_attr "type" "arith_media")])
1422 (define_insn "subdisi3_media"
1423 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1424 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1425 (match_operand:DI 2 "arith_reg_operand" "r")))]
1428 [(set_attr "type" "arith_media")
1429 (set_attr "highpart" "ignore")])
1431 (define_insn "subdi3_compact"
1432 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1433 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1434 (match_operand:DI 2 "arith_reg_operand" "r")))
1435 (clobber (reg:SI T_REG))]
1438 [(set_attr "length" "6")])
1441 [(set (match_operand:DI 0 "arith_reg_dest" "")
1442 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1443 (match_operand:DI 2 "arith_reg_operand" "")))
1444 (clobber (reg:SI T_REG))]
1445 "TARGET_SH1 && reload_completed"
1449 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1450 high0 = gen_rtx_REG (SImode,
1451 true_regnum (operands[0])
1452 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1453 high2 = gen_rtx_REG (SImode,
1454 true_regnum (operands[2])
1455 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456 emit_insn (gen_clrt ());
1457 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1458 emit_insn (gen_subc1 (high0, high0, high2));
1463 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1464 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1465 (match_operand:SI 2 "arith_reg_operand" "r"))
1468 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1473 [(set_attr "type" "arith")])
1475 (define_insn "subc1"
1476 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1477 (minus:SI (minus: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 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1486 ;; pattern for this case. This helps multimedia applications that compute
1487 ;; the sum of absolute differences.
1488 (define_insn "mov_neg_si_t"
1489 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1492 [(set_attr "type" "arith")])
1494 (define_insn "*subsi3_internal"
1495 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1496 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1497 (match_operand:SI 2 "arith_reg_operand" "r")))]
1500 [(set_attr "type" "arith")])
1502 (define_insn_and_split "*subsi3_media"
1503 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1504 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1505 (match_operand:SI 2 "extend_reg_operand" "r")))]
1507 && (operands[1] != constm1_rtx
1508 || (GET_CODE (operands[2]) != TRUNCATE
1509 && GET_CODE (operands[2]) != SUBREG))"
1511 "operands[1] == constm1_rtx"
1512 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1514 [(set_attr "type" "arith_media")
1515 (set_attr "highpart" "ignore")])
1518 [(set (match_operand:SI 0 "arith_reg_dest" "")
1519 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1520 "general_extend_operand"
1522 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1523 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1524 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1528 [(set (match_operand:SI 0 "arith_reg_dest" "")
1529 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1530 "general_extend_operand"
1532 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1533 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1534 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1536 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1537 ;; will sometimes save one instruction. Otherwise we might get
1538 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1541 (define_expand "subsi3"
1542 [(set (match_operand:SI 0 "arith_reg_operand" "")
1543 (minus:SI (match_operand:SI 1 "arith_operand" "")
1544 (match_operand:SI 2 "arith_reg_operand" "")))]
1548 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1550 emit_insn (gen_negsi2 (operands[0], operands[2]));
1551 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1556 if (!can_create_pseudo_p ()
1557 && ! arith_reg_or_0_operand (operands[1], SImode))
1559 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1560 operands[1] = force_reg (SImode, operands[1]);
1564 ;; -------------------------------------------------------------------------
1565 ;; Division instructions
1566 ;; -------------------------------------------------------------------------
1568 ;; We take advantage of the library routines which don't clobber as many
1569 ;; registers as a normal function call would.
1571 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1572 ;; also has an effect on the register that holds the address of the sfunc.
1573 ;; To make this work, we have an extra dummy insn that shows the use
1574 ;; of this register for reorg.
1576 (define_insn "use_sfunc_addr"
1577 [(set (reg:SI PR_REG)
1578 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1579 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1581 [(set_attr "length" "0")])
1583 (define_insn "udivsi3_sh2a"
1584 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1585 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1586 (match_operand:SI 2 "arith_reg_operand" "z")))]
1589 [(set_attr "type" "arith")
1590 (set_attr "in_delay_slot" "no")])
1592 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1593 ;; hard register 0. If we used hard register 0, then the next instruction
1594 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1595 ;; gets allocated to a stack slot that needs its address reloaded, then
1596 ;; there is nothing to prevent reload from using r0 to reload the address.
1597 ;; This reload would clobber the value in r0 we are trying to store.
1598 ;; If we let reload allocate r0, then this problem can never happen.
1600 (define_insn "udivsi3_i1"
1601 [(set (match_operand:SI 0 "register_operand" "=z")
1602 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1603 (clobber (reg:SI T_REG))
1604 (clobber (reg:SI PR_REG))
1605 (clobber (reg:SI R4_REG))
1606 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1607 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1609 [(set_attr "type" "sfunc")
1610 (set_attr "needs_delay_slot" "yes")])
1612 ; Since shmedia-nofpu code could be linked against shcompact code, and
1613 ; the udivsi3 libcall has the same name, we must consider all registers
1614 ; clobbered that are in the union of the registers clobbered by the
1615 ; shmedia and the shcompact implementation. Note, if the shcompact
1616 ; implementation actually used shcompact code, we'd need to clobber
1617 ; also r23 and fr23.
1618 (define_insn "udivsi3_i1_media"
1619 [(set (match_operand:SI 0 "register_operand" "=z")
1620 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1621 (clobber (reg:SI T_MEDIA_REG))
1622 (clobber (reg:SI PR_MEDIA_REG))
1623 (clobber (reg:SI R20_REG))
1624 (clobber (reg:SI R21_REG))
1625 (clobber (reg:SI R22_REG))
1626 (clobber (reg:DI TR0_REG))
1627 (clobber (reg:DI TR1_REG))
1628 (clobber (reg:DI TR2_REG))
1629 (use (match_operand 1 "target_reg_operand" "b"))]
1630 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1632 [(set_attr "type" "sfunc")
1633 (set_attr "needs_delay_slot" "yes")])
1635 (define_expand "udivsi3_i4_media"
1637 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1639 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1640 (set (match_dup 5) (float:DF (match_dup 3)))
1641 (set (match_dup 6) (float:DF (match_dup 4)))
1642 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1643 (set (match_dup 8) (fix:DI (match_dup 7)))
1644 (set (match_operand:SI 0 "register_operand" "")
1645 (truncate:SI (match_dup 8)))]
1646 "TARGET_SHMEDIA_FPU"
1649 operands[3] = gen_reg_rtx (DImode);
1650 operands[4] = gen_reg_rtx (DImode);
1651 operands[5] = gen_reg_rtx (DFmode);
1652 operands[6] = gen_reg_rtx (DFmode);
1653 operands[7] = gen_reg_rtx (DFmode);
1654 operands[8] = gen_reg_rtx (DImode);
1657 (define_insn "udivsi3_i4"
1658 [(set (match_operand:SI 0 "register_operand" "=y")
1659 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1660 (clobber (reg:SI T_REG))
1661 (clobber (reg:SI PR_REG))
1662 (clobber (reg:DF DR0_REG))
1663 (clobber (reg:DF DR2_REG))
1664 (clobber (reg:DF DR4_REG))
1665 (clobber (reg:SI R0_REG))
1666 (clobber (reg:SI R1_REG))
1667 (clobber (reg:SI R4_REG))
1668 (clobber (reg:SI R5_REG))
1669 (use (reg:PSI FPSCR_REG))
1670 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1671 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1673 [(set_attr "type" "sfunc")
1674 (set_attr "fp_mode" "double")
1675 (set_attr "needs_delay_slot" "yes")])
1677 (define_insn "udivsi3_i4_single"
1678 [(set (match_operand:SI 0 "register_operand" "=y")
1679 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1680 (clobber (reg:SI T_REG))
1681 (clobber (reg:SI PR_REG))
1682 (clobber (reg:DF DR0_REG))
1683 (clobber (reg:DF DR2_REG))
1684 (clobber (reg:DF DR4_REG))
1685 (clobber (reg:SI R0_REG))
1686 (clobber (reg:SI R1_REG))
1687 (clobber (reg:SI R4_REG))
1688 (clobber (reg:SI R5_REG))
1689 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1690 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1692 [(set_attr "type" "sfunc")
1693 (set_attr "needs_delay_slot" "yes")])
1695 (define_insn "udivsi3_i4_int"
1696 [(set (match_operand:SI 0 "register_operand" "=z")
1697 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1698 (clobber (reg:SI T_REG))
1699 (clobber (reg:SI R1_REG))
1700 (clobber (reg:SI PR_REG))
1701 (clobber (reg:SI MACH_REG))
1702 (clobber (reg:SI MACL_REG))
1703 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1706 [(set_attr "type" "sfunc")
1707 (set_attr "needs_delay_slot" "yes")])
1710 (define_expand "udivsi3"
1711 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1712 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1713 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1714 (parallel [(set (match_operand:SI 0 "register_operand" "")
1715 (udiv:SI (reg:SI R4_REG)
1717 (clobber (reg:SI T_REG))
1718 (clobber (reg:SI PR_REG))
1719 (clobber (reg:SI R4_REG))
1720 (use (match_dup 3))])]
1726 operands[3] = gen_reg_rtx (Pmode);
1727 /* Emit the move of the address to a pseudo outside of the libcall. */
1728 if (TARGET_DIVIDE_CALL_TABLE)
1730 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1731 that causes problems when the divide code is supposed to come from a
1732 separate library. Division by zero is undefined, so dividing 1 can be
1733 implemented by comparing with the divisor. */
1734 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1736 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1737 emit_insn (gen_cstoresi4 (operands[0], test,
1738 operands[1], operands[2]));
1741 else if (operands[2] == const0_rtx)
1743 emit_move_insn (operands[0], operands[2]);
1746 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1747 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1749 else if (TARGET_DIVIDE_CALL_FP)
1751 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1752 if (TARGET_FPU_SINGLE)
1753 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1755 last = gen_udivsi3_i4 (operands[0], operands[3]);
1757 else if (TARGET_SHMEDIA_FPU)
1759 operands[1] = force_reg (SImode, operands[1]);
1760 operands[2] = force_reg (SImode, operands[2]);
1761 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1764 else if (TARGET_SH2A)
1766 operands[1] = force_reg (SImode, operands[1]);
1767 operands[2] = force_reg (SImode, operands[2]);
1768 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1771 else if (TARGET_SH5)
1773 function_symbol (operands[3],
1774 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1778 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1779 else if (TARGET_FPU_ANY)
1780 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1782 last = gen_udivsi3_i1 (operands[0], operands[3]);
1786 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1787 last = gen_udivsi3_i1 (operands[0], operands[3]);
1789 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1790 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1795 (define_insn "divsi3_sh2a"
1796 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1797 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1798 (match_operand:SI 2 "arith_reg_operand" "z")))]
1801 [(set_attr "type" "arith")
1802 (set_attr "in_delay_slot" "no")])
1804 (define_insn "divsi3_i1"
1805 [(set (match_operand:SI 0 "register_operand" "=z")
1806 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1807 (clobber (reg:SI T_REG))
1808 (clobber (reg:SI PR_REG))
1809 (clobber (reg:SI R1_REG))
1810 (clobber (reg:SI R2_REG))
1811 (clobber (reg:SI R3_REG))
1812 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1813 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1815 [(set_attr "type" "sfunc")
1816 (set_attr "needs_delay_slot" "yes")])
1818 (define_insn "divsi3_i1_media"
1819 [(set (match_operand:SI 0 "register_operand" "=z")
1820 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1821 (clobber (reg:SI T_MEDIA_REG))
1822 (clobber (reg:SI PR_MEDIA_REG))
1823 (clobber (reg:SI R1_REG))
1824 (clobber (reg:SI R20_REG))
1825 (clobber (reg:SI R21_REG))
1826 (clobber (reg:SI TR0_REG))
1827 (use (match_operand 1 "target_reg_operand" "b"))]
1828 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1830 [(set_attr "type" "sfunc")])
1832 (define_insn "divsi3_media_2"
1833 [(set (match_operand:SI 0 "register_operand" "=z")
1834 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1835 (clobber (reg:SI T_MEDIA_REG))
1836 (clobber (reg:SI PR_MEDIA_REG))
1837 (clobber (reg:SI R1_REG))
1838 (clobber (reg:SI R21_REG))
1839 (clobber (reg:SI TR0_REG))
1840 (use (reg:SI R20_REG))
1841 (use (match_operand 1 "target_reg_operand" "b"))]
1842 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1844 [(set_attr "type" "sfunc")])
1846 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1847 ;; hard reg clobbers and data dependencies that we need when we want
1848 ;; to rematerialize the division into a call.
1849 (define_insn_and_split "divsi_inv_call"
1850 [(set (match_operand:SI 0 "register_operand" "=r")
1851 (div:SI (match_operand:SI 1 "register_operand" "r")
1852 (match_operand:SI 2 "register_operand" "r")))
1853 (clobber (reg:SI R4_REG))
1854 (clobber (reg:SI R5_REG))
1855 (clobber (reg:SI T_MEDIA_REG))
1856 (clobber (reg:SI PR_MEDIA_REG))
1857 (clobber (reg:SI R1_REG))
1858 (clobber (reg:SI R21_REG))
1859 (clobber (reg:SI TR0_REG))
1860 (clobber (reg:SI R20_REG))
1861 (use (match_operand:SI 3 "register_operand" "r"))]
1864 "&& (high_life_started || reload_completed)"
1865 [(set (match_dup 0) (match_dup 3))]
1867 [(set_attr "highpart" "must_split")])
1869 ;; This is the combiner pattern for -mdiv=inv:call .
1870 (define_insn_and_split "*divsi_inv_call_combine"
1871 [(set (match_operand:SI 0 "register_operand" "=z")
1872 (div:SI (match_operand:SI 1 "register_operand" "r")
1873 (match_operand:SI 2 "register_operand" "r")))
1874 (clobber (reg:SI R4_REG))
1875 (clobber (reg:SI R5_REG))
1876 (clobber (reg:SI T_MEDIA_REG))
1877 (clobber (reg:SI PR_MEDIA_REG))
1878 (clobber (reg:SI R1_REG))
1879 (clobber (reg:SI R21_REG))
1880 (clobber (reg:SI TR0_REG))
1881 (clobber (reg:SI R20_REG))
1882 (use (unspec:SI [(match_dup 1)
1883 (match_operand:SI 3 "" "")
1884 (unspec:SI [(match_operand:SI 4 "" "")
1886 (match_operand:DI 5 "" "")]
1888 (match_operand:DI 6 "" "")
1891 UNSPEC_DIV_INV_M3))]
1894 "&& (high_life_started || reload_completed)"
1898 const char *name = sh_divsi3_libfunc;
1899 enum sh_function_kind kind = SFUNC_GOT;
1902 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1903 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1904 while (TARGET_DIVIDE_INV_CALL2)
1906 rtx x = operands[3];
1908 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1910 x = XVECEXP (x, 0, 0);
1911 name = \"__sdivsi3_2\";
1912 kind = SFUNC_STATIC;
1913 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1916 sym = function_symbol (NULL, name, kind);
1917 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1920 [(set_attr "highpart" "must_split")])
1922 (define_expand "divsi3_i4_media"
1923 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1924 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1925 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1926 (set (match_operand:SI 0 "register_operand" "=r")
1927 (fix:SI (match_dup 5)))]
1928 "TARGET_SHMEDIA_FPU"
1931 operands[3] = gen_reg_rtx (DFmode);
1932 operands[4] = gen_reg_rtx (DFmode);
1933 operands[5] = gen_reg_rtx (DFmode);
1936 (define_insn "divsi3_i4"
1937 [(set (match_operand:SI 0 "register_operand" "=y")
1938 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1939 (clobber (reg:SI PR_REG))
1940 (clobber (reg:DF DR0_REG))
1941 (clobber (reg:DF DR2_REG))
1942 (use (reg:PSI FPSCR_REG))
1943 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1944 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1946 [(set_attr "type" "sfunc")
1947 (set_attr "fp_mode" "double")
1948 (set_attr "needs_delay_slot" "yes")])
1950 (define_insn "divsi3_i4_single"
1951 [(set (match_operand:SI 0 "register_operand" "=y")
1952 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1953 (clobber (reg:SI PR_REG))
1954 (clobber (reg:DF DR0_REG))
1955 (clobber (reg:DF DR2_REG))
1956 (clobber (reg:SI R2_REG))
1957 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1958 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1960 [(set_attr "type" "sfunc")
1961 (set_attr "needs_delay_slot" "yes")])
1963 (define_insn "divsi3_i4_int"
1964 [(set (match_operand:SI 0 "register_operand" "=z")
1965 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1966 (clobber (reg:SI T_REG))
1967 (clobber (reg:SI PR_REG))
1968 (clobber (reg:SI R1_REG))
1969 (clobber (reg:SI MACH_REG))
1970 (clobber (reg:SI MACL_REG))
1971 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1974 [(set_attr "type" "sfunc")
1975 (set_attr "needs_delay_slot" "yes")])
1977 (define_expand "divsi3"
1978 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1979 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1980 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1981 (parallel [(set (match_operand:SI 0 "register_operand" "")
1982 (div:SI (reg:SI R4_REG)
1984 (clobber (reg:SI T_REG))
1985 (clobber (reg:SI PR_REG))
1986 (clobber (reg:SI R1_REG))
1987 (clobber (reg:SI R2_REG))
1988 (clobber (reg:SI R3_REG))
1989 (use (match_dup 3))])]
1995 operands[3] = gen_reg_rtx (Pmode);
1996 /* Emit the move of the address to a pseudo outside of the libcall. */
1997 if (TARGET_DIVIDE_CALL_TABLE)
1999 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2000 last = gen_divsi3_i4_int (operands[0], operands[3]);
2002 else if (TARGET_DIVIDE_CALL_FP)
2004 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2005 if (TARGET_FPU_SINGLE)
2006 last = gen_divsi3_i4_single (operands[0], operands[3]);
2008 last = gen_divsi3_i4 (operands[0], operands[3]);
2010 else if (TARGET_SH2A)
2012 operands[1] = force_reg (SImode, operands[1]);
2013 operands[2] = force_reg (SImode, operands[2]);
2014 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2017 else if (TARGET_DIVIDE_INV)
2019 rtx dividend = operands[1];
2020 rtx divisor = operands[2];
2022 rtx nsb_res = gen_reg_rtx (DImode);
2023 rtx norm64 = gen_reg_rtx (DImode);
2024 rtx tab_ix = gen_reg_rtx (DImode);
2025 rtx norm32 = gen_reg_rtx (SImode);
2026 rtx i92 = force_reg (DImode, GEN_INT (92));
2027 rtx scratch0a = gen_reg_rtx (DImode);
2028 rtx scratch0b = gen_reg_rtx (DImode);
2029 rtx inv0 = gen_reg_rtx (SImode);
2030 rtx scratch1a = gen_reg_rtx (DImode);
2031 rtx scratch1b = gen_reg_rtx (DImode);
2032 rtx shift = gen_reg_rtx (DImode);
2034 rtx inv1 = gen_reg_rtx (SImode);
2035 rtx scratch2a = gen_reg_rtx (DImode);
2036 rtx scratch2b = gen_reg_rtx (SImode);
2037 rtx inv2 = gen_reg_rtx (SImode);
2038 rtx scratch3a = gen_reg_rtx (DImode);
2039 rtx scratch3b = gen_reg_rtx (DImode);
2040 rtx scratch3c = gen_reg_rtx (DImode);
2041 rtx scratch3d = gen_reg_rtx (SImode);
2042 rtx scratch3e = gen_reg_rtx (DImode);
2043 rtx result = gen_reg_rtx (SImode);
2045 if (! arith_reg_or_0_operand (dividend, SImode))
2046 dividend = force_reg (SImode, dividend);
2047 if (! arith_reg_operand (divisor, SImode))
2048 divisor = force_reg (SImode, divisor);
2049 if (flag_pic && Pmode != DImode)
2051 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2052 tab_base = gen_datalabel_ref (tab_base);
2053 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2057 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2058 tab_base = gen_datalabel_ref (tab_base);
2059 tab_base = force_reg (DImode, tab_base);
2061 if (TARGET_DIVIDE_INV20U)
2062 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2064 i2p27 = GEN_INT (0);
2065 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2066 i43 = force_reg (DImode, GEN_INT (43));
2069 emit_insn (gen_nsbdi (nsb_res,
2070 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2071 emit_insn (gen_ashldi3_media (norm64,
2072 gen_rtx_SUBREG (DImode, divisor, 0),
2074 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2075 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2076 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2077 inv0, scratch0a, scratch0b,
2078 scratch1a, scratch1b));
2079 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2080 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2082 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2084 scratch3a, scratch3b, scratch3c,
2085 scratch2a, scratch2b, scratch3d, scratch3e));
2086 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2087 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2088 else if (TARGET_DIVIDE_INV_FP)
2089 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2090 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2091 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2092 gen_reg_rtx (DFmode)));
2094 emit_move_insn (operands[0], result);
2097 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2099 operands[1] = force_reg (SImode, operands[1]);
2100 operands[2] = force_reg (SImode, operands[2]);
2101 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2104 else if (TARGET_SH5)
2106 if (TARGET_DIVIDE_CALL2)
2108 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2109 tab_base = gen_datalabel_ref (tab_base);
2110 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2112 if (TARGET_FPU_ANY && TARGET_SH1)
2113 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2114 else if (TARGET_DIVIDE_CALL2)
2115 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2117 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2120 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2121 (operands[0], operands[3]));
2122 else if (TARGET_FPU_ANY)
2123 last = gen_divsi3_i4_single (operands[0], operands[3]);
2125 last = gen_divsi3_i1 (operands[0], operands[3]);
2129 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2130 last = gen_divsi3_i1 (operands[0], operands[3]);
2132 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2133 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2138 ;; operands: scratch, tab_base, tab_ix
2139 ;; These are unspecs because we could generate an indexed addressing mode
2140 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2141 ;; confuse reload. See PR27117.
2143 (define_insn "divsi_inv_qitable"
2144 [(set (match_operand:DI 0 "register_operand" "=r")
2145 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2146 (match_operand:DI 2 "register_operand" "r")]
2147 UNSPEC_DIV_INV_TABLE)))]
2151 [(set_attr "type" "load_media")
2152 (set_attr "highpart" "user")])
2154 ;; operands: scratch, tab_base, tab_ix
2155 (define_insn "divsi_inv_hitable"
2156 [(set (match_operand:DI 0 "register_operand" "=r")
2157 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2158 (match_operand:DI 2 "register_operand" "r")]
2159 UNSPEC_DIV_INV_TABLE)))]
2163 [(set_attr "type" "load_media")
2164 (set_attr "highpart" "user")])
2166 ;; operands: inv0, tab_base, tab_ix, norm32
2167 ;; scratch equiv in sdivsi3_2: r19, r21
2168 (define_expand "divsi_inv_m0"
2169 [(set (match_operand:SI 0 "register_operand" "=r")
2170 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2171 (match_operand:DI 2 "register_operand" "r")
2172 (match_operand:SI 3 "register_operand" "r")]
2174 (clobber (match_operand:DI 4 "register_operand" "=r"))
2175 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2183 ldx.ub r20, r21, r19 // u0.8
2185 muls.l r25, r19, r19 // s2.38
2186 ldx.w r20, r21, r21 // s2.14
2187 shari r19, 24, r19 // truncate to s2.14
2188 sub r21, r19, r19 // some 11 bit inverse in s1.14
2191 rtx inv0 = operands[0];
2192 rtx tab_base = operands[1];
2193 rtx tab_ix = operands[2];
2194 rtx norm32 = operands[3];
2195 rtx scratch0 = operands[4];
2196 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2197 rtx scratch1 = operands[5];
2199 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2200 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2201 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2202 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2203 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2204 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2208 ;; operands: inv1, tab_base, tab_ix, norm32
2209 (define_insn_and_split "divsi_inv_m1"
2210 [(set (match_operand:SI 0 "register_operand" "=r")
2211 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2212 (match_operand:DI 2 "register_operand" "r")
2213 (match_operand:SI 3 "register_operand" "r")]
2215 (clobber (match_operand:SI 4 "register_operand" "=r"))
2216 (clobber (match_operand:DI 5 "register_operand" "=r"))
2217 (clobber (match_operand:DI 6 "register_operand" "=r"))
2218 (clobber (match_operand:DI 7 "register_operand" "=r"))
2219 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2222 "&& !can_create_pseudo_p ()"
2227 muls.l r19, r19, r18 // u0.28
2228 muls.l r25, r18, r18 // s2.58
2229 shlli r19, 45, r0 // multiply by two and convert to s2.58
2231 shari r18, 28, r18 // some 18 bit inverse in s1.30
2234 rtx inv1 = operands[0];
2235 rtx tab_base = operands[1];
2236 rtx tab_ix = operands[2];
2237 rtx norm32 = operands[3];
2238 rtx inv0 = operands[4];
2239 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2240 rtx scratch0a = operands[5];
2241 rtx scratch0b = operands[6];
2242 rtx scratch0 = operands[7];
2243 rtx scratch1 = operands[8];
2244 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2246 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2247 scratch0a, scratch0b));
2248 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2249 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2250 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2251 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2252 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2256 ;; operands: inv2, norm32, inv1, i92
2257 (define_insn_and_split "divsi_inv_m2"
2258 [(set (match_operand:SI 0 "register_operand" "=r")
2259 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2260 (match_operand:SI 2 "register_operand" "r")
2261 (match_operand:DI 3 "register_operand" "r")]
2263 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2266 "&& !can_create_pseudo_p ()"
2271 muls.l r18, r25, r0 // s2.60
2272 shari r0, 16, r0 // s-16.44
2274 muls.l r0, r18, r19 // s-16.74
2275 shari r19, 30, r19 // s-16.44
2277 rtx inv2 = operands[0];
2278 rtx norm32 = operands[1];
2279 rtx inv1 = operands[2];
2280 rtx i92 = operands[3];
2281 rtx scratch0 = operands[4];
2282 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2284 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2285 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2286 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2287 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2288 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2292 (define_insn_and_split "divsi_inv_m3"
2293 [(set (match_operand:SI 0 "register_operand" "=r")
2294 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2295 (match_operand:SI 2 "register_operand" "r")
2296 (match_operand:SI 3 "register_operand" "r")
2297 (match_operand:DI 4 "register_operand" "r")
2298 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2299 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2301 (clobber (match_operand:DI 7 "register_operand" "=r"))
2302 (clobber (match_operand:DI 8 "register_operand" "=r"))
2303 (clobber (match_operand:DI 9 "register_operand" "=r"))
2304 (clobber (match_operand:DI 10 "register_operand" "=r"))
2305 (clobber (match_operand:SI 11 "register_operand" "=r"))
2306 (clobber (match_operand:SI 12 "register_operand" "=r"))
2307 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2310 "&& !can_create_pseudo_p ()"
2315 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2316 r0: scratch0 r19: scratch1 r21: scratch2
2318 muls.l r18, r4, r25 // s32.30
2319 muls.l r19, r4, r19 // s15.30
2321 shari r19, 14, r19 // s18.-14
2327 rtx result = operands[0];
2328 rtx dividend = operands[1];
2329 rtx inv1 = operands[2];
2330 rtx inv2 = operands[3];
2331 rtx shift = operands[4];
2332 rtx scratch0 = operands[7];
2333 rtx scratch1 = operands[8];
2334 rtx scratch2 = operands[9];
2336 if (satisfies_constraint_N (dividend))
2338 emit_move_insn (result, dividend);
2342 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2343 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2344 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2345 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2346 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2347 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2348 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2352 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2353 ;; inv1: tab_base, tab_ix, norm32
2354 ;; inv2: norm32, inv1, i92
2355 (define_insn_and_split "divsi_inv_m1_3"
2356 [(set (match_operand:SI 0 "register_operand" "=r")
2357 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2358 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2359 (match_operand:DI 3 "register_operand" "r")
2360 (match_operand:SI 4 "register_operand" "r")]
2362 (unspec:SI [(match_dup 4)
2363 (unspec:SI [(match_dup 2)
2365 (match_dup 4)] UNSPEC_DIV_INV_M1)
2366 (match_operand:SI 5 "" "")]
2368 (match_operand:DI 6 "register_operand" "r")
2369 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2370 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2372 (clobber (match_operand:DI 9 "register_operand" "=r"))
2373 (clobber (match_operand:DI 10 "register_operand" "=r"))
2374 (clobber (match_operand:DI 11 "register_operand" "=r"))
2375 (clobber (match_operand:DI 12 "register_operand" "=r"))
2376 (clobber (match_operand:SI 13 "register_operand" "=r"))
2377 (clobber (match_operand:SI 14 "register_operand" "=r"))
2378 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2380 && (TARGET_DIVIDE_INV_MINLAT
2381 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2383 "&& !can_create_pseudo_p ()"
2387 rtx result = operands[0];
2388 rtx dividend = operands[1];
2389 rtx tab_base = operands[2];
2390 rtx tab_ix = operands[3];
2391 rtx norm32 = operands[4];
2392 /* rtx i92 = operands[5]; */
2393 rtx shift = operands[6];
2394 rtx i2p27 = operands[7];
2395 rtx i43 = operands[8];
2396 rtx scratch0 = operands[9];
2397 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2398 rtx scratch1 = operands[10];
2399 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2400 rtx scratch2 = operands[11];
2401 rtx scratch3 = operands[12];
2402 rtx scratch4 = operands[13];
2403 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2404 rtx scratch5 = operands[14];
2405 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2406 rtx scratch6 = operands[15];
2408 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2409 scratch0, scratch1));
2410 /* inv0 == scratch4 */
2411 if (! TARGET_DIVIDE_INV20U)
2413 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2415 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2419 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2420 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2422 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2423 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2424 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2425 /* inv1 == scratch4 */
2427 if (TARGET_DIVIDE_INV_MINLAT)
2429 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2430 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2431 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2432 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2433 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2434 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2435 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2436 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2437 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2438 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2439 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2443 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2444 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2445 emit_insn (gen_nsbdi (scratch6,
2446 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2447 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2448 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2449 emit_insn (gen_divsi_inv20 (scratch2,
2450 norm32, scratch4, dividend,
2451 scratch6, scratch3, i43,
2452 /* scratch0 may be shared with i2p27. */
2453 scratch0, scratch1, scratch5,
2454 label, label, i2p27));
2456 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2457 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2461 (define_insn "divsi_inv20"
2462 [(set (match_operand:DI 0 "register_operand" "=&r")
2463 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2464 (match_operand:SI 2 "register_operand" "r")
2465 (match_operand:SI 3 "register_operand" "r")
2466 (match_operand:DI 4 "register_operand" "r")
2467 (match_operand:DI 5 "register_operand" "r")
2468 (match_operand:DI 6 "register_operand" "r")
2469 (match_operand:DI 12 "register_operand" "r")
2470 (match_operand 10 "target_operand" "b")
2471 (match_operand 11 "immediate_operand" "i")]
2473 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2474 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2475 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2477 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2480 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2481 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2482 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2483 %10 label (tr), %11 label (imm)
2485 muls.l inv1, norm32, scratch0 // s2.60
2486 muls.l inv1, dividend, result // s32.30
2487 xor i2p27, result_sign, round_scratch
2488 bge/u dividend_nsb, i43, tr.. (label)
2489 shari scratch0, 16, scratch0 // s-16.44
2490 muls.l sratch0_si, inv1, scratch0 // s-16.74
2491 sub result, round_scratch, result
2492 shari dividend, 14, scratch1 // s19.-14
2493 shari scratch0, 30, scratch0 // s-16.44
2494 muls.l scratch0, scratch1, round_scratch // s15.30
2496 sub result, round_scratch, result */
2498 int likely = TARGET_DIVIDE_INV20L;
2500 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2501 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2502 output_asm_insn (likely
2503 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2504 : \"bge/u\t%4, %6, %10\", operands);
2505 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2506 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2507 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2509 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2510 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2513 (define_insn_and_split "divsi_inv_fp"
2514 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2515 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2516 (match_operand:SI 2 "register_operand" "rf")))
2517 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2518 (clobber (match_operand:SI 4 "register_operand" "=r"))
2519 (clobber (match_operand:SI 5 "register_operand" "=r"))
2520 (clobber (match_operand:DF 6 "register_operand" "=r"))
2521 (clobber (match_operand:DF 7 "register_operand" "=r"))
2522 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2523 "TARGET_SHMEDIA_FPU"
2525 "&& (high_life_started || reload_completed)"
2526 [(set (match_dup 0) (match_dup 3))]
2528 [(set_attr "highpart" "must_split")])
2530 ;; If a matching group of divide-by-inverse instructions is in the same
2531 ;; basic block after gcse & loop optimizations, we want to transform them
2532 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2533 (define_insn_and_split "*divsi_inv_fp_combine"
2534 [(set (match_operand:SI 0 "register_operand" "=f")
2535 (div:SI (match_operand:SI 1 "register_operand" "f")
2536 (match_operand:SI 2 "register_operand" "f")))
2537 (use (unspec:SI [(match_dup 1)
2538 (match_operand:SI 3 "" "")
2539 (unspec:SI [(match_operand:SI 4 "" "")
2541 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2542 (match_operand:DI 6 "" "")
2544 (const_int 0)] UNSPEC_DIV_INV_M3))
2545 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2546 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2547 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2548 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2549 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2550 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2553 [(set (match_dup 9) (float:DF (match_dup 1)))
2554 (set (match_dup 10) (float:DF (match_dup 2)))
2555 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2557 (fix:SI (match_dup 11)))
2558 (set (match_dup 0) (match_dup 8))]
2561 if (! fp_arith_reg_operand (operands[1], SImode))
2563 emit_move_insn (operands[7], operands[1]);
2564 operands[1] = operands[7];
2566 if (! fp_arith_reg_operand (operands[2], SImode))
2568 emit_move_insn (operands[8], operands[2]);
2569 operands[2] = operands[8];
2572 [(set_attr "highpart" "must_split")])
2574 ;; -------------------------------------------------------------------------
2575 ;; Multiplication instructions
2576 ;; -------------------------------------------------------------------------
2578 (define_insn "umulhisi3_i"
2579 [(set (reg:SI MACL_REG)
2580 (mult:SI (zero_extend:SI
2581 (match_operand:HI 0 "arith_reg_operand" "r"))
2583 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2586 [(set_attr "type" "smpy")])
2588 (define_insn "mulhisi3_i"
2589 [(set (reg:SI MACL_REG)
2590 (mult:SI (sign_extend:SI
2591 (match_operand:HI 0 "arith_reg_operand" "r"))
2593 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2596 [(set_attr "type" "smpy")])
2598 (define_expand "mulhisi3"
2599 [(set (reg:SI MACL_REG)
2600 (mult:SI (sign_extend:SI
2601 (match_operand:HI 1 "arith_reg_operand" ""))
2603 (match_operand:HI 2 "arith_reg_operand" ""))))
2604 (set (match_operand:SI 0 "arith_reg_operand" "")
2611 macl = gen_rtx_REG (SImode, MACL_REG);
2613 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2614 insn = get_insns ();
2616 /* expand_binop can't find a suitable code in umul_widen_optab to
2617 make a REG_EQUAL note from, so make one here.
2618 See also smulsi3_highpart.
2619 ??? Alternatively, we could put this at the calling site of expand_binop,
2620 i.e. expand_expr. */
2621 /* Use emit_libcall_block for loop invariant code motion and to make
2622 a REG_EQUAL note. */
2623 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2628 (define_expand "umulhisi3"
2629 [(set (reg:SI MACL_REG)
2630 (mult:SI (zero_extend:SI
2631 (match_operand:HI 1 "arith_reg_operand" ""))
2633 (match_operand:HI 2 "arith_reg_operand" ""))))
2634 (set (match_operand:SI 0 "arith_reg_operand" "")
2641 macl = gen_rtx_REG (SImode, MACL_REG);
2643 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2644 insn = get_insns ();
2646 /* expand_binop can't find a suitable code in umul_widen_optab to
2647 make a REG_EQUAL note from, so make one here.
2648 See also smulsi3_highpart.
2649 ??? Alternatively, we could put this at the calling site of expand_binop,
2650 i.e. expand_expr. */
2651 /* Use emit_libcall_block for loop invariant code motion and to make
2652 a REG_EQUAL note. */
2653 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2658 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2659 ;; a call to a routine which clobbers known registers.
2662 [(set (match_operand:SI 1 "register_operand" "=z")
2663 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2664 (clobber (reg:SI MACL_REG))
2665 (clobber (reg:SI T_REG))
2666 (clobber (reg:SI PR_REG))
2667 (clobber (reg:SI R3_REG))
2668 (clobber (reg:SI R2_REG))
2669 (clobber (reg:SI R1_REG))
2670 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2673 [(set_attr "type" "sfunc")
2674 (set_attr "needs_delay_slot" "yes")])
2676 (define_expand "mulsi3_call"
2677 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2678 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2679 (parallel[(set (match_operand:SI 0 "register_operand" "")
2680 (mult:SI (reg:SI R4_REG)
2682 (clobber (reg:SI MACL_REG))
2683 (clobber (reg:SI T_REG))
2684 (clobber (reg:SI PR_REG))
2685 (clobber (reg:SI R3_REG))
2686 (clobber (reg:SI R2_REG))
2687 (clobber (reg:SI R1_REG))
2688 (use (match_operand:SI 3 "register_operand" ""))])]
2692 (define_insn "mul_r"
2693 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2694 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2695 (match_operand:SI 2 "arith_reg_operand" "z")))]
2698 [(set_attr "type" "dmpy")])
2700 (define_insn "mul_l"
2701 [(set (reg:SI MACL_REG)
2702 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2703 (match_operand:SI 1 "arith_reg_operand" "r")))]
2706 [(set_attr "type" "dmpy")])
2708 (define_expand "mulsi3"
2709 [(set (reg:SI MACL_REG)
2710 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2711 (match_operand:SI 2 "arith_reg_operand" "")))
2712 (set (match_operand:SI 0 "arith_reg_operand" "")
2719 /* The address must be set outside the libcall,
2720 since it goes into a pseudo. */
2721 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2722 rtx addr = force_reg (SImode, sym);
2723 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2729 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2731 emit_insn (gen_mul_l (operands[1], operands[2]));
2732 /* consec_sets_giv can only recognize the first insn that sets a
2733 giv as the giv insn. So we must tag this also with a REG_EQUAL
2735 emit_insn (gen_movsi_i ((operands[0]), macl));
2740 (define_insn "mulsidi3_i"
2741 [(set (reg:SI MACH_REG)
2745 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2746 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2748 (set (reg:SI MACL_REG)
2749 (mult:SI (match_dup 0)
2753 [(set_attr "type" "dmpy")])
2755 (define_expand "mulsidi3"
2756 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2757 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2758 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2759 "TARGET_SH2 || TARGET_SHMEDIA"
2764 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2770 (define_insn "mulsidi3_media"
2771 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2772 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2773 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2776 [(set_attr "type" "dmpy_media")
2777 (set_attr "highpart" "ignore")])
2779 (define_insn "mulsidi3_compact"
2780 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2782 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2783 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2784 (clobber (reg:SI MACH_REG))
2785 (clobber (reg:SI MACL_REG))]
2790 [(set (match_operand:DI 0 "arith_reg_dest" "")
2792 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2793 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2794 (clobber (reg:SI MACH_REG))
2795 (clobber (reg:SI MACL_REG))]
2800 rtx low_dst = gen_lowpart (SImode, operands[0]);
2801 rtx high_dst = gen_highpart (SImode, operands[0]);
2803 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2805 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2806 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2807 /* We need something to tag the possible REG_EQUAL notes on to. */
2808 emit_move_insn (operands[0], operands[0]);
2812 (define_insn "umulsidi3_i"
2813 [(set (reg:SI MACH_REG)
2817 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2818 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2820 (set (reg:SI MACL_REG)
2821 (mult:SI (match_dup 0)
2825 [(set_attr "type" "dmpy")])
2827 (define_expand "umulsidi3"
2828 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2829 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2830 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2831 "TARGET_SH2 || TARGET_SHMEDIA"
2836 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2842 (define_insn "umulsidi3_media"
2843 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2844 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2845 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2848 [(set_attr "type" "dmpy_media")
2849 (set_attr "highpart" "ignore")])
2851 (define_insn "umulsidi3_compact"
2852 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2854 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2855 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2856 (clobber (reg:SI MACH_REG))
2857 (clobber (reg:SI MACL_REG))]
2862 [(set (match_operand:DI 0 "arith_reg_dest" "")
2863 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2864 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2865 (clobber (reg:SI MACH_REG))
2866 (clobber (reg:SI MACL_REG))]
2871 rtx low_dst = gen_lowpart (SImode, operands[0]);
2872 rtx high_dst = gen_highpart (SImode, operands[0]);
2874 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2876 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2877 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2878 /* We need something to tag the possible REG_EQUAL notes on to. */
2879 emit_move_insn (operands[0], operands[0]);
2883 (define_insn "smulsi3_highpart_i"
2884 [(set (reg:SI MACH_REG)
2888 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2889 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2891 (clobber (reg:SI MACL_REG))]
2894 [(set_attr "type" "dmpy")])
2896 (define_expand "smulsi3_highpart"
2898 [(set (reg:SI MACH_REG)
2902 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2903 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2905 (clobber (reg:SI MACL_REG))])
2906 (set (match_operand:SI 0 "arith_reg_operand" "")
2913 mach = gen_rtx_REG (SImode, MACH_REG);
2915 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2916 insn = get_insns ();
2918 /* expand_binop can't find a suitable code in mul_highpart_optab to
2919 make a REG_EQUAL note from, so make one here.
2920 See also {,u}mulhisi.
2921 ??? Alternatively, we could put this at the calling site of expand_binop,
2922 i.e. expand_mult_highpart. */
2923 /* Use emit_libcall_block for loop invariant code motion and to make
2924 a REG_EQUAL note. */
2925 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2930 (define_insn "umulsi3_highpart_i"
2931 [(set (reg:SI MACH_REG)
2935 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2936 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2938 (clobber (reg:SI MACL_REG))]
2941 [(set_attr "type" "dmpy")])
2943 (define_expand "umulsi3_highpart"
2945 [(set (reg:SI MACH_REG)
2949 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2950 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2952 (clobber (reg:SI MACL_REG))])
2953 (set (match_operand:SI 0 "arith_reg_operand" "")
2960 mach = gen_rtx_REG (SImode, MACH_REG);
2962 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2963 insn = get_insns ();
2965 /* Use emit_libcall_block for loop invariant code motion and to make
2966 a REG_EQUAL note. */
2967 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2972 (define_insn_and_split "muldi3"
2973 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2974 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2975 (match_operand:DI 2 "arith_reg_operand" "r")))
2976 (clobber (match_scratch:DI 3 "=&r"))
2977 (clobber (match_scratch:DI 4 "=r"))]
2984 rtx op3_v2si, op2_v2si;
2986 op3_v2si = operands[3];
2987 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2989 op3_v2si = XEXP (op3_v2si, 0);
2990 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2992 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2993 op2_v2si = operands[2];
2994 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2996 op2_v2si = XEXP (op2_v2si, 0);
2997 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2999 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3000 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3001 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3002 emit_insn (gen_umulsidi3_media (operands[4],
3003 sh_gen_truncate (SImode, operands[1], 0),
3004 sh_gen_truncate (SImode, operands[2], 0)));
3005 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3006 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3007 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3008 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3013 ;; -------------------------------------------------------------------------
3014 ;; Logical operations
3015 ;; -------------------------------------------------------------------------
3017 (define_insn "*andsi3_compact"
3018 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3019 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3020 (match_operand:SI 2 "logical_operand" "r,K08")))]
3023 [(set_attr "type" "arith")])
3025 (define_insn "*andsi3_media"
3026 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3027 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3028 (match_operand:SI 2 "logical_operand" "r,I10")))]
3033 [(set_attr "type" "arith_media")])
3035 (define_insn "*andsi3_bclr"
3036 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3037 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3038 (match_operand:SI 2 "const_int_operand" "Psz")))]
3039 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3041 [(set_attr "type" "arith")])
3043 ;; If the constant is 255, then emit an extu.b instruction instead of an
3044 ;; and, since that will give better code.
3046 (define_expand "andsi3"
3047 [(set (match_operand:SI 0 "arith_reg_operand" "")
3048 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3049 (match_operand:SI 2 "logical_operand" "")))]
3054 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3056 emit_insn (gen_zero_extendqisi2 (operands[0],
3057 gen_lowpart (QImode, operands[1])));
3062 (define_insn_and_split "anddi3"
3063 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3064 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3065 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3072 && ! logical_operand (operands[2], DImode)"
3076 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3077 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3079 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3082 [(set_attr "type" "arith_media")])
3084 (define_insn "andcsi3"
3085 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3086 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3087 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3090 [(set_attr "type" "arith_media")])
3092 (define_insn "andcdi3"
3093 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3094 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3095 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3098 [(set_attr "type" "arith_media")])
3100 (define_expand "iorsi3"
3101 [(set (match_operand:SI 0 "arith_reg_operand" "")
3102 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3103 (match_operand:SI 2 "logical_operand" "")))]
3107 (define_insn "*iorsi3_compact"
3108 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3109 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3110 (match_operand:SI 2 "logical_operand" "r,K08")))]
3112 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3114 [(set_attr "type" "arith")])
3116 (define_insn "*iorsi3_media"
3117 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3118 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3119 (match_operand:SI 2 "logical_operand" "r,I10")))]
3124 [(set_attr "type" "arith_media")])
3126 (define_insn "*iorsi3_bset"
3127 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3128 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3129 (match_operand:SI 2 "const_int_operand" "Pso")))]
3130 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3132 [(set_attr "type" "arith")])
3134 (define_insn "iordi3"
3135 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3136 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3137 (match_operand:DI 2 "logical_operand" "r,I10")))]
3142 [(set_attr "type" "arith_media")])
3144 (define_insn_and_split "*logical_sidi3"
3145 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3146 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3147 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3148 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3151 "&& reload_completed"
3152 [(set (match_dup 0) (match_dup 3))]
3156 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3157 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3158 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3161 (define_insn_and_split "*logical_sidisi3"
3162 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3163 (truncate:SI (sign_extend:DI
3164 (match_operator:SI 3 "logical_operator"
3165 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3166 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3170 [(set (match_dup 0) (match_dup 3))])
3172 (define_insn_and_split "*logical_sidi3_2"
3173 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3174 (sign_extend:DI (truncate:SI (sign_extend:DI
3175 (match_operator:SI 3 "logical_operator"
3176 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3177 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3181 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3183 (define_expand "xorsi3"
3184 [(set (match_operand:SI 0 "arith_reg_operand" "")
3185 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3186 (match_operand:SI 2 "xor_operand" "")))]
3190 (define_insn "*xorsi3_compact"
3191 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3192 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3193 (match_operand:SI 2 "logical_operand" "K08,r")))]
3196 [(set_attr "type" "arith")])
3198 (define_insn "*xorsi3_media"
3199 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3200 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3201 (match_operand:SI 2 "xor_operand" "r,I06")))]
3206 [(set_attr "type" "arith_media")])
3208 ;; Store the complements of the T bit in a register.
3209 (define_insn "xorsi3_movrt"
3210 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3211 (xor:SI (reg:SI T_REG)
3215 [(set_attr "type" "arith")])
3217 (define_insn "xordi3"
3218 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3219 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3220 (match_operand:DI 2 "xor_operand" "r,I06")))]
3225 [(set_attr "type" "arith_media")])
3227 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3228 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3230 [(set (match_operand:DI 0 "arith_reg_dest" "")
3231 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3232 [(match_operand 1 "any_register_operand" "")
3233 (match_operand 2 "any_register_operand" "")])))]
3235 [(set (match_dup 5) (match_dup 4))
3236 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3239 enum machine_mode inmode = GET_MODE (operands[1]);
3242 if (GET_CODE (operands[0]) == SUBREG)
3244 offset = SUBREG_BYTE (operands[0]);
3245 operands[0] = SUBREG_REG (operands[0]);
3247 gcc_assert (REG_P (operands[0]));
3248 if (! TARGET_LITTLE_ENDIAN)
3249 offset += 8 - GET_MODE_SIZE (inmode);
3250 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3253 ;; -------------------------------------------------------------------------
3254 ;; Shifts and rotates
3255 ;; -------------------------------------------------------------------------
3257 (define_expand "rotldi3"
3258 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3259 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3260 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3262 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3264 (define_insn "rotldi3_mextr"
3265 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3266 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3267 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3271 static char templ[16];
3273 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3274 8 - (int) (INTVAL (operands[2]) >> 3));
3277 [(set_attr "type" "arith_media")])
3279 (define_expand "rotrdi3"
3280 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3281 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3282 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3284 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3286 (define_insn "rotrdi3_mextr"
3287 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3288 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3289 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3293 static char templ[16];
3295 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3298 [(set_attr "type" "arith_media")])
3301 [(set (match_operand:DI 0 "arith_reg_dest" "")
3302 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3303 "ua_address_operand" "")))
3304 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3306 (clobber (match_operand:DI 3 "register_operand" ""))]
3308 [(match_dup 4) (match_dup 5)]
3311 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3312 (operands[3], operands[1]));
3313 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3314 GEN_INT (56), GEN_INT (8));
3317 (define_insn "rotlsi3_1"
3318 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3319 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3322 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3325 [(set_attr "type" "arith")])
3327 (define_insn "rotlsi3_31"
3328 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3329 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3331 (clobber (reg:SI T_REG))]
3334 [(set_attr "type" "arith")])
3336 (define_insn "rotlsi3_16"
3337 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3338 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3342 [(set_attr "type" "arith")])
3344 (define_expand "rotlsi3"
3345 [(set (match_operand:SI 0 "arith_reg_dest" "")
3346 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3347 (match_operand:SI 2 "immediate_operand" "")))]
3351 static const char rot_tab[] = {
3352 000, 000, 000, 000, 000, 000, 010, 001,
3353 001, 001, 011, 013, 003, 003, 003, 003,
3354 003, 003, 003, 003, 003, 013, 012, 002,
3355 002, 002, 010, 000, 000, 000, 000, 000,
3360 if (!CONST_INT_P (operands[2]))
3362 count = INTVAL (operands[2]);
3363 choice = rot_tab[count];
3364 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3370 emit_move_insn (operands[0], operands[1]);
3371 count -= (count & 16) * 2;
3374 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3381 parts[0] = gen_reg_rtx (SImode);
3382 parts[1] = gen_reg_rtx (SImode);
3383 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3384 emit_move_insn (parts[choice-1], operands[1]);
3385 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3386 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3387 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3388 count = (count & ~16) - 8;
3392 for (; count > 0; count--)
3393 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3394 for (; count < 0; count++)
3395 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3400 (define_insn "*rotlhi3_8"
3401 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3402 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3406 [(set_attr "type" "arith")])
3408 (define_expand "rotlhi3"
3409 [(set (match_operand:HI 0 "arith_reg_operand" "")
3410 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3411 (match_operand:HI 2 "immediate_operand" "")))]
3415 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3422 (define_insn "ashlsi3_sh2a"
3423 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3424 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3425 (match_operand:SI 2 "arith_reg_operand" "r")))]
3428 [(set_attr "type" "arith")
3429 (set_attr "length" "4")])
3431 ;; This pattern is used by init_expmed for computing the costs of shift
3434 (define_insn_and_split "ashlsi3_std"
3435 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3436 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3437 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3438 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3440 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3448 && CONST_INT_P (operands[2])
3449 && ! satisfies_constraint_P27 (operands[2])"
3450 [(set (match_dup 3) (match_dup 2))
3452 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3453 (clobber (match_dup 4))])]
3454 "operands[4] = gen_rtx_SCRATCH (SImode);"
3455 [(set_attr "length" "*,*,*,4")
3456 (set_attr "type" "dyn_shift,arith,arith,arith")])
3458 (define_insn "ashlhi3_k"
3459 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3460 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3461 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3462 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3466 [(set_attr "type" "arith")])
3468 (define_insn "ashlsi3_n"
3469 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3471 (match_operand:SI 2 "const_int_operand" "n")))
3472 (clobber (reg:SI T_REG))]
3473 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3475 [(set (attr "length")
3476 (cond [(match_test "shift_insns_rtx (insn)")
3478 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3480 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3482 (const_string "8")))
3483 (set_attr "type" "arith")])
3486 [(set (match_operand:SI 0 "arith_reg_dest" "")
3487 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3488 (match_operand:SI 2 "const_int_operand" "")))
3489 (clobber (reg:SI T_REG))]
3490 "TARGET_SH1 && reload_completed"
3491 [(use (reg:SI R0_REG))]
3494 gen_shifty_op (ASHIFT, operands);
3498 (define_insn "ashlsi3_media"
3499 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3500 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3501 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3506 [(set_attr "type" "arith_media")
3507 (set_attr "highpart" "ignore")])
3509 (define_expand "ashlsi3"
3510 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3511 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3512 (match_operand:SI 2 "nonmemory_operand" "")))
3513 (clobber (reg:SI T_REG))])]
3519 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3522 if (CONST_INT_P (operands[2])
3523 && sh_dynamicalize_shift_p (operands[2]))
3524 operands[2] = force_reg (SImode, operands[2]);
3527 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3530 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3534 (define_insn "*ashlhi3_n"
3535 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3536 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3537 (match_operand:HI 2 "const_int_operand" "n")))
3538 (clobber (reg:SI T_REG))]
3541 [(set (attr "length")
3542 (cond [(match_test "shift_insns_rtx (insn)")
3544 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3546 (const_string "6")))
3547 (set_attr "type" "arith")])
3549 (define_expand "ashlhi3"
3550 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3551 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3552 (match_operand:SI 2 "nonmemory_operand" "")))
3553 (clobber (reg:SI T_REG))])]
3557 if (!CONST_INT_P (operands[2]))
3559 /* It may be possible to call gen_ashlhi3 directly with more generic
3560 operands. Make sure operands[1] is a HImode register here. */
3561 if (!arith_reg_operand (operands[1], HImode))
3562 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3566 [(set (match_operand:HI 0 "arith_reg_dest" "")
3567 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3568 (match_operand:HI 2 "const_int_operand" "")))
3569 (clobber (reg:SI T_REG))]
3570 "TARGET_SH1 && reload_completed"
3571 [(use (reg:SI R0_REG))]
3574 gen_shifty_hi_op (ASHIFT, operands);
3579 ; arithmetic shift right
3582 (define_insn "ashrsi3_sh2a"
3583 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3584 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3585 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3588 [(set_attr "type" "dyn_shift")
3589 (set_attr "length" "4")])
3591 (define_insn "ashrsi3_k"
3592 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3593 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3594 (match_operand:SI 2 "const_int_operand" "M")))
3595 (clobber (reg:SI T_REG))]
3596 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3598 [(set_attr "type" "arith")])
3600 ;; We can't do HImode right shifts correctly unless we start out with an
3601 ;; explicit zero / sign extension; doing that would result in worse overall
3602 ;; code, so just let the machine independent code widen the mode.
3603 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3606 ;; ??? This should be a define expand.
3608 (define_insn "ashrsi2_16"
3609 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3610 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3614 [(set_attr "length" "4")])
3617 [(set (match_operand:SI 0 "arith_reg_dest" "")
3618 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3621 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3622 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3623 "operands[2] = gen_lowpart (HImode, operands[0]);")
3625 ;; ??? This should be a define expand.
3627 (define_insn "ashrsi2_31"
3628 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3629 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3631 (clobber (reg:SI T_REG))]
3634 [(set_attr "length" "4")])
3637 [(set (match_operand:SI 0 "arith_reg_dest" "")
3638 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3640 (clobber (reg:SI T_REG))]
3645 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3646 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3651 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3653 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3655 && peep2_reg_dead_p (2, operands[0])
3656 && peep2_reg_dead_p (2, operands[1])"
3660 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3664 (define_insn "ashlsi_c"
3665 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3666 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3668 (lt:SI (match_dup 1) (const_int 0)))]
3671 [(set_attr "type" "arith")])
3673 (define_insn "*ashlsi_c_void"
3674 [(set (reg:SI T_REG)
3675 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3676 (clobber (match_scratch:SI 1 "=0"))]
3677 "TARGET_SH1 && cse_not_expected"
3679 [(set_attr "type" "arith")])
3681 (define_insn "ashrsi3_d"
3682 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3687 [(set_attr "type" "dyn_shift")])
3689 (define_insn "ashrsi3_n"
3690 [(set (reg:SI R4_REG)
3691 (ashiftrt:SI (reg:SI R4_REG)
3692 (match_operand:SI 0 "const_int_operand" "i")))
3693 (clobber (reg:SI T_REG))
3694 (clobber (reg:SI PR_REG))
3695 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3698 [(set_attr "type" "sfunc")
3699 (set_attr "needs_delay_slot" "yes")])
3701 (define_insn "ashrsi3_media"
3702 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3703 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3704 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3709 [(set_attr "type" "arith_media")
3710 (set_attr "highpart" "ignore")])
3712 (define_expand "ashrsi3"
3713 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3714 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3715 (match_operand:SI 2 "nonmemory_operand" "")))
3716 (clobber (reg:SI T_REG))])]
3722 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3725 if (expand_ashiftrt (operands))
3731 ;; logical shift right
3733 (define_insn "lshrsi3_sh2a"
3734 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3736 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3739 [(set_attr "type" "dyn_shift")
3740 (set_attr "length" "4")])
3742 (define_insn "lshrsi3_d"
3743 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3744 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3745 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3748 [(set_attr "type" "dyn_shift")])
3750 ;; Only the single bit shift clobbers the T bit.
3752 (define_insn "lshrsi3_m"
3753 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3754 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3755 (match_operand:SI 2 "const_int_operand" "M")))
3756 (clobber (reg:SI T_REG))]
3757 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3759 [(set_attr "type" "arith")])
3761 (define_insn "lshrsi3_k"
3762 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3763 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3764 (match_operand:SI 2 "const_int_operand" "P27")))]
3765 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3766 && ! satisfies_constraint_M (operands[2])"
3768 [(set_attr "type" "arith")])
3770 (define_insn "lshrsi3_n"
3771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3773 (match_operand:SI 2 "const_int_operand" "n")))
3774 (clobber (reg:SI T_REG))]
3775 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3777 [(set (attr "length")
3778 (cond [(match_test "shift_insns_rtx (insn)")
3780 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3782 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3784 (const_string "8")))
3785 (set_attr "type" "arith")])
3788 [(set (match_operand:SI 0 "arith_reg_dest" "")
3789 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3790 (match_operand:SI 2 "const_int_operand" "")))
3791 (clobber (reg:SI T_REG))]
3792 "TARGET_SH1 && reload_completed"
3793 [(use (reg:SI R0_REG))]
3796 gen_shifty_op (LSHIFTRT, operands);
3800 (define_insn "lshrsi3_media"
3801 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3802 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3803 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3808 [(set_attr "type" "arith_media")
3809 (set_attr "highpart" "ignore")])
3811 (define_expand "lshrsi3"
3812 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3813 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3814 (match_operand:SI 2 "nonmemory_operand" "")))
3815 (clobber (reg:SI T_REG))])]
3821 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3824 if (CONST_INT_P (operands[2])
3825 && sh_dynamicalize_shift_p (operands[2]))
3826 operands[2] = force_reg (SImode, operands[2]);
3827 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3829 rtx count = copy_to_mode_reg (SImode, operands[2]);
3830 emit_insn (gen_negsi2 (count, count));
3831 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3834 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3838 ;; ??? This should be a define expand.
3840 (define_insn "ashldi3_k"
3841 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3842 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3844 (clobber (reg:SI T_REG))]
3846 "shll %R0\;rotcl %S0"
3847 [(set_attr "length" "4")
3848 (set_attr "type" "arith")])
3850 ;; Expander for DImode shift left with SImode operations.
3852 (define_expand "ashldi3_std"
3853 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3854 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3855 (match_operand:DI 2 "const_int_operand" "n")))]
3856 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3859 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3860 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3861 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3862 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3863 rtx dst = gen_reg_rtx (DImode);
3864 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3865 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3868 tmp0 = gen_reg_rtx (SImode);
3869 tmp1 = gen_reg_rtx (SImode);
3870 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3871 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3872 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3873 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3874 emit_move_insn (operands[0], dst);
3878 (define_insn "ashldi3_media"
3879 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3880 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3881 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3886 [(set_attr "type" "arith_media")])
3888 (define_insn "*ashldisi3_media"
3889 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3890 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3891 (match_operand:DI 2 "const_int_operand" "n")))]
3892 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3893 "shlli.l %1, %2, %0"
3894 [(set_attr "type" "arith_media")
3895 (set_attr "highpart" "ignore")])
3897 (define_expand "ashldi3"
3898 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3899 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3900 (match_operand:DI 2 "immediate_operand" "")))
3901 (clobber (reg:SI T_REG))])]
3907 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3910 if (CONST_INT_P (operands[2])
3911 && INTVAL (operands[2]) == 1)
3913 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3916 else if (CONST_INT_P (operands[2])
3917 && INTVAL (operands[2]) < 32)
3919 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3926 ;; ??? This should be a define expand.
3928 (define_insn "lshrdi3_k"
3929 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3930 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3932 (clobber (reg:SI T_REG))]
3934 "shlr %S0\;rotcr %R0"
3935 [(set_attr "length" "4")
3936 (set_attr "type" "arith")])
3938 (define_insn "lshrdi3_media"
3939 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3940 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3941 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3943 && (arith_reg_dest (operands[0], DImode)
3944 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3948 [(set_attr "type" "arith_media")])
3950 (define_insn "*lshrdisi3_media"
3951 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3952 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3953 (match_operand:DI 2 "const_int_operand" "n")))]
3954 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3955 "shlri.l %1, %2, %0"
3956 [(set_attr "type" "arith_media")
3957 (set_attr "highpart" "ignore")])
3959 (define_expand "lshrdi3"
3960 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3961 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3962 (match_operand:DI 2 "immediate_operand" "")))
3963 (clobber (reg:SI T_REG))])]
3969 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3972 if (!CONST_INT_P (operands[2])
3973 || INTVAL (operands[2]) != 1)
3977 ;; ??? This should be a define expand.
3979 (define_insn "ashrdi3_k"
3980 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3981 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3983 (clobber (reg:SI T_REG))]
3985 "shar %S0\;rotcr %R0"
3986 [(set_attr "length" "4")
3987 (set_attr "type" "arith")])
3989 (define_insn "ashrdi3_media"
3990 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3991 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3992 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3994 && (arith_reg_dest (operands[0], DImode)
3995 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
3999 [(set_attr "type" "arith_media")])
4001 (define_insn "*ashrdisi3_media"
4002 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4003 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004 (match_operand:DI 2 "const_int_operand" "n")))]
4005 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4006 "shari.l %1, %2, %0"
4007 [(set_attr "type" "arith_media")
4008 (set_attr "highpart" "ignore")])
4010 (define_insn "ashrdisi3_media_high"
4011 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4013 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4014 (match_operand:DI 2 "const_int_operand" "n"))))]
4015 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4017 [(set_attr "type" "arith_media")])
4019 (define_insn "ashrdisi3_media_opaque"
4020 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4021 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4022 (match_operand:DI 2 "const_int_operand" "n")]
4026 [(set_attr "type" "arith_media")])
4028 (define_expand "ashrdi3"
4029 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4030 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4031 (match_operand:DI 2 "immediate_operand" "")))
4032 (clobber (reg:SI T_REG))])]
4038 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4041 if (!CONST_INT_P (operands[2])
4042 || INTVAL (operands[2]) != 1)
4046 ;; combined left/right shift
4049 [(set (match_operand:SI 0 "register_operand" "")
4050 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4051 (match_operand:SI 2 "const_int_operand" ""))
4052 (match_operand:SI 3 "const_int_operand" "")))]
4053 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4054 [(use (reg:SI R0_REG))]
4055 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4059 [(set (match_operand:SI 0 "register_operand" "")
4060 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4061 (match_operand:SI 2 "const_int_operand" ""))
4062 (match_operand:SI 3 "const_int_operand" "")))
4063 (clobber (reg:SI T_REG))]
4064 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4065 [(use (reg:SI R0_REG))]
4066 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4070 [(set (match_operand:SI 0 "register_operand" "=r")
4071 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4072 (match_operand:SI 2 "const_int_operand" "n"))
4073 (match_operand:SI 3 "const_int_operand" "n")))
4074 (clobber (reg:SI T_REG))]
4075 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4077 [(set (attr "length")
4078 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4080 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4082 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4084 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4086 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4088 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4090 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4091 (const_string "16")]
4092 (const_string "18")))
4093 (set_attr "type" "arith")])
4096 [(set (match_operand:SI 0 "register_operand" "=z")
4097 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4098 (match_operand:SI 2 "const_int_operand" "n"))
4099 (match_operand:SI 3 "const_int_operand" "n")))
4100 (clobber (reg:SI T_REG))]
4101 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4103 [(set (attr "length")
4104 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4106 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4108 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4110 (const_string "10")))
4111 (set_attr "type" "arith")])
4113 ;; shift left / and combination with a scratch register: The combine pass
4114 ;; does not accept the individual instructions, even though they are
4115 ;; cheap. But it needs a precise description so that it is usable after
4117 (define_insn "and_shl_scratch"
4118 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4122 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4123 (match_operand:SI 2 "const_int_operand" "N,n"))
4124 (match_operand:SI 3 "" "0,r"))
4125 (match_operand:SI 4 "const_int_operand" "n,n"))
4126 (match_operand:SI 5 "const_int_operand" "n,n")))
4127 (clobber (reg:SI T_REG))]
4130 [(set (attr "length")
4131 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4133 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4135 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4137 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4138 (const_string "10")]
4139 (const_string "12")))
4140 (set_attr "type" "arith")])
4143 [(set (match_operand:SI 0 "register_operand" "")
4147 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4148 (match_operand:SI 2 "const_int_operand" ""))
4149 (match_operand:SI 3 "register_operand" ""))
4150 (match_operand:SI 4 "const_int_operand" ""))
4151 (match_operand:SI 5 "const_int_operand" "")))
4152 (clobber (reg:SI T_REG))]
4154 [(use (reg:SI R0_REG))]
4157 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4159 if (INTVAL (operands[2]))
4161 gen_shifty_op (LSHIFTRT, operands);
4163 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4164 operands[2] = operands[4];
4165 gen_shifty_op (ASHIFT, operands);
4166 if (INTVAL (operands[5]))
4168 operands[2] = operands[5];
4169 gen_shifty_op (LSHIFTRT, operands);
4174 ;; signed left/right shift combination.
4176 [(set (match_operand:SI 0 "register_operand" "")
4178 (ashift:SI (match_operand:SI 1 "register_operand" "")
4179 (match_operand:SI 2 "const_int_operand" ""))
4180 (match_operand:SI 3 "const_int_operand" "")
4182 (clobber (reg:SI T_REG))]
4184 [(use (reg:SI R0_REG))]
4185 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4188 (define_insn "shl_sext_ext"
4189 [(set (match_operand:SI 0 "register_operand" "=r")
4191 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4192 (match_operand:SI 2 "const_int_operand" "n"))
4193 (match_operand:SI 3 "const_int_operand" "n")
4195 (clobber (reg:SI T_REG))]
4196 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4198 [(set (attr "length")
4199 (cond [(match_test "shl_sext_length (insn)")
4201 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4203 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4205 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4207 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4209 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4211 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4213 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4214 (const_string "16")]
4215 (const_string "18")))
4216 (set_attr "type" "arith")])
4218 (define_insn "shl_sext_sub"
4219 [(set (match_operand:SI 0 "register_operand" "=z")
4221 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4222 (match_operand:SI 2 "const_int_operand" "n"))
4223 (match_operand:SI 3 "const_int_operand" "n")
4225 (clobber (reg:SI T_REG))]
4226 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4228 [(set (attr "length")
4229 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4231 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4233 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4235 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4236 (const_string "12")]
4237 (const_string "14")))
4238 (set_attr "type" "arith")])
4240 ;; These patterns are found in expansions of DImode shifts by 16, and
4241 ;; allow the xtrct instruction to be generated from C source.
4243 (define_insn "xtrct_left"
4244 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4245 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4247 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4251 [(set_attr "type" "arith")])
4253 (define_insn "xtrct_right"
4254 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4255 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4257 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4261 [(set_attr "type" "arith")])
4263 ;; -------------------------------------------------------------------------
4265 ;; -------------------------------------------------------------------------
4268 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4269 (neg:SI (plus:SI (reg:SI T_REG)
4270 (match_operand:SI 1 "arith_reg_operand" "r"))))
4272 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4276 [(set_attr "type" "arith")])
4278 (define_insn "*negdi_media"
4279 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4280 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4283 [(set_attr "type" "arith_media")])
4285 (define_expand "negdi2"
4286 [(set (match_operand:DI 0 "arith_reg_operand" "")
4287 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4293 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4294 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4296 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4297 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4299 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4300 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4302 emit_insn (gen_clrt ());
4303 emit_insn (gen_negc (low_dst, low_src));
4304 emit_insn (gen_negc (high_dst, high_src));
4309 (define_insn "negsi2"
4310 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4311 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4314 [(set_attr "type" "arith")])
4316 (define_insn "one_cmplsi2"
4317 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4318 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4321 [(set_attr "type" "arith")])
4323 (define_expand "one_cmpldi2"
4324 [(set (match_operand:DI 0 "arith_reg_dest" "")
4325 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4327 "TARGET_SHMEDIA" "")
4329 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4330 This can be used as some kind of conditional execution, which is useful
4333 [(set (match_operand:SI 0 "arith_reg_dest" "")
4334 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4335 (match_operand:SI 1 "arith_reg_operand" ""))
4339 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4340 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4344 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4345 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4346 (match_operand:SI 1 "arith_reg_operand" "0")
4347 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4349 "bf 0f\;neg %2,%0\\n0:"
4350 [(set_attr "type" "arith") ;; poor approximation
4351 (set_attr "length" "4")])
4354 ;; -------------------------------------------------------------------------
4355 ;; Zero extension instructions
4356 ;; -------------------------------------------------------------------------
4358 (define_insn "zero_extendsidi2"
4359 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4360 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4362 "addz.l %1, r63, %0"
4363 [(set_attr "type" "arith_media")
4364 (set_attr "highpart" "extend")])
4366 (define_insn "zero_extendhidi2"
4367 [(set (match_operand:DI 0 "register_operand" "=r,r")
4368 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4373 [(set_attr "type" "*,load_media")
4374 (set (attr "highpart")
4375 (cond [(match_test "sh_contains_memref_p (insn)")
4376 (const_string "user")]
4377 (const_string "ignore")))])
4380 [(set (match_operand:DI 0 "register_operand" "")
4381 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4382 "TARGET_SHMEDIA && reload_completed"
4383 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4384 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4387 if (GET_CODE (operands[1]) == TRUNCATE)
4388 operands[1] = XEXP (operands[1], 0);
4391 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4392 ;; reload the entire truncate expression.
4393 (define_insn_and_split "*loaddi_trunc"
4394 [(set (match_operand 0 "any_register_operand" "=r")
4395 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4396 "TARGET_SHMEDIA && reload_completed"
4398 "TARGET_SHMEDIA && reload_completed"
4399 [(set (match_dup 0) (match_dup 1))]
4400 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4402 (define_insn "zero_extendqidi2"
4403 [(set (match_operand:DI 0 "register_operand" "=r,r")
4404 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4409 [(set_attr "type" "arith_media,load_media")
4410 (set (attr "highpart")
4411 (cond [(match_test "sh_contains_memref_p (insn)")
4412 (const_string "user")]
4413 (const_string "ignore")))])
4415 (define_expand "zero_extendhisi2"
4416 [(set (match_operand:SI 0 "arith_reg_operand" "")
4417 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4421 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4422 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4425 (define_insn "*zero_extendhisi2_compact"
4426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4427 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4430 [(set_attr "type" "arith")])
4432 (define_insn "*zero_extendhisi2_media"
4433 [(set (match_operand:SI 0 "register_operand" "=r,r")
4434 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4439 [(set_attr "type" "arith_media,load_media")
4440 (set (attr "highpart")
4441 (cond [(match_test "sh_contains_memref_p (insn)")
4442 (const_string "user")]
4443 (const_string "ignore")))])
4446 [(set (match_operand:SI 0 "register_operand" "")
4447 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4448 "TARGET_SHMEDIA && reload_completed"
4449 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4450 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4453 rtx op1 = operands[1];
4455 if (GET_CODE (op1) == TRUNCATE)
4456 op1 = XEXP (op1, 0);
4458 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4459 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4462 (define_expand "zero_extendqisi2"
4463 [(set (match_operand:SI 0 "arith_reg_operand" "")
4464 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4468 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4469 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4472 (define_insn "*zero_extendqisi2_compact"
4473 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4474 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4477 [(set_attr "type" "arith")])
4479 (define_insn "*zero_extendqisi2_media"
4480 [(set (match_operand:SI 0 "register_operand" "=r,r")
4481 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4486 [(set_attr "type" "arith_media,load_media")
4487 (set (attr "highpart")
4488 (cond [(match_test "sh_contains_memref_p (insn)")
4489 (const_string "user")]
4490 (const_string "ignore")))])
4492 (define_insn "zero_extendqihi2"
4493 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4494 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4497 [(set_attr "type" "arith")])
4499 ;; -------------------------------------------------------------------------
4500 ;; Sign extension instructions
4501 ;; -------------------------------------------------------------------------
4503 ;; ??? This should be a define expand.
4504 ;; ??? Or perhaps it should be dropped?
4506 ;; convert_move generates good code for SH[1-4].
4507 (define_insn "extendsidi2"
4508 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4509 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4515 [(set_attr "type" "arith_media,load_media,fpconv_media")
4516 (set (attr "highpart")
4517 (cond [(match_test "sh_contains_memref_p (insn)")
4518 (const_string "user")]
4519 (const_string "extend")))])
4521 (define_insn "extendhidi2"
4522 [(set (match_operand:DI 0 "register_operand" "=r,r")
4523 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4528 [(set_attr "type" "*,load_media")
4529 (set (attr "highpart")
4530 (cond [(match_test "sh_contains_memref_p (insn)")
4531 (const_string "user")]
4532 (const_string "ignore")))])
4535 [(set (match_operand:DI 0 "register_operand" "")
4536 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4537 "TARGET_SHMEDIA && reload_completed"
4538 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4539 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4542 if (GET_CODE (operands[1]) == TRUNCATE)
4543 operands[1] = XEXP (operands[1], 0);
4546 (define_insn "extendqidi2"
4547 [(set (match_operand:DI 0 "register_operand" "=r,r")
4548 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4553 [(set_attr "type" "*,load_media")
4554 (set (attr "highpart")
4555 (cond [(match_test "sh_contains_memref_p (insn)")
4556 (const_string "user")]
4557 (const_string "ignore")))])
4560 [(set (match_operand:DI 0 "register_operand" "")
4561 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4562 "TARGET_SHMEDIA && reload_completed"
4563 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4564 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4567 if (GET_CODE (operands[1]) == TRUNCATE)
4568 operands[1] = XEXP (operands[1], 0);
4571 (define_expand "extendhisi2"
4572 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4573 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4577 (define_insn "*extendhisi2_compact"
4578 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4579 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4584 [(set_attr "type" "arith,load")])
4586 (define_insn "*extendhisi2_media"
4587 [(set (match_operand:SI 0 "register_operand" "=r,r")
4588 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4593 [(set_attr "type" "arith_media,load_media")
4594 (set (attr "highpart")
4595 (cond [(match_test "sh_contains_memref_p (insn)")
4596 (const_string "user")]
4597 (const_string "ignore")))])
4600 [(set (match_operand:SI 0 "register_operand" "")
4601 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4602 "TARGET_SHMEDIA && reload_completed"
4603 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4604 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4607 rtx op1 = operands[1];
4608 if (GET_CODE (op1) == TRUNCATE)
4609 op1 = XEXP (op1, 0);
4611 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4612 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4615 (define_expand "extendqisi2"
4616 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4617 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4621 (define_insn "*extendqisi2_compact"
4622 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4623 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4628 [(set_attr "type" "arith,load")
4629 (set_attr_alternative "length"
4632 (match_test "TARGET_SH2A")
4633 (const_int 4) (const_int 2))])])
4635 (define_insn "*extendqisi2_media"
4636 [(set (match_operand:SI 0 "register_operand" "=r,r")
4637 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4642 [(set_attr "type" "arith_media,load_media")
4643 (set (attr "highpart")
4644 (cond [(match_test "sh_contains_memref_p (insn)")
4645 (const_string "user")]
4646 (const_string "ignore")))])
4649 [(set (match_operand:SI 0 "register_operand" "")
4650 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4651 "TARGET_SHMEDIA && reload_completed"
4652 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4653 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4656 rtx op1 = operands[1];
4657 if (GET_CODE (op1) == TRUNCATE)
4658 op1 = XEXP (op1, 0);
4660 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4661 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4664 (define_insn "extendqihi2"
4665 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4666 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4671 [(set_attr "type" "arith,load")
4672 (set_attr_alternative "length"
4675 (match_test "TARGET_SH2A")
4676 (const_int 4) (const_int 2))])])
4678 /* It would seem useful to combine the truncXi patterns into the movXi
4679 patterns, but unary operators are ignored when matching constraints,
4680 so we need separate patterns. */
4681 (define_insn "truncdisi2"
4682 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4683 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4692 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4693 (set (attr "highpart")
4694 (cond [(match_test "sh_contains_memref_p (insn)")
4695 (const_string "user")]
4696 (const_string "extend")))])
4698 (define_insn "truncdihi2"
4699 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4700 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4703 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4705 [(set_attr "type" "arith_media,store_media")
4706 (set_attr "length" "8,4")
4707 (set (attr "highpart")
4708 (cond [(match_test "sh_contains_memref_p (insn)")
4709 (const_string "user")]
4710 (const_string "extend")))])
4712 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4713 ; Because we use zero extension, we can't provide signed QImode compares
4714 ; using a simple compare or conditional branch insn.
4715 (define_insn "truncdiqi2"
4716 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4717 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4722 [(set_attr "type" "arith_media,store")
4723 (set (attr "highpart")
4724 (cond [(match_test "sh_contains_memref_p (insn)")
4725 (const_string "user")]
4726 (const_string "extend")))])
4727 ;; -------------------------------------------------------------------------
4728 ;; Move instructions
4729 ;; -------------------------------------------------------------------------
4731 ;; define push and pop so it is easy for sh.c
4732 ;; We can't use push and pop on SHcompact because the stack must always
4733 ;; be 8-byte aligned.
4735 (define_expand "push"
4736 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4737 (match_operand:SI 0 "register_operand" "r,l,x"))]
4738 "TARGET_SH1 && ! TARGET_SH5"
4741 (define_expand "pop"
4742 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4743 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4744 "TARGET_SH1 && ! TARGET_SH5"
4747 (define_expand "push_e"
4748 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4749 (match_operand:SF 0 "" ""))
4750 (use (reg:PSI FPSCR_REG))
4751 (clobber (scratch:SI))])]
4752 "TARGET_SH1 && ! TARGET_SH5"
4755 (define_insn "push_fpul"
4756 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4757 "TARGET_SH2E && ! TARGET_SH5"
4759 [(set_attr "type" "fstore")
4760 (set_attr "late_fp_use" "yes")
4761 (set_attr "hit_stack" "yes")])
4763 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4765 (define_expand "push_4"
4766 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4767 (match_operand:DF 0 "" ""))
4768 (use (reg:PSI FPSCR_REG))
4769 (clobber (scratch:SI))])]
4770 "TARGET_SH1 && ! TARGET_SH5"
4773 (define_expand "pop_e"
4774 [(parallel [(set (match_operand:SF 0 "" "")
4775 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4776 (use (reg:PSI FPSCR_REG))
4777 (clobber (scratch:SI))])]
4778 "TARGET_SH1 && ! TARGET_SH5"
4781 (define_insn "pop_fpul"
4782 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4783 "TARGET_SH2E && ! TARGET_SH5"
4785 [(set_attr "type" "load")
4786 (set_attr "hit_stack" "yes")])
4788 (define_expand "pop_4"
4789 [(parallel [(set (match_operand:DF 0 "" "")
4790 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4791 (use (reg:PSI FPSCR_REG))
4792 (clobber (scratch:SI))])]
4793 "TARGET_SH1 && ! TARGET_SH5"
4796 (define_expand "push_fpscr"
4801 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4802 gen_rtx_PRE_DEC (Pmode,
4803 stack_pointer_rtx)),
4805 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4809 (define_expand "pop_fpscr"
4814 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4815 gen_frame_mem (PSImode,
4816 gen_rtx_POST_INC (Pmode,
4817 stack_pointer_rtx))));
4818 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4822 ;; These two patterns can happen as the result of optimization, when
4823 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4824 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4827 [(set (reg:SI T_REG) (const_int 0))]
4832 [(set (reg:SI T_REG) (const_int 1))]
4836 ;; Define additional pop for SH1 and SH2 so it does not get
4837 ;; placed in the delay slot.
4838 (define_insn "*movsi_pop"
4839 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
4840 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
4841 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
4847 [(set_attr "type" "load_si,mem_mac,pload")
4848 (set_attr "length" "2,2,2")
4849 (set_attr "in_delay_slot" "no,no,no")])
4851 ;; t/r must come after r/r, lest reload will try to reload stuff like
4852 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4853 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4854 (define_insn "movsi_i"
4855 [(set (match_operand:SI 0 "general_movdst_operand"
4856 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4857 (match_operand:SI 1 "general_movsrc_operand"
4858 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4862 && (register_operand (operands[0], SImode)
4863 || register_operand (operands[1], SImode))"
4881 [(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")
4882 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4884 ;; t/r must come after r/r, lest reload will try to reload stuff like
4885 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4886 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4887 ;; will require a reload.
4888 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4889 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4890 (define_insn "movsi_ie"
4891 [(set (match_operand:SI 0 "general_movdst_operand"
4892 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4893 (match_operand:SI 1 "general_movsrc_operand"
4894 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4895 "(TARGET_SH2E || TARGET_SH2A)
4896 && (register_operand (operands[0], SImode)
4897 || register_operand (operands[1], SImode))"
4924 ! move optimized away"
4925 [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4926 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4927 (set_attr_alternative "length"
4935 (match_test "TARGET_SH2A")
4936 (const_int 4) (const_int 2))
4941 (match_test "TARGET_SH2A")
4942 (const_int 4) (const_int 2))
4959 (define_insn "movsi_i_lowpart"
4960 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4961 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4963 && (register_operand (operands[0], SImode)
4964 || register_operand (operands[1], SImode))"
4975 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4977 (define_insn_and_split "load_ra"
4978 [(set (match_operand:SI 0 "general_movdst_operand" "")
4979 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4982 "&& ! currently_expanding_to_rtl"
4983 [(set (match_dup 0) (match_dup 1))]
4986 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4987 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4990 ;; The '?'s in the following constraints may not reflect the time taken
4991 ;; to perform the move. They are there to discourage the use of floating-
4992 ;; point registers for storing integer values.
4993 (define_insn "*movsi_media"
4994 [(set (match_operand:SI 0 "general_movdst_operand"
4995 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4996 (match_operand:SI 1 "general_movsrc_operand"
4997 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4999 && (register_operand (operands[0], SImode)
5000 || sh_register_operand (operands[1], SImode)
5001 || GET_CODE (operands[1]) == TRUNCATE)"
5016 [(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")
5017 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5018 (set (attr "highpart")
5019 (cond [(match_test "sh_contains_memref_p (insn)")
5020 (const_string "user")]
5021 (const_string "ignore")))])
5023 (define_insn "*movsi_media_nofpu"
5024 [(set (match_operand:SI 0 "general_movdst_operand"
5025 "=r,r,r,r,m,*b,r,*b")
5026 (match_operand:SI 1 "general_movsrc_operand"
5027 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5029 && (register_operand (operands[0], SImode)
5030 || sh_register_operand (operands[1], SImode)
5031 || GET_CODE (operands[1]) == TRUNCATE)"
5041 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5042 (set_attr "length" "4,4,8,4,4,4,4,12")
5043 (set (attr "highpart")
5044 (cond [(match_test "sh_contains_memref_p (insn)")
5045 (const_string "user")]
5046 (const_string "ignore")))])
5048 (define_expand "movsi_const"
5049 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5050 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5051 (const_int 16)] UNSPEC_EXTRACT_S16)))
5053 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5054 (const:SI (unspec:SI [(match_dup 1)
5055 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5056 "TARGET_SHMEDIA && reload_completed
5057 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5060 if (GET_CODE (operands[1]) == LABEL_REF
5061 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5062 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5063 else if (GOTOFF_P (operands[1]))
5065 rtx unspec = XEXP (operands[1], 0);
5067 if (! UNSPEC_GOTOFF_P (unspec))
5069 unspec = XEXP (unspec, 0);
5070 if (! UNSPEC_GOTOFF_P (unspec))
5073 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5074 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5075 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5079 (define_expand "movsi_const_16bit"
5080 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5081 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5082 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5083 "TARGET_SHMEDIA && flag_pic && reload_completed
5084 && GET_CODE (operands[1]) == SYMBOL_REF"
5088 [(set (match_operand:SI 0 "arith_reg_dest" "")
5089 (match_operand:SI 1 "immediate_operand" ""))]
5090 "TARGET_SHMEDIA && reload_completed
5091 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5095 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5097 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5103 [(set (match_operand:SI 0 "register_operand" "")
5104 (match_operand:SI 1 "immediate_operand" ""))]
5105 "TARGET_SHMEDIA && reload_completed
5106 && ((CONST_INT_P (operands[1])
5107 && ! satisfies_constraint_I16 (operands[1]))
5108 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5109 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5111 (define_expand "movsi"
5112 [(set (match_operand:SI 0 "general_movdst_operand" "")
5113 (match_operand:SI 1 "general_movsrc_operand" ""))]
5115 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5117 (define_expand "ic_invalidate_line"
5118 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5119 (match_dup 1)] UNSPEC_ICACHE)
5120 (clobber (scratch:SI))])]
5121 "TARGET_HARD_SH4 || TARGET_SH5"
5126 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5129 else if (TARGET_SHCOMPACT)
5131 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5132 operands[1] = force_reg (Pmode, operands[1]);
5133 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5136 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5138 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5141 operands[0] = force_reg (Pmode, operands[0]);
5142 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5146 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5147 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5148 ;; the requirement *1*00 for associative address writes. The alignment of
5149 ;; %0 implies that its least significant bit is cleared,
5150 ;; thus we clear the V bit of a matching entry if there is one.
5151 (define_insn "ic_invalidate_line_i"
5152 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5153 (match_operand:SI 1 "register_operand" "r")]
5155 (clobber (match_scratch:SI 2 "=&r"))]
5157 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5158 [(set_attr "length" "8")
5159 (set_attr "type" "cwb")])
5161 (define_insn "ic_invalidate_line_sh4a"
5162 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5164 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5165 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5166 [(set_attr "length" "16")
5167 (set_attr "type" "cwb")])
5169 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5170 ;; an add in the code that calculates the address.
5171 (define_insn "ic_invalidate_line_media"
5172 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5175 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5176 [(set_attr "length" "16")
5177 (set_attr "type" "invalidate_line_media")])
5179 (define_insn "ic_invalidate_line_compact"
5180 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5181 (match_operand:SI 1 "register_operand" "r")]
5183 (clobber (reg:SI PR_REG))]
5186 [(set_attr "type" "sfunc")
5187 (set_attr "needs_delay_slot" "yes")])
5189 (define_expand "initialize_trampoline"
5190 [(match_operand:SI 0 "" "")
5191 (match_operand:SI 1 "" "")
5192 (match_operand:SI 2 "" "")]
5198 tramp = force_reg (Pmode, operands[0]);
5199 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5201 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5202 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5204 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5208 (define_insn "initialize_trampoline_compact"
5209 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5210 (match_operand:SI 1 "register_operand" "r")
5211 (reg:SI R2_REG) (reg:SI R3_REG)]
5214 (clobber (reg:SI PR_REG))]
5217 [(set_attr "type" "sfunc")
5218 (set_attr "needs_delay_slot" "yes")])
5220 (define_insn "movqi_i"
5221 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5222 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5224 && (arith_reg_operand (operands[0], QImode)
5225 || arith_reg_operand (operands[1], QImode))"
5234 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5235 (set_attr_alternative "length"
5239 (match_test "TARGET_SH2A")
5240 (const_int 4) (const_int 2))
5242 (match_test "TARGET_SH2A")
5243 (const_int 4) (const_int 2))
5248 (define_insn "*movqi_media"
5249 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5250 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5252 && (arith_reg_operand (operands[0], QImode)
5253 || extend_reg_or_0_operand (operands[1], QImode))"
5259 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5260 (set (attr "highpart")
5261 (cond [(match_test "sh_contains_memref_p (insn)")
5262 (const_string "user")]
5263 (const_string "ignore")))])
5265 (define_expand "movqi"
5266 [(set (match_operand:QI 0 "general_operand" "")
5267 (match_operand:QI 1 "general_operand" ""))]
5269 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5271 (define_expand "reload_inqi"
5272 [(set (match_operand:SI 2 "" "=&r")
5273 (match_operand:QI 1 "inqhi_operand" ""))
5274 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5275 (truncate:QI (match_dup 3)))]
5279 rtx inner = XEXP (operands[1], 0);
5280 int regno = REGNO (inner);
5282 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5283 operands[1] = gen_rtx_REG (SImode, regno);
5284 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5287 /* When storing r0, we have to avoid reg+reg addressing. */
5288 (define_insn "movhi_i"
5289 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5290 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5292 && (arith_reg_operand (operands[0], HImode)
5293 || arith_reg_operand (operands[1], HImode))
5294 && (!MEM_P (operands[0])
5295 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5296 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5297 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5307 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5309 (define_insn "*movhi_media"
5310 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5311 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5313 && (arith_reg_operand (operands[0], HImode)
5314 || arith_reg_or_0_operand (operands[1], HImode))"
5321 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5322 (set (attr "highpart")
5323 (cond [(match_test "sh_contains_memref_p (insn)")
5324 (const_string "user")]
5325 (const_string "ignore")))])
5328 [(set (match_operand:HI 0 "register_operand" "")
5329 (match_operand:HI 1 "immediate_operand" ""))]
5330 "TARGET_SHMEDIA && reload_completed
5331 && ! satisfies_constraint_I16 (operands[1])"
5332 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5334 (define_expand "movhi"
5335 [(set (match_operand:HI 0 "general_movdst_operand" "")
5336 (match_operand:HI 1 "general_movsrc_operand" ""))]
5338 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5340 (define_expand "reload_inhi"
5341 [(set (match_operand:SI 2 "" "=&r")
5342 (match_operand:HI 1 "inqhi_operand" ""))
5343 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5344 (truncate:HI (match_dup 3)))]
5348 rtx inner = XEXP (operands[1], 0);
5349 int regno = REGNO (inner);
5351 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5352 operands[1] = gen_rtx_REG (SImode, regno);
5353 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5356 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5357 ;; compiled with -m2 -ml -O3 -funroll-loops
5358 (define_insn "*movdi_i"
5359 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5360 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5362 && (arith_reg_operand (operands[0], DImode)
5363 || arith_reg_operand (operands[1], DImode))"
5364 "* return output_movedouble (insn, operands, DImode);"
5365 [(set_attr "length" "4")
5366 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5368 ;; If the output is a register and the input is memory or a register, we have
5369 ;; to be careful and see which word needs to be loaded first.
5372 [(set (match_operand:DI 0 "general_movdst_operand" "")
5373 (match_operand:DI 1 "general_movsrc_operand" ""))]
5374 "TARGET_SH1 && reload_completed"
5375 [(set (match_dup 2) (match_dup 3))
5376 (set (match_dup 4) (match_dup 5))]
5381 if ((MEM_P (operands[0])
5382 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5383 || (MEM_P (operands[1])
5384 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5387 switch (GET_CODE (operands[0]))
5390 regno = REGNO (operands[0]);
5393 regno = subreg_regno (operands[0]);
5403 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5405 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5406 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5407 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5408 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5412 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5413 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5414 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5415 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5418 if (operands[2] == 0 || operands[3] == 0
5419 || operands[4] == 0 || operands[5] == 0)
5423 ;; The '?'s in the following constraints may not reflect the time taken
5424 ;; to perform the move. They are there to discourage the use of floating-
5425 ;; point registers for storing integer values.
5426 (define_insn "*movdi_media"
5427 [(set (match_operand:DI 0 "general_movdst_operand"
5428 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5429 (match_operand:DI 1 "general_movsrc_operand"
5430 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5432 && (register_operand (operands[0], DImode)
5433 || sh_register_operand (operands[1], DImode))"
5448 [(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")
5449 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5451 (define_insn "*movdi_media_nofpu"
5452 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5453 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5455 && (register_operand (operands[0], DImode)
5456 || sh_register_operand (operands[1], DImode))"
5466 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5467 (set_attr "length" "4,4,16,4,4,4,4,*")])
5469 (define_insn "*movdi_media_I16"
5470 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5471 (match_operand:DI 1 "const_int_operand" "I16"))]
5472 "TARGET_SHMEDIA && reload_completed"
5474 [(set_attr "type" "arith_media")
5475 (set_attr "length" "4")])
5478 [(set (match_operand:DI 0 "arith_reg_dest" "")
5479 (match_operand:DI 1 "immediate_operand" ""))]
5480 "TARGET_SHMEDIA && reload_completed
5481 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5482 [(set (match_dup 0) (match_dup 1))]
5487 if (TARGET_SHMEDIA64)
5488 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5490 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5492 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5497 (define_expand "movdi_const"
5498 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5499 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5500 (const_int 48)] UNSPEC_EXTRACT_S16)))
5502 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5503 (const:DI (unspec:DI [(match_dup 1)
5504 (const_int 32)] UNSPEC_EXTRACT_U16))))
5506 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5507 (const:DI (unspec:DI [(match_dup 1)
5508 (const_int 16)] UNSPEC_EXTRACT_U16))))
5510 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5511 (const:DI (unspec:DI [(match_dup 1)
5512 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5513 "TARGET_SHMEDIA64 && reload_completed
5514 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5517 sh_mark_label (operands[1], 4);
5520 (define_expand "movdi_const_32bit"
5521 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5522 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5523 (const_int 16)] UNSPEC_EXTRACT_S16)))
5525 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5526 (const:DI (unspec:DI [(match_dup 1)
5527 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5528 "TARGET_SHMEDIA32 && reload_completed
5529 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5532 sh_mark_label (operands[1], 2);
5535 (define_expand "movdi_const_16bit"
5536 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5537 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5538 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5539 "TARGET_SHMEDIA && flag_pic && reload_completed
5540 && GET_CODE (operands[1]) == SYMBOL_REF"
5544 [(set (match_operand:DI 0 "ext_dest_operand" "")
5545 (match_operand:DI 1 "immediate_operand" ""))]
5546 "TARGET_SHMEDIA && reload_completed
5547 && CONST_INT_P (operands[1])
5548 && ! satisfies_constraint_I16 (operands[1])"
5549 [(set (match_dup 0) (match_dup 2))
5553 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5554 unsigned HOST_WIDE_INT low = val;
5555 unsigned HOST_WIDE_INT high = val;
5556 unsigned HOST_WIDE_INT sign;
5557 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5559 /* Zero-extend the 16 least-significant bits. */
5562 /* Arithmetic shift right the word by 16 bits. */
5564 if (GET_CODE (operands[0]) == SUBREG
5565 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5574 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5580 /* If we can't generate the constant with a two-insn movi / shori
5581 sequence, try some other strategies. */
5582 if (! CONST_OK_FOR_I16 (high))
5584 /* Try constant load / left shift. We know VAL != 0. */
5585 val2 = val ^ (val-1);
5588 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5590 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5591 || (! CONST_OK_FOR_I16 (high >> 16)
5592 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5594 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5595 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5596 GEN_INT (trailing_zeroes));
5600 /* Try constant load / right shift. */
5601 val2 = (val >> 15) + 1;
5602 if (val2 == (val2 & -val2))
5604 int shift = 49 - exact_log2 (val2);
5606 val2 = trunc_int_for_mode (val << shift, DImode);
5607 if (CONST_OK_FOR_I16 (val2))
5609 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5615 val2 = val & 0xffff;
5616 if ((val >> 16 & 0xffff) == val2
5617 && (val >> 32 & 0xffff) == val2
5618 && (val >> 48 & 0xffff) == val2)
5620 val2 = (HOST_WIDE_INT) val >> 48;
5621 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5622 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5625 /* Try movi / mshflo.l */
5626 val2 = (HOST_WIDE_INT) val >> 32;
5627 if (val2 == ((unsigned HOST_WIDE_INT)
5628 trunc_int_for_mode (val, SImode)))
5630 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5634 /* Try movi / mshflo.l w/ r63. */
5635 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5636 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5638 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5644 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5647 operands[2] = GEN_INT (val2);
5651 [(set (match_operand:DI 0 "ext_dest_operand" "")
5652 (match_operand:DI 1 "immediate_operand" ""))]
5653 "TARGET_SHMEDIA && reload_completed
5654 && GET_CODE (operands[1]) == CONST_DOUBLE"
5655 [(set (match_dup 0) (match_dup 2))
5657 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5660 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5661 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5662 unsigned HOST_WIDE_INT val = low;
5663 unsigned HOST_WIDE_INT sign;
5665 /* Zero-extend the 16 least-significant bits. */
5667 operands[1] = GEN_INT (val);
5669 /* Arithmetic shift right the double-word by 16 bits. */
5671 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5674 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5678 /* This will only be true if high is a sign-extension of low, i.e.,
5679 it must be either 0 or (unsigned)-1, and be zero iff the
5680 most-significant bit of low is set. */
5681 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5682 operands[2] = GEN_INT (low);
5684 operands[2] = immed_double_const (low, high, DImode);
5687 (define_insn "shori_media"
5688 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5689 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5691 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5692 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5696 [(set_attr "type" "arith_media,*")])
5698 (define_insn "*shori_media_si"
5699 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5700 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5702 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5706 (define_expand "movdi"
5707 [(set (match_operand:DI 0 "general_movdst_operand" "")
5708 (match_operand:DI 1 "general_movsrc_operand" ""))]
5710 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5712 (define_insn "movdf_media"
5713 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5714 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5716 && (register_operand (operands[0], DFmode)
5717 || sh_register_operand (operands[1], DFmode))"
5728 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5730 (define_insn "movdf_media_nofpu"
5731 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5732 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5734 && (register_operand (operands[0], DFmode)
5735 || sh_register_operand (operands[1], DFmode))"
5741 [(set_attr "type" "arith_media,*,load_media,store_media")])
5744 [(set (match_operand:DF 0 "arith_reg_dest" "")
5745 (match_operand:DF 1 "immediate_operand" ""))]
5746 "TARGET_SHMEDIA && reload_completed"
5747 [(set (match_dup 3) (match_dup 2))]
5750 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5752 REAL_VALUE_TYPE value;
5754 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5755 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5757 if (HOST_BITS_PER_WIDE_INT >= 64)
5758 operands[2] = immed_double_const ((unsigned long) values[endian]
5759 | ((HOST_WIDE_INT) values[1 - endian]
5763 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5764 operands[2] = immed_double_const (values[endian], values[1 - endian],
5768 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5771 ;; ??? This should be a define expand.
5773 (define_insn "movdf_k"
5774 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5775 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5777 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5778 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5779 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5780 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5781 && (arith_reg_operand (operands[0], DFmode)
5782 || arith_reg_operand (operands[1], DFmode))"
5783 "* return output_movedouble (insn, operands, DFmode);"
5784 [(set_attr "length" "4")
5785 (set_attr "type" "move,pcload,load,store")])
5787 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5788 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5789 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5790 ;; the d/m/c/X alternative, which is split later into single-precision
5791 ;; instructions. And when not optimizing, no splits are done before fixing
5792 ;; up pcloads, so we need usable length information for that.
5793 (define_insn "movdf_i4"
5794 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5795 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5796 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5797 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5798 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5799 && (arith_reg_operand (operands[0], DFmode)
5800 || arith_reg_operand (operands[1], DFmode))"
5802 switch (which_alternative)
5806 return "fmov %1,%0";
5807 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5808 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5810 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5813 return "fmov.d %1,%0";
5818 [(set_attr_alternative "length"
5819 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5821 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5822 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5823 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5825 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5826 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5827 ;; increment or decrement r15 explicitly.
5829 (match_test "TARGET_SHCOMPACT")
5830 (const_int 10) (const_int 8))
5832 (match_test "TARGET_SHCOMPACT")
5833 (const_int 10) (const_int 8))])
5834 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5835 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5836 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5837 (const_string "double")
5838 (const_string "none")))])
5840 ;; Moving DFmode between fp/general registers through memory
5841 ;; (the top of the stack) is faster than moving through fpul even for
5842 ;; little endian. Because the type of an instruction is important for its
5843 ;; scheduling, it is beneficial to split these operations, rather than
5844 ;; emitting them in one single chunk, even if this will expose a stack
5845 ;; use that will prevent scheduling of other stack accesses beyond this
5848 [(set (match_operand:DF 0 "register_operand" "")
5849 (match_operand:DF 1 "register_operand" ""))
5850 (use (match_operand:PSI 2 "fpscr_operand" ""))
5851 (clobber (match_scratch:SI 3 "=X"))]
5852 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5853 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5859 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5861 emit_move_insn (stack_pointer_rtx,
5862 plus_constant (stack_pointer_rtx, -8));
5863 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5866 tos = gen_tmp_stack_mem (DFmode,
5867 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5868 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5869 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5870 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5871 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5872 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5874 tos = gen_tmp_stack_mem (DFmode,
5875 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5876 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5877 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5878 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5880 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5884 ;; local-alloc sometimes allocates scratch registers even when not required,
5885 ;; so we must be prepared to handle these.
5887 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5889 [(set (match_operand:DF 0 "general_movdst_operand" "")
5890 (match_operand:DF 1 "general_movsrc_operand" ""))
5891 (use (match_operand:PSI 2 "fpscr_operand" ""))
5892 (clobber (match_scratch:SI 3 ""))]
5893 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5895 && true_regnum (operands[0]) < 16
5896 && true_regnum (operands[1]) < 16"
5897 [(set (match_dup 0) (match_dup 1))]
5900 /* If this was a reg <-> mem operation with base + index reg addressing,
5901 we have to handle this in a special way. */
5902 rtx mem = operands[0];
5904 if (! memory_operand (mem, DFmode))
5909 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5910 mem = SUBREG_REG (mem);
5913 rtx addr = XEXP (mem, 0);
5914 if (GET_CODE (addr) == PLUS
5915 && REG_P (XEXP (addr, 0))
5916 && REG_P (XEXP (addr, 1)))
5919 rtx reg0 = gen_rtx_REG (Pmode, 0);
5920 rtx regop = operands[store_p], word0 ,word1;
5922 if (GET_CODE (regop) == SUBREG)
5923 alter_subreg (®op);
5924 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5928 mem = copy_rtx (mem);
5929 PUT_MODE (mem, SImode);
5930 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5931 alter_subreg (&word0);
5932 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5933 alter_subreg (&word1);
5934 if (store_p || ! refers_to_regno_p (REGNO (word0),
5935 REGNO (word0) + 1, addr, 0))
5938 ? gen_movsi_ie (mem, word0)
5939 : gen_movsi_ie (word0, mem));
5940 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5941 mem = copy_rtx (mem);
5943 ? gen_movsi_ie (mem, word1)
5944 : gen_movsi_ie (word1, mem));
5945 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5949 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5950 emit_insn (gen_movsi_ie (word1, mem));
5951 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5952 mem = copy_rtx (mem);
5953 emit_insn (gen_movsi_ie (word0, mem));
5960 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5962 [(set (match_operand:DF 0 "register_operand" "")
5963 (match_operand:DF 1 "memory_operand" ""))
5964 (use (match_operand:PSI 2 "fpscr_operand" ""))
5965 (clobber (reg:SI R0_REG))]
5966 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5967 [(parallel [(set (match_dup 0) (match_dup 1))
5969 (clobber (scratch:SI))])]
5972 (define_expand "reload_indf__frn"
5973 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5974 (match_operand:DF 1 "immediate_operand" "FQ"))
5975 (use (reg:PSI FPSCR_REG))
5976 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5980 (define_expand "reload_outdf__RnFRm"
5981 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5982 (match_operand:DF 1 "register_operand" "af,r"))
5983 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5987 ;; Simplify no-op moves.
5989 [(set (match_operand:SF 0 "register_operand" "")
5990 (match_operand:SF 1 "register_operand" ""))
5991 (use (match_operand:PSI 2 "fpscr_operand" ""))
5992 (clobber (match_scratch:SI 3 ""))]
5993 "TARGET_SH2E && reload_completed
5994 && true_regnum (operands[0]) == true_regnum (operands[1])"
5995 [(set (match_dup 0) (match_dup 0))]
5998 ;; fmovd substitute post-reload splits
6000 [(set (match_operand:DF 0 "register_operand" "")
6001 (match_operand:DF 1 "register_operand" ""))
6002 (use (match_operand:PSI 2 "fpscr_operand" ""))
6003 (clobber (match_scratch:SI 3 ""))]
6004 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6005 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6006 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6010 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6011 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6012 gen_rtx_REG (SFmode, src), operands[2]));
6013 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6014 gen_rtx_REG (SFmode, src + 1), operands[2]));
6019 [(set (match_operand:DF 0 "register_operand" "")
6020 (mem:DF (match_operand:SI 1 "register_operand" "")))
6021 (use (match_operand:PSI 2 "fpscr_operand" ""))
6022 (clobber (match_scratch:SI 3 ""))]
6023 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6024 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6025 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6029 int regno = true_regnum (operands[0]);
6031 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6033 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6034 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6035 regno + !! TARGET_LITTLE_ENDIAN),
6036 mem2, operands[2]));
6037 add_reg_note (insn, REG_INC, operands[1]);
6038 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6039 regno + ! TARGET_LITTLE_ENDIAN),
6040 change_address (mem, SFmode, NULL_RTX),
6046 [(set (match_operand:DF 0 "register_operand" "")
6047 (match_operand:DF 1 "memory_operand" ""))
6048 (use (match_operand:PSI 2 "fpscr_operand" ""))
6049 (clobber (match_scratch:SI 3 ""))]
6050 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6051 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6054 int regno = true_regnum (operands[0]);
6056 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6057 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6058 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6060 operands[1] = copy_rtx (mem2);
6061 addr = XEXP (mem2, 0);
6063 switch (GET_CODE (addr))
6066 /* This is complicated. If the register is an arithmetic register
6067 we can just fall through to the REG+DISP case below. Otherwise
6068 we have to use a combination of POST_INC and REG addressing... */
6069 if (! arith_reg_operand (operands[1], SFmode))
6071 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6072 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6073 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6075 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6077 /* If we have modified the stack pointer, the value that we have
6078 read with post-increment might be modified by an interrupt,
6079 so write it back. */
6080 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6081 emit_insn (gen_push_e (reg0));
6083 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6089 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6090 operands[1] = copy_rtx (operands[1]);
6091 XEXP (operands[1], 0) = plus_constant (addr, 4);
6092 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6096 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6097 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6099 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6100 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6112 [(set (match_operand:DF 0 "memory_operand" "")
6113 (match_operand:DF 1 "register_operand" ""))
6114 (use (match_operand:PSI 2 "fpscr_operand" ""))
6115 (clobber (match_scratch:SI 3 ""))]
6116 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6117 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6120 int regno = true_regnum (operands[1]);
6122 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6123 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6125 operands[0] = copy_rtx (operands[0]);
6126 PUT_MODE (operands[0], SFmode);
6127 addr = XEXP (operands[0], 0);
6129 switch (GET_CODE (addr))
6132 /* This is complicated. If the register is an arithmetic register
6133 we can just fall through to the REG+DISP case below. Otherwise
6134 we have to use a combination of REG and PRE_DEC addressing... */
6135 if (! arith_reg_operand (operands[0], SFmode))
6137 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6138 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6140 operands[0] = copy_rtx (operands[0]);
6141 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6143 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6144 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6150 /* Since REG+DISP addressing has already been decided upon by gcc
6151 we can rely upon it having chosen an arithmetic register as the
6152 register component of the address. Just emit the lower numbered
6153 register first, to the lower address, then the higher numbered
6154 register to the higher address. */
6155 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6157 operands[0] = copy_rtx (operands[0]);
6158 XEXP (operands[0], 0) = plus_constant (addr, 4);
6160 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6164 /* This is easy. Output the word to go to the higher address
6165 first (ie the word in the higher numbered register) then the
6166 word to go to the lower address. */
6168 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6169 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6171 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6172 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6184 ;; If the output is a register and the input is memory or a register, we have
6185 ;; to be careful and see which word needs to be loaded first.
6188 [(set (match_operand:DF 0 "general_movdst_operand" "")
6189 (match_operand:DF 1 "general_movsrc_operand" ""))]
6190 "TARGET_SH1 && reload_completed"
6191 [(set (match_dup 2) (match_dup 3))
6192 (set (match_dup 4) (match_dup 5))]
6197 if ((MEM_P (operands[0])
6198 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6199 || (MEM_P (operands[1])
6200 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6203 switch (GET_CODE (operands[0]))
6206 regno = REGNO (operands[0]);
6209 regno = subreg_regno (operands[0]);
6219 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6221 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6222 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6223 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6224 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6228 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6229 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6230 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6231 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6234 if (operands[2] == 0 || operands[3] == 0
6235 || operands[4] == 0 || operands[5] == 0)
6239 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6240 ;; used only once, let combine add in the index again.
6243 [(set (match_operand:SI 0 "register_operand" "")
6244 (match_operand:SI 1 "" ""))
6245 (clobber (match_operand 2 "register_operand" ""))]
6246 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6247 && ALLOW_INDEXED_ADDRESS"
6248 [(use (reg:SI R0_REG))]
6251 rtx addr, reg, const_int;
6253 if (!MEM_P (operands[1]))
6255 addr = XEXP (operands[1], 0);
6256 if (GET_CODE (addr) != PLUS)
6258 reg = XEXP (addr, 0);
6259 const_int = XEXP (addr, 1);
6260 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6261 && CONST_INT_P (const_int)))
6263 emit_move_insn (operands[2], const_int);
6264 emit_move_insn (operands[0],
6265 change_address (operands[1], VOIDmode,
6266 gen_rtx_PLUS (SImode, reg, operands[2])));
6271 [(set (match_operand:SI 1 "" "")
6272 (match_operand:SI 0 "register_operand" ""))
6273 (clobber (match_operand 2 "register_operand" ""))]
6274 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6275 && ALLOW_INDEXED_ADDRESS"
6276 [(use (reg:SI R0_REG))]
6279 rtx addr, reg, const_int;
6281 if (!MEM_P (operands[1]))
6283 addr = XEXP (operands[1], 0);
6284 if (GET_CODE (addr) != PLUS)
6286 reg = XEXP (addr, 0);
6287 const_int = XEXP (addr, 1);
6288 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6289 && CONST_INT_P (const_int)))
6291 emit_move_insn (operands[2], const_int);
6292 emit_move_insn (change_address (operands[1], VOIDmode,
6293 gen_rtx_PLUS (SImode, reg, operands[2])),
6298 (define_expand "movdf"
6299 [(set (match_operand:DF 0 "general_movdst_operand" "")
6300 (match_operand:DF 1 "general_movsrc_operand" ""))]
6304 if (prepare_move_operands (operands, DFmode)) DONE;
6307 if (TARGET_SHMEDIA_FPU)
6308 emit_insn (gen_movdf_media (operands[0], operands[1]));
6310 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6313 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6315 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6320 ;;This is incompatible with the way gcc uses subregs.
6321 ;;(define_insn "movv2sf_i"
6322 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6323 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6324 ;; "TARGET_SHMEDIA_FPU
6325 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6326 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6330 ;; fst%M0.p %m0, %1"
6331 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6333 (define_insn_and_split "movv2sf_i"
6334 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6335 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6336 "TARGET_SHMEDIA_FPU"
6338 "TARGET_SHMEDIA_FPU && reload_completed"
6339 [(set (match_dup 0) (match_dup 1))]
6342 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6343 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6346 (define_expand "movv2sf"
6347 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6348 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6349 "TARGET_SHMEDIA_FPU"
6352 if (prepare_move_operands (operands, V2SFmode))
6356 (define_expand "addv2sf3"
6357 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6358 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6359 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6360 "TARGET_SHMEDIA_FPU"
6363 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6367 (define_expand "subv2sf3"
6368 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6369 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6370 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6371 "TARGET_SHMEDIA_FPU"
6374 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6378 (define_expand "mulv2sf3"
6379 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6380 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6381 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6382 "TARGET_SHMEDIA_FPU"
6385 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6389 (define_expand "divv2sf3"
6390 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6391 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6392 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6393 "TARGET_SHMEDIA_FPU"
6396 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6400 (define_insn_and_split "*movv4sf_i"
6401 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6402 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6403 "TARGET_SHMEDIA_FPU"
6405 "&& reload_completed"
6411 for (i = 0; i < 4/2; i++)
6415 if (MEM_P (operands[0]))
6416 x = adjust_address (operands[0], V2SFmode,
6417 i * GET_MODE_SIZE (V2SFmode));
6419 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6421 if (MEM_P (operands[1]))
6422 y = adjust_address (operands[1], V2SFmode,
6423 i * GET_MODE_SIZE (V2SFmode));
6425 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6427 emit_insn (gen_movv2sf_i (x, y));
6432 [(set_attr "length" "8")])
6434 (define_expand "movv4sf"
6435 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6436 (match_operand:V4SF 1 "general_operand" ""))]
6437 "TARGET_SHMEDIA_FPU"
6440 if (prepare_move_operands (operands, V4SFmode))
6444 (define_insn_and_split "*movv16sf_i"
6445 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6446 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6447 "TARGET_SHMEDIA_FPU"
6449 "&& reload_completed"
6455 for (i = 0; i < 16/2; i++)
6459 if (MEM_P (operands[0]))
6460 x = adjust_address (operands[0], V2SFmode,
6461 i * GET_MODE_SIZE (V2SFmode));
6464 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6468 if (MEM_P (operands[1]))
6469 y = adjust_address (operands[1], V2SFmode,
6470 i * GET_MODE_SIZE (V2SFmode));
6473 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6477 emit_insn (gen_movv2sf_i (x, y));
6482 [(set_attr "length" "32")])
6484 (define_expand "movv16sf"
6485 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6486 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6487 "TARGET_SHMEDIA_FPU"
6490 if (prepare_move_operands (operands, V16SFmode))
6494 (define_insn "movsf_media"
6495 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6496 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6498 && (register_operand (operands[0], SFmode)
6499 || sh_register_operand (operands[1], SFmode))"
6510 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6511 (set (attr "highpart")
6512 (cond [(match_test "sh_contains_memref_p (insn)")
6513 (const_string "user")]
6514 (const_string "ignore")))])
6516 (define_insn "movsf_media_nofpu"
6517 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6518 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6520 && (register_operand (operands[0], SFmode)
6521 || sh_register_operand (operands[1], SFmode))"
6527 [(set_attr "type" "arith_media,*,load_media,store_media")
6528 (set (attr "highpart")
6529 (cond [(match_test "sh_contains_memref_p (insn)")
6530 (const_string "user")]
6531 (const_string "ignore")))])
6534 [(set (match_operand:SF 0 "arith_reg_dest" "")
6535 (match_operand:SF 1 "immediate_operand" ""))]
6536 "TARGET_SHMEDIA && reload_completed
6537 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6538 [(set (match_dup 3) (match_dup 2))]
6542 REAL_VALUE_TYPE value;
6544 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6545 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6546 operands[2] = GEN_INT (values);
6548 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6551 (define_insn "movsf_i"
6552 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6553 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6556 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6557 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6558 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6559 && (arith_reg_operand (operands[0], SFmode)
6560 || arith_reg_operand (operands[1], SFmode))"
6569 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6571 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6572 ;; update_flow_info would not know where to put REG_EQUAL notes
6573 ;; when the destination changes mode.
6574 (define_insn "movsf_ie"
6575 [(set (match_operand:SF 0 "general_movdst_operand"
6576 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6577 (match_operand:SF 1 "general_movsrc_operand"
6578 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6579 (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"))
6580 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6583 && (arith_reg_operand (operands[0], SFmode)
6584 || arith_reg_operand (operands[1], SFmode)
6585 || arith_reg_operand (operands[3], SImode)
6586 || (fpul_operand (operands[0], SFmode)
6587 && memory_operand (operands[1], SFmode)
6588 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6589 || (fpul_operand (operands[1], SFmode)
6590 && memory_operand (operands[0], SFmode)
6591 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6611 ! move optimized away"
6612 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6613 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6614 (set_attr_alternative "length"
6621 (match_test "TARGET_SH2A")
6622 (const_int 4) (const_int 2))
6624 (match_test "TARGET_SH2A")
6625 (const_int 4) (const_int 2))
6628 (match_test "TARGET_SH2A")
6629 (const_int 4) (const_int 2))
6631 (match_test "TARGET_SH2A")
6632 (const_int 4) (const_int 2))
6642 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6643 (const_string "single")
6644 (const_string "single")))])
6647 [(set (match_operand:SF 0 "register_operand" "")
6648 (match_operand:SF 1 "register_operand" ""))
6649 (use (match_operand:PSI 2 "fpscr_operand" ""))
6650 (clobber (reg:SI FPUL_REG))]
6652 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6654 (clobber (scratch:SI))])
6655 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6657 (clobber (scratch:SI))])]
6660 (define_expand "movsf"
6661 [(set (match_operand:SF 0 "general_movdst_operand" "")
6662 (match_operand:SF 1 "general_movsrc_operand" ""))]
6666 if (prepare_move_operands (operands, SFmode))
6670 if (TARGET_SHMEDIA_FPU)
6671 emit_insn (gen_movsf_media (operands[0], operands[1]));
6673 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6678 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6683 (define_insn "mov_nop"
6684 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6687 [(set_attr "length" "0")
6688 (set_attr "type" "nil")])
6690 (define_expand "reload_insf__frn"
6691 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6692 (match_operand:SF 1 "immediate_operand" "FQ"))
6693 (use (reg:PSI FPSCR_REG))
6694 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6698 (define_expand "reload_insi__i_fpul"
6699 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6700 (match_operand:SI 1 "immediate_operand" "i"))
6701 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6705 (define_expand "ptabs"
6706 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6710 if (!TARGET_PT_FIXED)
6712 rtx eq = operands[1];
6714 /* ??? For canonical RTL we really should remove any CONST from EQ
6715 before wrapping it in the AND, and finally wrap the EQ into a
6716 const if is constant. However, for reload we must expose the
6717 input register or symbolic constant, and we can't have
6718 different insn structures outside of the operands for different
6719 alternatives of the same pattern. */
6720 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6723 = (gen_rtx_IF_THEN_ELSE
6726 gen_rtx_MEM (PDImode, operands[1]),
6727 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6728 PDImode, operands[1])));
6732 ;; expanded by ptabs expander.
6733 (define_insn "*extendsipdi_media"
6734 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6735 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6739 (mem:PDI (match_dup 1))
6740 (sign_extend:PDI (match_dup 1))))]
6741 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6745 [(set_attr "type" "ptabs_media,pt_media")
6746 (set_attr "length" "4,*")])
6748 (define_insn "*truncdipdi_media"
6749 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6750 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6754 (mem:PDI (match_dup 1))
6755 (truncate:PDI (match_dup 1))))]
6756 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6760 [(set_attr "type" "ptabs_media,pt_media")
6761 (set_attr "length" "4,*")])
6763 (define_insn "*movsi_y"
6764 [(set (match_operand:SI 0 "register_operand" "=y,y")
6765 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6766 (clobber (match_scratch:SI 2 "=&z,r"))]
6768 && (reload_in_progress || reload_completed)"
6770 [(set_attr "length" "4")
6771 (set_attr "type" "pcload,move")])
6774 [(set (match_operand:SI 0 "register_operand" "")
6775 (match_operand:SI 1 "immediate_operand" ""))
6776 (clobber (match_operand:SI 2 "register_operand" ""))]
6778 [(set (match_dup 2) (match_dup 1))
6779 (set (match_dup 0) (match_dup 2))]
6783 [(set (match_operand:SI 0 "register_operand" "")
6784 (match_operand:SI 1 "memory_operand" ""))
6785 (clobber (reg:SI R0_REG))]
6787 [(set (match_dup 0) (match_dup 1))]
6790 ;; ------------------------------------------------------------------------
6791 ;; Define the real conditional branch instructions.
6792 ;; ------------------------------------------------------------------------
6794 (define_insn "branch_true"
6795 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6796 (label_ref (match_operand 0 "" ""))
6799 "* return output_branch (1, insn, operands);"
6800 [(set_attr "type" "cbranch")])
6802 (define_insn "branch_false"
6803 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6804 (label_ref (match_operand 0 "" ""))
6807 "* return output_branch (0, insn, operands);"
6808 [(set_attr "type" "cbranch")])
6810 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6811 ;; which destination is too far away.
6812 ;; The const_int_operand is distinct for each branch target; it avoids
6813 ;; unwanted matches with redundant_insn.
6814 (define_insn "block_branch_redirect"
6815 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6818 [(set_attr "length" "0")])
6820 ;; This one has the additional purpose to record a possible scratch register
6821 ;; for the following branch.
6822 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6823 ;; because the insn then might be deemed dead and deleted. And we can't
6824 ;; make the use in the jump insn explicit because that would disable
6825 ;; delay slot scheduling from the target.
6826 (define_insn "indirect_jump_scratch"
6827 [(set (match_operand:SI 0 "register_operand" "=r")
6828 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6829 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6832 [(set_attr "length" "0")])
6834 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6835 ;; being pulled into the delay slot of a condbranch that has been made to
6836 ;; jump around the unconditional jump because it was out of range.
6837 (define_insn "stuff_delay_slot"
6839 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6840 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6843 [(set_attr "length" "0")
6844 (set_attr "cond_delay_slot" "yes")])
6846 ;; Conditional branch insns
6848 (define_expand "cbranchint4_media"
6850 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6851 [(match_operand 1 "" "")
6852 (match_operand 2 "" "")])
6853 (match_operand 3 "" "")
6858 enum machine_mode mode = GET_MODE (operands[1]);
6859 if (mode == VOIDmode)
6860 mode = GET_MODE (operands[2]);
6861 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6863 operands[1] = force_reg (mode, operands[1]);
6864 if (CONSTANT_P (operands[2])
6865 && (! satisfies_constraint_I06 (operands[2])))
6866 operands[2] = force_reg (mode, operands[2]);
6870 if (operands[1] != const0_rtx)
6871 operands[1] = force_reg (mode, operands[1]);
6872 if (operands[2] != const0_rtx)
6873 operands[2] = force_reg (mode, operands[2]);
6875 switch (GET_CODE (operands[0]))
6881 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6882 VOIDmode, operands[2], operands[1]);
6883 operands[1] = XEXP (operands[0], 0);
6884 operands[2] = XEXP (operands[0], 1);
6887 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6888 VOIDmode, operands[1], operands[2]);
6891 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6894 (define_expand "cbranchfp4_media"
6896 (if_then_else (match_operator 0 "sh_float_comparison_operator"
6897 [(match_operand 1 "" "")
6898 (match_operand 2 "" "")])
6899 (match_operand 3 "" "")
6904 rtx tmp = gen_reg_rtx (SImode);
6906 if (GET_CODE (operands[0]) == NE)
6907 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6909 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6910 operands[1], operands[2]);
6912 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6914 if (GET_CODE (cmp) == GET_CODE (operands[0]))
6915 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6917 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6919 operands[2] = const0_rtx;
6920 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6923 (define_insn "*beq_media_i"
6925 (if_then_else (match_operator 3 "equality_comparison_operator"
6926 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6927 (match_operand:DI 2 "arith_operand" "r,I06")])
6928 (match_operand 0 "target_operand" "b,b")
6933 b%o3i%' %1, %2, %0%>"
6934 [(set_attr "type" "cbranch_media")])
6936 (define_insn "*beq_media_i32"
6938 (if_then_else (match_operator 3 "equality_comparison_operator"
6939 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6940 (match_operand:SI 2 "arith_operand" "r,I06")])
6941 (match_operand 0 "target_operand" "b,b")
6946 b%o3i%' %1, %2, %0%>"
6947 [(set_attr "type" "cbranch_media")])
6949 (define_insn "*bgt_media_i"
6951 (if_then_else (match_operator 3 "greater_comparison_operator"
6952 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6953 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6954 (match_operand 0 "target_operand" "b")
6957 "b%o3%' %N1, %N2, %0%>"
6958 [(set_attr "type" "cbranch_media")])
6960 (define_insn "*bgt_media_i32"
6962 (if_then_else (match_operator 3 "greater_comparison_operator"
6963 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6964 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6965 (match_operand 0 "target_operand" "b")
6968 "b%o3%' %N1, %N2, %0%>"
6969 [(set_attr "type" "cbranch_media")])
6971 ;; These are only needed to make invert_jump() happy - otherwise, jump
6972 ;; optimization will be silently disabled.
6973 (define_insn "*blt_media_i"
6975 (if_then_else (match_operator 3 "less_comparison_operator"
6976 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6977 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6978 (match_operand 0 "target_operand" "b")
6981 "b%o3%' %N2, %N1, %0%>"
6982 [(set_attr "type" "cbranch_media")])
6984 (define_insn "*blt_media_i32"
6986 (if_then_else (match_operator 3 "less_comparison_operator"
6987 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6988 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6989 (match_operand 0 "target_operand" "b")
6992 "b%o3%' %N2, %N1, %0%>"
6993 [(set_attr "type" "cbranch_media")])
6995 ;; combiner splitter for test-and-branch on single bit in register. This
6996 ;; is endian dependent because the non-paradoxical subreg looks different
7001 (match_operator 3 "equality_comparison_operator"
7002 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7003 "extend_reg_operand" "")
7007 "const_int_operand" "")) 0)
7009 (match_operand 0 "target_operand" "")
7011 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7012 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7013 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7014 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7018 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7019 operands[6] = (GET_CODE (operands[3]) == EQ
7020 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7021 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7024 ; operand 0 is the loop count pseudo register
7025 ; operand 1 is the number of loop iterations or 0 if it is unknown
7026 ; operand 2 is the maximum number of loop iterations
7027 ; operand 3 is the number of levels of enclosed loops
7028 ; operand 4 is the label to jump to at the top of the loop
7030 (define_expand "doloop_end"
7031 [(parallel [(set (pc) (if_then_else
7032 (ne:SI (match_operand:SI 0 "" "")
7034 (label_ref (match_operand 4 "" ""))
7037 (plus:SI (match_dup 0) (const_int -1)))
7038 (clobber (reg:SI T_REG))])]
7042 if (GET_MODE (operands[0]) != SImode)
7047 (define_insn_and_split "doloop_end_split"
7049 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7051 (label_ref (match_operand 1 "" ""))
7053 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7054 (plus (match_dup 2) (const_int -1)))
7055 (clobber (reg:SI T_REG))]
7059 [(parallel [(set (reg:SI T_REG)
7060 (eq:SI (match_dup 2) (const_int 1)))
7061 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7062 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7063 (label_ref (match_dup 1))
7066 [(set_attr "type" "cbranch")])
7069 ;; ------------------------------------------------------------------------
7070 ;; Jump and linkage insns
7071 ;; ------------------------------------------------------------------------
7073 (define_insn "jump_compact"
7075 (label_ref (match_operand 0 "" "")))]
7076 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7079 /* The length is 16 if the delay slot is unfilled. */
7080 if (get_attr_length(insn) > 4)
7081 return output_far_jump(insn, operands[0]);
7083 return \"bra %l0%#\";
7085 [(set_attr "type" "jump")
7086 (set_attr "needs_delay_slot" "yes")])
7088 ;; ??? It would be much saner to explicitly use the scratch register
7089 ;; in the jump insn, and have indirect_jump_scratch only set it,
7090 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7091 ;; from the target then, as it uses simplejump_p.
7092 ;;(define_insn "jump_compact_far"
7094 ;; (label_ref (match_operand 0 "" "")))
7095 ;; (use (match_operand 1 "register_operand" "r")]
7097 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7098 ;; [(set_attr "type" "jump")
7099 ;; (set_attr "needs_delay_slot" "yes")])
7101 (define_insn "jump_media"
7103 (match_operand 0 "target_operand" "b"))]
7106 [(set_attr "type" "jump_media")])
7108 (define_expand "jump"
7110 (label_ref (match_operand 0 "" "")))]
7115 emit_jump_insn (gen_jump_compact (operands[0]));
7116 else if (TARGET_SHMEDIA)
7118 if (reload_in_progress || reload_completed)
7120 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7126 (define_insn "force_mode_for_call"
7127 [(use (reg:PSI FPSCR_REG))]
7130 [(set_attr "length" "0")
7131 (set (attr "fp_mode")
7132 (if_then_else (eq_attr "fpu_single" "yes")
7133 (const_string "single") (const_string "double")))])
7135 (define_insn "calli"
7136 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7137 (match_operand 1 "" ""))
7138 (use (reg:PSI FPSCR_REG))
7139 (clobber (reg:SI PR_REG))]
7143 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7144 return \"jsr/n\\t@%0\";
7146 return \"jsr\\t@%0%#\";
7149 [(set_attr "type" "call")
7150 (set (attr "fp_mode")
7151 (if_then_else (eq_attr "fpu_single" "yes")
7152 (const_string "single") (const_string "double")))
7153 (set_attr "needs_delay_slot" "yes")
7154 (set_attr "fp_set" "unknown")])
7156 ;; This is TBR relative jump instruction for SH2A architecture.
7157 ;; Its use is enabled assigning an attribute "function_vector"
7158 ;; and the vector number to a function during its declaration.
7160 (define_insn "calli_tbr_rel"
7161 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7162 (match_operand 1 "" ""))
7163 (use (reg:PSI FPSCR_REG))
7164 (clobber (reg:SI PR_REG))]
7165 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7168 unsigned HOST_WIDE_INT vect_num;
7169 vect_num = sh2a_get_function_vector_number (operands[0]);
7170 operands[2] = GEN_INT (vect_num * 4);
7172 return \"jsr/n\\t@@(%O2,tbr)\";
7174 [(set_attr "type" "call")
7175 (set (attr "fp_mode")
7176 (if_then_else (eq_attr "fpu_single" "yes")
7177 (const_string "single") (const_string "double")))
7178 (set_attr "needs_delay_slot" "no")
7179 (set_attr "fp_set" "unknown")])
7181 ;; This is a pc-rel call, using bsrf, for use with PIC.
7183 (define_insn "calli_pcrel"
7184 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7185 (match_operand 1 "" ""))
7186 (use (reg:PSI FPSCR_REG))
7187 (use (reg:SI PIC_REG))
7188 (use (match_operand 2 "" ""))
7189 (clobber (reg:SI PR_REG))]
7192 [(set_attr "type" "call")
7193 (set (attr "fp_mode")
7194 (if_then_else (eq_attr "fpu_single" "yes")
7195 (const_string "single") (const_string "double")))
7196 (set_attr "needs_delay_slot" "yes")
7197 (set_attr "fp_set" "unknown")])
7199 (define_insn_and_split "call_pcrel"
7200 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7201 (match_operand 1 "" ""))
7202 (use (reg:PSI FPSCR_REG))
7203 (use (reg:SI PIC_REG))
7204 (clobber (reg:SI PR_REG))
7205 (clobber (match_scratch:SI 2 "=r"))]
7212 rtx lab = PATTERN (gen_call_site ());
7214 if (SYMBOL_REF_LOCAL_P (operands[0]))
7215 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7217 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7218 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7221 [(set_attr "type" "call")
7222 (set (attr "fp_mode")
7223 (if_then_else (eq_attr "fpu_single" "yes")
7224 (const_string "single") (const_string "double")))
7225 (set_attr "needs_delay_slot" "yes")
7226 (set_attr "fp_set" "unknown")])
7228 (define_insn "call_compact"
7229 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7230 (match_operand 1 "" ""))
7231 (match_operand 2 "immediate_operand" "n")
7232 (use (reg:SI R0_REG))
7233 (use (reg:SI R1_REG))
7234 (use (reg:PSI FPSCR_REG))
7235 (clobber (reg:SI PR_REG))]
7236 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7238 [(set_attr "type" "call")
7239 (set (attr "fp_mode")
7240 (if_then_else (eq_attr "fpu_single" "yes")
7241 (const_string "single") (const_string "double")))
7242 (set_attr "needs_delay_slot" "yes")])
7244 (define_insn "call_compact_rettramp"
7245 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7246 (match_operand 1 "" ""))
7247 (match_operand 2 "immediate_operand" "n")
7248 (use (reg:SI R0_REG))
7249 (use (reg:SI R1_REG))
7250 (use (reg:PSI FPSCR_REG))
7251 (clobber (reg:SI R10_REG))
7252 (clobber (reg:SI PR_REG))]
7253 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7255 [(set_attr "type" "call")
7256 (set (attr "fp_mode")
7257 (if_then_else (eq_attr "fpu_single" "yes")
7258 (const_string "single") (const_string "double")))
7259 (set_attr "needs_delay_slot" "yes")])
7261 (define_insn "call_media"
7262 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7263 (match_operand 1 "" ""))
7264 (clobber (reg:DI PR_MEDIA_REG))]
7267 [(set_attr "type" "jump_media")])
7269 (define_insn "call_valuei"
7270 [(set (match_operand 0 "" "=rf")
7271 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7272 (match_operand 2 "" "")))
7273 (use (reg:PSI FPSCR_REG))
7274 (clobber (reg:SI PR_REG))]
7278 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7279 return \"jsr/n\\t@%1\";
7281 return \"jsr\\t@%1%#\";
7283 [(set_attr "type" "call")
7284 (set (attr "fp_mode")
7285 (if_then_else (eq_attr "fpu_single" "yes")
7286 (const_string "single") (const_string "double")))
7287 (set_attr "needs_delay_slot" "yes")
7288 (set_attr "fp_set" "unknown")])
7290 ;; This is TBR relative jump instruction for SH2A architecture.
7291 ;; Its use is enabled assigning an attribute "function_vector"
7292 ;; and the vector number to a function during its declaration.
7294 (define_insn "call_valuei_tbr_rel"
7295 [(set (match_operand 0 "" "=rf")
7296 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7297 (match_operand 2 "" "")))
7298 (use (reg:PSI FPSCR_REG))
7299 (clobber (reg:SI PR_REG))]
7300 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7303 unsigned HOST_WIDE_INT vect_num;
7304 vect_num = sh2a_get_function_vector_number (operands[1]);
7305 operands[3] = GEN_INT (vect_num * 4);
7307 return \"jsr/n\\t@@(%O3,tbr)\";
7309 [(set_attr "type" "call")
7310 (set (attr "fp_mode")
7311 (if_then_else (eq_attr "fpu_single" "yes")
7312 (const_string "single") (const_string "double")))
7313 (set_attr "needs_delay_slot" "no")
7314 (set_attr "fp_set" "unknown")])
7316 (define_insn "call_valuei_pcrel"
7317 [(set (match_operand 0 "" "=rf")
7318 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7319 (match_operand 2 "" "")))
7320 (use (reg:PSI FPSCR_REG))
7321 (use (reg:SI PIC_REG))
7322 (use (match_operand 3 "" ""))
7323 (clobber (reg:SI PR_REG))]
7326 [(set_attr "type" "call")
7327 (set (attr "fp_mode")
7328 (if_then_else (eq_attr "fpu_single" "yes")
7329 (const_string "single") (const_string "double")))
7330 (set_attr "needs_delay_slot" "yes")
7331 (set_attr "fp_set" "unknown")])
7333 (define_insn_and_split "call_value_pcrel"
7334 [(set (match_operand 0 "" "=rf")
7335 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7336 (match_operand 2 "" "")))
7337 (use (reg:PSI FPSCR_REG))
7338 (use (reg:SI PIC_REG))
7339 (clobber (reg:SI PR_REG))
7340 (clobber (match_scratch:SI 3 "=r"))]
7347 rtx lab = PATTERN (gen_call_site ());
7349 if (SYMBOL_REF_LOCAL_P (operands[1]))
7350 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7352 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7353 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7354 operands[2], copy_rtx (lab)));
7357 [(set_attr "type" "call")
7358 (set (attr "fp_mode")
7359 (if_then_else (eq_attr "fpu_single" "yes")
7360 (const_string "single") (const_string "double")))
7361 (set_attr "needs_delay_slot" "yes")
7362 (set_attr "fp_set" "unknown")])
7364 (define_insn "call_value_compact"
7365 [(set (match_operand 0 "" "=rf")
7366 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7367 (match_operand 2 "" "")))
7368 (match_operand 3 "immediate_operand" "n")
7369 (use (reg:SI R0_REG))
7370 (use (reg:SI R1_REG))
7371 (use (reg:PSI FPSCR_REG))
7372 (clobber (reg:SI PR_REG))]
7373 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7375 [(set_attr "type" "call")
7376 (set (attr "fp_mode")
7377 (if_then_else (eq_attr "fpu_single" "yes")
7378 (const_string "single") (const_string "double")))
7379 (set_attr "needs_delay_slot" "yes")])
7381 (define_insn "call_value_compact_rettramp"
7382 [(set (match_operand 0 "" "=rf")
7383 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7384 (match_operand 2 "" "")))
7385 (match_operand 3 "immediate_operand" "n")
7386 (use (reg:SI R0_REG))
7387 (use (reg:SI R1_REG))
7388 (use (reg:PSI FPSCR_REG))
7389 (clobber (reg:SI R10_REG))
7390 (clobber (reg:SI PR_REG))]
7391 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7393 [(set_attr "type" "call")
7394 (set (attr "fp_mode")
7395 (if_then_else (eq_attr "fpu_single" "yes")
7396 (const_string "single") (const_string "double")))
7397 (set_attr "needs_delay_slot" "yes")])
7399 (define_insn "call_value_media"
7400 [(set (match_operand 0 "" "=rf")
7401 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7402 (match_operand 2 "" "")))
7403 (clobber (reg:DI PR_MEDIA_REG))]
7406 [(set_attr "type" "jump_media")])
7408 (define_expand "call"
7409 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7410 (match_operand 1 "" ""))
7411 (match_operand 2 "" "")
7412 (use (reg:PSI FPSCR_REG))
7413 (clobber (reg:SI PR_REG))])]
7419 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7420 emit_call_insn (gen_call_media (operands[0], operands[1]));
7423 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7425 rtx cookie_rtx = operands[2];
7426 long cookie = INTVAL (cookie_rtx);
7427 rtx func = XEXP (operands[0], 0);
7432 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7434 rtx reg = gen_reg_rtx (Pmode);
7436 emit_insn (gen_symGOTPLT2reg (reg, func));
7440 func = legitimize_pic_address (func, Pmode, 0);
7443 r0 = gen_rtx_REG (SImode, R0_REG);
7444 r1 = gen_rtx_REG (SImode, R1_REG);
7446 /* Since such a call function may use all call-clobbered
7447 registers, we force a mode switch earlier, so that we don't
7448 run out of registers when adjusting fpscr for the call. */
7449 emit_insn (gen_force_mode_for_call ());
7452 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7454 operands[0] = force_reg (SImode, operands[0]);
7456 emit_move_insn (r0, func);
7457 emit_move_insn (r1, cookie_rtx);
7459 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7460 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7463 emit_call_insn (gen_call_compact (operands[0], operands[1],
7468 else if (TARGET_SHCOMPACT && flag_pic
7469 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7470 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7472 rtx reg = gen_reg_rtx (Pmode);
7474 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7475 XEXP (operands[0], 0) = reg;
7477 if (!flag_pic && TARGET_SH2A
7478 && MEM_P (operands[0])
7479 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7481 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7483 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7488 if (flag_pic && TARGET_SH2
7489 && MEM_P (operands[0])
7490 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7492 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7497 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7498 operands[1] = operands[2];
7501 emit_call_insn (gen_calli (operands[0], operands[1]));
7505 (define_insn "call_pop_compact"
7506 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7507 (match_operand 1 "" ""))
7508 (match_operand 2 "immediate_operand" "n")
7509 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7510 (match_operand 3 "immediate_operand" "n")))
7511 (use (reg:SI R0_REG))
7512 (use (reg:SI R1_REG))
7513 (use (reg:PSI FPSCR_REG))
7514 (clobber (reg:SI PR_REG))]
7515 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7517 [(set_attr "type" "call")
7518 (set (attr "fp_mode")
7519 (if_then_else (eq_attr "fpu_single" "yes")
7520 (const_string "single") (const_string "double")))
7521 (set_attr "needs_delay_slot" "yes")])
7523 (define_insn "call_pop_compact_rettramp"
7524 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7525 (match_operand 1 "" ""))
7526 (match_operand 2 "immediate_operand" "n")
7527 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7528 (match_operand 3 "immediate_operand" "n")))
7529 (use (reg:SI R0_REG))
7530 (use (reg:SI R1_REG))
7531 (use (reg:PSI FPSCR_REG))
7532 (clobber (reg:SI R10_REG))
7533 (clobber (reg:SI PR_REG))]
7534 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7536 [(set_attr "type" "call")
7537 (set (attr "fp_mode")
7538 (if_then_else (eq_attr "fpu_single" "yes")
7539 (const_string "single") (const_string "double")))
7540 (set_attr "needs_delay_slot" "yes")])
7542 (define_expand "call_pop"
7543 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7544 (match_operand 1 "" ""))
7545 (match_operand 2 "" "")
7546 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7547 (match_operand 3 "" "")))])]
7556 gcc_assert (operands[2] && INTVAL (operands[2]));
7557 cookie_rtx = operands[2];
7558 cookie = INTVAL (cookie_rtx);
7559 func = XEXP (operands[0], 0);
7563 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7565 rtx reg = gen_reg_rtx (Pmode);
7566 emit_insn (gen_symGOTPLT2reg (reg, func));
7570 func = legitimize_pic_address (func, Pmode, 0);
7573 r0 = gen_rtx_REG (SImode, R0_REG);
7574 r1 = gen_rtx_REG (SImode, R1_REG);
7576 /* Since such a call function may use all call-clobbered
7577 registers, we force a mode switch earlier, so that we don't
7578 run out of registers when adjusting fpscr for the call. */
7579 emit_insn (gen_force_mode_for_call ());
7581 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7583 operands[0] = force_reg (SImode, operands[0]);
7585 emit_move_insn (r0, func);
7586 emit_move_insn (r1, cookie_rtx);
7588 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7589 emit_call_insn (gen_call_pop_compact_rettramp
7590 (operands[0], operands[1], operands[2], operands[3]));
7592 emit_call_insn (gen_call_pop_compact
7593 (operands[0], operands[1], operands[2], operands[3]));
7598 (define_expand "call_value"
7599 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7600 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7601 (match_operand 2 "" "")))
7602 (match_operand 3 "" "")
7603 (use (reg:PSI FPSCR_REG))
7604 (clobber (reg:SI PR_REG))])]
7610 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7611 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7615 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7617 rtx cookie_rtx = operands[3];
7618 long cookie = INTVAL (cookie_rtx);
7619 rtx func = XEXP (operands[1], 0);
7624 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7626 rtx reg = gen_reg_rtx (Pmode);
7628 emit_insn (gen_symGOTPLT2reg (reg, func));
7632 func = legitimize_pic_address (func, Pmode, 0);
7635 r0 = gen_rtx_REG (SImode, R0_REG);
7636 r1 = gen_rtx_REG (SImode, R1_REG);
7638 /* Since such a call function may use all call-clobbered
7639 registers, we force a mode switch earlier, so that we don't
7640 run out of registers when adjusting fpscr for the call. */
7641 emit_insn (gen_force_mode_for_call ());
7644 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7646 operands[1] = force_reg (SImode, operands[1]);
7648 emit_move_insn (r0, func);
7649 emit_move_insn (r1, cookie_rtx);
7651 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7652 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7657 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7658 operands[2], operands[3]));
7662 else if (TARGET_SHCOMPACT && flag_pic
7663 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7664 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7666 rtx reg = gen_reg_rtx (Pmode);
7668 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7669 XEXP (operands[1], 0) = reg;
7671 if (!flag_pic && TARGET_SH2A
7672 && MEM_P (operands[1])
7673 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7675 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7677 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7678 XEXP (operands[1], 0), operands[2]));
7682 if (flag_pic && TARGET_SH2
7683 && MEM_P (operands[1])
7684 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7686 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7691 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7693 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7697 (define_insn "sibcalli"
7698 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7699 (match_operand 1 "" ""))
7700 (use (reg:PSI FPSCR_REG))
7704 [(set_attr "needs_delay_slot" "yes")
7705 (set (attr "fp_mode")
7706 (if_then_else (eq_attr "fpu_single" "yes")
7707 (const_string "single") (const_string "double")))
7708 (set_attr "type" "jump_ind")])
7710 (define_insn "sibcalli_pcrel"
7711 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7712 (match_operand 1 "" ""))
7713 (use (match_operand 2 "" ""))
7714 (use (reg:PSI FPSCR_REG))
7718 [(set_attr "needs_delay_slot" "yes")
7719 (set (attr "fp_mode")
7720 (if_then_else (eq_attr "fpu_single" "yes")
7721 (const_string "single") (const_string "double")))
7722 (set_attr "type" "jump_ind")])
7724 ;; This uses an unspec to describe that the symbol_ref is very close.
7725 (define_insn "sibcalli_thunk"
7726 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7728 (match_operand 1 "" ""))
7729 (use (reg:PSI FPSCR_REG))
7733 [(set_attr "needs_delay_slot" "yes")
7734 (set (attr "fp_mode")
7735 (if_then_else (eq_attr "fpu_single" "yes")
7736 (const_string "single") (const_string "double")))
7737 (set_attr "type" "jump")
7738 (set_attr "length" "2")])
7740 (define_insn_and_split "sibcall_pcrel"
7741 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7742 (match_operand 1 "" ""))
7743 (use (reg:PSI FPSCR_REG))
7744 (clobber (match_scratch:SI 2 "=k"))
7752 rtx lab = PATTERN (gen_call_site ());
7755 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7756 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7758 SIBLING_CALL_P (call_insn) = 1;
7761 [(set_attr "needs_delay_slot" "yes")
7762 (set (attr "fp_mode")
7763 (if_then_else (eq_attr "fpu_single" "yes")
7764 (const_string "single") (const_string "double")))
7765 (set_attr "type" "jump_ind")])
7767 (define_insn "sibcall_compact"
7768 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7769 (match_operand 1 "" ""))
7771 (use (match_operand:SI 2 "register_operand" "z,x"))
7772 (use (reg:SI R1_REG))
7773 (use (reg:PSI FPSCR_REG))
7774 ;; We want to make sure the `x' above will only match MACH_REG
7775 ;; because sibcall_epilogue may clobber MACL_REG.
7776 (clobber (reg:SI MACL_REG))]
7780 jmp @%0\\n sts %2, r0"
7781 [(set_attr "needs_delay_slot" "yes,no")
7782 (set_attr "length" "2,4")
7783 (set (attr "fp_mode") (const_string "single"))
7784 (set_attr "type" "jump_ind")])
7786 (define_insn "sibcall_media"
7787 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7788 (match_operand 1 "" ""))
7789 (use (reg:SI PR_MEDIA_REG))
7793 [(set_attr "type" "jump_media")])
7795 (define_expand "sibcall"
7797 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7798 (match_operand 1 "" ""))
7799 (match_operand 2 "" "")
7800 (use (reg:PSI FPSCR_REG))
7807 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7808 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7811 else if (TARGET_SHCOMPACT && operands[2]
7812 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7814 rtx cookie_rtx = operands[2];
7815 long cookie = INTVAL (cookie_rtx);
7816 rtx func = XEXP (operands[0], 0);
7821 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7823 rtx reg = gen_reg_rtx (Pmode);
7825 emit_insn (gen_symGOT2reg (reg, func));
7829 func = legitimize_pic_address (func, Pmode, 0);
7832 /* FIXME: if we could tell whether all argument registers are
7833 already taken, we could decide whether to force the use of
7834 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7835 simple way to tell. We could use the CALL_COOKIE, but we
7836 can't currently tell a register used for regular argument
7837 passing from one that is unused. If we leave it up to reload
7838 to decide which register to use, it seems to always choose
7839 R0_REG, which leaves no available registers in SIBCALL_REGS
7840 to hold the address of the trampoline. */
7841 mach = gen_rtx_REG (SImode, MACH_REG);
7842 r1 = gen_rtx_REG (SImode, R1_REG);
7844 /* Since such a call function may use all call-clobbered
7845 registers, we force a mode switch earlier, so that we don't
7846 run out of registers when adjusting fpscr for the call. */
7847 emit_insn (gen_force_mode_for_call ());
7850 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7852 operands[0] = force_reg (SImode, operands[0]);
7854 /* We don't need a return trampoline, since the callee will
7855 return directly to the upper caller. */
7856 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7858 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7859 cookie_rtx = GEN_INT (cookie);
7862 emit_move_insn (mach, func);
7863 emit_move_insn (r1, cookie_rtx);
7865 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7868 else if (TARGET_SHCOMPACT && flag_pic
7869 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7870 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7872 rtx reg = gen_reg_rtx (Pmode);
7874 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7875 XEXP (operands[0], 0) = reg;
7877 if (flag_pic && TARGET_SH2
7878 && MEM_P (operands[0])
7879 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7880 /* The PLT needs the PIC register, but the epilogue would have
7881 to restore it, so we can only use PC-relative PIC calls for
7882 static functions. */
7883 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7885 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7889 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7891 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7895 (define_insn "sibcall_valuei"
7896 [(set (match_operand 0 "" "=rf")
7897 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7898 (match_operand 2 "" "")))
7899 (use (reg:PSI FPSCR_REG))
7903 [(set_attr "needs_delay_slot" "yes")
7904 (set (attr "fp_mode")
7905 (if_then_else (eq_attr "fpu_single" "yes")
7906 (const_string "single") (const_string "double")))
7907 (set_attr "type" "jump_ind")])
7909 (define_insn "sibcall_valuei_pcrel"
7910 [(set (match_operand 0 "" "=rf")
7911 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7912 (match_operand 2 "" "")))
7913 (use (match_operand 3 "" ""))
7914 (use (reg:PSI FPSCR_REG))
7918 [(set_attr "needs_delay_slot" "yes")
7919 (set (attr "fp_mode")
7920 (if_then_else (eq_attr "fpu_single" "yes")
7921 (const_string "single") (const_string "double")))
7922 (set_attr "type" "jump_ind")])
7924 (define_insn_and_split "sibcall_value_pcrel"
7925 [(set (match_operand 0 "" "=rf")
7926 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7927 (match_operand 2 "" "")))
7928 (use (reg:PSI FPSCR_REG))
7929 (clobber (match_scratch:SI 3 "=k"))
7937 rtx lab = PATTERN (gen_call_site ());
7940 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7941 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7945 SIBLING_CALL_P (call_insn) = 1;
7948 [(set_attr "needs_delay_slot" "yes")
7949 (set (attr "fp_mode")
7950 (if_then_else (eq_attr "fpu_single" "yes")
7951 (const_string "single") (const_string "double")))
7952 (set_attr "type" "jump_ind")])
7954 (define_insn "sibcall_value_compact"
7955 [(set (match_operand 0 "" "=rf,rf")
7956 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7957 (match_operand 2 "" "")))
7959 (use (match_operand:SI 3 "register_operand" "z,x"))
7960 (use (reg:SI R1_REG))
7961 (use (reg:PSI FPSCR_REG))
7962 ;; We want to make sure the `x' above will only match MACH_REG
7963 ;; because sibcall_epilogue may clobber MACL_REG.
7964 (clobber (reg:SI MACL_REG))]
7968 jmp @%1\\n sts %3, r0"
7969 [(set_attr "needs_delay_slot" "yes,no")
7970 (set_attr "length" "2,4")
7971 (set (attr "fp_mode") (const_string "single"))
7972 (set_attr "type" "jump_ind")])
7974 (define_insn "sibcall_value_media"
7975 [(set (match_operand 0 "" "=rf")
7976 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7977 (match_operand 2 "" "")))
7978 (use (reg:SI PR_MEDIA_REG))
7982 [(set_attr "type" "jump_media")])
7984 (define_expand "sibcall_value"
7986 [(set (match_operand 0 "arith_reg_operand" "")
7987 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7988 (match_operand 2 "" "")))
7989 (match_operand 3 "" "")
7990 (use (reg:PSI FPSCR_REG))
7997 operands[1] = shmedia_prepare_call_address (operands[1], 1);
7998 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8002 else if (TARGET_SHCOMPACT && operands[3]
8003 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8005 rtx cookie_rtx = operands[3];
8006 long cookie = INTVAL (cookie_rtx);
8007 rtx func = XEXP (operands[1], 0);
8012 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8014 rtx reg = gen_reg_rtx (Pmode);
8016 emit_insn (gen_symGOT2reg (reg, func));
8020 func = legitimize_pic_address (func, Pmode, 0);
8023 /* FIXME: if we could tell whether all argument registers are
8024 already taken, we could decide whether to force the use of
8025 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8026 simple way to tell. We could use the CALL_COOKIE, but we
8027 can't currently tell a register used for regular argument
8028 passing from one that is unused. If we leave it up to reload
8029 to decide which register to use, it seems to always choose
8030 R0_REG, which leaves no available registers in SIBCALL_REGS
8031 to hold the address of the trampoline. */
8032 mach = gen_rtx_REG (SImode, MACH_REG);
8033 r1 = gen_rtx_REG (SImode, R1_REG);
8035 /* Since such a call function may use all call-clobbered
8036 registers, we force a mode switch earlier, so that we don't
8037 run out of registers when adjusting fpscr for the call. */
8038 emit_insn (gen_force_mode_for_call ());
8041 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8043 operands[1] = force_reg (SImode, operands[1]);
8045 /* We don't need a return trampoline, since the callee will
8046 return directly to the upper caller. */
8047 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8049 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8050 cookie_rtx = GEN_INT (cookie);
8053 emit_move_insn (mach, func);
8054 emit_move_insn (r1, cookie_rtx);
8056 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8057 operands[2], mach));
8060 else if (TARGET_SHCOMPACT && flag_pic
8061 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8062 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8064 rtx reg = gen_reg_rtx (Pmode);
8066 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8067 XEXP (operands[1], 0) = reg;
8069 if (flag_pic && TARGET_SH2
8070 && MEM_P (operands[1])
8071 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8072 /* The PLT needs the PIC register, but the epilogue would have
8073 to restore it, so we can only use PC-relative PIC calls for
8074 static functions. */
8075 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8077 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8078 XEXP (operands[1], 0),
8083 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8085 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8089 (define_insn "call_value_pop_compact"
8090 [(set (match_operand 0 "" "=rf")
8091 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8092 (match_operand 2 "" "")))
8093 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8094 (match_operand 4 "immediate_operand" "n")))
8095 (match_operand 3 "immediate_operand" "n")
8096 (use (reg:SI R0_REG))
8097 (use (reg:SI R1_REG))
8098 (use (reg:PSI FPSCR_REG))
8099 (clobber (reg:SI PR_REG))]
8100 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8102 [(set_attr "type" "call")
8103 (set (attr "fp_mode")
8104 (if_then_else (eq_attr "fpu_single" "yes")
8105 (const_string "single") (const_string "double")))
8106 (set_attr "needs_delay_slot" "yes")])
8108 (define_insn "call_value_pop_compact_rettramp"
8109 [(set (match_operand 0 "" "=rf")
8110 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8111 (match_operand 2 "" "")))
8112 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8113 (match_operand 4 "immediate_operand" "n")))
8114 (match_operand 3 "immediate_operand" "n")
8115 (use (reg:SI R0_REG))
8116 (use (reg:SI R1_REG))
8117 (use (reg:PSI FPSCR_REG))
8118 (clobber (reg:SI R10_REG))
8119 (clobber (reg:SI PR_REG))]
8120 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8122 [(set_attr "type" "call")
8123 (set (attr "fp_mode")
8124 (if_then_else (eq_attr "fpu_single" "yes")
8125 (const_string "single") (const_string "double")))
8126 (set_attr "needs_delay_slot" "yes")])
8128 (define_expand "call_value_pop"
8129 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8130 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8131 (match_operand 2 "" "")))
8132 (match_operand 3 "" "")
8133 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8134 (match_operand 4 "" "")))])]
8143 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8144 cookie_rtx = operands[3];
8145 cookie = INTVAL (cookie_rtx);
8146 func = XEXP (operands[1], 0);
8150 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8152 rtx reg = gen_reg_rtx (Pmode);
8154 emit_insn (gen_symGOTPLT2reg (reg, func));
8158 func = legitimize_pic_address (func, Pmode, 0);
8161 r0 = gen_rtx_REG (SImode, R0_REG);
8162 r1 = gen_rtx_REG (SImode, R1_REG);
8164 /* Since such a call function may use all call-clobbered
8165 registers, we force a mode switch earlier, so that we don't
8166 run out of registers when adjusting fpscr for the call. */
8167 emit_insn (gen_force_mode_for_call ());
8169 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8171 operands[1] = force_reg (SImode, operands[1]);
8173 emit_move_insn (r0, func);
8174 emit_move_insn (r1, cookie_rtx);
8176 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8177 emit_call_insn (gen_call_value_pop_compact_rettramp
8178 (operands[0], operands[1], operands[2],
8179 operands[3], operands[4]));
8181 emit_call_insn (gen_call_value_pop_compact
8182 (operands[0], operands[1], operands[2],
8183 operands[3], operands[4]));
8188 (define_expand "sibcall_epilogue"
8193 sh_expand_epilogue (1);
8194 if (TARGET_SHCOMPACT)
8198 /* If epilogue clobbers r0, preserve it in macl. */
8199 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8200 if ((set = single_set (insn))
8201 && REG_P (SET_DEST (set))
8202 && REGNO (SET_DEST (set)) == R0_REG)
8204 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8205 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8207 /* We can't tell at this point whether the sibcall is a
8208 sibcall_compact and, if it is, whether it uses r0 or
8209 mach as operand 2, so let the instructions that
8210 preserve r0 be optimized away if r0 turns out to be
8212 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8213 emit_move_insn (r0, tmp);
8220 (define_insn "indirect_jump_compact"
8222 (match_operand:SI 0 "arith_reg_operand" "r"))]
8225 [(set_attr "needs_delay_slot" "yes")
8226 (set_attr "type" "jump_ind")])
8228 (define_expand "indirect_jump"
8230 (match_operand 0 "register_operand" ""))]
8234 if (GET_MODE (operands[0]) != Pmode)
8235 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8238 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8239 ;; which can be present in structured code from indirect jumps which can not
8240 ;; be present in structured code. This allows -fprofile-arcs to work.
8242 ;; For SH1 processors.
8243 (define_insn "casesi_jump_1"
8245 (match_operand:SI 0 "register_operand" "r"))
8246 (use (label_ref (match_operand 1 "" "")))]
8249 [(set_attr "needs_delay_slot" "yes")
8250 (set_attr "type" "jump_ind")])
8252 ;; For all later processors.
8253 (define_insn "casesi_jump_2"
8254 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8255 (label_ref (match_operand 1 "" ""))))
8256 (use (label_ref (match_operand 2 "" "")))]
8258 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8260 [(set_attr "needs_delay_slot" "yes")
8261 (set_attr "type" "jump_ind")])
8263 (define_insn "casesi_jump_media"
8264 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8265 (use (label_ref (match_operand 1 "" "")))]
8268 [(set_attr "type" "jump_media")])
8270 ;; Call subroutine returning any type.
8271 ;; ??? This probably doesn't work.
8273 (define_expand "untyped_call"
8274 [(parallel [(call (match_operand 0 "" "")
8276 (match_operand 1 "" "")
8277 (match_operand 2 "" "")])]
8278 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8283 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8285 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8287 rtx set = XVECEXP (operands[2], 0, i);
8288 emit_move_insn (SET_DEST (set), SET_SRC (set));
8291 /* The optimizer does not know that the call sets the function value
8292 registers we stored in the result block. We avoid problems by
8293 claiming that all hard registers are used and clobbered at this
8295 emit_insn (gen_blockage ());
8300 ;; ------------------------------------------------------------------------
8302 ;; ------------------------------------------------------------------------
8305 [(set (reg:SI T_REG)
8306 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8307 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8308 (plus:SI (match_dup 1) (const_int -1)))]
8311 [(set_attr "type" "arith")])
8318 ;; Load address of a label. This is only generated by the casesi expand,
8319 ;; and by machine_dependent_reorg (fixing up fp moves).
8320 ;; This must use unspec, because this only works for labels that are
8324 [(set (reg:SI R0_REG)
8325 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8328 [(set_attr "in_delay_slot" "no")
8329 (set_attr "type" "arith")])
8331 ;; machine_dependent_reorg will make this a `mova'.
8332 (define_insn "mova_const"
8333 [(set (reg:SI R0_REG)
8334 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8337 [(set_attr "in_delay_slot" "no")
8338 (set_attr "type" "arith")])
8340 (define_expand "GOTaddr2picreg"
8341 [(set (reg:SI R0_REG)
8342 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8344 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8345 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8348 if (TARGET_VXWORKS_RTP)
8350 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8351 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8352 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8356 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8357 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8361 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8362 rtx pic = operands[0];
8363 rtx lab = PATTERN (gen_call_site ());
8366 equiv = operands[1];
8367 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8368 UNSPEC_PCREL_SYMOFF);
8369 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8371 if (Pmode == SImode)
8373 emit_insn (gen_movsi_const (pic, operands[1]));
8374 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8378 emit_insn (gen_movdi_const (pic, operands[1]));
8379 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8382 insn = emit_move_insn (operands[0], tr);
8384 set_unique_reg_note (insn, REG_EQUAL, equiv);
8391 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8394 (define_expand "vxworks_picreg"
8395 [(set (reg:SI PIC_REG)
8396 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8397 (set (reg:SI R0_REG)
8398 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8399 (set (reg:SI PIC_REG)
8400 (mem:SI (reg:SI PIC_REG)))
8401 (set (reg:SI PIC_REG)
8402 (mem:SI (plus:SI (reg:SI PIC_REG)
8404 "TARGET_VXWORKS_RTP")
8407 [(set (match_operand 0 "target_reg_operand" "=b")
8408 (const (unspec [(match_operand 1 "" "Csy")]
8409 UNSPEC_DATALABEL)))]
8410 "TARGET_SHMEDIA && flag_pic
8411 && satisfies_constraint_Csy (operands[1])"
8412 "ptb/u datalabel %1, %0"
8413 [(set_attr "type" "ptabs_media")
8414 (set_attr "length" "*")])
8416 (define_insn "ptrel_si"
8417 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8418 (plus:SI (match_operand:SI 1 "register_operand" "r")
8420 (match_operand:SI 2 "" "")]
8422 "%O2: ptrel/u %1, %0"
8423 [(set_attr "type" "ptabs_media")])
8425 (define_insn "ptrel_di"
8426 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8427 (plus:DI (match_operand:DI 1 "register_operand" "r")
8429 (match_operand:DI 2 "" "")]
8431 "%O2: ptrel/u %1, %0"
8432 [(set_attr "type" "ptabs_media")])
8434 (define_expand "builtin_setjmp_receiver"
8435 [(match_operand 0 "" "")]
8439 emit_insn (gen_GOTaddr2picreg ());
8443 (define_expand "call_site"
8444 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8448 static HOST_WIDE_INT i = 0;
8449 operands[0] = GEN_INT (i);
8453 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8454 ;; in symGOT_load expand.
8456 (define_insn_and_split "chk_guard_add"
8457 [(set (match_operand:SI 0 "register_operand" "=&r")
8458 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8463 "TARGET_SH1 && reload_completed"
8464 [(set (match_dup 0) (reg:SI PIC_REG))
8465 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8467 [(set_attr "type" "arith")])
8469 (define_expand "sym_label2reg"
8470 [(set (match_operand:SI 0 "" "")
8471 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8472 (const (plus:SI (match_operand:SI 2 "" "")
8477 (define_expand "symGOT_load"
8478 [(set (match_dup 2) (match_operand 1 "" ""))
8479 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8480 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8486 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8487 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8491 rtx reg = operands[2];
8493 if (Pmode == DImode)
8496 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8498 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8503 emit_insn (gen_movsi_const (reg, operands[1]));
8505 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8509 emit_move_insn (operands[2], operands[1]);
8511 /* When stack protector inserts codes after the result is set to
8512 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8513 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8514 when rX is a GOT address for the guard symbol. Ugly but doesn't
8515 matter because this is a rare situation. */
8517 && flag_stack_protect
8518 && GET_CODE (operands[1]) == CONST
8519 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8520 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8521 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8522 \"__stack_chk_guard\") == 0)
8523 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8525 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8526 gen_rtx_REG (Pmode, PIC_REG)));
8528 /* N.B. This is not constant for a GOTPLT relocation. */
8529 mem = gen_rtx_MEM (Pmode, operands[3]);
8530 MEM_NOTRAP_P (mem) = 1;
8531 /* ??? Should we have a special alias set for the GOT? */
8532 emit_move_insn (operands[0], mem);
8537 (define_expand "sym2GOT"
8538 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8542 (define_expand "symGOT2reg"
8543 [(match_operand 0 "" "") (match_operand 1 "" "")]
8549 gotsym = gen_sym2GOT (operands[1]);
8550 PUT_MODE (gotsym, Pmode);
8551 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8553 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8558 (define_expand "symGOTPLT2reg"
8559 [(match_operand 0 "" "") (match_operand 1 "" "")]
8563 rtx pltsym = gen_rtx_CONST (Pmode,
8564 gen_rtx_UNSPEC (Pmode,
8565 gen_rtvec (1, operands[1]),
8567 emit_insn (gen_symGOT_load (operands[0], pltsym));
8571 (define_expand "sym2GOTOFF"
8572 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8576 (define_expand "symGOTOFF2reg"
8577 [(match_operand 0 "" "") (match_operand 1 "" "")]
8581 rtx gotoffsym, insn;
8582 rtx t = (!can_create_pseudo_p ()
8584 : gen_reg_rtx (GET_MODE (operands[0])));
8586 gotoffsym = gen_sym2GOTOFF (operands[1]);
8587 PUT_MODE (gotoffsym, Pmode);
8588 emit_move_insn (t, gotoffsym);
8589 insn = emit_move_insn (operands[0],
8590 gen_rtx_PLUS (Pmode, t,
8591 gen_rtx_REG (Pmode, PIC_REG)));
8593 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8598 (define_expand "symPLT_label2reg"
8599 [(set (match_operand:SI 0 "" "")
8602 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8603 (const:SI (plus:SI (match_operand:SI 2 "" "")
8604 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8605 ;; Even though the PIC register is not really used by the call
8606 ;; sequence in which this is expanded, the PLT code assumes the PIC
8607 ;; register is set, so we must not skip its initialization. Since
8608 ;; we only use this expand as part of calling sequences, and never
8609 ;; to take the address of a function, this is the best point to
8610 ;; insert the (use). Using the PLT to take the address of a
8611 ;; function would be wrong, not only because the PLT entry could
8612 ;; then be called from a function that doesn't initialize the PIC
8613 ;; register to the proper GOT, but also because pointers to the
8614 ;; same function might not compare equal, should they be set by
8615 ;; different shared libraries.
8616 (use (reg:SI PIC_REG))]
8620 (define_expand "sym2PIC"
8621 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8625 ;; TLS code generation.
8626 ;; ??? this should be a define_insn_and_split
8627 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8628 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8631 (define_insn "tls_global_dynamic"
8632 [(set (match_operand:SI 0 "register_operand" "=&z")
8633 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8636 (use (reg:PSI FPSCR_REG))
8637 (use (reg:SI PIC_REG))
8638 (clobber (reg:SI PR_REG))
8639 (clobber (scratch:SI))]
8645 \\tmova\\t2f,r0\\n\\
8646 \\tmov.l\\t2f,r1\\n\\
8649 \\tadd\\tr12,r4\\n\\
8653 1:\\t.long\\t%a1@TLSGD\\n\\
8654 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8657 [(set_attr "type" "tls_load")
8658 (set_attr "length" "26")])
8660 (define_insn "tls_local_dynamic"
8661 [(set (match_operand:SI 0 "register_operand" "=&z")
8662 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8665 (use (reg:PSI FPSCR_REG))
8666 (use (reg:SI PIC_REG))
8667 (clobber (reg:SI PR_REG))
8668 (clobber (scratch:SI))]
8674 \\tmova\\t2f,r0\\n\\
8675 \\tmov.l\\t2f,r1\\n\\
8678 \\tadd\\tr12,r4\\n\\
8682 1:\\t.long\\t%a1@TLSLDM\\n\\
8683 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8686 [(set_attr "type" "tls_load")
8687 (set_attr "length" "26")])
8689 (define_expand "sym2DTPOFF"
8690 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8694 (define_expand "symDTPOFF2reg"
8695 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8700 rtx t = (!can_create_pseudo_p ()
8702 : gen_reg_rtx (GET_MODE (operands[0])));
8704 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8705 PUT_MODE (dtpoffsym, Pmode);
8706 emit_move_insn (t, dtpoffsym);
8707 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8711 (define_expand "sym2GOTTPOFF"
8712 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8716 (define_insn "tls_initial_exec"
8717 [(set (match_operand:SI 0 "register_operand" "=&r")
8718 (unspec:SI [(match_operand:SI 1 "" "")]
8720 (use (reg:SI GBR_REG))
8721 (use (reg:SI PIC_REG))
8722 (clobber (reg:SI R0_REG))]
8728 \\tstc\\tgbr,%0\\n\\
8729 \\tmov.l\\t@(r0,r12),r0\\n\\
8733 1:\\t.long\\t%a1\\n\\
8736 [(set_attr "type" "tls_load")
8737 (set_attr "length" "16")])
8739 (define_expand "sym2TPOFF"
8740 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8744 (define_expand "symTPOFF2reg"
8745 [(match_operand 0 "" "") (match_operand 1 "" "")]
8751 tpoffsym = gen_sym2TPOFF (operands[1]);
8752 PUT_MODE (tpoffsym, Pmode);
8753 emit_move_insn (operands[0], tpoffsym);
8757 (define_insn "load_gbr"
8758 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8759 (use (reg:SI GBR_REG))]
8762 [(set_attr "type" "tls_load")])
8764 ;; case instruction for switch statements.
8766 ;; Operand 0 is index
8767 ;; operand 1 is the minimum bound
8768 ;; operand 2 is the maximum bound - minimum bound + 1
8769 ;; operand 3 is CODE_LABEL for the table;
8770 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8772 (define_expand "casesi"
8773 [(match_operand:SI 0 "arith_reg_operand" "")
8774 (match_operand:SI 1 "arith_reg_operand" "")
8775 (match_operand:SI 2 "arith_reg_operand" "")
8776 (match_operand 3 "" "") (match_operand 4 "" "")]
8780 rtx reg = gen_reg_rtx (SImode);
8781 rtx reg2 = gen_reg_rtx (SImode);
8784 rtx reg = gen_reg_rtx (DImode);
8785 rtx reg2 = gen_reg_rtx (DImode);
8786 rtx reg3 = gen_reg_rtx (Pmode);
8787 rtx reg4 = gen_reg_rtx (Pmode);
8788 rtx reg5 = gen_reg_rtx (Pmode);
8791 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8792 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8793 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8795 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8796 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8797 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8798 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8799 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8800 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8801 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8802 (Pmode, operands[3])));
8803 /* Messy: can we subreg to clean this up? */
8804 if (Pmode == DImode)
8805 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8807 load = gen_casesi_load_media (reg4,
8808 gen_rtx_SUBREG (DImode, reg3, 0),
8810 PUT_MODE (SET_SRC (load), Pmode);
8812 /* ??? The following add could be eliminated if we used ptrel. */
8813 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8814 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8818 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8819 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8820 /* If optimizing, casesi_worker depends on the mode of the instruction
8821 before label it 'uses' - operands[3]. */
8822 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8824 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8826 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8828 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8829 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8830 operands[3], but to lab. We will fix this up in
8831 machine_dependent_reorg. */
8836 (define_expand "casesi_0"
8837 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8838 (set (match_dup 4) (minus:SI (match_dup 4)
8839 (match_operand:SI 1 "arith_operand" "")))
8841 (gtu:SI (match_dup 4)
8842 (match_operand:SI 2 "arith_reg_operand" "")))
8844 (if_then_else (ne (reg:SI T_REG)
8846 (label_ref (match_operand 3 "" ""))
8851 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8852 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8853 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8855 (define_insn "casesi_worker_0"
8856 [(set (match_operand:SI 0 "register_operand" "=r,r")
8857 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8858 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8859 (clobber (match_scratch:SI 3 "=X,1"))
8860 (clobber (match_scratch:SI 4 "=&z,z"))]
8865 [(set (match_operand:SI 0 "register_operand" "")
8866 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8867 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8868 (clobber (match_scratch:SI 3 ""))
8869 (clobber (match_scratch:SI 4 ""))]
8870 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8871 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8872 (parallel [(set (match_dup 0)
8873 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8874 (label_ref (match_dup 2))] UNSPEC_CASESI))
8875 (clobber (match_dup 3))])
8876 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8877 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8880 [(set (match_operand:SI 0 "register_operand" "")
8881 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8882 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8883 (clobber (match_scratch:SI 3 ""))
8884 (clobber (match_scratch:SI 4 ""))]
8885 "TARGET_SH2 && reload_completed"
8886 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8887 (parallel [(set (match_dup 0)
8888 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8889 (label_ref (match_dup 2))] UNSPEC_CASESI))
8890 (clobber (match_dup 3))])]
8891 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8893 (define_insn "casesi_worker_1"
8894 [(set (match_operand:SI 0 "register_operand" "=r,r")
8895 (unspec:SI [(reg:SI R0_REG)
8896 (match_operand:SI 1 "register_operand" "0,r")
8897 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8898 (clobber (match_scratch:SI 3 "=X,1"))]
8902 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8904 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8906 switch (GET_MODE (diff_vec))
8909 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8911 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8913 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8914 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8915 return \"mov.b @(r0,%1),%0\";
8920 [(set_attr "length" "4")])
8922 (define_insn "casesi_worker_2"
8923 [(set (match_operand:SI 0 "register_operand" "=r,r")
8924 (unspec:SI [(reg:SI R0_REG)
8925 (match_operand:SI 1 "register_operand" "0,r")
8926 (label_ref (match_operand 2 "" ""))
8927 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8928 (clobber (match_operand:SI 4 "" "=X,1"))]
8929 "TARGET_SH2 && reload_completed && flag_pic"
8932 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8935 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8937 switch (GET_MODE (diff_vec))
8940 output_asm_insn (\"shll2 %1\", operands);
8941 load = \"mov.l @(r0,%1),%0\"; break;
8943 output_asm_insn (\"add %1,%1\", operands);
8944 load = \"mov.w @(r0,%1),%0\"; break;
8946 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8947 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8949 load = \"mov.b @(r0,%1),%0\";
8954 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8957 [(set_attr "length" "8")])
8959 (define_insn "casesi_shift_media"
8960 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8961 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8962 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8967 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8969 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8971 switch (GET_MODE (diff_vec))
8974 return \"shlli %1, 2, %0\";
8976 return \"shlli %1, 1, %0\";
8978 if (rtx_equal_p (operands[0], operands[1]))
8980 return \"add %1, r63, %0\";
8985 [(set_attr "type" "arith_media")])
8987 (define_insn "casesi_load_media"
8988 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8989 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8990 (match_operand:DI 2 "arith_reg_operand" "r")
8991 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8995 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8997 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8999 switch (GET_MODE (diff_vec))
9002 return \"ldx.l %1, %2, %0\";
9005 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9006 return \"ldx.uw %1, %2, %0\";
9008 return \"ldx.w %1, %2, %0\";
9010 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9011 return \"ldx.ub %1, %2, %0\";
9012 return \"ldx.b %1, %2, %0\";
9017 [(set_attr "type" "load_media")])
9019 (define_expand "return"
9021 "reload_completed && ! sh_need_epilogue ()"
9026 emit_jump_insn (gen_return_media ());
9030 if (TARGET_SHCOMPACT
9031 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9033 emit_jump_insn (gen_shcompact_return_tramp ());
9038 (define_insn "*return_i"
9040 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9041 && (crtl->args.info.call_cookie
9042 & CALL_COOKIE_RET_TRAMP (1)))
9044 && lookup_attribute (\"trap_exit\",
9045 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9048 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9049 && !current_function_interrupt)
9054 [(set_attr "type" "return")
9055 (set_attr "needs_delay_slot" "yes")])
9057 ;; trapa has no delay slot.
9058 (define_insn "*return_trapa"
9060 "TARGET_SH1 && !TARGET_SHCOMPACT
9061 && reload_completed"
9063 [(set_attr "type" "return")])
9065 (define_expand "shcompact_return_tramp"
9068 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9071 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9073 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9074 emit_jump_insn (gen_shcompact_return_tramp_i ());
9078 (define_insn "shcompact_return_tramp_i"
9079 [(parallel [(return) (use (reg:SI R0_REG))])]
9081 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9083 [(set_attr "type" "jump_ind")
9084 (set_attr "needs_delay_slot" "yes")])
9086 (define_insn "return_media_i"
9087 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9088 "TARGET_SHMEDIA && reload_completed"
9090 [(set_attr "type" "jump_media")])
9092 (define_insn "return_media_rte"
9094 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9096 [(set_attr "type" "jump_media")])
9098 (define_expand "return_media"
9100 "TARGET_SHMEDIA && reload_completed"
9103 int tr_regno = sh_media_register_for_return ();
9106 if (current_function_interrupt)
9108 emit_jump_insn (gen_return_media_rte ());
9113 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9115 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9117 tr = gen_rtx_REG (Pmode, tr_regno);
9118 emit_move_insn (tr, r18);
9121 tr = gen_rtx_REG (Pmode, tr_regno);
9123 emit_jump_insn (gen_return_media_i (tr));
9127 (define_insn "shcompact_preserve_incoming_args"
9128 [(set (match_operand:SI 0 "register_operand" "+r")
9129 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9132 [(set_attr "length" "0")])
9134 (define_insn "shcompact_incoming_args"
9135 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9136 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9137 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9138 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9139 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9140 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9141 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9142 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9143 (set (mem:BLK (reg:SI MACL_REG))
9144 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9145 (use (reg:SI R0_REG))
9146 (clobber (reg:SI R0_REG))
9147 (clobber (reg:SI MACL_REG))
9148 (clobber (reg:SI MACH_REG))
9149 (clobber (reg:SI PR_REG))]
9152 [(set_attr "needs_delay_slot" "yes")])
9154 (define_insn "shmedia_save_restore_regs_compact"
9155 [(set (reg:SI SP_REG)
9156 (plus:SI (reg:SI SP_REG)
9157 (match_operand:SI 0 "immediate_operand" "i")))
9158 (use (reg:SI R0_REG))
9159 (clobber (reg:SI PR_REG))]
9161 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9162 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9164 [(set_attr "needs_delay_slot" "yes")])
9166 (define_expand "prologue"
9169 "sh_expand_prologue (); DONE;")
9171 (define_expand "epilogue"
9176 sh_expand_epilogue (0);
9177 emit_jump_insn (gen_return ());
9181 (define_expand "eh_return"
9182 [(use (match_operand 0 "register_operand" ""))]
9185 rtx ra = operands[0];
9187 if (TARGET_SHMEDIA64)
9188 emit_insn (gen_eh_set_ra_di (ra));
9190 emit_insn (gen_eh_set_ra_si (ra));
9195 ;; Clobber the return address on the stack. We can't expand this
9196 ;; until we know where it will be put in the stack frame.
9198 (define_insn "eh_set_ra_si"
9199 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9201 (clobber (match_scratch:SI 1 "=&r"))]
9202 "! TARGET_SHMEDIA64"
9205 (define_insn "eh_set_ra_di"
9206 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9208 (clobber (match_scratch:DI 1 "=&r"))]
9213 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9215 (clobber (match_scratch 1 ""))]
9220 sh_set_return_address (operands[0], operands[1]);
9224 (define_insn "blockage"
9225 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9228 [(set_attr "length" "0")])
9230 ;; Define movml instructions for SH2A target. Currently they are
9231 ;; used to push and pop all banked registers only.
9233 (define_insn "movml_push_banked"
9234 [(set (match_operand:SI 0 "register_operand" "=r")
9235 (plus (match_dup 0) (const_int -32)))
9236 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9237 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9238 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9239 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9240 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9241 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9242 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9243 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9244 "TARGET_SH2A && REGNO (operands[0]) == 15"
9246 [(set_attr "in_delay_slot" "no")])
9248 (define_insn "movml_pop_banked"
9249 [(set (match_operand:SI 0 "register_operand" "=r")
9250 (plus (match_dup 0) (const_int 32)))
9251 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9252 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9253 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9254 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9255 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9256 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9257 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9258 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9259 "TARGET_SH2A && REGNO (operands[0]) == 15"
9261 [(set_attr "in_delay_slot" "no")])
9263 ;; ------------------------------------------------------------------------
9265 ;; ------------------------------------------------------------------------
9268 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9269 (eq:SI (reg:SI T_REG) (const_int 1)))]
9272 [(set_attr "type" "arith")])
9274 (define_expand "cstore4_media"
9275 [(set (match_operand:SI 0 "register_operand" "=r")
9276 (match_operator:SI 1 "sh_float_comparison_operator"
9277 [(match_operand 2 "logical_operand" "")
9278 (match_operand 3 "cmp_operand" "")]))]
9282 enum machine_mode mode = GET_MODE (operands[2]);
9283 enum rtx_code code = GET_CODE (operands[1]);
9285 if (mode == VOIDmode)
9286 mode = GET_MODE (operands[3]);
9287 if (operands[2] == const0_rtx)
9289 if (code == EQ || code == NE)
9290 operands[2] = operands[3], operands[3] = const0_rtx;
9293 operands[2] = force_reg (mode, operands[2]);
9294 if (operands[3] != const0_rtx)
9295 operands[3] = force_reg (mode, operands[3]);
9301 swap = invert = !FLOAT_MODE_P (mode);
9306 swap = FLOAT_MODE_P (mode), invert = !swap;
9311 swap = true, invert = false;
9318 swap = invert = false;
9322 swap = invert = true;
9331 rtx tem = operands[2];
9332 operands[2] = operands[3];
9334 code = swap_condition (code);
9339 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9340 code = reverse_condition (code);
9341 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9342 emit_insn (gen_cstore4_media (tem, operands[1],
9343 operands[2], operands[3]));
9346 operands[3] = const0_rtx;
9349 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9352 (define_expand "cstoresi4"
9353 [(set (match_operand:SI 0 "register_operand" "=r")
9354 (match_operator:SI 1 "comparison_operator"
9355 [(match_operand:SI 2 "cmpsi_operand" "")
9356 (match_operand:SI 3 "arith_operand" "")]))]
9357 "TARGET_SH1 || TARGET_SHMEDIA"
9358 "if (TARGET_SHMEDIA)
9360 emit_insn (gen_cstore4_media (operands[0], operands[1],
9361 operands[2], operands[3]));
9365 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9366 && sh_expand_t_scc (operands))
9369 if (! currently_expanding_to_rtl)
9372 sh_emit_compare_and_set (operands, SImode);
9376 (define_expand "cstoredi4"
9377 [(set (match_operand:SI 0 "register_operand" "=r")
9378 (match_operator:SI 1 "comparison_operator"
9379 [(match_operand:DI 2 "arith_operand" "")
9380 (match_operand:DI 3 "arith_operand" "")]))]
9381 "TARGET_SH2 || TARGET_SHMEDIA"
9382 "if (TARGET_SHMEDIA)
9384 emit_insn (gen_cstore4_media (operands[0], operands[1],
9385 operands[2], operands[3]));
9389 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9390 && sh_expand_t_scc (operands))
9393 if (! currently_expanding_to_rtl)
9396 sh_emit_compare_and_set (operands, DImode);
9402 ;; sne moves the complement of the T reg to DEST like this:
9406 ;; This is better than xoring compare result with 1 because it does
9407 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9410 (define_expand "movnegt"
9411 [(set (match_dup 1) (const_int -1))
9412 (parallel [(set (match_operand:SI 0 "" "")
9413 (neg:SI (plus:SI (reg:SI T_REG)
9416 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9421 operands[1] = gen_reg_rtx (SImode);
9425 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9426 ;; This prevents a regression that occurred when we switched from xor to
9430 [(set (match_operand:SI 0 "arith_reg_dest" "")
9431 (plus:SI (reg:SI T_REG)
9434 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9435 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9438 (define_expand "cstoresf4"
9439 [(set (match_operand:SI 0 "register_operand" "=r")
9440 (match_operator:SI 1 "sh_float_comparison_operator"
9441 [(match_operand:SF 2 "arith_operand" "")
9442 (match_operand:SF 3 "arith_operand" "")]))]
9443 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9444 "if (TARGET_SHMEDIA)
9446 emit_insn (gen_cstore4_media (operands[0], operands[1],
9447 operands[2], operands[3]));
9451 if (! currently_expanding_to_rtl)
9454 sh_emit_compare_and_set (operands, SFmode);
9458 (define_expand "cstoredf4"
9459 [(set (match_operand:SI 0 "register_operand" "=r")
9460 (match_operator:SI 1 "sh_float_comparison_operator"
9461 [(match_operand:DF 2 "arith_operand" "")
9462 (match_operand:DF 3 "arith_operand" "")]))]
9463 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9464 "if (TARGET_SHMEDIA)
9466 emit_insn (gen_cstore4_media (operands[0], operands[1],
9467 operands[2], operands[3]));
9471 if (! currently_expanding_to_rtl)
9474 sh_emit_compare_and_set (operands, DFmode);
9479 ;; -------------------------------------------------------------------------
9480 ;; Instructions to cope with inline literal tables
9481 ;; -------------------------------------------------------------------------
9483 ; 2 byte integer in line
9485 (define_insn "consttable_2"
9486 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9487 (match_operand 1 "" "")]
9492 if (operands[1] != const0_rtx)
9493 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9496 [(set_attr "length" "2")
9497 (set_attr "in_delay_slot" "no")])
9499 ; 4 byte integer in line
9501 (define_insn "consttable_4"
9502 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9503 (match_operand 1 "" "")]
9508 if (operands[1] != const0_rtx)
9510 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9511 mark_symbol_refs_as_used (operands[0]);
9515 [(set_attr "length" "4")
9516 (set_attr "in_delay_slot" "no")])
9518 ; 8 byte integer in line
9520 (define_insn "consttable_8"
9521 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9522 (match_operand 1 "" "")]
9527 if (operands[1] != const0_rtx)
9528 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9531 [(set_attr "length" "8")
9532 (set_attr "in_delay_slot" "no")])
9534 ; 4 byte floating point
9536 (define_insn "consttable_sf"
9537 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9538 (match_operand 1 "" "")]
9543 if (operands[1] != const0_rtx)
9546 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9547 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9551 [(set_attr "length" "4")
9552 (set_attr "in_delay_slot" "no")])
9554 ; 8 byte floating point
9556 (define_insn "consttable_df"
9557 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9558 (match_operand 1 "" "")]
9563 if (operands[1] != const0_rtx)
9566 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9567 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9571 [(set_attr "length" "8")
9572 (set_attr "in_delay_slot" "no")])
9574 ;; Alignment is needed for some constant tables; it may also be added for
9575 ;; Instructions at the start of loops, or after unconditional branches.
9576 ;; ??? We would get more accurate lengths if we did instruction
9577 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9578 ;; here is too conservative.
9580 ; align to a two byte boundary
9582 (define_expand "align_2"
9583 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9587 ; align to a four byte boundary
9588 ;; align_4 and align_log are instructions for the starts of loops, or
9589 ;; after unconditional branches, which may take up extra room.
9591 (define_expand "align_4"
9592 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9596 ; align to a cache line boundary
9598 (define_insn "align_log"
9599 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9602 [(set_attr "length" "0")
9603 (set_attr "in_delay_slot" "no")])
9605 ; emitted at the end of the literal table, used to emit the
9606 ; 32bit branch labels if needed.
9608 (define_insn "consttable_end"
9609 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9611 "* return output_jump_label_table ();"
9612 [(set_attr "in_delay_slot" "no")])
9614 ; emitted at the end of the window in the literal table.
9616 (define_insn "consttable_window_end"
9617 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9620 [(set_attr "length" "0")
9621 (set_attr "in_delay_slot" "no")])
9623 ;; -------------------------------------------------------------------------
9625 ;; -------------------------------------------------------------------------
9627 ;; String/block move insn.
9629 (define_expand "movmemsi"
9630 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9631 (mem:BLK (match_operand:BLK 1 "" "")))
9632 (use (match_operand:SI 2 "nonmemory_operand" ""))
9633 (use (match_operand:SI 3 "immediate_operand" ""))
9634 (clobber (reg:SI PR_REG))
9635 (clobber (reg:SI R4_REG))
9636 (clobber (reg:SI R5_REG))
9637 (clobber (reg:SI R0_REG))])]
9638 "TARGET_SH1 && ! TARGET_SH5"
9641 if(expand_block_move (operands))
9646 (define_insn "block_move_real"
9647 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9648 (mem:BLK (reg:SI R5_REG)))
9649 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9650 (clobber (reg:SI PR_REG))
9651 (clobber (reg:SI R0_REG))])]
9652 "TARGET_SH1 && ! TARGET_HARD_SH4"
9654 [(set_attr "type" "sfunc")
9655 (set_attr "needs_delay_slot" "yes")])
9657 (define_insn "block_lump_real"
9658 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9659 (mem:BLK (reg:SI R5_REG)))
9660 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9661 (use (reg:SI R6_REG))
9662 (clobber (reg:SI PR_REG))
9663 (clobber (reg:SI T_REG))
9664 (clobber (reg:SI R4_REG))
9665 (clobber (reg:SI R5_REG))
9666 (clobber (reg:SI R6_REG))
9667 (clobber (reg:SI R0_REG))])]
9668 "TARGET_SH1 && ! TARGET_HARD_SH4"
9670 [(set_attr "type" "sfunc")
9671 (set_attr "needs_delay_slot" "yes")])
9673 (define_insn "block_move_real_i4"
9674 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9675 (mem:BLK (reg:SI R5_REG)))
9676 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9677 (clobber (reg:SI PR_REG))
9678 (clobber (reg:SI R0_REG))
9679 (clobber (reg:SI R1_REG))
9680 (clobber (reg:SI R2_REG))])]
9683 [(set_attr "type" "sfunc")
9684 (set_attr "needs_delay_slot" "yes")])
9686 (define_insn "block_lump_real_i4"
9687 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9688 (mem:BLK (reg:SI R5_REG)))
9689 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9690 (use (reg:SI R6_REG))
9691 (clobber (reg:SI PR_REG))
9692 (clobber (reg:SI T_REG))
9693 (clobber (reg:SI R4_REG))
9694 (clobber (reg:SI R5_REG))
9695 (clobber (reg:SI R6_REG))
9696 (clobber (reg:SI R0_REG))
9697 (clobber (reg:SI R1_REG))
9698 (clobber (reg:SI R2_REG))
9699 (clobber (reg:SI R3_REG))])]
9702 [(set_attr "type" "sfunc")
9703 (set_attr "needs_delay_slot" "yes")])
9705 ;; -------------------------------------------------------------------------
9706 ;; Floating point instructions.
9707 ;; -------------------------------------------------------------------------
9709 ;; ??? All patterns should have a type attribute.
9711 (define_expand "movpsi"
9712 [(set (match_operand:PSI 0 "register_operand" "")
9713 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9714 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9717 ;; The c / m alternative is a fake to guide reload to load directly into
9718 ;; fpscr, since reload doesn't know how to use post-increment.
9719 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9720 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9721 ;; predicate after reload.
9722 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9723 ;; like a mac -> gpr move.
9724 (define_insn "fpu_switch"
9725 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9726 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9728 && (! reload_completed
9729 || true_regnum (operands[0]) != FPSCR_REG
9730 || !MEM_P (operands[1])
9731 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9733 ! precision stays the same
9742 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9743 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9746 [(set (reg:PSI FPSCR_REG)
9747 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9748 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9751 rtx fpscr, mem, new_insn;
9753 fpscr = SET_DEST (PATTERN (curr_insn));
9754 mem = SET_SRC (PATTERN (curr_insn));
9755 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9757 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9758 add_reg_note (new_insn, REG_INC, operands[0]);
9763 [(set (reg:PSI FPSCR_REG)
9764 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9765 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9766 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9769 rtx fpscr, mem, new_insn;
9771 fpscr = SET_DEST (PATTERN (curr_insn));
9772 mem = SET_SRC (PATTERN (curr_insn));
9773 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9775 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9776 add_reg_note (new_insn, REG_INC, operands[0]);
9778 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9779 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9783 ;; ??? This uses the fp unit, but has no type indicating that.
9784 ;; If we did that, this would either give a bogus latency or introduce
9785 ;; a bogus FIFO constraint.
9786 ;; Since this insn is currently only used for prologues/epilogues,
9787 ;; it is probably best to claim no function unit, which matches the
9789 (define_insn "toggle_sz"
9790 [(set (reg:PSI FPSCR_REG)
9791 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9792 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9794 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9796 ;; There's no way we can use it today, since optimize mode switching
9797 ;; doesn't enable us to know from which mode we're switching to the
9798 ;; mode it requests, to tell whether we can use a relative mode switch
9799 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9801 (define_insn "toggle_pr"
9802 [(set (reg:PSI FPSCR_REG)
9803 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9804 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9806 [(set_attr "type" "fpscr_toggle")])
9808 (define_expand "addsf3"
9809 [(set (match_operand:SF 0 "arith_reg_operand" "")
9810 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9811 (match_operand:SF 2 "arith_reg_operand" "")))]
9812 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9817 expand_sf_binop (&gen_addsf3_i, operands);
9822 (define_insn "*addsf3_media"
9823 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9824 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9825 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9826 "TARGET_SHMEDIA_FPU"
9828 [(set_attr "type" "fparith_media")])
9830 (define_insn_and_split "unary_sf_op"
9831 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9836 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9837 (match_operator:SF 2 "unary_float_operator"
9838 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9839 (parallel [(match_operand 4
9840 "const_int_operand" "n")]))]))
9841 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9842 "TARGET_SHMEDIA_FPU"
9844 "TARGET_SHMEDIA_FPU && reload_completed"
9845 [(set (match_dup 5) (match_dup 6))]
9848 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9849 rtx op1 = gen_rtx_REG (SFmode,
9850 (true_regnum (operands[1])
9851 + (INTVAL (operands[4]) ^ endian)));
9853 operands[7] = gen_rtx_REG (SFmode,
9854 (true_regnum (operands[0])
9855 + (INTVAL (operands[3]) ^ endian)));
9856 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9858 [(set_attr "type" "fparith_media")])
9860 (define_insn_and_split "binary_sf_op0"
9861 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9863 (match_operator:SF 3 "binary_float_operator"
9864 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9865 (parallel [(const_int 0)]))
9866 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9867 (parallel [(const_int 0)]))])
9870 (parallel [(const_int 1)]))))]
9871 "TARGET_SHMEDIA_FPU"
9873 "&& reload_completed"
9874 [(set (match_dup 4) (match_dup 5))]
9877 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9878 rtx op1 = gen_rtx_REG (SFmode,
9879 true_regnum (operands[1]) + endian);
9880 rtx op2 = gen_rtx_REG (SFmode,
9881 true_regnum (operands[2]) + endian);
9883 operands[4] = gen_rtx_REG (SFmode,
9884 true_regnum (operands[0]) + endian);
9885 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9887 [(set_attr "type" "fparith_media")])
9889 (define_insn_and_split "binary_sf_op1"
9890 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9894 (parallel [(const_int 0)]))
9895 (match_operator:SF 3 "binary_float_operator"
9896 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9897 (parallel [(const_int 1)]))
9898 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9899 (parallel [(const_int 1)]))])))]
9900 "TARGET_SHMEDIA_FPU"
9902 "&& reload_completed"
9903 [(set (match_dup 4) (match_dup 5))]
9906 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9907 rtx op1 = gen_rtx_REG (SFmode,
9908 true_regnum (operands[1]) + (1 ^ endian));
9909 rtx op2 = gen_rtx_REG (SFmode,
9910 true_regnum (operands[2]) + (1 ^ endian));
9912 operands[4] = gen_rtx_REG (SFmode,
9913 true_regnum (operands[0]) + (1 ^ endian));
9914 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9916 [(set_attr "type" "fparith_media")])
9918 (define_insn "addsf3_i"
9919 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9920 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9921 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9922 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9925 [(set_attr "type" "fp")
9926 (set_attr "fp_mode" "single")])
9928 (define_expand "subsf3"
9929 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9930 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9931 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9932 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9937 expand_sf_binop (&gen_subsf3_i, operands);
9942 (define_insn "*subsf3_media"
9943 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9944 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9945 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9946 "TARGET_SHMEDIA_FPU"
9948 [(set_attr "type" "fparith_media")])
9950 (define_insn "subsf3_i"
9951 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9952 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9953 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9954 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9957 [(set_attr "type" "fp")
9958 (set_attr "fp_mode" "single")])
9960 (define_expand "mulsf3"
9961 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9962 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9963 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9964 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9967 (define_insn "*mulsf3_media"
9968 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9969 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9970 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9971 "TARGET_SHMEDIA_FPU"
9973 [(set_attr "type" "fparith_media")])
9975 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9976 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9977 ;; we start out with a mulsf pattern that does not depend on fpscr.
9978 ;; This is split after combine to introduce the dependency, in order to
9979 ;; get mode switching and scheduling right.
9980 (define_insn_and_split "mulsf3_ie"
9981 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9982 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9983 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9986 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9990 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9994 [(set_attr "type" "fp")])
9996 (define_insn "mulsf3_i4"
9997 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9998 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9999 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10000 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10003 [(set_attr "type" "fp")
10004 (set_attr "fp_mode" "single")])
10006 (define_insn "mac_media"
10007 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10008 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10009 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10010 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10011 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10012 "fmac.s %1, %2, %0"
10013 [(set_attr "type" "fparith_media")])
10015 (define_insn "*macsf3"
10016 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10017 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10018 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10019 (match_operand:SF 3 "arith_reg_operand" "0")))
10020 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10021 "TARGET_SH2E && TARGET_FMAC"
10023 [(set_attr "type" "fp")
10024 (set_attr "fp_mode" "single")])
10026 (define_expand "divsf3"
10027 [(set (match_operand:SF 0 "arith_reg_operand" "")
10028 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10029 (match_operand:SF 2 "arith_reg_operand" "")))]
10030 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10035 expand_sf_binop (&gen_divsf3_i, operands);
10040 (define_insn "*divsf3_media"
10041 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10042 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10043 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10044 "TARGET_SHMEDIA_FPU"
10045 "fdiv.s %1, %2, %0"
10046 [(set_attr "type" "fdiv_media")])
10048 (define_insn "divsf3_i"
10049 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10050 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10051 (match_operand:SF 2 "arith_reg_operand" "f")))
10052 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10055 [(set_attr "type" "fdiv")
10056 (set_attr "fp_mode" "single")])
10058 (define_insn "floatdisf2"
10059 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10060 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10061 "TARGET_SHMEDIA_FPU"
10063 [(set_attr "type" "fpconv_media")])
10065 (define_expand "floatsisf2"
10066 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10067 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10068 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10071 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10073 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10078 (define_insn "*floatsisf2_media"
10079 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10080 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10081 "TARGET_SHMEDIA_FPU"
10083 [(set_attr "type" "fpconv_media")])
10085 (define_insn "floatsisf2_i4"
10086 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10087 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10088 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10089 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10091 [(set_attr "type" "fp")
10092 (set_attr "fp_mode" "single")])
10094 (define_insn "*floatsisf2_ie"
10095 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10096 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10097 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10099 [(set_attr "type" "fp")])
10101 (define_insn "fix_truncsfdi2"
10102 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10103 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10104 "TARGET_SHMEDIA_FPU"
10106 [(set_attr "type" "fpconv_media")])
10108 (define_expand "fix_truncsfsi2"
10109 [(set (match_operand:SI 0 "fpul_operand" "=y")
10110 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10111 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10114 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10116 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10121 (define_insn "*fix_truncsfsi2_media"
10122 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10123 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10124 "TARGET_SHMEDIA_FPU"
10126 [(set_attr "type" "fpconv_media")])
10128 (define_insn "fix_truncsfsi2_i4"
10129 [(set (match_operand:SI 0 "fpul_operand" "=y")
10130 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10131 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10132 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10134 [(set_attr "type" "ftrc_s")
10135 (set_attr "fp_mode" "single")])
10137 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10138 ;; fix_truncsfsi2_i4.
10139 ;; (define_insn "fix_truncsfsi2_i4_2"
10140 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10141 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10142 ;; (use (reg:PSI FPSCR_REG))
10143 ;; (clobber (reg:SI FPUL_REG))]
10146 ;; [(set_attr "length" "4")
10147 ;; (set_attr "fp_mode" "single")])
10150 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10151 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10152 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10153 ;; (clobber (reg:SI FPUL_REG))]
10155 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10156 ;; (use (match_dup 2))])
10157 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10159 (define_insn "*fixsfsi"
10160 [(set (match_operand:SI 0 "fpul_operand" "=y")
10161 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10162 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10164 [(set_attr "type" "fp")])
10166 (define_insn "cmpgtsf_t"
10167 [(set (reg:SI T_REG)
10168 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10169 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10170 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10172 [(set_attr "type" "fp_cmp")
10173 (set_attr "fp_mode" "single")])
10175 (define_insn "cmpeqsf_t"
10176 [(set (reg:SI T_REG)
10177 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10178 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10179 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10181 [(set_attr "type" "fp_cmp")
10182 (set_attr "fp_mode" "single")])
10184 (define_insn "ieee_ccmpeqsf_t"
10185 [(set (reg:SI T_REG)
10186 (ior:SI (reg:SI T_REG)
10187 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10188 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10189 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10190 "* return output_ieee_ccmpeq (insn, operands);"
10191 [(set_attr "length" "4")])
10194 (define_insn "cmpgtsf_t_i4"
10195 [(set (reg:SI T_REG)
10196 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10197 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10198 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10199 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10201 [(set_attr "type" "fp_cmp")
10202 (set_attr "fp_mode" "single")])
10204 (define_insn "cmpeqsf_t_i4"
10205 [(set (reg:SI T_REG)
10206 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10207 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10208 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10209 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10211 [(set_attr "type" "fp_cmp")
10212 (set_attr "fp_mode" "single")])
10214 (define_insn "*ieee_ccmpeqsf_t_4"
10215 [(set (reg:SI T_REG)
10216 (ior:SI (reg:SI T_REG)
10217 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10218 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10219 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10220 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10221 "* return output_ieee_ccmpeq (insn, operands);"
10222 [(set_attr "length" "4")
10223 (set_attr "fp_mode" "single")])
10225 (define_insn "cmpeqsf_media"
10226 [(set (match_operand:SI 0 "register_operand" "=r")
10227 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10228 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10229 "TARGET_SHMEDIA_FPU"
10230 "fcmpeq.s %1, %2, %0"
10231 [(set_attr "type" "fcmp_media")])
10233 (define_insn "cmpgtsf_media"
10234 [(set (match_operand:SI 0 "register_operand" "=r")
10235 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10236 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10237 "TARGET_SHMEDIA_FPU"
10238 "fcmpgt.s %1, %2, %0"
10239 [(set_attr "type" "fcmp_media")])
10241 (define_insn "cmpgesf_media"
10242 [(set (match_operand:SI 0 "register_operand" "=r")
10243 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10244 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10245 "TARGET_SHMEDIA_FPU"
10246 "fcmpge.s %1, %2, %0"
10247 [(set_attr "type" "fcmp_media")])
10249 (define_insn "cmpunsf_media"
10250 [(set (match_operand:SI 0 "register_operand" "=r")
10251 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10252 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10253 "TARGET_SHMEDIA_FPU"
10254 "fcmpun.s %1, %2, %0"
10255 [(set_attr "type" "fcmp_media")])
10257 (define_expand "cbranchsf4"
10259 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10260 [(match_operand:SF 1 "arith_operand" "")
10261 (match_operand:SF 2 "arith_operand" "")])
10262 (match_operand 3 "" "")
10264 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10267 if (TARGET_SHMEDIA)
10268 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10271 sh_emit_compare_and_branch (operands, SFmode);
10275 (define_expand "negsf2"
10276 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10277 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10278 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10283 expand_sf_unop (&gen_negsf2_i, operands);
10288 (define_insn "*negsf2_media"
10289 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10290 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10291 "TARGET_SHMEDIA_FPU"
10293 [(set_attr "type" "fmove_media")])
10295 (define_insn "negsf2_i"
10296 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10297 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10298 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10301 [(set_attr "type" "fmove")
10302 (set_attr "fp_mode" "single")])
10304 (define_expand "sqrtsf2"
10305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10306 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10307 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10312 expand_sf_unop (&gen_sqrtsf2_i, operands);
10317 (define_insn "*sqrtsf2_media"
10318 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10319 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10320 "TARGET_SHMEDIA_FPU"
10322 [(set_attr "type" "fdiv_media")])
10324 (define_insn "sqrtsf2_i"
10325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10326 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10327 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10330 [(set_attr "type" "fdiv")
10331 (set_attr "fp_mode" "single")])
10333 (define_insn "rsqrtsf2"
10334 [(set (match_operand:SF 0 "register_operand" "=f")
10335 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10336 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10337 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10338 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10339 && operands[1] == CONST1_RTX (SFmode)"
10341 [(set_attr "type" "fsrra")
10342 (set_attr "fp_mode" "single")])
10344 (define_insn "fsca"
10345 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10347 (unspec:SF [(mult:SF
10348 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10349 (match_operand:SF 2 "immediate_operand" "i"))
10351 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10353 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10354 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10355 && operands[2] == sh_fsca_int2sf ()"
10357 [(set_attr "type" "fsca")
10358 (set_attr "fp_mode" "single")])
10360 (define_expand "sinsf2"
10361 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10362 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10364 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10367 rtx scaled = gen_reg_rtx (SFmode);
10368 rtx truncated = gen_reg_rtx (SImode);
10369 rtx fsca = gen_reg_rtx (V2SFmode);
10370 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10372 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10373 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10374 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10375 get_fpscr_rtx ()));
10376 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10380 (define_expand "cossf2"
10381 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10382 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10384 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10387 rtx scaled = gen_reg_rtx (SFmode);
10388 rtx truncated = gen_reg_rtx (SImode);
10389 rtx fsca = gen_reg_rtx (V2SFmode);
10390 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10392 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10393 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10394 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10395 get_fpscr_rtx ()));
10396 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10400 (define_expand "sindf2"
10401 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10402 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10404 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10407 rtx scaled = gen_reg_rtx (DFmode);
10408 rtx truncated = gen_reg_rtx (SImode);
10409 rtx fsca = gen_reg_rtx (V2SFmode);
10410 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10411 rtx sfresult = gen_reg_rtx (SFmode);
10413 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10414 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10415 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10416 get_fpscr_rtx ()));
10417 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10418 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10422 (define_expand "cosdf2"
10423 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10424 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10426 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10429 rtx scaled = gen_reg_rtx (DFmode);
10430 rtx truncated = gen_reg_rtx (SImode);
10431 rtx fsca = gen_reg_rtx (V2SFmode);
10432 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10433 rtx sfresult = gen_reg_rtx (SFmode);
10435 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10436 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10437 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10438 get_fpscr_rtx ()));
10439 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10440 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10444 (define_expand "abssf2"
10445 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10446 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10447 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10452 expand_sf_unop (&gen_abssf2_i, operands);
10457 (define_insn "*abssf2_media"
10458 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10459 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10460 "TARGET_SHMEDIA_FPU"
10462 [(set_attr "type" "fmove_media")])
10464 (define_insn "abssf2_i"
10465 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10466 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10467 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10470 [(set_attr "type" "fmove")
10471 (set_attr "fp_mode" "single")])
10473 (define_expand "adddf3"
10474 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10475 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10476 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10477 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10480 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10482 expand_df_binop (&gen_adddf3_i, operands);
10487 (define_insn "*adddf3_media"
10488 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10489 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10490 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10491 "TARGET_SHMEDIA_FPU"
10492 "fadd.d %1, %2, %0"
10493 [(set_attr "type" "dfparith_media")])
10495 (define_insn "adddf3_i"
10496 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10497 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10498 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10499 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10500 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10502 [(set_attr "type" "dfp_arith")
10503 (set_attr "fp_mode" "double")])
10505 (define_expand "subdf3"
10506 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10507 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10508 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10509 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10512 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10514 expand_df_binop (&gen_subdf3_i, operands);
10519 (define_insn "*subdf3_media"
10520 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10521 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10522 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10523 "TARGET_SHMEDIA_FPU"
10524 "fsub.d %1, %2, %0"
10525 [(set_attr "type" "dfparith_media")])
10527 (define_insn "subdf3_i"
10528 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10529 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10530 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10531 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10532 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10534 [(set_attr "type" "dfp_arith")
10535 (set_attr "fp_mode" "double")])
10537 (define_expand "muldf3"
10538 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10539 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10540 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10541 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10544 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10546 expand_df_binop (&gen_muldf3_i, operands);
10551 (define_insn "*muldf3_media"
10552 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10553 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10554 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10555 "TARGET_SHMEDIA_FPU"
10556 "fmul.d %1, %2, %0"
10557 [(set_attr "type" "dfmul_media")])
10559 (define_insn "muldf3_i"
10560 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10561 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10562 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10563 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10564 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10566 [(set_attr "type" "dfp_mul")
10567 (set_attr "fp_mode" "double")])
10569 (define_expand "divdf3"
10570 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10571 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10572 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10573 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10576 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10578 expand_df_binop (&gen_divdf3_i, operands);
10583 (define_insn "*divdf3_media"
10584 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10585 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10586 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10587 "TARGET_SHMEDIA_FPU"
10588 "fdiv.d %1, %2, %0"
10589 [(set_attr "type" "dfdiv_media")])
10591 (define_insn "divdf3_i"
10592 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10593 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10594 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10595 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10596 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10598 [(set_attr "type" "dfdiv")
10599 (set_attr "fp_mode" "double")])
10601 (define_insn "floatdidf2"
10602 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10603 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10604 "TARGET_SHMEDIA_FPU"
10606 [(set_attr "type" "dfpconv_media")])
10608 (define_expand "floatsidf2"
10609 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10610 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10611 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10614 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10616 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10617 get_fpscr_rtx ()));
10622 (define_insn "*floatsidf2_media"
10623 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10624 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10625 "TARGET_SHMEDIA_FPU"
10627 [(set_attr "type" "dfpconv_media")])
10629 (define_insn "floatsidf2_i"
10630 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10632 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10633 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10635 [(set_attr "type" "dfp_conv")
10636 (set_attr "fp_mode" "double")])
10638 (define_insn "fix_truncdfdi2"
10639 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10640 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10641 "TARGET_SHMEDIA_FPU"
10643 [(set_attr "type" "dfpconv_media")])
10645 (define_expand "fix_truncdfsi2"
10646 [(set (match_operand:SI 0 "fpul_operand" "")
10647 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10648 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10651 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10653 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10654 get_fpscr_rtx ()));
10659 (define_insn "*fix_truncdfsi2_media"
10660 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10661 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10662 "TARGET_SHMEDIA_FPU"
10664 [(set_attr "type" "dfpconv_media")])
10666 (define_insn "fix_truncdfsi2_i"
10667 [(set (match_operand:SI 0 "fpul_operand" "=y")
10668 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10669 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10670 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10672 [(set_attr "type" "dfp_conv")
10673 (set_attr "dfp_comp" "no")
10674 (set_attr "fp_mode" "double")])
10676 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10677 ;; fix_truncdfsi2_i.
10678 ;; (define_insn "fix_truncdfsi2_i4"
10679 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10680 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10681 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10682 ;; (clobber (reg:SI FPUL_REG))]
10685 ;; [(set_attr "length" "4")
10686 ;; (set_attr "fp_mode" "double")])
10689 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10690 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10691 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10692 ;; (clobber (reg:SI FPUL_REG))]
10694 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10695 ;; (use (match_dup 2))])
10696 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10698 (define_insn "cmpgtdf_t"
10699 [(set (reg:SI T_REG)
10700 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10701 (match_operand:DF 1 "arith_reg_operand" "f")))
10702 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10703 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10705 [(set_attr "type" "dfp_cmp")
10706 (set_attr "fp_mode" "double")])
10708 (define_insn "cmpeqdf_t"
10709 [(set (reg:SI T_REG)
10710 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10711 (match_operand:DF 1 "arith_reg_operand" "f")))
10712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10713 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10715 [(set_attr "type" "dfp_cmp")
10716 (set_attr "fp_mode" "double")])
10718 (define_insn "*ieee_ccmpeqdf_t"
10719 [(set (reg:SI T_REG)
10720 (ior:SI (reg:SI T_REG)
10721 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10722 (match_operand:DF 1 "arith_reg_operand" "f"))))
10723 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10724 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10725 "* return output_ieee_ccmpeq (insn, operands);"
10726 [(set_attr "length" "4")
10727 (set_attr "fp_mode" "double")])
10729 (define_insn "cmpeqdf_media"
10730 [(set (match_operand:SI 0 "register_operand" "=r")
10731 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10733 "TARGET_SHMEDIA_FPU"
10734 "fcmpeq.d %1,%2,%0"
10735 [(set_attr "type" "fcmp_media")])
10737 (define_insn "cmpgtdf_media"
10738 [(set (match_operand:SI 0 "register_operand" "=r")
10739 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10741 "TARGET_SHMEDIA_FPU"
10742 "fcmpgt.d %1,%2,%0"
10743 [(set_attr "type" "fcmp_media")])
10745 (define_insn "cmpgedf_media"
10746 [(set (match_operand:SI 0 "register_operand" "=r")
10747 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10748 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10749 "TARGET_SHMEDIA_FPU"
10750 "fcmpge.d %1,%2,%0"
10751 [(set_attr "type" "fcmp_media")])
10753 (define_insn "cmpundf_media"
10754 [(set (match_operand:SI 0 "register_operand" "=r")
10755 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10756 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10757 "TARGET_SHMEDIA_FPU"
10758 "fcmpun.d %1,%2,%0"
10759 [(set_attr "type" "fcmp_media")])
10761 (define_expand "cbranchdf4"
10763 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10764 [(match_operand:DF 1 "arith_operand" "")
10765 (match_operand:DF 2 "arith_operand" "")])
10766 (match_operand 3 "" "")
10768 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10771 if (TARGET_SHMEDIA)
10772 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10775 sh_emit_compare_and_branch (operands, DFmode);
10780 (define_expand "negdf2"
10781 [(set (match_operand:DF 0 "arith_reg_operand" "")
10782 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10783 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10786 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10788 expand_df_unop (&gen_negdf2_i, operands);
10793 (define_insn "*negdf2_media"
10794 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10795 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10796 "TARGET_SHMEDIA_FPU"
10798 [(set_attr "type" "fmove_media")])
10800 (define_insn "negdf2_i"
10801 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10802 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10803 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10804 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10806 [(set_attr "type" "fmove")
10807 (set_attr "fp_mode" "double")])
10809 (define_expand "sqrtdf2"
10810 [(set (match_operand:DF 0 "arith_reg_operand" "")
10811 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10812 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10815 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10817 expand_df_unop (&gen_sqrtdf2_i, operands);
10822 (define_insn "*sqrtdf2_media"
10823 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10824 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10825 "TARGET_SHMEDIA_FPU"
10827 [(set_attr "type" "dfdiv_media")])
10829 (define_insn "sqrtdf2_i"
10830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10831 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10832 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10833 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10835 [(set_attr "type" "dfdiv")
10836 (set_attr "fp_mode" "double")])
10838 (define_expand "absdf2"
10839 [(set (match_operand:DF 0 "arith_reg_operand" "")
10840 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10841 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10844 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10846 expand_df_unop (&gen_absdf2_i, operands);
10851 (define_insn "*absdf2_media"
10852 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10853 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10854 "TARGET_SHMEDIA_FPU"
10856 [(set_attr "type" "fmove_media")])
10858 (define_insn "absdf2_i"
10859 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10860 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10861 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10862 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10864 [(set_attr "type" "fmove")
10865 (set_attr "fp_mode" "double")])
10867 (define_expand "extendsfdf2"
10868 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10869 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10870 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10873 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10875 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10876 get_fpscr_rtx ()));
10881 (define_insn "*extendsfdf2_media"
10882 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10883 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10884 "TARGET_SHMEDIA_FPU"
10886 [(set_attr "type" "dfpconv_media")])
10888 (define_insn "extendsfdf2_i4"
10889 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10890 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10891 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10892 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10894 [(set_attr "type" "fp")
10895 (set_attr "fp_mode" "double")])
10897 (define_expand "truncdfsf2"
10898 [(set (match_operand:SF 0 "fpul_operand" "")
10899 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10900 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10903 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10905 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10906 get_fpscr_rtx ()));
10911 (define_insn "*truncdfsf2_media"
10912 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10913 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10914 "TARGET_SHMEDIA_FPU"
10916 [(set_attr "type" "dfpconv_media")])
10918 (define_insn "truncdfsf2_i4"
10919 [(set (match_operand:SF 0 "fpul_operand" "=y")
10920 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10921 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10922 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10924 [(set_attr "type" "fp")
10925 (set_attr "fp_mode" "double")])
10927 ;; Bit field extract patterns. These give better code for packed bitfields,
10928 ;; because they allow auto-increment addresses to be generated.
10930 (define_expand "insv"
10931 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10932 (match_operand:SI 1 "immediate_operand" "")
10933 (match_operand:SI 2 "immediate_operand" ""))
10934 (match_operand:SI 3 "general_operand" ""))]
10935 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10938 rtx addr_target, orig_address, shift_reg, qi_val;
10939 HOST_WIDE_INT bitsize, size, v = 0;
10940 rtx x = operands[3];
10942 if (TARGET_SH2A && TARGET_BITOPS
10943 && (satisfies_constraint_Sbw (operands[0])
10944 || satisfies_constraint_Sbv (operands[0]))
10945 && satisfies_constraint_M (operands[1])
10946 && satisfies_constraint_K03 (operands[2]))
10948 if (satisfies_constraint_N (operands[3]))
10950 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10953 else if (satisfies_constraint_M (operands[3]))
10955 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10958 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10959 && satisfies_constraint_M (operands[1]))
10961 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10964 else if (REG_P (operands[3])
10965 && satisfies_constraint_M (operands[1]))
10967 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10968 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10972 /* ??? expmed doesn't care for non-register predicates. */
10973 if (! memory_operand (operands[0], VOIDmode)
10974 || ! immediate_operand (operands[1], VOIDmode)
10975 || ! immediate_operand (operands[2], VOIDmode)
10976 || ! general_operand (x, VOIDmode))
10978 /* If this isn't a 16 / 24 / 32 bit field, or if
10979 it doesn't start on a byte boundary, then fail. */
10980 bitsize = INTVAL (operands[1]);
10981 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10982 || (INTVAL (operands[2]) % 8) != 0)
10985 size = bitsize / 8;
10986 orig_address = XEXP (operands[0], 0);
10987 shift_reg = gen_reg_rtx (SImode);
10988 if (CONST_INT_P (x))
10991 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10995 emit_insn (gen_movsi (shift_reg, operands[3]));
10996 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10998 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11000 operands[0] = replace_equiv_address (operands[0], addr_target);
11001 emit_insn (gen_movqi (operands[0], qi_val));
11005 if (CONST_INT_P (x))
11007 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11010 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11011 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11013 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11014 emit_insn (gen_movqi (operands[0], qi_val));
11020 (define_insn "movua"
11021 [(set (match_operand:SI 0 "register_operand" "=z")
11022 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11026 [(set_attr "type" "movua")])
11028 ;; We shouldn't need this, but cse replaces increments with references
11029 ;; to other regs before flow has a chance to create post_inc
11030 ;; addressing modes, and only postreload's cse_move2add brings the
11031 ;; increments back to a usable form.
11033 [(set (match_operand:SI 0 "register_operand" "")
11034 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11035 (const_int 32) (const_int 0)))
11036 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11037 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11038 [(set (match_operand:SI 0 "register_operand" "")
11039 (sign_extract:SI (mem:SI (post_inc:SI
11040 (match_operand:SI 1 "register_operand" "")))
11041 (const_int 32) (const_int 0)))]
11044 (define_expand "extv"
11045 [(set (match_operand:SI 0 "register_operand" "")
11046 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11047 (match_operand 2 "const_int_operand" "")
11048 (match_operand 3 "const_int_operand" "")))]
11049 "TARGET_SH4A_ARCH || TARGET_SH2A"
11051 if (TARGET_SH2A && TARGET_BITOPS
11052 && (satisfies_constraint_Sbw (operands[1])
11053 || satisfies_constraint_Sbv (operands[1]))
11054 && satisfies_constraint_M (operands[2])
11055 && satisfies_constraint_K03 (operands[3]))
11057 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11058 if (REGNO (operands[0]) != T_REG)
11059 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11062 if (TARGET_SH4A_ARCH
11063 && INTVAL (operands[2]) == 32
11064 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11065 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11067 rtx src = adjust_address (operands[1], BLKmode, 0);
11068 set_mem_size (src, 4);
11069 emit_insn (gen_movua (operands[0], src));
11076 (define_expand "extzv"
11077 [(set (match_operand:SI 0 "register_operand" "")
11078 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11079 (match_operand 2 "const_int_operand" "")
11080 (match_operand 3 "const_int_operand" "")))]
11081 "TARGET_SH4A_ARCH || TARGET_SH2A"
11083 if (TARGET_SH2A && TARGET_BITOPS
11084 && (satisfies_constraint_Sbw (operands[1])
11085 || satisfies_constraint_Sbv (operands[1]))
11086 && satisfies_constraint_M (operands[2])
11087 && satisfies_constraint_K03 (operands[3]))
11089 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11090 if (REGNO (operands[0]) != T_REG)
11091 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11094 if (TARGET_SH4A_ARCH
11095 && INTVAL (operands[2]) == 32
11096 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11097 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11099 rtx src = adjust_address (operands[1], BLKmode, 0);
11100 set_mem_size (src, 4);
11101 emit_insn (gen_movua (operands[0], src));
11108 ;; SH2A instructions for bitwise operations.
11110 ;; Clear a bit in a memory location.
11111 (define_insn "bclr_m2a"
11112 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11114 (not:QI (ashift:QI (const_int 1)
11115 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11117 "TARGET_SH2A && TARGET_BITOPS"
11120 bclr.b\\t%1,@(0,%t0)"
11121 [(set_attr "length" "4,4")])
11123 (define_insn "bclrmem_m2a"
11124 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11125 (and:QI (match_dup 0)
11126 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11127 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11130 bclr.b\\t%W1,@(0,%t0)"
11131 [(set_attr "length" "4,4")])
11133 ;; Set a bit in a memory location.
11134 (define_insn "bset_m2a"
11135 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11137 (ashift:QI (const_int 1)
11138 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11140 "TARGET_SH2A && TARGET_BITOPS"
11143 bset.b\\t%1,@(0,%t0)"
11144 [(set_attr "length" "4,4")])
11146 (define_insn "bsetmem_m2a"
11147 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11148 (ior:QI (match_dup 0)
11149 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11150 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11153 bset.b\\t%V1,@(0,%t0)"
11154 [(set_attr "length" "4,4")])
11156 ;;; Transfer the contents of the T bit to a specified bit of memory.
11157 (define_insn "bst_m2a"
11158 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11159 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11161 (not:QI (ashift:QI (const_int 1)
11162 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11165 (ashift:QI (const_int 1) (match_dup 1))
11167 "TARGET_SH2A && TARGET_BITOPS"
11170 bst.b\\t%1,@(0,%t0)"
11171 [(set_attr "length" "4")])
11173 ;; Store a specified bit of memory in the T bit.
11174 (define_insn "bld_m2a"
11175 [(set (reg:SI T_REG)
11177 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11179 (match_operand 1 "const_int_operand" "K03,K03")))]
11180 "TARGET_SH2A && TARGET_BITOPS"
11183 bld.b\\t%1,@(0,%t0)"
11184 [(set_attr "length" "4,4")])
11186 ;; Store a specified bit of memory in the T bit.
11187 (define_insn "bldsign_m2a"
11188 [(set (reg:SI T_REG)
11190 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11192 (match_operand 1 "const_int_operand" "K03,K03")))]
11193 "TARGET_SH2A && TARGET_BITOPS"
11196 bld.b\\t%1,@(0,%t0)"
11197 [(set_attr "length" "4,4")])
11199 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11200 (define_insn "bld_reg"
11201 [(set (reg:SI T_REG)
11202 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11204 (match_operand 1 "const_int_operand" "K03")))]
11208 (define_insn "*bld_regqi"
11209 [(set (reg:SI T_REG)
11210 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11212 (match_operand 1 "const_int_operand" "K03")))]
11216 ;; Take logical and of a specified bit of memory with the T bit and
11217 ;; store its result in the T bit.
11218 (define_insn "band_m2a"
11219 [(set (reg:SI T_REG)
11220 (and:SI (reg:SI T_REG)
11222 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11224 (match_operand 1 "const_int_operand" "K03,K03"))))]
11225 "TARGET_SH2A && TARGET_BITOPS"
11228 band.b\\t%1,@(0,%t0)"
11229 [(set_attr "length" "4,4")])
11231 (define_insn "bandreg_m2a"
11232 [(set (match_operand:SI 0 "register_operand" "=r,r")
11233 (and:SI (zero_extract:SI
11234 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11236 (match_operand 2 "const_int_operand" "K03,K03"))
11237 (match_operand:SI 3 "register_operand" "r,r")))]
11238 "TARGET_SH2A && TARGET_BITOPS"
11240 band.b\\t%2,%1\;movt\\t%0
11241 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11242 [(set_attr "length" "6,6")])
11244 ;; Take logical or of a specified bit of memory with the T bit and
11245 ;; store its result in the T bit.
11246 (define_insn "bor_m2a"
11247 [(set (reg:SI T_REG)
11248 (ior:SI (reg:SI T_REG)
11250 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11252 (match_operand 1 "const_int_operand" "K03,K03"))))]
11253 "TARGET_SH2A && TARGET_BITOPS"
11256 bor.b\\t%1,@(0,%t0)"
11257 [(set_attr "length" "4,4")])
11259 (define_insn "borreg_m2a"
11260 [(set (match_operand:SI 0 "register_operand" "=r,r")
11261 (ior:SI (zero_extract:SI
11262 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11264 (match_operand 2 "const_int_operand" "K03,K03"))
11265 (match_operand:SI 3 "register_operand" "=r,r")))]
11266 "TARGET_SH2A && TARGET_BITOPS"
11268 bor.b\\t%2,%1\;movt\\t%0
11269 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11270 [(set_attr "length" "6,6")])
11272 ;; Take exclusive or of a specified bit of memory with the T bit and
11273 ;; store its result in the T bit.
11274 (define_insn "bxor_m2a"
11275 [(set (reg:SI T_REG)
11276 (xor:SI (reg:SI T_REG)
11278 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11280 (match_operand 1 "const_int_operand" "K03,K03"))))]
11281 "TARGET_SH2A && TARGET_BITOPS"
11284 bxor.b\\t%1,@(0,%t0)"
11285 [(set_attr "length" "4,4")])
11287 (define_insn "bxorreg_m2a"
11288 [(set (match_operand:SI 0 "register_operand" "=r,r")
11289 (xor:SI (zero_extract:SI
11290 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11292 (match_operand 2 "const_int_operand" "K03,K03"))
11293 (match_operand:SI 3 "register_operand" "=r,r")))]
11294 "TARGET_SH2A && TARGET_BITOPS"
11296 bxor.b\\t%2,%1\;movt\\t%0
11297 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11298 [(set_attr "length" "6,6")])
11301 ;; -------------------------------------------------------------------------
11303 ;; -------------------------------------------------------------------------
11304 ;; This matches cases where the bit in a memory location is set.
11306 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11307 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11309 (ior:SI (match_dup 0)
11310 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11312 (match_operand 3 "arith_reg_operand" "r,r"))]
11313 "TARGET_SH2A && TARGET_BITOPS
11314 && satisfies_constraint_Pso (operands[2])
11315 && REGNO (operands[0]) == REGNO (operands[3])"
11316 [(set (match_dup 1)
11317 (ior:QI (match_dup 1)
11321 ;; This matches cases where the bit in a memory location is cleared.
11323 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11324 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11326 (and:SI (match_dup 0)
11327 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11329 (match_operand 3 "arith_reg_operand" "r,r"))]
11330 "TARGET_SH2A && TARGET_BITOPS
11331 && satisfies_constraint_Psz (operands[2])
11332 && REGNO (operands[0]) == REGNO (operands[3])"
11333 [(set (match_dup 1)
11334 (and:QI (match_dup 1)
11338 ;; This matches cases where a stack pointer increment at the start of the
11339 ;; epilogue combines with a stack slot read loading the return value.
11342 [(set (match_operand:SI 0 "arith_reg_operand" "")
11343 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11344 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11345 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11348 ;; See the comment on the dt combiner pattern above.
11351 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11352 (plus:SI (match_dup 0)
11354 (set (reg:SI T_REG)
11355 (eq:SI (match_dup 0)
11360 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11361 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11362 ;; reload when the constant is too large for a reg+offset address.
11364 ;; ??? We would get much better code if this was done in reload. This would
11365 ;; require modifying find_reloads_address to recognize that if the constant
11366 ;; is out-of-range for an immediate add, then we get better code by reloading
11367 ;; the constant into a register than by reloading the sum into a register,
11368 ;; since the former is one instruction shorter if the address does not need
11369 ;; to be offsettable. Unfortunately this does not work, because there is
11370 ;; only one register, r0, that can be used as an index register. This register
11371 ;; is also the function return value register. So, if we try to force reload
11372 ;; to use double-reg addresses, then we end up with some instructions that
11373 ;; need to use r0 twice. The only way to fix this is to change the calling
11374 ;; convention so that r0 is not used to return values.
11377 [(set (match_operand:SI 0 "register_operand" "=r")
11378 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11379 (set (mem:SI (match_dup 0))
11380 (match_operand:SI 2 "general_movsrc_operand" ""))]
11381 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11382 "mov.l %2,@(%0,%1)")
11385 [(set (match_operand:SI 0 "register_operand" "=r")
11386 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11387 (set (match_operand:SI 2 "general_movdst_operand" "")
11388 (mem:SI (match_dup 0)))]
11389 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11390 "mov.l @(%0,%1),%2")
11393 [(set (match_operand:SI 0 "register_operand" "=r")
11394 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11395 (set (mem:HI (match_dup 0))
11396 (match_operand:HI 2 "general_movsrc_operand" ""))]
11397 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11398 "mov.w %2,@(%0,%1)")
11401 [(set (match_operand:SI 0 "register_operand" "=r")
11402 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11403 (set (match_operand:HI 2 "general_movdst_operand" "")
11404 (mem:HI (match_dup 0)))]
11405 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11406 "mov.w @(%0,%1),%2")
11409 [(set (match_operand:SI 0 "register_operand" "=r")
11410 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11411 (set (mem:QI (match_dup 0))
11412 (match_operand:QI 2 "general_movsrc_operand" ""))]
11413 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11414 "mov.b %2,@(%0,%1)")
11417 [(set (match_operand:SI 0 "register_operand" "=r")
11418 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11419 (set (match_operand:QI 2 "general_movdst_operand" "")
11420 (mem:QI (match_dup 0)))]
11421 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11422 "mov.b @(%0,%1),%2")
11425 [(set (match_operand:SI 0 "register_operand" "=r")
11426 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11427 (set (mem:SF (match_dup 0))
11428 (match_operand:SF 2 "general_movsrc_operand" ""))]
11429 "TARGET_SH1 && REGNO (operands[0]) == 0
11430 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11431 || (GET_CODE (operands[2]) == SUBREG
11432 && REGNO (SUBREG_REG (operands[2])) < 16))
11433 && reg_unused_after (operands[0], insn)"
11434 "mov.l %2,@(%0,%1)")
11437 [(set (match_operand:SI 0 "register_operand" "=r")
11438 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11439 (set (match_operand:SF 2 "general_movdst_operand" "")
11441 (mem:SF (match_dup 0)))]
11442 "TARGET_SH1 && REGNO (operands[0]) == 0
11443 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11444 || (GET_CODE (operands[2]) == SUBREG
11445 && REGNO (SUBREG_REG (operands[2])) < 16))
11446 && reg_unused_after (operands[0], insn)"
11447 "mov.l @(%0,%1),%2")
11450 [(set (match_operand:SI 0 "register_operand" "=r")
11451 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11452 (set (mem:SF (match_dup 0))
11453 (match_operand:SF 2 "general_movsrc_operand" ""))]
11454 "TARGET_SH2E && REGNO (operands[0]) == 0
11455 && ((REG_P (operands[2])
11456 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11457 || (GET_CODE (operands[2]) == SUBREG
11458 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11459 && reg_unused_after (operands[0], insn)"
11460 "fmov{.s|} %2,@(%0,%1)")
11463 [(set (match_operand:SI 0 "register_operand" "=r")
11464 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11465 (set (match_operand:SF 2 "general_movdst_operand" "")
11467 (mem:SF (match_dup 0)))]
11468 "TARGET_SH2E && REGNO (operands[0]) == 0
11469 && ((REG_P (operands[2])
11470 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11471 || (GET_CODE (operands[2]) == SUBREG
11472 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11473 && reg_unused_after (operands[0], insn)"
11474 "fmov{.s|} @(%0,%1),%2")
11476 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11477 (define_insn "sp_switch_1"
11478 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11482 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11483 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11484 return \"mov r0,r15\";
11486 [(set_attr "length" "10")])
11488 ;; Switch back to the original stack for interrupt functions with the
11489 ;; sp_switch attribute. */
11490 (define_insn "sp_switch_2"
11493 "mov.l @r15+,r15\;mov.l @r15+,r0"
11494 [(set_attr "length" "4")])
11496 ;; Integer vector moves
11498 (define_expand "movv8qi"
11499 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11500 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11502 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11504 (define_insn "movv8qi_i"
11505 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11506 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11508 && (register_operand (operands[0], V8QImode)
11509 || sh_register_operand (operands[1], V8QImode))"
11516 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11517 (set_attr "length" "4,4,16,4,4")])
11520 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11521 (subreg:V8QI (const_int 0) 0))]
11523 [(set (match_dup 0)
11524 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11525 (const_int 0) (const_int 0) (const_int 0)
11526 (const_int 0) (const_int 0)]))])
11529 [(set (match_operand 0 "arith_reg_dest" "")
11530 (match_operand 1 "sh_rep_vec" ""))]
11531 "TARGET_SHMEDIA && reload_completed
11532 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11533 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11534 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11535 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11536 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11537 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11538 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11539 [(set (match_dup 0) (match_dup 1))
11543 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11544 rtx elt1 = XVECEXP (operands[1], 0, 1);
11547 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11551 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11552 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11554 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11555 operands[1] = XVECEXP (operands[1], 0, 0);
11558 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11560 = GEN_INT (TARGET_LITTLE_ENDIAN
11561 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11562 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11565 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11567 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11573 [(set (match_operand 0 "arith_reg_dest" "")
11574 (match_operand 1 "sh_const_vec" ""))]
11575 "TARGET_SHMEDIA && reload_completed
11576 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11577 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11578 [(set (match_dup 0) (match_dup 1))]
11581 rtx v = operands[1];
11582 enum machine_mode new_mode
11583 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11585 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11587 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11590 (define_expand "movv2hi"
11591 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11592 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11594 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11596 (define_insn "movv2hi_i"
11597 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11598 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11600 && (register_operand (operands[0], V2HImode)
11601 || sh_register_operand (operands[1], V2HImode))"
11608 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11609 (set_attr "length" "4,4,16,4,4")
11610 (set (attr "highpart")
11611 (cond [(match_test "sh_contains_memref_p (insn)")
11612 (const_string "user")]
11613 (const_string "ignore")))])
11615 (define_expand "movv4hi"
11616 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11617 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11619 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11621 (define_insn "movv4hi_i"
11622 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11623 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11625 && (register_operand (operands[0], V4HImode)
11626 || sh_register_operand (operands[1], V4HImode))"
11633 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11634 (set_attr "length" "4,4,16,4,4")
11635 (set_attr "highpart" "depend")])
11637 (define_expand "movv2si"
11638 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11639 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11641 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11643 (define_insn "movv2si_i"
11644 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11645 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11647 && (register_operand (operands[0], V2SImode)
11648 || sh_register_operand (operands[1], V2SImode))"
11655 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11656 (set_attr "length" "4,4,16,4,4")
11657 (set_attr "highpart" "depend")])
11659 ;; Multimedia Intrinsics
11661 (define_insn "absv2si2"
11662 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11663 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11666 [(set_attr "type" "mcmp_media")
11667 (set_attr "highpart" "depend")])
11669 (define_insn "absv4hi2"
11670 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11671 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11674 [(set_attr "type" "mcmp_media")
11675 (set_attr "highpart" "depend")])
11677 (define_insn "addv2si3"
11678 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11679 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11680 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11682 "madd.l %1, %2, %0"
11683 [(set_attr "type" "arith_media")
11684 (set_attr "highpart" "depend")])
11686 (define_insn "addv4hi3"
11687 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11688 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11689 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11691 "madd.w %1, %2, %0"
11692 [(set_attr "type" "arith_media")
11693 (set_attr "highpart" "depend")])
11695 (define_insn_and_split "addv2hi3"
11696 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11697 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11698 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11705 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11706 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11707 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11708 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11709 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11711 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11712 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11715 [(set_attr "highpart" "must_split")])
11717 (define_insn "ssaddv2si3"
11718 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11719 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11720 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11722 "madds.l %1, %2, %0"
11723 [(set_attr "type" "mcmp_media")
11724 (set_attr "highpart" "depend")])
11726 (define_insn "usaddv8qi3"
11727 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11728 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11729 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11731 "madds.ub %1, %2, %0"
11732 [(set_attr "type" "mcmp_media")
11733 (set_attr "highpart" "depend")])
11735 (define_insn "ssaddv4hi3"
11736 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11737 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11738 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11740 "madds.w %1, %2, %0"
11741 [(set_attr "type" "mcmp_media")
11742 (set_attr "highpart" "depend")])
11744 (define_insn "negcmpeqv8qi"
11745 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11746 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11747 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11749 "mcmpeq.b %N1, %N2, %0"
11750 [(set_attr "type" "mcmp_media")
11751 (set_attr "highpart" "depend")])
11753 (define_insn "negcmpeqv2si"
11754 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11755 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11756 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11758 "mcmpeq.l %N1, %N2, %0"
11759 [(set_attr "type" "mcmp_media")
11760 (set_attr "highpart" "depend")])
11762 (define_insn "negcmpeqv4hi"
11763 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11764 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11765 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11767 "mcmpeq.w %N1, %N2, %0"
11768 [(set_attr "type" "mcmp_media")
11769 (set_attr "highpart" "depend")])
11771 (define_insn "negcmpgtuv8qi"
11772 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11773 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11774 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11776 "mcmpgt.ub %N1, %N2, %0"
11777 [(set_attr "type" "mcmp_media")
11778 (set_attr "highpart" "depend")])
11780 (define_insn "negcmpgtv2si"
11781 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11782 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11783 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11785 "mcmpgt.l %N1, %N2, %0"
11786 [(set_attr "type" "mcmp_media")
11787 (set_attr "highpart" "depend")])
11789 (define_insn "negcmpgtv4hi"
11790 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11791 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11792 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11794 "mcmpgt.w %N1, %N2, %0"
11795 [(set_attr "type" "mcmp_media")
11796 (set_attr "highpart" "depend")])
11798 (define_insn "mcmv"
11799 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11800 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11801 (match_operand:DI 2 "arith_reg_operand" "r"))
11802 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11803 (not:DI (match_dup 2)))))]
11806 [(set_attr "type" "arith_media")
11807 (set_attr "highpart" "depend")])
11809 (define_insn "mcnvs_lw"
11810 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11812 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11813 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11815 "mcnvs.lw %N1, %N2, %0"
11816 [(set_attr "type" "mcmp_media")])
11818 (define_insn "mcnvs_wb"
11819 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11821 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11822 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11824 "mcnvs.wb %N1, %N2, %0"
11825 [(set_attr "type" "mcmp_media")])
11827 (define_insn "mcnvs_wub"
11828 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11830 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11831 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11833 "mcnvs.wub %N1, %N2, %0"
11834 [(set_attr "type" "mcmp_media")])
11836 (define_insn "mextr_rl"
11837 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11838 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11839 (match_operand:HI 3 "mextr_bit_offset" "i"))
11840 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11841 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11842 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11845 static char templ[21];
11847 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11848 (int) INTVAL (operands[3]) >> 3);
11851 [(set_attr "type" "arith_media")])
11853 (define_insn "*mextr_lr"
11854 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11855 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11856 (match_operand:HI 3 "mextr_bit_offset" "i"))
11857 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11858 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11859 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11862 static char templ[21];
11864 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11865 (int) INTVAL (operands[4]) >> 3);
11868 [(set_attr "type" "arith_media")])
11870 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11871 ; vector then varies depending on endianness.
11872 (define_expand "mextr1"
11873 [(match_operand:DI 0 "arith_reg_dest" "")
11874 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11875 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11879 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11880 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11884 (define_expand "mextr2"
11885 [(match_operand:DI 0 "arith_reg_dest" "")
11886 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11887 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11891 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11892 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11896 (define_expand "mextr3"
11897 [(match_operand:DI 0 "arith_reg_dest" "")
11898 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11899 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11903 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11904 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11908 (define_expand "mextr4"
11909 [(match_operand:DI 0 "arith_reg_dest" "")
11910 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11911 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11915 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11916 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11920 (define_expand "mextr5"
11921 [(match_operand:DI 0 "arith_reg_dest" "")
11922 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11923 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11927 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11928 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11932 (define_expand "mextr6"
11933 [(match_operand:DI 0 "arith_reg_dest" "")
11934 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11935 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11939 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11940 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11944 (define_expand "mextr7"
11945 [(match_operand:DI 0 "arith_reg_dest" "")
11946 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11947 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11951 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11952 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11956 (define_expand "mmacfx_wl"
11957 [(match_operand:V2SI 0 "arith_reg_dest" "")
11958 (match_operand:V2HI 1 "extend_reg_operand" "")
11959 (match_operand:V2HI 2 "extend_reg_operand" "")
11960 (match_operand:V2SI 3 "arith_reg_operand" "")]
11964 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11965 operands[1], operands[2]));
11969 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11971 (define_insn "mmacfx_wl_i"
11972 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11974 (match_operand:V2SI 1 "arith_reg_operand" "0")
11979 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11980 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11983 "mmacfx.wl %2, %3, %0"
11984 [(set_attr "type" "mac_media")
11985 (set_attr "highpart" "depend")])
11987 (define_expand "mmacnfx_wl"
11988 [(match_operand:V2SI 0 "arith_reg_dest" "")
11989 (match_operand:V2HI 1 "extend_reg_operand" "")
11990 (match_operand:V2HI 2 "extend_reg_operand" "")
11991 (match_operand:V2SI 3 "arith_reg_operand" "")]
11995 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11996 operands[1], operands[2]));
12000 (define_insn "mmacnfx_wl_i"
12001 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12003 (match_operand:V2SI 1 "arith_reg_operand" "0")
12008 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12009 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12012 "mmacnfx.wl %2, %3, %0"
12013 [(set_attr "type" "mac_media")
12014 (set_attr "highpart" "depend")])
12016 (define_insn "mulv2si3"
12017 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12018 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12019 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12021 "mmul.l %1, %2, %0"
12022 [(set_attr "type" "d2mpy_media")
12023 (set_attr "highpart" "depend")])
12025 (define_insn "mulv4hi3"
12026 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12027 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12028 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12030 "mmul.w %1, %2, %0"
12031 [(set_attr "type" "dmpy_media")
12032 (set_attr "highpart" "depend")])
12034 (define_insn "mmulfx_l"
12035 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12039 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12040 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12043 "mmulfx.l %1, %2, %0"
12044 [(set_attr "type" "d2mpy_media")
12045 (set_attr "highpart" "depend")])
12047 (define_insn "mmulfx_w"
12048 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12052 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12053 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12056 "mmulfx.w %1, %2, %0"
12057 [(set_attr "type" "dmpy_media")
12058 (set_attr "highpart" "depend")])
12060 (define_insn "mmulfxrp_w"
12061 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12066 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12067 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12071 "mmulfxrp.w %1, %2, %0"
12072 [(set_attr "type" "dmpy_media")
12073 (set_attr "highpart" "depend")])
12076 (define_expand "mmulhi_wl"
12077 [(match_operand:V2SI 0 "arith_reg_dest" "")
12078 (match_operand:V4HI 1 "arith_reg_operand" "")
12079 (match_operand:V4HI 2 "arith_reg_operand" "")]
12083 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12084 (operands[0], operands[1], operands[2]));
12088 (define_expand "mmullo_wl"
12089 [(match_operand:V2SI 0 "arith_reg_dest" "")
12090 (match_operand:V4HI 1 "arith_reg_operand" "")
12091 (match_operand:V4HI 2 "arith_reg_operand" "")]
12095 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12096 (operands[0], operands[1], operands[2]));
12100 (define_insn "mmul23_wl"
12101 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12104 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12105 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12106 (parallel [(const_int 2) (const_int 3)])))]
12108 "* return (TARGET_LITTLE_ENDIAN
12109 ? \"mmulhi.wl %1, %2, %0\"
12110 : \"mmullo.wl %1, %2, %0\");"
12111 [(set_attr "type" "dmpy_media")
12112 (set (attr "highpart")
12113 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12114 (const_string "user")))])
12116 (define_insn "mmul01_wl"
12117 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12120 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12121 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12122 (parallel [(const_int 0) (const_int 1)])))]
12124 "* return (TARGET_LITTLE_ENDIAN
12125 ? \"mmullo.wl %1, %2, %0\"
12126 : \"mmulhi.wl %1, %2, %0\");"
12127 [(set_attr "type" "dmpy_media")
12128 (set (attr "highpart")
12129 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12130 (const_string "user")))])
12133 (define_expand "mmulsum_wq"
12134 [(match_operand:DI 0 "arith_reg_dest" "")
12135 (match_operand:V4HI 1 "arith_reg_operand" "")
12136 (match_operand:V4HI 2 "arith_reg_operand" "")
12137 (match_operand:DI 3 "arith_reg_operand" "")]
12141 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12142 operands[1], operands[2]));
12146 (define_insn "mmulsum_wq_i"
12147 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12148 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12153 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12154 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12155 (parallel [(const_int 0)]))
12156 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12157 (sign_extend:V4DI (match_dup 3)))
12158 (parallel [(const_int 1)])))
12160 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12161 (sign_extend:V4DI (match_dup 3)))
12162 (parallel [(const_int 2)]))
12163 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12164 (sign_extend:V4DI (match_dup 3)))
12165 (parallel [(const_int 3)]))))))]
12167 "mmulsum.wq %2, %3, %0"
12168 [(set_attr "type" "mac_media")])
12170 (define_expand "mperm_w"
12171 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12172 (match_operand:V4HI 1 "arith_reg_operand" "r")
12173 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12177 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12178 (operands[0], operands[1], operands[2]));
12182 ; This use of vec_select isn't exactly correct according to rtl.texi
12183 ; (because not constant), but it seems a straightforward extension.
12184 (define_insn "mperm_w_little"
12185 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12187 (match_operand:V4HI 1 "arith_reg_operand" "r")
12189 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12190 (const_int 2) (const_int 0))
12191 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12192 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12193 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12194 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12195 "mperm.w %1, %N2, %0"
12196 [(set_attr "type" "arith_media")])
12198 (define_insn "mperm_w_big"
12199 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12201 (match_operand:V4HI 1 "arith_reg_operand" "r")
12203 [(zero_extract:QI (not:QI (match_operand:QI 2
12204 "extend_reg_or_0_operand" "rZ"))
12205 (const_int 2) (const_int 0))
12206 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12207 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12208 (zero_extract:QI (not:QI (match_dup 2))
12209 (const_int 2) (const_int 6))])))]
12210 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12211 "mperm.w %1, %N2, %0"
12212 [(set_attr "type" "arith_media")])
12214 (define_insn "mperm_w0"
12215 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12216 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12217 "trunc_hi_operand" "r"))))]
12219 "mperm.w %1, r63, %0"
12220 [(set_attr "type" "arith_media")
12221 (set_attr "highpart" "ignore")])
12223 (define_expand "msad_ubq"
12224 [(match_operand:DI 0 "arith_reg_dest" "")
12225 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12226 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12227 (match_operand:DI 3 "arith_reg_operand" "")]
12231 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12232 operands[1], operands[2]));
12236 (define_insn "msad_ubq_i"
12237 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12242 (match_operand:DI 1 "arith_reg_operand" "0")
12243 (abs:DI (vec_select:DI
12246 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12248 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12249 (parallel [(const_int 0)]))))
12250 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12251 (zero_extend:V8DI (match_dup 3)))
12252 (parallel [(const_int 1)]))))
12254 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12255 (zero_extend:V8DI (match_dup 3)))
12256 (parallel [(const_int 2)])))
12257 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12258 (zero_extend:V8DI (match_dup 3)))
12259 (parallel [(const_int 3)])))))
12262 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12263 (zero_extend:V8DI (match_dup 3)))
12264 (parallel [(const_int 4)])))
12265 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12266 (zero_extend:V8DI (match_dup 3)))
12267 (parallel [(const_int 5)]))))
12269 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12270 (zero_extend:V8DI (match_dup 3)))
12271 (parallel [(const_int 6)])))
12272 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12273 (zero_extend:V8DI (match_dup 3)))
12274 (parallel [(const_int 7)])))))))]
12276 "msad.ubq %N2, %N3, %0"
12277 [(set_attr "type" "mac_media")])
12279 (define_insn "mshalds_l"
12280 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12283 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12284 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12285 (const_int 31)))))]
12287 "mshalds.l %1, %2, %0"
12288 [(set_attr "type" "mcmp_media")
12289 (set_attr "highpart" "depend")])
12291 (define_insn "mshalds_w"
12292 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12295 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12296 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12297 (const_int 15)))))]
12299 "mshalds.w %1, %2, %0"
12300 [(set_attr "type" "mcmp_media")
12301 (set_attr "highpart" "depend")])
12303 (define_insn "ashrv2si3"
12304 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12305 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12306 (match_operand:DI 2 "arith_reg_operand" "r")))]
12308 "mshard.l %1, %2, %0"
12309 [(set_attr "type" "arith_media")
12310 (set_attr "highpart" "depend")])
12312 (define_insn "ashrv4hi3"
12313 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12314 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12315 (match_operand:DI 2 "arith_reg_operand" "r")))]
12317 "mshard.w %1, %2, %0"
12318 [(set_attr "type" "arith_media")
12319 (set_attr "highpart" "depend")])
12321 (define_insn "mshards_q"
12322 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12324 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12325 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12327 "mshards.q %1, %N2, %0"
12328 [(set_attr "type" "mcmp_media")])
12330 (define_expand "mshfhi_b"
12331 [(match_operand:V8QI 0 "arith_reg_dest" "")
12332 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12333 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12337 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12338 (operands[0], operands[1], operands[2]));
12342 (define_expand "mshflo_b"
12343 [(match_operand:V8QI 0 "arith_reg_dest" "")
12344 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12345 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12349 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12350 (operands[0], operands[1], operands[2]));
12354 (define_insn "mshf4_b"
12356 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12358 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12359 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12360 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12361 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12363 "* return (TARGET_LITTLE_ENDIAN
12364 ? \"mshfhi.b %N1, %N2, %0\"
12365 : \"mshflo.b %N1, %N2, %0\");"
12366 [(set_attr "type" "arith_media")
12367 (set (attr "highpart")
12368 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12369 (const_string "user")))])
12371 (define_insn "mshf0_b"
12373 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12375 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12376 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12377 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12378 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12380 "* return (TARGET_LITTLE_ENDIAN
12381 ? \"mshflo.b %N1, %N2, %0\"
12382 : \"mshfhi.b %N1, %N2, %0\");"
12383 [(set_attr "type" "arith_media")
12384 (set (attr "highpart")
12385 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12386 (const_string "user")))])
12388 (define_expand "mshfhi_l"
12389 [(match_operand:V2SI 0 "arith_reg_dest" "")
12390 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12391 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12395 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12396 (operands[0], operands[1], operands[2]));
12400 (define_expand "mshflo_l"
12401 [(match_operand:V2SI 0 "arith_reg_dest" "")
12402 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12403 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12407 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12408 (operands[0], operands[1], operands[2]));
12412 (define_insn "mshf4_l"
12413 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12415 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12416 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12417 (parallel [(const_int 1) (const_int 3)])))]
12419 "* return (TARGET_LITTLE_ENDIAN
12420 ? \"mshfhi.l %N1, %N2, %0\"
12421 : \"mshflo.l %N1, %N2, %0\");"
12422 [(set_attr "type" "arith_media")
12423 (set (attr "highpart")
12424 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12425 (const_string "user")))])
12427 (define_insn "mshf0_l"
12428 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12430 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12431 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12432 (parallel [(const_int 0) (const_int 2)])))]
12434 "* return (TARGET_LITTLE_ENDIAN
12435 ? \"mshflo.l %N1, %N2, %0\"
12436 : \"mshfhi.l %N1, %N2, %0\");"
12437 [(set_attr "type" "arith_media")
12438 (set (attr "highpart")
12439 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12440 (const_string "user")))])
12442 (define_expand "mshfhi_w"
12443 [(match_operand:V4HI 0 "arith_reg_dest" "")
12444 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12445 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12449 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12450 (operands[0], operands[1], operands[2]));
12454 (define_expand "mshflo_w"
12455 [(match_operand:V4HI 0 "arith_reg_dest" "")
12456 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12457 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12461 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12462 (operands[0], operands[1], operands[2]));
12466 (define_insn "mshf4_w"
12467 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12469 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12470 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12471 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12473 "* return (TARGET_LITTLE_ENDIAN
12474 ? \"mshfhi.w %N1, %N2, %0\"
12475 : \"mshflo.w %N1, %N2, %0\");"
12476 [(set_attr "type" "arith_media")
12477 (set (attr "highpart")
12478 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12479 (const_string "user")))])
12481 (define_insn "mshf0_w"
12482 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12484 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12485 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12486 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12488 "* return (TARGET_LITTLE_ENDIAN
12489 ? \"mshflo.w %N1, %N2, %0\"
12490 : \"mshfhi.w %N1, %N2, %0\");"
12491 [(set_attr "type" "arith_media")
12492 (set (attr "highpart")
12493 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12494 (const_string "user")))])
12496 (define_insn "mshflo_w_x"
12497 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12499 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12500 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12501 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12503 "mshflo.w %N1, %N2, %0"
12504 [(set_attr "type" "arith_media")
12505 (set_attr "highpart" "ignore")])
12507 /* These are useful to expand ANDs and as combiner patterns. */
12508 (define_insn_and_split "mshfhi_l_di"
12509 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12510 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12512 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12513 (const_int -4294967296))))]
12516 mshfhi.l %N1, %N2, %0
12518 "TARGET_SHMEDIA && reload_completed
12519 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12520 [(set (match_dup 3) (match_dup 4))
12521 (set (match_dup 5) (match_dup 6))]
12524 operands[3] = gen_lowpart (SImode, operands[0]);
12525 operands[4] = gen_highpart (SImode, operands[1]);
12526 operands[5] = gen_highpart (SImode, operands[0]);
12527 operands[6] = gen_highpart (SImode, operands[2]);
12529 [(set_attr "type" "arith_media")])
12531 (define_insn "*mshfhi_l_di_rev"
12532 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12533 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12534 (const_int -4294967296))
12535 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12538 "mshfhi.l %N2, %N1, %0"
12539 [(set_attr "type" "arith_media")])
12542 [(set (match_operand:DI 0 "arith_reg_dest" "")
12543 (ior:DI (zero_extend:DI (match_operand:SI 1
12544 "extend_reg_or_0_operand" ""))
12545 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12546 (const_int -4294967296))))
12547 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12552 emit_insn (gen_ashldi3_media (operands[3],
12553 simplify_gen_subreg (DImode, operands[1],
12556 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12560 (define_insn "mshflo_l_di"
12561 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12562 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12563 (const_int 4294967295))
12564 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12568 "mshflo.l %N1, %N2, %0"
12569 [(set_attr "type" "arith_media")
12570 (set_attr "highpart" "ignore")])
12572 (define_insn "*mshflo_l_di_rev"
12573 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12574 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12576 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12577 (const_int 4294967295))))]
12580 "mshflo.l %N2, %N1, %0"
12581 [(set_attr "type" "arith_media")
12582 (set_attr "highpart" "ignore")])
12584 ;; Combiner pattern for trampoline initialization.
12585 (define_insn_and_split "*double_shori"
12586 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12587 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12589 (match_operand:DI 2 "const_int_operand" "n")))]
12591 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12593 "rtx_equal_p (operands[0], operands[1])"
12597 HOST_WIDE_INT v = INTVAL (operands[2]);
12599 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12600 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12603 [(set_attr "highpart" "ignore")])
12606 (define_insn "*mshflo_l_di_x"
12607 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12608 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12610 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12614 "mshflo.l %N1, %N2, %0"
12615 [(set_attr "type" "arith_media")
12616 (set_attr "highpart" "ignore")])
12618 (define_insn_and_split "concat_v2sf"
12619 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12620 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12621 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12622 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12626 mshflo.l %N1, %N2, %0
12629 "TARGET_SHMEDIA && reload_completed
12630 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12631 [(set (match_dup 3) (match_dup 1))
12632 (set (match_dup 4) (match_dup 2))]
12635 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12636 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12638 [(set_attr "type" "arith_media")
12639 (set_attr "highpart" "ignore")])
12641 (define_insn "*mshflo_l_di_x_rev"
12642 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12643 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12645 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12648 "mshflo.l %N2, %N1, %0"
12649 [(set_attr "type" "arith_media")
12650 (set_attr "highpart" "ignore")])
12652 (define_insn "ashlv2si3"
12653 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12654 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12655 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12657 "mshlld.l %1, %2, %0"
12658 [(set_attr "type" "arith_media")
12659 (set_attr "highpart" "depend")])
12662 [(set (match_operand 0 "any_register_operand" "")
12663 (match_operator 3 "shift_operator"
12664 [(match_operand 1 "any_register_operand" "")
12665 (match_operand 2 "shift_count_reg_operand" "")]))]
12666 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12667 [(set (match_dup 0) (match_dup 3))]
12670 rtx count = operands[2];
12671 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12673 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12674 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12675 || GET_CODE (count) == TRUNCATE)
12676 count = XEXP (count, 0);
12677 inner_mode = GET_MODE (count);
12678 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12679 subreg_lowpart_offset (outer_mode, inner_mode));
12680 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12681 operands[1], count);
12684 (define_insn "ashlv4hi3"
12685 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12686 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12687 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12689 "mshlld.w %1, %2, %0"
12690 [(set_attr "type" "arith_media")
12691 (set_attr "highpart" "depend")])
12693 (define_insn "lshrv2si3"
12694 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12695 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12696 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12698 "mshlrd.l %1, %2, %0"
12699 [(set_attr "type" "arith_media")
12700 (set_attr "highpart" "depend")])
12702 (define_insn "lshrv4hi3"
12703 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12704 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12705 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12707 "mshlrd.w %1, %2, %0"
12708 [(set_attr "type" "arith_media")
12709 (set_attr "highpart" "depend")])
12711 (define_insn "subv2si3"
12712 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12713 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12714 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12716 "msub.l %N1, %2, %0"
12717 [(set_attr "type" "arith_media")
12718 (set_attr "highpart" "depend")])
12720 (define_insn "subv4hi3"
12721 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12722 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12723 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12725 "msub.w %N1, %2, %0"
12726 [(set_attr "type" "arith_media")
12727 (set_attr "highpart" "depend")])
12729 (define_insn_and_split "subv2hi3"
12730 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12731 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12732 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12739 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12740 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12741 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12742 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12743 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12745 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12746 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12749 [(set_attr "highpart" "must_split")])
12751 (define_insn "sssubv2si3"
12752 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12753 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12754 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12756 "msubs.l %N1, %2, %0"
12757 [(set_attr "type" "mcmp_media")
12758 (set_attr "highpart" "depend")])
12760 (define_insn "ussubv8qi3"
12761 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12762 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12763 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12765 "msubs.ub %N1, %2, %0"
12766 [(set_attr "type" "mcmp_media")
12767 (set_attr "highpart" "depend")])
12769 (define_insn "sssubv4hi3"
12770 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12771 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12772 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12774 "msubs.w %N1, %2, %0"
12775 [(set_attr "type" "mcmp_media")
12776 (set_attr "highpart" "depend")])
12778 ;; Floating Point Intrinsics
12780 (define_insn "fcosa_s"
12781 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12782 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12786 [(set_attr "type" "atrans_media")])
12788 (define_insn "fsina_s"
12789 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12790 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12794 [(set_attr "type" "atrans_media")])
12796 (define_insn "fipr"
12797 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12798 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12799 "fp_arith_reg_operand" "f")
12800 (match_operand:V4SF 2
12801 "fp_arith_reg_operand" "f"))
12802 (parallel [(const_int 0)]))
12803 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12804 (parallel [(const_int 1)])))
12805 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12806 (parallel [(const_int 2)]))
12807 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12808 (parallel [(const_int 3)])))))]
12810 "fipr.s %1, %2, %0"
12811 [(set_attr "type" "fparith_media")])
12813 (define_insn "fsrra_s"
12814 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12815 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12819 [(set_attr "type" "atrans_media")])
12821 (define_insn "ftrv"
12822 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12826 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12827 (parallel [(const_int 0) (const_int 5)
12828 (const_int 10) (const_int 15)]))
12829 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12831 (vec_select:V4SF (match_dup 1)
12832 (parallel [(const_int 4) (const_int 9)
12833 (const_int 14) (const_int 3)]))
12834 (vec_select:V4SF (match_dup 2)
12835 (parallel [(const_int 1) (const_int 2)
12836 (const_int 3) (const_int 0)]))))
12839 (vec_select:V4SF (match_dup 1)
12840 (parallel [(const_int 8) (const_int 13)
12841 (const_int 2) (const_int 7)]))
12842 (vec_select:V4SF (match_dup 2)
12843 (parallel [(const_int 2) (const_int 3)
12844 (const_int 0) (const_int 1)])))
12846 (vec_select:V4SF (match_dup 1)
12847 (parallel [(const_int 12) (const_int 1)
12848 (const_int 6) (const_int 11)]))
12849 (vec_select:V4SF (match_dup 2)
12850 (parallel [(const_int 3) (const_int 0)
12851 (const_int 1) (const_int 2)]))))))]
12853 "ftrv.s %1, %2, %0"
12854 [(set_attr "type" "fparith_media")])
12856 (define_insn "ldhi_l"
12857 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12859 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12862 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12866 [(set_attr "type" "load_media")])
12868 (define_insn "ldhi_q"
12869 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12871 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12874 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12878 [(set_attr "type" "load_media")])
12880 (define_insn_and_split "*ldhi_q_comb0"
12881 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12883 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12884 "register_operand" "r")
12885 (match_operand:SI 2
12886 "ua_offset" "I06"))
12889 (plus:SI (and:SI (match_dup 1) (const_int 7))
12892 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12896 "emit_insn (gen_ldhi_q (operands[0],
12897 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12901 (define_insn_and_split "*ldhi_q_comb1"
12902 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12904 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12905 "register_operand" "r")
12906 (match_operand:SI 2
12907 "ua_offset" "I06"))
12910 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12911 "ua_offset" "I06"))
12915 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12916 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12920 "emit_insn (gen_ldhi_q (operands[0],
12921 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12925 (define_insn "ldlo_l"
12926 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12928 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12930 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12931 (and:SI (match_dup 1) (const_int 3))))]
12934 [(set_attr "type" "load_media")])
12936 (define_insn "ldlo_q"
12937 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12939 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12941 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12942 (and:SI (match_dup 1) (const_int 7))))]
12945 [(set_attr "type" "load_media")])
12947 (define_insn_and_split "*ldlo_q_comb0"
12948 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12950 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12951 (match_operand:SI 2 "ua_offset" "I06"))
12953 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12954 (and:SI (match_dup 1) (const_int 7))))]
12955 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12959 "emit_insn (gen_ldlo_q (operands[0],
12960 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12963 (define_insn_and_split "*ldlo_q_comb1"
12964 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12966 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12967 (match_operand:SI 2 "ua_offset" "I06"))
12969 (minus:SI (const_int 8)
12970 (and:SI (plus:SI (match_dup 1)
12971 (match_operand:SI 3 "ua_offset" "I06"))
12973 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12974 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12975 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12979 "emit_insn (gen_ldlo_q (operands[0],
12980 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12983 (define_insn "sthi_l"
12984 [(set (zero_extract:SI
12985 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12988 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12990 (match_operand:SI 1 "arith_reg_operand" "r"))]
12993 [(set_attr "type" "ustore_media")])
12995 ;; All unaligned stores are considered to be 'narrow' because they typically
12996 ;; operate on less that a quadword, and when they operate on a full quadword,
12997 ;; the vanilla store high / store low sequence will cause a stall if not
12998 ;; scheduled apart.
12999 (define_insn "sthi_q"
13000 [(set (zero_extract:DI
13001 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13004 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13006 (match_operand:DI 1 "arith_reg_operand" "r"))]
13009 [(set_attr "type" "ustore_media")])
13011 (define_insn_and_split "*sthi_q_comb0"
13012 [(set (zero_extract:DI
13013 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13014 "register_operand" "r")
13015 (match_operand:SI 1 "ua_offset"
13019 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13021 (match_operand:DI 2 "arith_reg_operand" "r"))]
13022 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13026 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13030 (define_insn_and_split "*sthi_q_comb1"
13031 [(set (zero_extract:DI
13032 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13033 "register_operand" "r")
13034 (match_operand:SI 1 "ua_offset"
13038 (plus:SI (and:SI (plus:SI (match_dup 0)
13039 (match_operand:SI 2 "ua_offset" "I06"))
13043 (match_operand:DI 3 "arith_reg_operand" "r"))]
13044 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13045 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13049 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13053 ;; This is highpart user because the address is used as full 64 bit.
13054 (define_insn "stlo_l"
13055 [(set (zero_extract:SI
13056 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13058 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13059 (and:SI (match_dup 0) (const_int 3)))
13060 (match_operand:SI 1 "arith_reg_operand" "r"))]
13063 [(set_attr "type" "ustore_media")])
13065 (define_insn "stlo_q"
13066 [(set (zero_extract:DI
13067 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13069 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13070 (and:SI (match_dup 0) (const_int 7)))
13071 (match_operand:DI 1 "arith_reg_operand" "r"))]
13074 [(set_attr "type" "ustore_media")])
13076 (define_insn_and_split "*stlo_q_comb0"
13077 [(set (zero_extract:DI
13078 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13079 (match_operand:SI 1 "ua_offset" "I06"))
13081 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13082 (and:SI (match_dup 0) (const_int 7)))
13083 (match_operand:DI 2 "arith_reg_operand" "r"))]
13084 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13088 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13092 (define_insn_and_split "*stlo_q_comb1"
13093 [(set (zero_extract:DI
13094 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13095 (match_operand:SI 1 "ua_offset" "I06"))
13097 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13098 (match_operand:SI 2
13099 "ua_offset" "I06"))
13101 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13102 (match_operand:DI 3 "arith_reg_operand" "r"))]
13103 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13107 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13111 (define_insn "ldhi_l64"
13112 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13114 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13117 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13121 [(set_attr "type" "load_media")])
13123 (define_insn "ldhi_q64"
13124 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13126 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13129 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13133 [(set_attr "type" "load_media")])
13135 (define_insn "ldlo_l64"
13136 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13138 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13140 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13141 (and:DI (match_dup 1) (const_int 3))))]
13144 [(set_attr "type" "load_media")])
13146 (define_insn "ldlo_q64"
13147 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13149 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13151 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13152 (and:DI (match_dup 1) (const_int 7))))]
13155 [(set_attr "type" "load_media")])
13157 (define_insn "sthi_l64"
13158 [(set (zero_extract:SI
13159 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13162 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13164 (match_operand:SI 1 "arith_reg_operand" "r"))]
13167 [(set_attr "type" "ustore_media")])
13169 (define_insn "sthi_q64"
13170 [(set (zero_extract:DI
13171 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13174 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13176 (match_operand:DI 1 "arith_reg_operand" "r"))]
13179 [(set_attr "type" "ustore_media")])
13181 (define_insn "stlo_l64"
13182 [(set (zero_extract:SI
13183 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13185 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13186 (and:DI (match_dup 0) (const_int 3)))
13187 (match_operand:SI 1 "arith_reg_operand" "r"))]
13190 [(set_attr "type" "ustore_media")])
13192 (define_insn "stlo_q64"
13193 [(set (zero_extract:DI
13194 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13196 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13197 (and:DI (match_dup 0) (const_int 7)))
13198 (match_operand:DI 1 "arith_reg_operand" "r"))]
13201 [(set_attr "type" "ustore_media")])
13204 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13205 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13209 [(set_attr "type" "arith_media")])
13211 (define_insn "nsbsi"
13212 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13214 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13218 [(set_attr "type" "arith_media")])
13220 (define_insn "nsbdi"
13221 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13223 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13227 [(set_attr "type" "arith_media")])
13229 (define_expand "ffsdi2"
13230 [(set (match_operand:DI 0 "arith_reg_dest" "")
13231 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13235 rtx scratch = gen_reg_rtx (DImode);
13238 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13239 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13240 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13241 emit_insn (gen_nsbdi (scratch, scratch));
13242 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13243 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13244 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13245 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13250 (define_expand "ffssi2"
13251 [(set (match_operand:SI 0 "arith_reg_dest" "")
13252 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13256 rtx scratch = gen_reg_rtx (SImode);
13257 rtx discratch = gen_reg_rtx (DImode);
13260 emit_insn (gen_adddi3 (discratch,
13261 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13263 emit_insn (gen_andcdi3 (discratch,
13264 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13266 emit_insn (gen_nsbsi (scratch, discratch));
13267 last = emit_insn (gen_subsi3 (operands[0],
13268 force_reg (SImode, GEN_INT (63)), scratch));
13269 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13274 (define_insn "byterev"
13275 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13276 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13277 (parallel [(const_int 7) (const_int 6) (const_int 5)
13278 (const_int 4) (const_int 3) (const_int 2)
13279 (const_int 1) (const_int 0)])))]
13282 [(set_attr "type" "arith_media")])
13284 (define_insn "*prefetch_media"
13285 [(prefetch (match_operand:QI 0 "address_operand" "p")
13286 (match_operand:SI 1 "const_int_operand" "n")
13287 (match_operand:SI 2 "const_int_operand" "n"))]
13291 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13292 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13295 [(set_attr "type" "other")])
13297 (define_insn "*prefetch_i4"
13298 [(prefetch (match_operand:SI 0 "register_operand" "r")
13299 (match_operand:SI 1 "const_int_operand" "n")
13300 (match_operand:SI 2 "const_int_operand" "n"))]
13301 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13304 return \"pref @%0\";
13306 [(set_attr "type" "other")])
13308 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13309 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13310 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13311 (define_expand "prefetch"
13312 [(prefetch (match_operand 0 "address_operand" "p")
13313 (match_operand:SI 1 "const_int_operand" "n")
13314 (match_operand:SI 2 "const_int_operand" "n"))]
13315 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13316 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13319 if (GET_MODE (operands[0]) != Pmode
13320 || !CONST_INT_P (operands[1])
13321 || !CONST_INT_P (operands[2]))
13323 if (! TARGET_SHMEDIA)
13324 operands[0] = force_reg (Pmode, operands[0]);
13327 (define_insn "prefetch_m2a"
13328 [(prefetch (match_operand:SI 0 "register_operand" "r")
13329 (match_operand:SI 1 "const_int_operand" "n")
13330 (match_operand:SI 2 "const_int_operand" "n"))]
13333 [(set_attr "type" "other")])
13335 (define_insn "alloco_i"
13336 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13337 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13343 if (GET_CODE (operands[0]) == PLUS)
13345 xops[0] = XEXP (operands[0], 0);
13346 xops[1] = XEXP (operands[0], 1);
13350 xops[0] = operands[0];
13351 xops[1] = const0_rtx;
13353 output_asm_insn (\"alloco %0, %1\", xops);
13356 [(set_attr "type" "other")])
13359 [(set (match_operand 0 "any_register_operand" "")
13360 (match_operand 1 "" ""))]
13361 "TARGET_SHMEDIA && reload_completed"
13362 [(set (match_dup 0) (match_dup 1))]
13367 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13372 ; Stack Protector Patterns
13374 (define_expand "stack_protect_set"
13375 [(set (match_operand 0 "memory_operand" "")
13376 (match_operand 1 "memory_operand" ""))]
13379 if (TARGET_SHMEDIA)
13381 if (TARGET_SHMEDIA64)
13382 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13384 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13387 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13392 (define_insn "stack_protect_set_si"
13393 [(set (match_operand:SI 0 "memory_operand" "=m")
13394 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13395 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13397 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13398 [(set_attr "type" "other")
13399 (set_attr "length" "6")])
13401 (define_insn "stack_protect_set_si_media"
13402 [(set (match_operand:SI 0 "memory_operand" "=m")
13403 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13404 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13406 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13407 [(set_attr "type" "other")
13408 (set_attr "length" "12")])
13410 (define_insn "stack_protect_set_di_media"
13411 [(set (match_operand:DI 0 "memory_operand" "=m")
13412 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13413 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13415 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13416 [(set_attr "type" "other")
13417 (set_attr "length" "12")])
13419 (define_expand "stack_protect_test"
13420 [(match_operand 0 "memory_operand" "")
13421 (match_operand 1 "memory_operand" "")
13422 (match_operand 2 "" "")]
13425 if (TARGET_SHMEDIA)
13427 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13430 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13431 if (TARGET_SHMEDIA64)
13433 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13435 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13439 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13441 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13446 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13447 emit_jump_insn (gen_branch_true (operands[2]));
13453 (define_insn "stack_protect_test_si"
13454 [(set (reg:SI T_REG)
13455 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13456 (match_operand:SI 1 "memory_operand" "m")]
13458 (set (match_scratch:SI 2 "=&r") (const_int 0))
13459 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13461 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13462 [(set_attr "type" "other")
13463 (set_attr "length" "10")])
13465 (define_insn "stack_protect_test_si_media"
13466 [(set (match_operand:SI 0 "register_operand" "=&r")
13467 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13468 (match_operand:SI 2 "memory_operand" "m")]
13470 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13472 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13473 [(set_attr "type" "other")
13474 (set_attr "length" "16")])
13476 (define_insn "stack_protect_test_di_media"
13477 [(set (match_operand:DI 0 "register_operand" "=&r")
13478 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13479 (match_operand:DI 2 "memory_operand" "m")]
13481 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13483 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13484 [(set_attr "type" "other")
13485 (set_attr "length" "16")])