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)
157 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
158 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
159 (UNSPEC_EXTRACT_S16 43)
160 (UNSPEC_EXTRACT_U16 44)
162 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
165 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
166 (UNSPEC_PCREL_SYMOFF 46)
168 ;; These are used with unspec_volatile.
174 (UNSPECV_WINDOW_END 10)
175 (UNSPECV_CONST_END 11)
176 (UNSPECV_EH_RETURN 12)
179 ;; -------------------------------------------------------------------------
181 ;; -------------------------------------------------------------------------
186 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
187 (const (symbol_ref "sh_cpu_attr")))
189 (define_attr "endian" "big,little"
190 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
191 (const_string "little") (const_string "big"))))
193 ;; Indicate if the default fpu mode is single precision.
194 (define_attr "fpu_single" "yes,no"
195 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
196 (const_string "yes") (const_string "no"))))
198 (define_attr "fmovd" "yes,no"
199 (const (if_then_else (symbol_ref "TARGET_FMOVD")
200 (const_string "yes") (const_string "no"))))
202 (define_attr "pipe_model" "sh1,sh4,sh5media"
204 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
205 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
206 (const_string "sh1"))))
208 ;; cbranch conditional branch instructions
209 ;; jump unconditional jumps
210 ;; arith ordinary arithmetic
211 ;; arith3 a compound insn that behaves similarly to a sequence of
212 ;; three insns of type arith
213 ;; arith3b like above, but might end with a redirected branch
215 ;; load_si Likewise, SImode variant for general register.
216 ;; fload Likewise, but load to fp register.
218 ;; fstore floating point register to memory
219 ;; move general purpose register to register
220 ;; movi8 8-bit immediate to general purpose register
221 ;; mt_group other sh4 mt instructions
222 ;; fmove register to register, floating point
223 ;; smpy word precision integer multiply
224 ;; dmpy longword or doublelongword precision integer multiply
226 ;; pload load of pr reg, which can't be put into delay slot of rts
227 ;; prset copy register to pr reg, ditto
228 ;; pstore store of pr reg, which can't be put into delay slot of jsr
229 ;; prget copy pr to register, ditto
230 ;; pcload pc relative load of constant value
231 ;; pcfload Likewise, but load to fp register.
232 ;; pcload_si Likewise, SImode variant for general register.
233 ;; rte return from exception
234 ;; sfunc special function call with known used registers
235 ;; call function call
237 ;; fpscr_toggle toggle a bit in the fpscr
238 ;; fdiv floating point divide (or square root)
239 ;; gp_fpul move from general purpose register to fpul
240 ;; fpul_gp move from fpul to general purpose register
241 ;; mac_gp move from mac[lh] to general purpose register
242 ;; gp_mac move from general purpose register to mac[lh]
243 ;; mac_mem move from mac[lh] to memory
244 ;; mem_mac move from memory to mac[lh]
245 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
246 ;; ftrc_s fix_truncsfsi2_i4
247 ;; dfdiv double precision floating point divide (or square root)
248 ;; cwb ic_invalidate_line_i
249 ;; movua SH4a unaligned load
250 ;; fsrra square root reciprocal approximate
251 ;; fsca sine and cosine approximate
252 ;; tls_load load TLS related address
253 ;; arith_media SHmedia arithmetic, logical, and shift instructions
254 ;; cbranch_media SHmedia conditional branch instructions
255 ;; cmp_media SHmedia compare instructions
256 ;; dfdiv_media SHmedia double precision divide and square root
257 ;; dfmul_media SHmedia double precision multiply instruction
258 ;; dfparith_media SHmedia double precision floating point arithmetic
259 ;; dfpconv_media SHmedia double precision floating point conversions
260 ;; dmpy_media SHmedia longword multiply
261 ;; fcmp_media SHmedia floating point compare instructions
262 ;; fdiv_media SHmedia single precision divide and square root
263 ;; fload_media SHmedia floating point register load instructions
264 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
265 ;; fparith_media SHmedia single precision floating point arithmetic
266 ;; fpconv_media SHmedia single precision floating point conversions
267 ;; fstore_media SHmedia floating point register store instructions
268 ;; gettr_media SHmedia gettr instruction
269 ;; invalidate_line_media SHmedia invalidate_line sequence
270 ;; jump_media SHmedia unconditional branch instructions
271 ;; load_media SHmedia general register load instructions
272 ;; pt_media SHmedia pt instruction (expanded by assembler)
273 ;; ptabs_media SHmedia ptabs instruction
274 ;; store_media SHmedia general register store instructions
275 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
276 ;; mac_media SHmedia mac-style fixed point operations
277 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
278 ;; atrans_media SHmedia approximate transcendental functions
279 ;; ustore_media SHmedia unaligned stores
280 ;; nil no-op move, will be deleted.
283 "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"
284 (const_string "other"))
286 ;; We define a new attribute namely "insn_class".We use
287 ;; this for the DFA based pipeline description.
289 ;; mt_group SH4 "mt" group instructions.
291 ;; ex_group SH4 "ex" group instructions.
293 ;; ls_group SH4 "ls" group instructions.
296 (define_attr "insn_class"
297 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
298 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
299 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
300 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
301 (eq_attr "type" "cbranch,jump") (const_string "br_group")
302 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
303 (const_string "fe_group")
304 (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")]
305 (const_string "none")))
306 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
307 ;; so these do not belong in an insn group, although they are modeled
308 ;; with their own define_insn_reservations.
310 ;; Indicate what precision must be selected in fpscr for this insn, if any.
312 (define_attr "fp_mode" "single,double,none" (const_string "none"))
314 ;; Indicate if the fpu mode is set by this instruction
315 ;; "unknown" must have the value as "none" in fp_mode, and means
316 ;; that the instruction/abi has left the processor in an unknown
318 ;; "none" means that nothing has changed and no mode is set.
319 ;; This attribute is only used for the Renesas ABI.
320 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322 ; If a conditional branch destination is within -252..258 bytes away
323 ; from the instruction it can be 2 bytes long. Something in the
324 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
325 ; branches are initially assumed to be 16 bytes long.
326 ; In machine_dependent_reorg, we split all branches that are longer than
329 ;; The maximum range used for SImode constant pool entries is 1018. A final
330 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
331 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
332 ;; instruction around the pool table, 2 bytes of alignment before the table,
333 ;; and 30 bytes of alignment after the table. That gives a maximum total
334 ;; pool size of 1058 bytes.
335 ;; Worst case code/pool content size ratio is 1:2 (using asms).
336 ;; Thus, in the worst case, there is one instruction in front of a maximum
337 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
338 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
339 ;; If we have a forward branch, the initial table will be put after the
340 ;; unconditional branch.
342 ;; ??? We could do much better by keeping track of the actual pcloads within
343 ;; the branch range and in the pcload range in front of the branch range.
345 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347 (define_attr "short_cbranch_p" "no,yes"
348 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
350 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
354 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356 ] (const_string "no")))
358 (define_attr "med_branch_p" "no,yes"
359 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
362 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
367 ] (const_string "no")))
369 (define_attr "med_cbranch_p" "no,yes"
370 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
373 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
375 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
378 ] (const_string "no")))
380 (define_attr "braf_branch_p" "no,yes"
381 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
383 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
386 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
388 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
391 ] (const_string "no")))
393 (define_attr "braf_cbranch_p" "no,yes"
394 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
396 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
399 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
401 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
404 ] (const_string "no")))
406 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
407 ; For wider ranges, we need a combination of a code and a data part.
408 ; If we can get a scratch register for a long range jump, the code
409 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
410 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
411 ; long; otherwise, it must be 6 bytes long.
413 ; All other instructions are two bytes long by default.
415 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
416 ;; but getattrtab doesn't understand this.
417 (define_attr "length" ""
418 (cond [(eq_attr "type" "cbranch")
419 (cond [(eq_attr "short_cbranch_p" "yes")
421 (eq_attr "med_cbranch_p" "yes")
423 (eq_attr "braf_cbranch_p" "yes")
425 ;; ??? using pc is not computed transitively.
426 (ne (match_dup 0) (match_dup 0))
428 (ne (symbol_ref ("flag_pic")) (const_int 0))
431 (eq_attr "type" "jump")
432 (cond [(eq_attr "med_branch_p" "yes")
434 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
436 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
438 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
439 (symbol_ref "code_for_indirect_jump_scratch"))))
440 (cond [(eq_attr "braf_branch_p" "yes")
442 (eq (symbol_ref "flag_pic") (const_int 0))
444 (ne (symbol_ref "TARGET_SH2") (const_int 0))
445 (const_int 10)] (const_int 18))
446 (eq_attr "braf_branch_p" "yes")
448 ;; ??? using pc is not computed transitively.
449 (ne (match_dup 0) (match_dup 0))
451 (ne (symbol_ref ("flag_pic")) (const_int 0))
454 (eq_attr "type" "pt_media")
455 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
456 (const_int 20) (const_int 12))
457 (and (eq_attr "type" "jump_media")
458 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
460 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
464 ;; DFA descriptions for the pipelines
467 (include "shmedia.md")
470 (include "predicates.md")
471 (include "constraints.md")
473 ;; Definitions for filling delay slots
475 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
477 (define_attr "banked" "yes,no"
478 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
480 (const_string "yes")]
481 (const_string "no")))
483 ;; ??? This should be (nil) instead of (const_int 0)
484 (define_attr "hit_stack" "yes,no"
485 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
488 (const_string "yes")))
490 (define_attr "interrupt_function" "no,yes"
491 (const (symbol_ref "current_function_interrupt")))
493 (define_attr "in_delay_slot" "yes,no"
494 (cond [(eq_attr "type" "cbranch") (const_string "no")
495 (eq_attr "type" "pcload,pcload_si") (const_string "no")
496 (eq_attr "needs_delay_slot" "yes") (const_string "no")
497 (eq_attr "length" "2") (const_string "yes")
498 ] (const_string "no")))
500 (define_attr "cond_delay_slot" "yes,no"
501 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
502 ] (const_string "no")))
504 (define_attr "is_sfunc" ""
505 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
507 (define_attr "is_mac_media" ""
508 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
510 (define_attr "branch_zero" "yes,no"
511 (cond [(eq_attr "type" "!cbranch") (const_string "no")
512 (ne (symbol_ref "(next_active_insn (insn)\
513 == (prev_active_insn\
514 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
515 && get_attr_length (next_active_insn (insn)) == 2")
517 (const_string "yes")]
518 (const_string "no")))
520 ;; SH4 Double-precision computation with double-precision result -
521 ;; the two halves are ready at different times.
522 (define_attr "dfp_comp" "yes,no"
523 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
524 (const_string "no")))
526 ;; Insns for which the latency of a preceding fp insn is decreased by one.
527 (define_attr "late_fp_use" "yes,no" (const_string "no"))
528 ;; And feeding insns for which this relevant.
529 (define_attr "any_fp_comp" "yes,no"
530 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
531 (const_string "yes")]
532 (const_string "no")))
534 (define_attr "any_int_load" "yes,no"
535 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
536 (const_string "yes")]
537 (const_string "no")))
539 (define_attr "highpart" "user, ignore, extend, depend, must_split"
540 (const_string "user"))
543 (eq_attr "needs_delay_slot" "yes")
544 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
546 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
547 ;; and thus we can't put a pop instruction in its delay slot.
548 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
549 ;; instruction can go in the delay slot.
551 ;; Since a normal return (rts) implicitly uses the PR register,
552 ;; we can't allow PR register loads in an rts delay slot.
555 (eq_attr "type" "return")
556 [(and (eq_attr "in_delay_slot" "yes")
557 (ior (and (eq_attr "interrupt_function" "no")
558 (eq_attr "type" "!pload,prset"))
559 (and (eq_attr "interrupt_function" "yes")
561 (eq (symbol_ref "TARGET_SH3") (const_int 0))
562 (eq_attr "hit_stack" "no")
563 (eq_attr "banked" "no"))))) (nil) (nil)])
565 ;; Since a call implicitly uses the PR register, we can't allow
566 ;; a PR register store in a jsr delay slot.
569 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
570 [(and (eq_attr "in_delay_slot" "yes")
571 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
573 ;; Say that we have annulled true branches, since this gives smaller and
574 ;; faster code when branches are predicted as not taken.
576 ;; ??? The non-annulled condition should really be "in_delay_slot",
577 ;; but insns that can be filled in non-annulled get priority over insns
578 ;; that can only be filled in anulled.
581 (and (eq_attr "type" "cbranch")
582 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
583 ;; SH2e has a hardware bug that pretty much prohibits the use of
584 ;; annuled delay slots.
585 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
586 (not (eq_attr "cpu" "sh2e"))) (nil)])
588 ;; -------------------------------------------------------------------------
589 ;; SImode signed integer comparisons
590 ;; -------------------------------------------------------------------------
594 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
595 (match_operand:SI 1 "logical_operand" "K08,r"))
599 [(set_attr "type" "mt_group")])
601 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
602 ;; That would still allow reload to create cmpi instructions, but would
603 ;; perhaps allow forcing the constant into a register when that is better.
604 ;; Probably should use r0 for mem/imm compares, but force constant into a
605 ;; register for pseudo/imm compares.
607 (define_insn "cmpeqsi_t"
609 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
610 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
616 [(set_attr "type" "mt_group")])
618 (define_insn "cmpgtsi_t"
620 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
621 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
626 [(set_attr "type" "mt_group")])
628 (define_insn "cmpgesi_t"
630 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
631 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
636 [(set_attr "type" "mt_group")])
638 ;; -------------------------------------------------------------------------
639 ;; SImode compare and branch
640 ;; -------------------------------------------------------------------------
642 (define_expand "cbranchsi4"
644 (if_then_else (match_operator 0 "comparison_operator"
645 [(match_operand:SI 1 "arith_operand" "")
646 (match_operand:SI 2 "arith_operand" "")])
647 (label_ref (match_operand 3 "" ""))
649 (clobber (reg:SI T_REG))]
652 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
653 operands[2], operands[3]));
654 else if (TARGET_CBRANCHDI4)
655 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
657 sh_emit_compare_and_branch (operands, SImode);
660 ;; -------------------------------------------------------------------------
661 ;; SImode unsigned integer comparisons
662 ;; -------------------------------------------------------------------------
664 (define_insn_and_split "cmpgeusi_t"
666 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
667 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
670 "&& operands[1] == CONST0_RTX (SImode)"
674 emit_insn (gen_sett ());
677 [(set_attr "type" "mt_group")])
679 (define_insn "cmpgtusi_t"
681 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
682 (match_operand:SI 1 "arith_reg_operand" "r")))]
685 [(set_attr "type" "mt_group")])
688 ;; -------------------------------------------------------------------------
689 ;; DImode compare and branch
690 ;; -------------------------------------------------------------------------
693 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
694 ;; Therefore, we aim to have a set of three branches that go straight to the
695 ;; destination, i.e. only one of them is taken at any one time.
696 ;; This mechanism should also be slightly better for the sh4-200.
698 (define_expand "cbranchdi4"
700 (if_then_else (match_operator 0 "comparison_operator"
701 [(match_operand:DI 1 "arith_operand" "")
702 (match_operand:DI 2 "arith_operand" "")])
703 (label_ref (match_operand 3 "" ""))
705 (clobber (match_dup 4))
706 (clobber (reg:SI T_REG))]
707 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
710 enum rtx_code comparison;
714 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
715 operands[2], operands[3]));
719 else if (!TARGET_CBRANCHDI4)
721 sh_emit_compare_and_branch (operands, DImode);
727 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
730 comparison = prepare_cbranch_operands (operands, DImode,
731 LAST_AND_UNUSED_RTX_CODE);
732 if (comparison != GET_CODE (operands[0]))
734 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
735 operands[4] = gen_rtx_SCRATCH (SImode);
739 (define_insn_and_split "cbranchdi4_i"
741 (if_then_else (match_operator 0 "comparison_operator"
742 [(match_operand:DI 1 "arith_operand" "r,r")
743 (match_operand:DI 2 "arith_operand" "rN,I08")])
744 (label_ref (match_operand 3 "" ""))
746 (clobber (match_scratch:SI 4 "=X,&r"))
747 (clobber (reg:SI T_REG))]
750 "&& reload_completed"
754 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
759 ;; -------------------------------------------------------------------------
760 ;; DImode signed integer comparisons
761 ;; -------------------------------------------------------------------------
765 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
766 (match_operand:DI 1 "arith_operand" "r"))
769 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
771 [(set_attr "length" "6")
772 (set_attr "type" "arith3b")])
774 (define_insn "cmpeqdi_t"
776 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
777 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
780 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
781 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
782 [(set_attr "length" "6")
783 (set_attr "type" "arith3b")])
787 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
788 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
789 ;; If we applied this split when not optimizing, it would only be
790 ;; applied during the machine-dependent reorg, when no new basic blocks
792 "TARGET_SH1 && reload_completed && optimize"
793 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
794 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
795 (label_ref (match_dup 6))
797 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
802 = gen_rtx_REG (SImode,
803 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
805 = (operands[1] == const0_rtx
807 : gen_rtx_REG (SImode,
808 true_regnum (operands[1])
809 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
810 operands[4] = gen_lowpart (SImode, operands[0]);
811 operands[5] = gen_lowpart (SImode, operands[1]);
812 operands[6] = gen_label_rtx ();
815 (define_insn "cmpgtdi_t"
817 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
818 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
821 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
822 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
823 [(set_attr "length" "8")
824 (set_attr "type" "arith3")])
826 (define_insn "cmpgedi_t"
828 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
829 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
832 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
834 [(set_attr "length" "8,2")
835 (set_attr "type" "arith3,mt_group")])
837 ;; -------------------------------------------------------------------------
838 ;; DImode unsigned integer comparisons
839 ;; -------------------------------------------------------------------------
841 (define_insn "cmpgeudi_t"
843 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
844 (match_operand:DI 1 "arith_reg_operand" "r")))]
846 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
847 [(set_attr "length" "8")
848 (set_attr "type" "arith3")])
850 (define_insn "cmpgtudi_t"
852 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
853 (match_operand:DI 1 "arith_reg_operand" "r")))]
855 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
856 [(set_attr "length" "8")
857 (set_attr "type" "arith3")])
859 (define_insn "cmpeqsi_media"
860 [(set (match_operand:SI 0 "register_operand" "=r")
861 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
862 (match_operand:SI 2 "cmp_operand" "Nr")))]
865 [(set_attr "type" "cmp_media")])
867 (define_insn "cmpeqdi_media"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (eq:SI (match_operand:DI 1 "register_operand" "%r")
870 (match_operand:DI 2 "cmp_operand" "Nr")))]
873 [(set_attr "type" "cmp_media")])
875 (define_insn "cmpgtsi_media"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
878 (match_operand:SI 2 "cmp_operand" "rN")))]
881 [(set_attr "type" "cmp_media")])
883 (define_insn "cmpgtdi_media"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
886 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
889 [(set_attr "type" "cmp_media")])
891 (define_insn "cmpgtusi_media"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
894 (match_operand:SI 2 "cmp_operand" "rN")))]
896 "cmpgtu %N1, %N2, %0"
897 [(set_attr "type" "cmp_media")])
899 (define_insn "cmpgtudi_media"
900 [(set (match_operand:SI 0 "register_operand" "=r")
901 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
902 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
904 "cmpgtu %N1, %N2, %0"
905 [(set_attr "type" "cmp_media")])
907 ; These two patterns are for combine.
908 (define_insn "*cmpne0sisi_media"
909 [(set (match_operand:SI 0 "register_operand" "=r")
910 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
913 [(set_attr "type" "cmp_media")])
915 ;; -------------------------------------------------------------------------
916 ;; Conditional move instructions
917 ;; -------------------------------------------------------------------------
919 ;; The insn names may seem reversed, but note that cmveq performs the move
920 ;; if op1 == 0, and cmvne does it if op1 != 0.
922 (define_insn "movdicc_false"
923 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
924 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
926 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
927 (match_operand:DI 3 "arith_reg_operand" "0")))]
930 [(set_attr "type" "arith_media")])
932 (define_insn "movdicc_true"
933 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
934 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
936 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
937 (match_operand:DI 3 "arith_reg_operand" "0")))]
940 [(set_attr "type" "arith_media")])
943 [(set (match_operand:DI 0 "arith_reg_dest" "")
944 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
945 [(match_operand:DI 1 "arith_reg_operand" "")
947 (match_operand:DI 2 "arith_reg_dest" "")
949 (set (match_dup 2) (match_dup 0))]
950 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
952 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
955 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
956 VOIDmode, operands[1], CONST0_RTX (DImode));
960 [(set (match_operand:DI 0 "general_movdst_operand" "")
961 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
962 (set (match_operand:DI 2 "arith_reg_dest" "")
963 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
964 [(match_operand:DI 3 "arith_reg_operand" "")
968 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
970 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
973 (define_expand "movdicc"
974 [(set (match_operand:DI 0 "register_operand" "")
975 (if_then_else:DI (match_operand 1 "comparison_operator" "")
976 (match_operand:DI 2 "register_operand" "")
977 (match_operand:DI 3 "register_operand" "")))]
981 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
982 && GET_MODE (XEXP (operands[1], 0)) == DImode
983 && XEXP (operands[1], 1) == const0_rtx)
987 if (!can_create_pseudo_p ())
990 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
991 GET_CODE (operands[1]),
992 XEXP (operands[1], 0),
993 XEXP (operands[1], 1));
999 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1000 ;; SImode to DImode.
1001 (define_insn "movsicc_false"
1002 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1003 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1005 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1006 (match_operand:SI 3 "arith_reg_operand" "0")))]
1009 [(set_attr "type" "arith_media")])
1011 (define_insn "movsicc_true"
1012 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1013 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1015 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1016 (match_operand:SI 3 "arith_reg_operand" "0")))]
1019 [(set_attr "type" "arith_media")])
1022 [(set (match_operand:SI 0 "arith_reg_dest" "")
1023 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1024 [(match_operand:SI 1 "arith_reg_operand" "")
1026 (match_operand:SI 2 "arith_reg_dest" "")
1028 (set (match_dup 2) (match_dup 0))]
1029 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1031 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1034 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1035 VOIDmode, operands[1], CONST0_RTX (SImode));
1039 [(set (match_operand:SI 0 "general_movdst_operand" "")
1040 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1041 (set (match_operand:SI 2 "arith_reg_dest" "")
1042 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1043 [(match_operand:SI 3 "arith_reg_operand" "")
1047 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1048 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1050 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1053 replace_rtx (operands[4], operands[0], operands[1]);
1057 [(set (match_operand 0 "any_register_operand" "")
1058 (match_operand 1 "any_register_operand" ""))
1059 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1060 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1061 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1062 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1063 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1064 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1065 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1066 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1067 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1068 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1069 && (REGNO_REG_CLASS (REGNO (operands[0]))
1070 == REGNO_REG_CLASS (REGNO (operands[2])))
1071 && (REGNO_REG_CLASS (REGNO (operands[1]))
1072 == REGNO_REG_CLASS (REGNO (operands[0])))"
1073 [(set (match_dup 0) (match_dup 3))
1074 (set (match_dup 4) (match_dup 5))]
1077 rtx set1, set2, insn2;
1078 rtx replacements[4];
1080 /* We want to replace occurrences of operands[0] with operands[1] and
1081 operands[2] with operands[0] in operands[4]/operands[5].
1082 Doing just two replace_rtx calls naively would result in the second
1083 replacement undoing all that the first did if operands[1] and operands[2]
1084 are identical, so we must do this simultaneously. */
1085 replacements[0] = operands[0];
1086 replacements[1] = operands[1];
1087 replacements[2] = operands[2];
1088 replacements[3] = operands[0];
1089 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1090 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1091 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1094 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1095 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1096 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1097 /* The operands array is aliased to recog_data.operand, which gets
1098 clobbered by extract_insn, so finish with it now. */
1099 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1100 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1101 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1102 always uses emit_insn. */
1103 /* Check that we don't violate matching constraints or earlyclobbers. */
1104 extract_insn (emit_insn (set1));
1105 if (! constrain_operands (1))
1107 insn2 = emit (set2);
1108 if (GET_CODE (insn2) == BARRIER)
1110 extract_insn (insn2);
1111 if (! constrain_operands (1))
1115 tmp = replacements[0];
1116 replacements[0] = replacements[1];
1117 replacements[1] = tmp;
1118 tmp = replacements[2];
1119 replacements[2] = replacements[3];
1120 replacements[3] = tmp;
1121 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1122 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1123 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1129 ;; The register allocator is rather clumsy in handling multi-way conditional
1130 ;; moves, so allow the combiner to make them, and we split them up after
1132 (define_insn_and_split "*movsicc_umin"
1133 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1134 (umin:SI (if_then_else:SI
1135 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1137 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1138 (match_operand:SI 3 "register_operand" "0"))
1139 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1140 (clobber (match_scratch:SI 5 "=&r"))]
1141 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1143 "TARGET_SHMEDIA && reload_completed"
1147 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1149 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1150 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1155 (define_insn "*movsicc_t_false"
1156 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1157 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1158 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1159 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1160 "TARGET_PRETEND_CMOVE
1161 && (arith_reg_operand (operands[1], SImode)
1162 || (immediate_operand (operands[1], SImode)
1163 && satisfies_constraint_I08 (operands[1])))"
1164 "bt 0f\;mov %1,%0\\n0:"
1165 [(set_attr "type" "mt_group,arith") ;; poor approximation
1166 (set_attr "length" "4")])
1168 (define_insn "*movsicc_t_true"
1169 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1170 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1171 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1172 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1173 "TARGET_PRETEND_CMOVE
1174 && (arith_reg_operand (operands[1], SImode)
1175 || (immediate_operand (operands[1], SImode)
1176 && satisfies_constraint_I08 (operands[1])))"
1177 "bf 0f\;mov %1,%0\\n0:"
1178 [(set_attr "type" "mt_group,arith") ;; poor approximation
1179 (set_attr "length" "4")])
1181 (define_expand "movsicc"
1182 [(set (match_operand:SI 0 "arith_reg_dest" "")
1183 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1184 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1185 (match_operand:SI 3 "arith_reg_operand" "")))]
1186 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1189 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1190 && GET_MODE (XEXP (operands[1], 0)) == SImode
1192 || (REG_P (XEXP (operands[1], 0))
1193 && REGNO (XEXP (operands[1], 0)) == T_REG))
1194 && XEXP (operands[1], 1) == const0_rtx)
1197 else if (TARGET_PRETEND_CMOVE)
1199 enum rtx_code code = GET_CODE (operands[1]);
1200 enum rtx_code new_code = code;
1201 rtx op0 = XEXP (operands[1], 0);
1202 rtx op1 = XEXP (operands[1], 1);
1204 if (! currently_expanding_to_rtl)
1208 case LT: case LE: case LEU: case LTU:
1209 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1212 new_code = reverse_condition (code);
1214 case EQ: case GT: case GE: case GEU: case GTU:
1219 sh_emit_scc_to_t (new_code, op0, op1);
1220 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1221 gen_rtx_REG (SImode, T_REG), const0_rtx);
1225 if (!can_create_pseudo_p ())
1228 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1229 GET_CODE (operands[1]),
1230 XEXP (operands[1], 0),
1231 XEXP (operands[1], 1));
1237 (define_expand "movqicc"
1238 [(set (match_operand:QI 0 "register_operand" "")
1239 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1240 (match_operand:QI 2 "register_operand" "")
1241 (match_operand:QI 3 "register_operand" "")))]
1245 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1246 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1247 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1248 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1252 ;; -------------------------------------------------------------------------
1253 ;; Addition instructions
1254 ;; -------------------------------------------------------------------------
1256 (define_expand "adddi3"
1257 [(set (match_operand:DI 0 "arith_reg_operand" "")
1258 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1259 (match_operand:DI 2 "arith_operand" "")))]
1265 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1267 operands[2] = force_reg (DImode, operands[2]);
1268 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1273 (define_insn "*adddi3_media"
1274 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1275 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1276 (match_operand:DI 2 "arith_operand" "r,I10")))]
1281 [(set_attr "type" "arith_media")])
1283 (define_insn "*adddisi3_media"
1284 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1285 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1286 (match_operand:DI 2 "arith_operand" "r,I10")))]
1291 [(set_attr "type" "arith_media")
1292 (set_attr "highpart" "ignore")])
1294 (define_insn "adddi3z_media"
1295 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1297 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1298 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1300 "addz.l %1, %N2, %0"
1301 [(set_attr "type" "arith_media")
1302 (set_attr "highpart" "ignore")])
1304 (define_insn "adddi3_compact"
1305 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1306 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1307 (match_operand:DI 2 "arith_reg_operand" "r")))
1308 (clobber (reg:SI T_REG))]
1311 [(set_attr "length" "6")])
1314 [(set (match_operand:DI 0 "arith_reg_dest" "")
1315 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1316 (match_operand:DI 2 "arith_reg_operand" "")))
1317 (clobber (reg:SI T_REG))]
1318 "TARGET_SH1 && reload_completed"
1322 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1323 high0 = gen_rtx_REG (SImode,
1324 true_regnum (operands[0])
1325 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1326 high2 = gen_rtx_REG (SImode,
1327 true_regnum (operands[2])
1328 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1329 emit_insn (gen_clrt ());
1330 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1331 emit_insn (gen_addc1 (high0, high0, high2));
1336 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1337 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1338 (match_operand:SI 2 "arith_reg_operand" "r"))
1341 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1344 [(set_attr "type" "arith")])
1346 (define_insn "addc1"
1347 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1348 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1349 (match_operand:SI 2 "arith_reg_operand" "r"))
1351 (clobber (reg:SI T_REG))]
1354 [(set_attr "type" "arith")])
1356 (define_expand "addsi3"
1357 [(set (match_operand:SI 0 "arith_reg_operand" "")
1358 (plus:SI (match_operand:SI 1 "arith_operand" "")
1359 (match_operand:SI 2 "arith_operand" "")))]
1364 operands[1] = force_reg (SImode, operands[1]);
1367 (define_insn "addsi3_media"
1368 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1369 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1370 (match_operand:SI 2 "arith_operand" "r,I10")))]
1375 [(set_attr "type" "arith_media")
1376 (set_attr "highpart" "ignore")])
1378 (define_insn "addsidi3_media"
1379 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1380 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1382 (match_operand:SI 2 "arith_operand"
1388 [(set_attr "type" "arith_media")
1389 (set_attr "highpart" "ignore")])
1391 (define_insn "*addsi3_compact"
1392 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1393 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1394 (match_operand:SI 2 "arith_operand" "rI08")))]
1397 [(set_attr "type" "arith")])
1399 ;; -------------------------------------------------------------------------
1400 ;; Subtraction instructions
1401 ;; -------------------------------------------------------------------------
1403 (define_expand "subdi3"
1404 [(set (match_operand:DI 0 "arith_reg_operand" "")
1405 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1406 (match_operand:DI 2 "arith_reg_operand" "")))]
1412 operands[1] = force_reg (DImode, operands[1]);
1413 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1418 (define_insn "*subdi3_media"
1419 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1420 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1421 (match_operand:DI 2 "arith_reg_operand" "r")))]
1424 [(set_attr "type" "arith_media")])
1426 (define_insn "subdisi3_media"
1427 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1428 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1429 (match_operand:DI 2 "arith_reg_operand" "r")))]
1432 [(set_attr "type" "arith_media")
1433 (set_attr "highpart" "ignore")])
1435 (define_insn "subdi3_compact"
1436 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1437 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1438 (match_operand:DI 2 "arith_reg_operand" "r")))
1439 (clobber (reg:SI T_REG))]
1442 [(set_attr "length" "6")])
1445 [(set (match_operand:DI 0 "arith_reg_dest" "")
1446 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1447 (match_operand:DI 2 "arith_reg_operand" "")))
1448 (clobber (reg:SI T_REG))]
1449 "TARGET_SH1 && reload_completed"
1453 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1454 high0 = gen_rtx_REG (SImode,
1455 true_regnum (operands[0])
1456 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1457 high2 = gen_rtx_REG (SImode,
1458 true_regnum (operands[2])
1459 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1460 emit_insn (gen_clrt ());
1461 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1462 emit_insn (gen_subc1 (high0, high0, high2));
1467 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1468 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1469 (match_operand:SI 2 "arith_reg_operand" "r"))
1472 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1477 [(set_attr "type" "arith")])
1479 (define_insn "subc1"
1480 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1481 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1482 (match_operand:SI 2 "arith_reg_operand" "r"))
1484 (clobber (reg:SI T_REG))]
1487 [(set_attr "type" "arith")])
1489 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1490 ;; pattern for this case. This helps multimedia applications that compute
1491 ;; the sum of absolute differences.
1492 (define_insn "mov_neg_si_t"
1493 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1496 [(set_attr "type" "arith")])
1498 (define_insn "*subsi3_internal"
1499 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1500 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1501 (match_operand:SI 2 "arith_reg_operand" "r")))]
1504 [(set_attr "type" "arith")])
1506 (define_insn_and_split "*subsi3_media"
1507 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1508 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1509 (match_operand:SI 2 "extend_reg_operand" "r")))]
1511 && (operands[1] != constm1_rtx
1512 || (GET_CODE (operands[2]) != TRUNCATE
1513 && GET_CODE (operands[2]) != SUBREG))"
1515 "operands[1] == constm1_rtx"
1516 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1518 [(set_attr "type" "arith_media")
1519 (set_attr "highpart" "ignore")])
1522 [(set (match_operand:SI 0 "arith_reg_dest" "")
1523 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1524 "general_extend_operand"
1526 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1527 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1528 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1532 [(set (match_operand:SI 0 "arith_reg_dest" "")
1533 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1534 "general_extend_operand"
1536 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1537 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1538 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1540 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1541 ;; will sometimes save one instruction. Otherwise we might get
1542 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1545 (define_expand "subsi3"
1546 [(set (match_operand:SI 0 "arith_reg_operand" "")
1547 (minus:SI (match_operand:SI 1 "arith_operand" "")
1548 (match_operand:SI 2 "arith_reg_operand" "")))]
1552 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1554 emit_insn (gen_negsi2 (operands[0], operands[2]));
1555 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1560 if (!can_create_pseudo_p ()
1561 && ! arith_reg_or_0_operand (operands[1], SImode))
1563 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1564 operands[1] = force_reg (SImode, operands[1]);
1568 ;; -------------------------------------------------------------------------
1569 ;; Division instructions
1570 ;; -------------------------------------------------------------------------
1572 ;; We take advantage of the library routines which don't clobber as many
1573 ;; registers as a normal function call would.
1575 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1576 ;; also has an effect on the register that holds the address of the sfunc.
1577 ;; To make this work, we have an extra dummy insn that shows the use
1578 ;; of this register for reorg.
1580 (define_insn "use_sfunc_addr"
1581 [(set (reg:SI PR_REG)
1582 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1583 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1585 [(set_attr "length" "0")])
1587 (define_insn "udivsi3_sh2a"
1588 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1589 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1590 (match_operand:SI 2 "arith_reg_operand" "z")))]
1593 [(set_attr "type" "arith")
1594 (set_attr "in_delay_slot" "no")])
1596 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1597 ;; hard register 0. If we used hard register 0, then the next instruction
1598 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1599 ;; gets allocated to a stack slot that needs its address reloaded, then
1600 ;; there is nothing to prevent reload from using r0 to reload the address.
1601 ;; This reload would clobber the value in r0 we are trying to store.
1602 ;; If we let reload allocate r0, then this problem can never happen.
1604 (define_insn "udivsi3_i1"
1605 [(set (match_operand:SI 0 "register_operand" "=z")
1606 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1607 (clobber (reg:SI T_REG))
1608 (clobber (reg:SI PR_REG))
1609 (clobber (reg:SI R4_REG))
1610 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1611 "TARGET_SH1 && ! TARGET_SH4"
1613 [(set_attr "type" "sfunc")
1614 (set_attr "needs_delay_slot" "yes")])
1616 ; Since shmedia-nofpu code could be linked against shcompact code, and
1617 ; the udivsi3 libcall has the same name, we must consider all registers
1618 ; clobbered that are in the union of the registers clobbered by the
1619 ; shmedia and the shcompact implementation. Note, if the shcompact
1620 ; implementation actually used shcompact code, we'd need to clobber
1621 ; also r23 and fr23.
1622 (define_insn "udivsi3_i1_media"
1623 [(set (match_operand:SI 0 "register_operand" "=z")
1624 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1625 (clobber (reg:SI T_MEDIA_REG))
1626 (clobber (reg:SI PR_MEDIA_REG))
1627 (clobber (reg:SI R20_REG))
1628 (clobber (reg:SI R21_REG))
1629 (clobber (reg:SI R22_REG))
1630 (clobber (reg:DI TR0_REG))
1631 (clobber (reg:DI TR1_REG))
1632 (clobber (reg:DI TR2_REG))
1633 (use (match_operand 1 "target_reg_operand" "b"))]
1634 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1636 [(set_attr "type" "sfunc")
1637 (set_attr "needs_delay_slot" "yes")])
1639 (define_expand "udivsi3_i4_media"
1641 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1643 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1644 (set (match_dup 5) (float:DF (match_dup 3)))
1645 (set (match_dup 6) (float:DF (match_dup 4)))
1646 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1647 (set (match_dup 8) (fix:DI (match_dup 7)))
1648 (set (match_operand:SI 0 "register_operand" "")
1649 (truncate:SI (match_dup 8)))]
1650 "TARGET_SHMEDIA_FPU"
1653 operands[3] = gen_reg_rtx (DImode);
1654 operands[4] = gen_reg_rtx (DImode);
1655 operands[5] = gen_reg_rtx (DFmode);
1656 operands[6] = gen_reg_rtx (DFmode);
1657 operands[7] = gen_reg_rtx (DFmode);
1658 operands[8] = gen_reg_rtx (DImode);
1661 (define_insn "udivsi3_i4"
1662 [(set (match_operand:SI 0 "register_operand" "=y")
1663 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1664 (clobber (reg:SI T_REG))
1665 (clobber (reg:SI PR_REG))
1666 (clobber (reg:DF DR0_REG))
1667 (clobber (reg:DF DR2_REG))
1668 (clobber (reg:DF DR4_REG))
1669 (clobber (reg:SI R0_REG))
1670 (clobber (reg:SI R1_REG))
1671 (clobber (reg:SI R4_REG))
1672 (clobber (reg:SI R5_REG))
1673 (use (reg:PSI FPSCR_REG))
1674 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1675 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1677 [(set_attr "type" "sfunc")
1678 (set_attr "fp_mode" "double")
1679 (set_attr "needs_delay_slot" "yes")])
1681 (define_insn "udivsi3_i4_single"
1682 [(set (match_operand:SI 0 "register_operand" "=y")
1683 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1684 (clobber (reg:SI T_REG))
1685 (clobber (reg:SI PR_REG))
1686 (clobber (reg:DF DR0_REG))
1687 (clobber (reg:DF DR2_REG))
1688 (clobber (reg:DF DR4_REG))
1689 (clobber (reg:SI R0_REG))
1690 (clobber (reg:SI R1_REG))
1691 (clobber (reg:SI R4_REG))
1692 (clobber (reg:SI R5_REG))
1693 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1694 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1696 [(set_attr "type" "sfunc")
1697 (set_attr "needs_delay_slot" "yes")])
1699 (define_insn "udivsi3_i4_int"
1700 [(set (match_operand:SI 0 "register_operand" "=z")
1701 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1702 (clobber (reg:SI T_REG))
1703 (clobber (reg:SI R1_REG))
1704 (clobber (reg:SI PR_REG))
1705 (clobber (reg:SI MACH_REG))
1706 (clobber (reg:SI MACL_REG))
1707 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1710 [(set_attr "type" "sfunc")
1711 (set_attr "needs_delay_slot" "yes")])
1714 (define_expand "udivsi3"
1715 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1716 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1717 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1718 (parallel [(set (match_operand:SI 0 "register_operand" "")
1719 (udiv:SI (reg:SI R4_REG)
1721 (clobber (reg:SI T_REG))
1722 (clobber (reg:SI PR_REG))
1723 (clobber (reg:SI R4_REG))
1724 (use (match_dup 3))])]
1730 operands[3] = gen_reg_rtx (Pmode);
1731 /* Emit the move of the address to a pseudo outside of the libcall. */
1732 if (TARGET_DIVIDE_CALL_TABLE)
1734 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1735 that causes problems when the divide code is supposed to come from a
1736 separate library. Division by zero is undefined, so dividing 1 can be
1737 implemented by comparing with the divisor. */
1738 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1740 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1741 emit_insn (gen_cstoresi4 (operands[0], test,
1742 operands[1], operands[2]));
1745 else if (operands[2] == const0_rtx)
1747 emit_move_insn (operands[0], operands[2]);
1750 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1751 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1753 else if (TARGET_DIVIDE_CALL_FP)
1755 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1756 if (TARGET_FPU_SINGLE)
1757 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1759 last = gen_udivsi3_i4 (operands[0], operands[3]);
1761 else if (TARGET_SHMEDIA_FPU)
1763 operands[1] = force_reg (SImode, operands[1]);
1764 operands[2] = force_reg (SImode, operands[2]);
1765 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1768 else if (TARGET_SH2A)
1770 operands[1] = force_reg (SImode, operands[1]);
1771 operands[2] = force_reg (SImode, operands[2]);
1772 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1775 else if (TARGET_SH5)
1777 function_symbol (operands[3],
1778 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1782 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1783 else if (TARGET_FPU_ANY)
1784 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1786 last = gen_udivsi3_i1 (operands[0], operands[3]);
1790 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1791 last = gen_udivsi3_i1 (operands[0], operands[3]);
1793 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1794 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1799 (define_insn "divsi3_sh2a"
1800 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1801 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1802 (match_operand:SI 2 "arith_reg_operand" "z")))]
1805 [(set_attr "type" "arith")
1806 (set_attr "in_delay_slot" "no")])
1808 (define_insn "divsi3_i1"
1809 [(set (match_operand:SI 0 "register_operand" "=z")
1810 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1811 (clobber (reg:SI T_REG))
1812 (clobber (reg:SI PR_REG))
1813 (clobber (reg:SI R1_REG))
1814 (clobber (reg:SI R2_REG))
1815 (clobber (reg:SI R3_REG))
1816 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1817 "TARGET_SH1 && ! TARGET_SH4"
1819 [(set_attr "type" "sfunc")
1820 (set_attr "needs_delay_slot" "yes")])
1822 (define_insn "divsi3_i1_media"
1823 [(set (match_operand:SI 0 "register_operand" "=z")
1824 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1825 (clobber (reg:SI T_MEDIA_REG))
1826 (clobber (reg:SI PR_MEDIA_REG))
1827 (clobber (reg:SI R1_REG))
1828 (clobber (reg:SI R20_REG))
1829 (clobber (reg:SI R21_REG))
1830 (clobber (reg:SI TR0_REG))
1831 (use (match_operand 1 "target_reg_operand" "b"))]
1832 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1834 [(set_attr "type" "sfunc")])
1836 (define_insn "divsi3_media_2"
1837 [(set (match_operand:SI 0 "register_operand" "=z")
1838 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1839 (clobber (reg:SI T_MEDIA_REG))
1840 (clobber (reg:SI PR_MEDIA_REG))
1841 (clobber (reg:SI R1_REG))
1842 (clobber (reg:SI R21_REG))
1843 (clobber (reg:SI TR0_REG))
1844 (use (reg:SI R20_REG))
1845 (use (match_operand 1 "target_reg_operand" "b"))]
1846 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1848 [(set_attr "type" "sfunc")])
1850 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1851 ;; hard reg clobbers and data dependencies that we need when we want
1852 ;; to rematerialize the division into a call.
1853 (define_insn_and_split "divsi_inv_call"
1854 [(set (match_operand:SI 0 "register_operand" "=r")
1855 (div:SI (match_operand:SI 1 "register_operand" "r")
1856 (match_operand:SI 2 "register_operand" "r")))
1857 (clobber (reg:SI R4_REG))
1858 (clobber (reg:SI R5_REG))
1859 (clobber (reg:SI T_MEDIA_REG))
1860 (clobber (reg:SI PR_MEDIA_REG))
1861 (clobber (reg:SI R1_REG))
1862 (clobber (reg:SI R21_REG))
1863 (clobber (reg:SI TR0_REG))
1864 (clobber (reg:SI R20_REG))
1865 (use (match_operand:SI 3 "register_operand" "r"))]
1868 "&& (high_life_started || reload_completed)"
1869 [(set (match_dup 0) (match_dup 3))]
1871 [(set_attr "highpart" "must_split")])
1873 ;; This is the combiner pattern for -mdiv=inv:call .
1874 (define_insn_and_split "*divsi_inv_call_combine"
1875 [(set (match_operand:SI 0 "register_operand" "=z")
1876 (div:SI (match_operand:SI 1 "register_operand" "r")
1877 (match_operand:SI 2 "register_operand" "r")))
1878 (clobber (reg:SI R4_REG))
1879 (clobber (reg:SI R5_REG))
1880 (clobber (reg:SI T_MEDIA_REG))
1881 (clobber (reg:SI PR_MEDIA_REG))
1882 (clobber (reg:SI R1_REG))
1883 (clobber (reg:SI R21_REG))
1884 (clobber (reg:SI TR0_REG))
1885 (clobber (reg:SI R20_REG))
1886 (use (unspec:SI [(match_dup 1)
1887 (match_operand:SI 3 "" "")
1888 (unspec:SI [(match_operand:SI 4 "" "")
1890 (match_operand:DI 5 "" "")]
1892 (match_operand:DI 6 "" "")
1895 UNSPEC_DIV_INV_M3))]
1898 "&& (high_life_started || reload_completed)"
1902 const char *name = sh_divsi3_libfunc;
1903 enum sh_function_kind kind = SFUNC_GOT;
1906 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1907 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1908 while (TARGET_DIVIDE_INV_CALL2)
1910 rtx x = operands[3];
1912 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1914 x = XVECEXP (x, 0, 0);
1915 name = \"__sdivsi3_2\";
1916 kind = SFUNC_STATIC;
1917 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1920 sym = function_symbol (NULL, name, kind);
1921 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1924 [(set_attr "highpart" "must_split")])
1926 (define_expand "divsi3_i4_media"
1927 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1928 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1929 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1930 (set (match_operand:SI 0 "register_operand" "=r")
1931 (fix:SI (match_dup 5)))]
1932 "TARGET_SHMEDIA_FPU"
1935 operands[3] = gen_reg_rtx (DFmode);
1936 operands[4] = gen_reg_rtx (DFmode);
1937 operands[5] = gen_reg_rtx (DFmode);
1940 (define_insn "divsi3_i4"
1941 [(set (match_operand:SI 0 "register_operand" "=y")
1942 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1943 (clobber (reg:SI PR_REG))
1944 (clobber (reg:DF DR0_REG))
1945 (clobber (reg:DF DR2_REG))
1946 (use (reg:PSI FPSCR_REG))
1947 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1948 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1950 [(set_attr "type" "sfunc")
1951 (set_attr "fp_mode" "double")
1952 (set_attr "needs_delay_slot" "yes")])
1954 (define_insn "divsi3_i4_single"
1955 [(set (match_operand:SI 0 "register_operand" "=y")
1956 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1957 (clobber (reg:SI PR_REG))
1958 (clobber (reg:DF DR0_REG))
1959 (clobber (reg:DF DR2_REG))
1960 (clobber (reg:SI R2_REG))
1961 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1964 [(set_attr "type" "sfunc")
1965 (set_attr "needs_delay_slot" "yes")])
1967 (define_insn "divsi3_i4_int"
1968 [(set (match_operand:SI 0 "register_operand" "=z")
1969 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970 (clobber (reg:SI T_REG))
1971 (clobber (reg:SI PR_REG))
1972 (clobber (reg:SI R1_REG))
1973 (clobber (reg:SI MACH_REG))
1974 (clobber (reg:SI MACL_REG))
1975 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1978 [(set_attr "type" "sfunc")
1979 (set_attr "needs_delay_slot" "yes")])
1981 (define_expand "divsi3"
1982 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1983 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1984 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1985 (parallel [(set (match_operand:SI 0 "register_operand" "")
1986 (div:SI (reg:SI R4_REG)
1988 (clobber (reg:SI T_REG))
1989 (clobber (reg:SI PR_REG))
1990 (clobber (reg:SI R1_REG))
1991 (clobber (reg:SI R2_REG))
1992 (clobber (reg:SI R3_REG))
1993 (use (match_dup 3))])]
1999 operands[3] = gen_reg_rtx (Pmode);
2000 /* Emit the move of the address to a pseudo outside of the libcall. */
2001 if (TARGET_DIVIDE_CALL_TABLE)
2003 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2004 last = gen_divsi3_i4_int (operands[0], operands[3]);
2006 else if (TARGET_DIVIDE_CALL_FP)
2008 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2009 if (TARGET_FPU_SINGLE)
2010 last = gen_divsi3_i4_single (operands[0], operands[3]);
2012 last = gen_divsi3_i4 (operands[0], operands[3]);
2014 else if (TARGET_SH2A)
2016 operands[1] = force_reg (SImode, operands[1]);
2017 operands[2] = force_reg (SImode, operands[2]);
2018 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2021 else if (TARGET_DIVIDE_INV)
2023 rtx dividend = operands[1];
2024 rtx divisor = operands[2];
2026 rtx nsb_res = gen_reg_rtx (DImode);
2027 rtx norm64 = gen_reg_rtx (DImode);
2028 rtx tab_ix = gen_reg_rtx (DImode);
2029 rtx norm32 = gen_reg_rtx (SImode);
2030 rtx i92 = force_reg (DImode, GEN_INT (92));
2031 rtx scratch0a = gen_reg_rtx (DImode);
2032 rtx scratch0b = gen_reg_rtx (DImode);
2033 rtx inv0 = gen_reg_rtx (SImode);
2034 rtx scratch1a = gen_reg_rtx (DImode);
2035 rtx scratch1b = gen_reg_rtx (DImode);
2036 rtx shift = gen_reg_rtx (DImode);
2038 rtx inv1 = gen_reg_rtx (SImode);
2039 rtx scratch2a = gen_reg_rtx (DImode);
2040 rtx scratch2b = gen_reg_rtx (SImode);
2041 rtx inv2 = gen_reg_rtx (SImode);
2042 rtx scratch3a = gen_reg_rtx (DImode);
2043 rtx scratch3b = gen_reg_rtx (DImode);
2044 rtx scratch3c = gen_reg_rtx (DImode);
2045 rtx scratch3d = gen_reg_rtx (SImode);
2046 rtx scratch3e = gen_reg_rtx (DImode);
2047 rtx result = gen_reg_rtx (SImode);
2049 if (! arith_reg_or_0_operand (dividend, SImode))
2050 dividend = force_reg (SImode, dividend);
2051 if (! arith_reg_operand (divisor, SImode))
2052 divisor = force_reg (SImode, divisor);
2053 if (flag_pic && Pmode != DImode)
2055 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2056 tab_base = gen_datalabel_ref (tab_base);
2057 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2061 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2062 tab_base = gen_datalabel_ref (tab_base);
2063 tab_base = force_reg (DImode, tab_base);
2065 if (TARGET_DIVIDE_INV20U)
2066 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2068 i2p27 = GEN_INT (0);
2069 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2070 i43 = force_reg (DImode, GEN_INT (43));
2073 emit_insn (gen_nsbdi (nsb_res,
2074 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2075 emit_insn (gen_ashldi3_media (norm64,
2076 gen_rtx_SUBREG (DImode, divisor, 0),
2078 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2079 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2080 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2081 inv0, scratch0a, scratch0b,
2082 scratch1a, scratch1b));
2083 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2084 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2086 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2088 scratch3a, scratch3b, scratch3c,
2089 scratch2a, scratch2b, scratch3d, scratch3e));
2090 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2091 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2092 else if (TARGET_DIVIDE_INV_FP)
2093 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2094 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2095 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2096 gen_reg_rtx (DFmode)));
2098 emit_move_insn (operands[0], result);
2101 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2103 operands[1] = force_reg (SImode, operands[1]);
2104 operands[2] = force_reg (SImode, operands[2]);
2105 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2108 else if (TARGET_SH5)
2110 if (TARGET_DIVIDE_CALL2)
2112 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2113 tab_base = gen_datalabel_ref (tab_base);
2114 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2116 if (TARGET_FPU_ANY && TARGET_SH1)
2117 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2118 else if (TARGET_DIVIDE_CALL2)
2119 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2121 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2124 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2125 (operands[0], operands[3]));
2126 else if (TARGET_FPU_ANY)
2127 last = gen_divsi3_i4_single (operands[0], operands[3]);
2129 last = gen_divsi3_i1 (operands[0], operands[3]);
2133 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2134 last = gen_divsi3_i1 (operands[0], operands[3]);
2136 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2137 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2142 ;; operands: scratch, tab_base, tab_ix
2143 ;; These are unspecs because we could generate an indexed addressing mode
2144 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2145 ;; confuse reload. See PR27117.
2147 (define_insn "divsi_inv_qitable"
2148 [(set (match_operand:DI 0 "register_operand" "=r")
2149 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2150 (match_operand:DI 2 "register_operand" "r")]
2151 UNSPEC_DIV_INV_TABLE)))]
2155 [(set_attr "type" "load_media")
2156 (set_attr "highpart" "user")])
2158 ;; operands: scratch, tab_base, tab_ix
2159 (define_insn "divsi_inv_hitable"
2160 [(set (match_operand:DI 0 "register_operand" "=r")
2161 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2162 (match_operand:DI 2 "register_operand" "r")]
2163 UNSPEC_DIV_INV_TABLE)))]
2167 [(set_attr "type" "load_media")
2168 (set_attr "highpart" "user")])
2170 ;; operands: inv0, tab_base, tab_ix, norm32
2171 ;; scratch equiv in sdivsi3_2: r19, r21
2172 (define_expand "divsi_inv_m0"
2173 [(set (match_operand:SI 0 "register_operand" "=r")
2174 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2175 (match_operand:DI 2 "register_operand" "r")
2176 (match_operand:SI 3 "register_operand" "r")]
2178 (clobber (match_operand:DI 4 "register_operand" "=r"))
2179 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2187 ldx.ub r20, r21, r19 // u0.8
2189 muls.l r25, r19, r19 // s2.38
2190 ldx.w r20, r21, r21 // s2.14
2191 shari r19, 24, r19 // truncate to s2.14
2192 sub r21, r19, r19 // some 11 bit inverse in s1.14
2195 rtx inv0 = operands[0];
2196 rtx tab_base = operands[1];
2197 rtx tab_ix = operands[2];
2198 rtx norm32 = operands[3];
2199 rtx scratch0 = operands[4];
2200 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2201 rtx scratch1 = operands[5];
2203 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2204 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2205 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2206 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2207 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2208 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2212 ;; operands: inv1, tab_base, tab_ix, norm32
2213 (define_insn_and_split "divsi_inv_m1"
2214 [(set (match_operand:SI 0 "register_operand" "=r")
2215 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2216 (match_operand:DI 2 "register_operand" "r")
2217 (match_operand:SI 3 "register_operand" "r")]
2219 (clobber (match_operand:SI 4 "register_operand" "=r"))
2220 (clobber (match_operand:DI 5 "register_operand" "=r"))
2221 (clobber (match_operand:DI 6 "register_operand" "=r"))
2222 (clobber (match_operand:DI 7 "register_operand" "=r"))
2223 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2226 "&& !can_create_pseudo_p ()"
2231 muls.l r19, r19, r18 // u0.28
2232 muls.l r25, r18, r18 // s2.58
2233 shlli r19, 45, r0 // multiply by two and convert to s2.58
2235 shari r18, 28, r18 // some 18 bit inverse in s1.30
2238 rtx inv1 = operands[0];
2239 rtx tab_base = operands[1];
2240 rtx tab_ix = operands[2];
2241 rtx norm32 = operands[3];
2242 rtx inv0 = operands[4];
2243 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2244 rtx scratch0a = operands[5];
2245 rtx scratch0b = operands[6];
2246 rtx scratch0 = operands[7];
2247 rtx scratch1 = operands[8];
2248 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2250 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2251 scratch0a, scratch0b));
2252 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2253 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2254 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2255 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2256 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2260 ;; operands: inv2, norm32, inv1, i92
2261 (define_insn_and_split "divsi_inv_m2"
2262 [(set (match_operand:SI 0 "register_operand" "=r")
2263 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2264 (match_operand:SI 2 "register_operand" "r")
2265 (match_operand:DI 3 "register_operand" "r")]
2267 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2270 "&& !can_create_pseudo_p ()"
2275 muls.l r18, r25, r0 // s2.60
2276 shari r0, 16, r0 // s-16.44
2278 muls.l r0, r18, r19 // s-16.74
2279 shari r19, 30, r19 // s-16.44
2281 rtx inv2 = operands[0];
2282 rtx norm32 = operands[1];
2283 rtx inv1 = operands[2];
2284 rtx i92 = operands[3];
2285 rtx scratch0 = operands[4];
2286 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2288 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2289 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2290 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2291 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2292 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2296 (define_insn_and_split "divsi_inv_m3"
2297 [(set (match_operand:SI 0 "register_operand" "=r")
2298 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2299 (match_operand:SI 2 "register_operand" "r")
2300 (match_operand:SI 3 "register_operand" "r")
2301 (match_operand:DI 4 "register_operand" "r")
2302 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2303 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2305 (clobber (match_operand:DI 7 "register_operand" "=r"))
2306 (clobber (match_operand:DI 8 "register_operand" "=r"))
2307 (clobber (match_operand:DI 9 "register_operand" "=r"))
2308 (clobber (match_operand:DI 10 "register_operand" "=r"))
2309 (clobber (match_operand:SI 11 "register_operand" "=r"))
2310 (clobber (match_operand:SI 12 "register_operand" "=r"))
2311 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2314 "&& !can_create_pseudo_p ()"
2319 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2320 r0: scratch0 r19: scratch1 r21: scratch2
2322 muls.l r18, r4, r25 // s32.30
2323 muls.l r19, r4, r19 // s15.30
2325 shari r19, 14, r19 // s18.-14
2331 rtx result = operands[0];
2332 rtx dividend = operands[1];
2333 rtx inv1 = operands[2];
2334 rtx inv2 = operands[3];
2335 rtx shift = operands[4];
2336 rtx scratch0 = operands[7];
2337 rtx scratch1 = operands[8];
2338 rtx scratch2 = operands[9];
2340 if (satisfies_constraint_N (dividend))
2342 emit_move_insn (result, dividend);
2346 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2347 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2348 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2349 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2350 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2351 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2352 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2356 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2357 ;; inv1: tab_base, tab_ix, norm32
2358 ;; inv2: norm32, inv1, i92
2359 (define_insn_and_split "divsi_inv_m1_3"
2360 [(set (match_operand:SI 0 "register_operand" "=r")
2361 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2362 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2363 (match_operand:DI 3 "register_operand" "r")
2364 (match_operand:SI 4 "register_operand" "r")]
2366 (unspec:SI [(match_dup 4)
2367 (unspec:SI [(match_dup 2)
2369 (match_dup 4)] UNSPEC_DIV_INV_M1)
2370 (match_operand:SI 5 "" "")]
2372 (match_operand:DI 6 "register_operand" "r")
2373 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2374 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2376 (clobber (match_operand:DI 9 "register_operand" "=r"))
2377 (clobber (match_operand:DI 10 "register_operand" "=r"))
2378 (clobber (match_operand:DI 11 "register_operand" "=r"))
2379 (clobber (match_operand:DI 12 "register_operand" "=r"))
2380 (clobber (match_operand:SI 13 "register_operand" "=r"))
2381 (clobber (match_operand:SI 14 "register_operand" "=r"))
2382 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2384 && (TARGET_DIVIDE_INV_MINLAT
2385 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2387 "&& !can_create_pseudo_p ()"
2391 rtx result = operands[0];
2392 rtx dividend = operands[1];
2393 rtx tab_base = operands[2];
2394 rtx tab_ix = operands[3];
2395 rtx norm32 = operands[4];
2396 /* rtx i92 = operands[5]; */
2397 rtx shift = operands[6];
2398 rtx i2p27 = operands[7];
2399 rtx i43 = operands[8];
2400 rtx scratch0 = operands[9];
2401 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2402 rtx scratch1 = operands[10];
2403 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2404 rtx scratch2 = operands[11];
2405 rtx scratch3 = operands[12];
2406 rtx scratch4 = operands[13];
2407 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2408 rtx scratch5 = operands[14];
2409 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2410 rtx scratch6 = operands[15];
2412 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2413 scratch0, scratch1));
2414 /* inv0 == scratch4 */
2415 if (! TARGET_DIVIDE_INV20U)
2417 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2419 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2423 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2424 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2426 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2427 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2428 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2429 /* inv1 == scratch4 */
2431 if (TARGET_DIVIDE_INV_MINLAT)
2433 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2434 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2435 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2436 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2437 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2438 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2439 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2440 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2441 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2442 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2443 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2447 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2448 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2449 emit_insn (gen_nsbdi (scratch6,
2450 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2451 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2452 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2453 emit_insn (gen_divsi_inv20 (scratch2,
2454 norm32, scratch4, dividend,
2455 scratch6, scratch3, i43,
2456 /* scratch0 may be shared with i2p27. */
2457 scratch0, scratch1, scratch5,
2458 label, label, i2p27));
2460 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2461 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2465 (define_insn "divsi_inv20"
2466 [(set (match_operand:DI 0 "register_operand" "=&r")
2467 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2468 (match_operand:SI 2 "register_operand" "r")
2469 (match_operand:SI 3 "register_operand" "r")
2470 (match_operand:DI 4 "register_operand" "r")
2471 (match_operand:DI 5 "register_operand" "r")
2472 (match_operand:DI 6 "register_operand" "r")
2473 (match_operand:DI 12 "register_operand" "r")
2474 (match_operand 10 "target_operand" "b")
2475 (match_operand 11 "immediate_operand" "i")]
2477 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2478 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2479 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2481 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2484 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2485 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2486 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2487 %10 label (tr), %11 label (imm)
2489 muls.l inv1, norm32, scratch0 // s2.60
2490 muls.l inv1, dividend, result // s32.30
2491 xor i2p27, result_sign, round_scratch
2492 bge/u dividend_nsb, i43, tr.. (label)
2493 shari scratch0, 16, scratch0 // s-16.44
2494 muls.l sratch0_si, inv1, scratch0 // s-16.74
2495 sub result, round_scratch, result
2496 shari dividend, 14, scratch1 // s19.-14
2497 shari scratch0, 30, scratch0 // s-16.44
2498 muls.l scratch0, scratch1, round_scratch // s15.30
2500 sub result, round_scratch, result */
2502 int likely = TARGET_DIVIDE_INV20L;
2504 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2505 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2506 output_asm_insn (likely
2507 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2508 : \"bge/u\t%4, %6, %10\", operands);
2509 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2510 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2511 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2513 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2514 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2517 (define_insn_and_split "divsi_inv_fp"
2518 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2519 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2520 (match_operand:SI 2 "register_operand" "rf")))
2521 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2522 (clobber (match_operand:SI 4 "register_operand" "=r"))
2523 (clobber (match_operand:SI 5 "register_operand" "=r"))
2524 (clobber (match_operand:DF 6 "register_operand" "=r"))
2525 (clobber (match_operand:DF 7 "register_operand" "=r"))
2526 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2527 "TARGET_SHMEDIA_FPU"
2529 "&& (high_life_started || reload_completed)"
2530 [(set (match_dup 0) (match_dup 3))]
2532 [(set_attr "highpart" "must_split")])
2534 ;; If a matching group of divide-by-inverse instructions is in the same
2535 ;; basic block after gcse & loop optimizations, we want to transform them
2536 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2537 (define_insn_and_split "*divsi_inv_fp_combine"
2538 [(set (match_operand:SI 0 "register_operand" "=f")
2539 (div:SI (match_operand:SI 1 "register_operand" "f")
2540 (match_operand:SI 2 "register_operand" "f")))
2541 (use (unspec:SI [(match_dup 1)
2542 (match_operand:SI 3 "" "")
2543 (unspec:SI [(match_operand:SI 4 "" "")
2545 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2546 (match_operand:DI 6 "" "")
2548 (const_int 0)] UNSPEC_DIV_INV_M3))
2549 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2550 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2551 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2552 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2553 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2554 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2557 [(set (match_dup 9) (float:DF (match_dup 1)))
2558 (set (match_dup 10) (float:DF (match_dup 2)))
2559 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2561 (fix:SI (match_dup 11)))
2562 (set (match_dup 0) (match_dup 8))]
2565 if (! fp_arith_reg_operand (operands[1], SImode))
2567 emit_move_insn (operands[7], operands[1]);
2568 operands[1] = operands[7];
2570 if (! fp_arith_reg_operand (operands[2], SImode))
2572 emit_move_insn (operands[8], operands[2]);
2573 operands[2] = operands[8];
2576 [(set_attr "highpart" "must_split")])
2578 ;; -------------------------------------------------------------------------
2579 ;; Multiplication instructions
2580 ;; -------------------------------------------------------------------------
2582 (define_insn "umulhisi3_i"
2583 [(set (reg:SI MACL_REG)
2584 (mult:SI (zero_extend:SI
2585 (match_operand:HI 0 "arith_reg_operand" "r"))
2587 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2590 [(set_attr "type" "smpy")])
2592 (define_insn "mulhisi3_i"
2593 [(set (reg:SI MACL_REG)
2594 (mult:SI (sign_extend:SI
2595 (match_operand:HI 0 "arith_reg_operand" "r"))
2597 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2600 [(set_attr "type" "smpy")])
2602 (define_expand "mulhisi3"
2603 [(set (reg:SI MACL_REG)
2604 (mult:SI (sign_extend:SI
2605 (match_operand:HI 1 "arith_reg_operand" ""))
2607 (match_operand:HI 2 "arith_reg_operand" ""))))
2608 (set (match_operand:SI 0 "arith_reg_operand" "")
2615 macl = gen_rtx_REG (SImode, MACL_REG);
2617 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2618 insn = get_insns ();
2620 /* expand_binop can't find a suitable code in umul_widen_optab to
2621 make a REG_EQUAL note from, so make one here.
2622 See also smulsi3_highpart.
2623 ??? Alternatively, we could put this at the calling site of expand_binop,
2624 i.e. expand_expr. */
2625 /* Use emit_libcall_block for loop invariant code motion and to make
2626 a REG_EQUAL note. */
2627 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2632 (define_expand "umulhisi3"
2633 [(set (reg:SI MACL_REG)
2634 (mult:SI (zero_extend:SI
2635 (match_operand:HI 1 "arith_reg_operand" ""))
2637 (match_operand:HI 2 "arith_reg_operand" ""))))
2638 (set (match_operand:SI 0 "arith_reg_operand" "")
2645 macl = gen_rtx_REG (SImode, MACL_REG);
2647 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2648 insn = get_insns ();
2650 /* expand_binop can't find a suitable code in umul_widen_optab to
2651 make a REG_EQUAL note from, so make one here.
2652 See also smulsi3_highpart.
2653 ??? Alternatively, we could put this at the calling site of expand_binop,
2654 i.e. expand_expr. */
2655 /* Use emit_libcall_block for loop invariant code motion and to make
2656 a REG_EQUAL note. */
2657 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2662 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2663 ;; a call to a routine which clobbers known registers.
2666 [(set (match_operand:SI 1 "register_operand" "=z")
2667 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2668 (clobber (reg:SI MACL_REG))
2669 (clobber (reg:SI T_REG))
2670 (clobber (reg:SI PR_REG))
2671 (clobber (reg:SI R3_REG))
2672 (clobber (reg:SI R2_REG))
2673 (clobber (reg:SI R1_REG))
2674 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2677 [(set_attr "type" "sfunc")
2678 (set_attr "needs_delay_slot" "yes")])
2680 (define_expand "mulsi3_call"
2681 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2682 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2683 (parallel[(set (match_operand:SI 0 "register_operand" "")
2684 (mult:SI (reg:SI R4_REG)
2686 (clobber (reg:SI MACL_REG))
2687 (clobber (reg:SI T_REG))
2688 (clobber (reg:SI PR_REG))
2689 (clobber (reg:SI R3_REG))
2690 (clobber (reg:SI R2_REG))
2691 (clobber (reg:SI R1_REG))
2692 (use (match_operand:SI 3 "register_operand" ""))])]
2696 (define_insn "mul_r"
2697 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2698 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2699 (match_operand:SI 2 "arith_reg_operand" "z")))]
2702 [(set_attr "type" "dmpy")])
2704 (define_insn "mul_l"
2705 [(set (reg:SI MACL_REG)
2706 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2707 (match_operand:SI 1 "arith_reg_operand" "r")))]
2710 [(set_attr "type" "dmpy")])
2712 (define_expand "mulsi3"
2713 [(set (reg:SI MACL_REG)
2714 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2715 (match_operand:SI 2 "arith_reg_operand" "")))
2716 (set (match_operand:SI 0 "arith_reg_operand" "")
2723 /* The address must be set outside the libcall,
2724 since it goes into a pseudo. */
2725 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2726 rtx addr = force_reg (SImode, sym);
2727 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2733 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2735 emit_insn (gen_mul_l (operands[1], operands[2]));
2736 /* consec_sets_giv can only recognize the first insn that sets a
2737 giv as the giv insn. So we must tag this also with a REG_EQUAL
2739 emit_insn (gen_movsi_i ((operands[0]), macl));
2744 (define_insn "mulsidi3_i"
2745 [(set (reg:SI MACH_REG)
2749 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2750 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2752 (set (reg:SI MACL_REG)
2753 (mult:SI (match_dup 0)
2757 [(set_attr "type" "dmpy")])
2759 (define_expand "mulsidi3"
2760 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2761 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2762 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2763 "TARGET_SH2 || TARGET_SHMEDIA"
2768 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2774 (define_insn "mulsidi3_media"
2775 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2776 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2777 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2780 [(set_attr "type" "dmpy_media")
2781 (set_attr "highpart" "ignore")])
2783 (define_insn "mulsidi3_compact"
2784 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2786 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2787 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2788 (clobber (reg:SI MACH_REG))
2789 (clobber (reg:SI MACL_REG))]
2794 [(set (match_operand:DI 0 "arith_reg_dest" "")
2796 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2797 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2798 (clobber (reg:SI MACH_REG))
2799 (clobber (reg:SI MACL_REG))]
2804 rtx low_dst = gen_lowpart (SImode, operands[0]);
2805 rtx high_dst = gen_highpart (SImode, operands[0]);
2807 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2809 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2810 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2811 /* We need something to tag the possible REG_EQUAL notes on to. */
2812 emit_move_insn (operands[0], operands[0]);
2816 (define_insn "umulsidi3_i"
2817 [(set (reg:SI MACH_REG)
2821 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2822 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2824 (set (reg:SI MACL_REG)
2825 (mult:SI (match_dup 0)
2829 [(set_attr "type" "dmpy")])
2831 (define_expand "umulsidi3"
2832 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2833 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2834 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2835 "TARGET_SH2 || TARGET_SHMEDIA"
2840 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2846 (define_insn "umulsidi3_media"
2847 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2848 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2849 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2852 [(set_attr "type" "dmpy_media")
2853 (set_attr "highpart" "ignore")])
2855 (define_insn "umulsidi3_compact"
2856 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2858 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2859 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2860 (clobber (reg:SI MACH_REG))
2861 (clobber (reg:SI MACL_REG))]
2866 [(set (match_operand:DI 0 "arith_reg_dest" "")
2867 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2868 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2869 (clobber (reg:SI MACH_REG))
2870 (clobber (reg:SI MACL_REG))]
2875 rtx low_dst = gen_lowpart (SImode, operands[0]);
2876 rtx high_dst = gen_highpart (SImode, operands[0]);
2878 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2880 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2881 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2882 /* We need something to tag the possible REG_EQUAL notes on to. */
2883 emit_move_insn (operands[0], operands[0]);
2887 (define_insn "smulsi3_highpart_i"
2888 [(set (reg:SI MACH_REG)
2892 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2893 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2895 (clobber (reg:SI MACL_REG))]
2898 [(set_attr "type" "dmpy")])
2900 (define_expand "smulsi3_highpart"
2902 [(set (reg:SI MACH_REG)
2906 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2907 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2909 (clobber (reg:SI MACL_REG))])
2910 (set (match_operand:SI 0 "arith_reg_operand" "")
2917 mach = gen_rtx_REG (SImode, MACH_REG);
2919 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2920 insn = get_insns ();
2922 /* expand_binop can't find a suitable code in mul_highpart_optab to
2923 make a REG_EQUAL note from, so make one here.
2924 See also {,u}mulhisi.
2925 ??? Alternatively, we could put this at the calling site of expand_binop,
2926 i.e. expand_mult_highpart. */
2927 /* Use emit_libcall_block for loop invariant code motion and to make
2928 a REG_EQUAL note. */
2929 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2934 (define_insn "umulsi3_highpart_i"
2935 [(set (reg:SI MACH_REG)
2939 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2940 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2942 (clobber (reg:SI MACL_REG))]
2945 [(set_attr "type" "dmpy")])
2947 (define_expand "umulsi3_highpart"
2949 [(set (reg:SI MACH_REG)
2953 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2954 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2956 (clobber (reg:SI MACL_REG))])
2957 (set (match_operand:SI 0 "arith_reg_operand" "")
2964 mach = gen_rtx_REG (SImode, MACH_REG);
2966 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2967 insn = get_insns ();
2969 /* Use emit_libcall_block for loop invariant code motion and to make
2970 a REG_EQUAL note. */
2971 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2976 (define_insn_and_split "muldi3"
2977 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2978 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2979 (match_operand:DI 2 "arith_reg_operand" "r")))
2980 (clobber (match_scratch:DI 3 "=&r"))
2981 (clobber (match_scratch:DI 4 "=r"))]
2988 rtx op3_v2si, op2_v2si;
2990 op3_v2si = operands[3];
2991 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2993 op3_v2si = XEXP (op3_v2si, 0);
2994 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2996 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2997 op2_v2si = operands[2];
2998 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3000 op2_v2si = XEXP (op2_v2si, 0);
3001 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3003 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3004 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3005 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3006 emit_insn (gen_umulsidi3_media (operands[4],
3007 sh_gen_truncate (SImode, operands[1], 0),
3008 sh_gen_truncate (SImode, operands[2], 0)));
3009 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3010 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3011 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3012 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3017 ;; -------------------------------------------------------------------------
3018 ;; Logical operations
3019 ;; -------------------------------------------------------------------------
3021 (define_insn "*andsi3_compact"
3022 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3023 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3024 (match_operand:SI 2 "logical_operand" "r,K08")))]
3027 [(set_attr "type" "arith")])
3029 (define_insn "*andsi3_media"
3030 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3031 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3032 (match_operand:SI 2 "logical_operand" "r,I10")))]
3037 [(set_attr "type" "arith_media")])
3039 (define_insn "*andsi3_bclr"
3040 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3041 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3042 (match_operand:SI 2 "const_int_operand" "Psz")))]
3043 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3045 [(set_attr "type" "arith")])
3047 ;; If the constant is 255, then emit an extu.b instruction instead of an
3048 ;; and, since that will give better code.
3050 (define_expand "andsi3"
3051 [(set (match_operand:SI 0 "arith_reg_operand" "")
3052 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3053 (match_operand:SI 2 "logical_operand" "")))]
3058 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3060 emit_insn (gen_zero_extendqisi2 (operands[0],
3061 gen_lowpart (QImode, operands[1])));
3066 (define_insn_and_split "anddi3"
3067 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3068 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3069 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3076 && ! logical_operand (operands[2], DImode)"
3080 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3081 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3083 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3086 [(set_attr "type" "arith_media")])
3088 (define_insn "andcsi3"
3089 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3090 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3091 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3094 [(set_attr "type" "arith_media")])
3096 (define_insn "andcdi3"
3097 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3098 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3099 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3102 [(set_attr "type" "arith_media")])
3104 (define_expand "iorsi3"
3105 [(set (match_operand:SI 0 "arith_reg_operand" "")
3106 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3107 (match_operand:SI 2 "logical_operand" "")))]
3111 (define_insn "*iorsi3_compact"
3112 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3113 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3114 (match_operand:SI 2 "logical_operand" "r,K08")))]
3116 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3118 [(set_attr "type" "arith")])
3120 (define_insn "*iorsi3_media"
3121 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3122 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3123 (match_operand:SI 2 "logical_operand" "r,I10")))]
3128 [(set_attr "type" "arith_media")])
3130 (define_insn "*iorsi3_bset"
3131 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3132 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3133 (match_operand:SI 2 "const_int_operand" "Pso")))]
3134 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3136 [(set_attr "type" "arith")])
3138 (define_insn "iordi3"
3139 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3140 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3141 (match_operand:DI 2 "logical_operand" "r,I10")))]
3146 [(set_attr "type" "arith_media")])
3148 (define_insn_and_split "*logical_sidi3"
3149 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3150 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3151 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3152 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3155 "&& reload_completed"
3156 [(set (match_dup 0) (match_dup 3))]
3160 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3161 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3162 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3165 (define_insn_and_split "*logical_sidisi3"
3166 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3167 (truncate:SI (sign_extend:DI
3168 (match_operator:SI 3 "logical_operator"
3169 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3170 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3174 [(set (match_dup 0) (match_dup 3))])
3176 (define_insn_and_split "*logical_sidi3_2"
3177 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3178 (sign_extend:DI (truncate:SI (sign_extend:DI
3179 (match_operator:SI 3 "logical_operator"
3180 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3181 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3185 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3187 (define_expand "xorsi3"
3188 [(set (match_operand:SI 0 "arith_reg_operand" "")
3189 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3190 (match_operand:SI 2 "xor_operand" "")))]
3194 (define_insn "*xorsi3_compact"
3195 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3196 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3197 (match_operand:SI 2 "logical_operand" "K08,r")))]
3200 [(set_attr "type" "arith")])
3202 (define_insn "*xorsi3_media"
3203 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3204 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3205 (match_operand:SI 2 "xor_operand" "r,I06")))]
3210 [(set_attr "type" "arith_media")])
3212 ;; Store the complements of the T bit in a register.
3213 (define_insn "xorsi3_movrt"
3214 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3215 (xor:SI (reg:SI T_REG)
3219 [(set_attr "type" "arith")])
3221 (define_insn "xordi3"
3222 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3223 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3224 (match_operand:DI 2 "xor_operand" "r,I06")))]
3229 [(set_attr "type" "arith_media")])
3231 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3232 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3234 [(set (match_operand:DI 0 "arith_reg_dest" "")
3235 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3236 [(match_operand 1 "any_register_operand" "")
3237 (match_operand 2 "any_register_operand" "")])))]
3239 [(set (match_dup 5) (match_dup 4))
3240 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3243 enum machine_mode inmode = GET_MODE (operands[1]);
3246 if (GET_CODE (operands[0]) == SUBREG)
3248 offset = SUBREG_BYTE (operands[0]);
3249 operands[0] = SUBREG_REG (operands[0]);
3251 gcc_assert (REG_P (operands[0]));
3252 if (! TARGET_LITTLE_ENDIAN)
3253 offset += 8 - GET_MODE_SIZE (inmode);
3254 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3257 ;; -------------------------------------------------------------------------
3258 ;; Shifts and rotates
3259 ;; -------------------------------------------------------------------------
3261 (define_expand "rotldi3"
3262 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3263 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3264 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3266 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3268 (define_insn "rotldi3_mextr"
3269 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3270 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3271 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3275 static char templ[16];
3277 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3278 8 - (int) (INTVAL (operands[2]) >> 3));
3281 [(set_attr "type" "arith_media")])
3283 (define_expand "rotrdi3"
3284 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3285 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3286 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3288 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3290 (define_insn "rotrdi3_mextr"
3291 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3292 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3293 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3297 static char templ[16];
3299 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3302 [(set_attr "type" "arith_media")])
3305 [(set (match_operand:DI 0 "arith_reg_dest" "")
3306 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3307 "ua_address_operand" "")))
3308 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3310 (clobber (match_operand:DI 3 "register_operand" ""))]
3312 [(match_dup 4) (match_dup 5)]
3315 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3316 (operands[3], operands[1]));
3317 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3318 GEN_INT (56), GEN_INT (8));
3321 (define_insn "rotlsi3_1"
3322 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3323 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3326 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3329 [(set_attr "type" "arith")])
3331 (define_insn "rotlsi3_31"
3332 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3333 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3335 (clobber (reg:SI T_REG))]
3338 [(set_attr "type" "arith")])
3340 (define_insn "rotlsi3_16"
3341 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3342 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3346 [(set_attr "type" "arith")])
3348 (define_expand "rotlsi3"
3349 [(set (match_operand:SI 0 "arith_reg_dest" "")
3350 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3351 (match_operand:SI 2 "immediate_operand" "")))]
3355 static const char rot_tab[] = {
3356 000, 000, 000, 000, 000, 000, 010, 001,
3357 001, 001, 011, 013, 003, 003, 003, 003,
3358 003, 003, 003, 003, 003, 013, 012, 002,
3359 002, 002, 010, 000, 000, 000, 000, 000,
3364 if (!CONST_INT_P (operands[2]))
3366 count = INTVAL (operands[2]);
3367 choice = rot_tab[count];
3368 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3374 emit_move_insn (operands[0], operands[1]);
3375 count -= (count & 16) * 2;
3378 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3385 parts[0] = gen_reg_rtx (SImode);
3386 parts[1] = gen_reg_rtx (SImode);
3387 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3388 emit_move_insn (parts[choice-1], operands[1]);
3389 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3390 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3391 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3392 count = (count & ~16) - 8;
3396 for (; count > 0; count--)
3397 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3398 for (; count < 0; count++)
3399 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3404 (define_insn "*rotlhi3_8"
3405 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3406 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3410 [(set_attr "type" "arith")])
3412 (define_expand "rotlhi3"
3413 [(set (match_operand:HI 0 "arith_reg_operand" "")
3414 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3415 (match_operand:HI 2 "immediate_operand" "")))]
3419 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3426 (define_insn "ashlsi3_sh2a"
3427 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3428 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3429 (match_operand:SI 2 "arith_reg_operand" "r")))]
3432 [(set_attr "type" "arith")
3433 (set_attr "length" "4")])
3435 ;; This pattern is used by init_expmed for computing the costs of shift
3438 (define_insn_and_split "ashlsi3_std"
3439 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3440 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3441 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3442 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3444 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3452 && CONST_INT_P (operands[2])
3453 && ! satisfies_constraint_P27 (operands[2])"
3454 [(set (match_dup 3) (match_dup 2))
3456 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3457 (clobber (match_dup 4))])]
3458 "operands[4] = gen_rtx_SCRATCH (SImode);"
3459 [(set_attr "length" "*,*,*,4")
3460 (set_attr "type" "dyn_shift,arith,arith,arith")])
3462 (define_insn "ashlhi3_k"
3463 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3464 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3465 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3466 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3470 [(set_attr "type" "arith")])
3472 (define_insn "ashlsi3_n"
3473 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3474 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3475 (match_operand:SI 2 "const_int_operand" "n")))
3476 (clobber (reg:SI T_REG))]
3477 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3479 [(set (attr "length")
3480 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3482 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3484 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3486 (const_string "8")))
3487 (set_attr "type" "arith")])
3490 [(set (match_operand:SI 0 "arith_reg_dest" "")
3491 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3492 (match_operand:SI 2 "const_int_operand" "")))
3493 (clobber (reg:SI T_REG))]
3494 "TARGET_SH1 && reload_completed"
3495 [(use (reg:SI R0_REG))]
3498 gen_shifty_op (ASHIFT, operands);
3502 (define_insn "ashlsi3_media"
3503 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3504 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3505 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3510 [(set_attr "type" "arith_media")
3511 (set_attr "highpart" "ignore")])
3513 (define_expand "ashlsi3"
3514 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3515 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3516 (match_operand:SI 2 "nonmemory_operand" "")))
3517 (clobber (reg:SI T_REG))])]
3523 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3526 if (CONST_INT_P (operands[2])
3527 && sh_dynamicalize_shift_p (operands[2]))
3528 operands[2] = force_reg (SImode, operands[2]);
3531 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3534 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3538 (define_insn "*ashlhi3_n"
3539 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3540 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3541 (match_operand:HI 2 "const_int_operand" "n")))
3542 (clobber (reg:SI T_REG))]
3545 [(set (attr "length")
3546 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3548 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3550 (const_string "6")))
3551 (set_attr "type" "arith")])
3553 (define_expand "ashlhi3"
3554 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3555 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3556 (match_operand:SI 2 "nonmemory_operand" "")))
3557 (clobber (reg:SI T_REG))])]
3561 if (!CONST_INT_P (operands[2]))
3563 /* It may be possible to call gen_ashlhi3 directly with more generic
3564 operands. Make sure operands[1] is a HImode register here. */
3565 if (!arith_reg_operand (operands[1], HImode))
3566 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3570 [(set (match_operand:HI 0 "arith_reg_dest" "")
3571 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3572 (match_operand:HI 2 "const_int_operand" "")))
3573 (clobber (reg:SI T_REG))]
3574 "TARGET_SH1 && reload_completed"
3575 [(use (reg:SI R0_REG))]
3578 gen_shifty_hi_op (ASHIFT, operands);
3583 ; arithmetic shift right
3586 (define_insn "ashrsi3_sh2a"
3587 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3588 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3589 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3592 [(set_attr "type" "dyn_shift")
3593 (set_attr "length" "4")])
3595 (define_insn "ashrsi3_k"
3596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3597 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3598 (match_operand:SI 2 "const_int_operand" "M")))
3599 (clobber (reg:SI T_REG))]
3600 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3602 [(set_attr "type" "arith")])
3604 ;; We can't do HImode right shifts correctly unless we start out with an
3605 ;; explicit zero / sign extension; doing that would result in worse overall
3606 ;; code, so just let the machine independent code widen the mode.
3607 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3610 ;; ??? This should be a define expand.
3612 (define_insn "ashrsi2_16"
3613 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3618 [(set_attr "length" "4")])
3621 [(set (match_operand:SI 0 "arith_reg_dest" "")
3622 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3625 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3626 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3627 "operands[2] = gen_lowpart (HImode, operands[0]);")
3629 ;; ??? This should be a define expand.
3631 (define_insn "ashrsi2_31"
3632 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3633 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3635 (clobber (reg:SI T_REG))]
3638 [(set_attr "length" "4")])
3641 [(set (match_operand:SI 0 "arith_reg_dest" "")
3642 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3644 (clobber (reg:SI T_REG))]
3649 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3650 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3655 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3657 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3659 && peep2_reg_dead_p (2, operands[0])
3660 && peep2_reg_dead_p (2, operands[1])"
3664 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3668 (define_insn "ashlsi_c"
3669 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3670 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3672 (lt:SI (match_dup 1) (const_int 0)))]
3675 [(set_attr "type" "arith")])
3677 (define_insn "*ashlsi_c_void"
3678 [(set (reg:SI T_REG)
3679 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3680 (clobber (match_scratch:SI 1 "=0"))]
3681 "TARGET_SH1 && cse_not_expected"
3683 [(set_attr "type" "arith")])
3685 (define_insn "ashrsi3_d"
3686 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3687 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3688 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3691 [(set_attr "type" "dyn_shift")])
3693 (define_insn "ashrsi3_n"
3694 [(set (reg:SI R4_REG)
3695 (ashiftrt:SI (reg:SI R4_REG)
3696 (match_operand:SI 0 "const_int_operand" "i")))
3697 (clobber (reg:SI T_REG))
3698 (clobber (reg:SI PR_REG))
3699 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3702 [(set_attr "type" "sfunc")
3703 (set_attr "needs_delay_slot" "yes")])
3705 (define_insn "ashrsi3_media"
3706 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3707 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3708 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3713 [(set_attr "type" "arith_media")
3714 (set_attr "highpart" "ignore")])
3716 (define_expand "ashrsi3"
3717 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3718 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3719 (match_operand:SI 2 "nonmemory_operand" "")))
3720 (clobber (reg:SI T_REG))])]
3726 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3729 if (expand_ashiftrt (operands))
3735 ;; logical shift right
3737 (define_insn "lshrsi3_sh2a"
3738 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3739 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3740 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3743 [(set_attr "type" "dyn_shift")
3744 (set_attr "length" "4")])
3746 (define_insn "lshrsi3_d"
3747 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3748 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3749 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3752 [(set_attr "type" "dyn_shift")])
3754 ;; Only the single bit shift clobbers the T bit.
3756 (define_insn "lshrsi3_m"
3757 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3758 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3759 (match_operand:SI 2 "const_int_operand" "M")))
3760 (clobber (reg:SI T_REG))]
3761 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3763 [(set_attr "type" "arith")])
3765 (define_insn "lshrsi3_k"
3766 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3767 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3768 (match_operand:SI 2 "const_int_operand" "P27")))]
3769 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3770 && ! satisfies_constraint_M (operands[2])"
3772 [(set_attr "type" "arith")])
3774 (define_insn "lshrsi3_n"
3775 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3776 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3777 (match_operand:SI 2 "const_int_operand" "n")))
3778 (clobber (reg:SI T_REG))]
3779 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3781 [(set (attr "length")
3782 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3784 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3786 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3788 (const_string "8")))
3789 (set_attr "type" "arith")])
3792 [(set (match_operand:SI 0 "arith_reg_dest" "")
3793 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3794 (match_operand:SI 2 "const_int_operand" "")))
3795 (clobber (reg:SI T_REG))]
3796 "TARGET_SH1 && reload_completed"
3797 [(use (reg:SI R0_REG))]
3800 gen_shifty_op (LSHIFTRT, operands);
3804 (define_insn "lshrsi3_media"
3805 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3806 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3807 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3812 [(set_attr "type" "arith_media")
3813 (set_attr "highpart" "ignore")])
3815 (define_expand "lshrsi3"
3816 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3817 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3818 (match_operand:SI 2 "nonmemory_operand" "")))
3819 (clobber (reg:SI T_REG))])]
3825 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3828 if (CONST_INT_P (operands[2])
3829 && sh_dynamicalize_shift_p (operands[2]))
3830 operands[2] = force_reg (SImode, operands[2]);
3831 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3833 rtx count = copy_to_mode_reg (SImode, operands[2]);
3834 emit_insn (gen_negsi2 (count, count));
3835 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3838 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3842 ;; ??? This should be a define expand.
3844 (define_insn "ashldi3_k"
3845 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3846 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3848 (clobber (reg:SI T_REG))]
3850 "shll %R0\;rotcl %S0"
3851 [(set_attr "length" "4")
3852 (set_attr "type" "arith")])
3854 ;; Expander for DImode shift left with SImode operations.
3856 (define_expand "ashldi3_std"
3857 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3858 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3859 (match_operand:DI 2 "const_int_operand" "n")))]
3860 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3863 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3864 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3865 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3866 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3867 rtx dst = gen_reg_rtx (DImode);
3868 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3869 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3872 tmp0 = gen_reg_rtx (SImode);
3873 tmp1 = gen_reg_rtx (SImode);
3874 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3875 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3876 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3877 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3878 emit_move_insn (operands[0], dst);
3882 (define_insn "ashldi3_media"
3883 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3884 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3885 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3890 [(set_attr "type" "arith_media")])
3892 (define_insn "*ashldisi3_media"
3893 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3894 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3895 (match_operand:DI 2 "const_int_operand" "n")))]
3896 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3897 "shlli.l %1, %2, %0"
3898 [(set_attr "type" "arith_media")
3899 (set_attr "highpart" "ignore")])
3901 (define_expand "ashldi3"
3902 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3903 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3904 (match_operand:DI 2 "immediate_operand" "")))
3905 (clobber (reg:SI T_REG))])]
3911 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3914 if (CONST_INT_P (operands[2])
3915 && INTVAL (operands[2]) == 1)
3917 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3920 else if (CONST_INT_P (operands[2])
3921 && INTVAL (operands[2]) < 32)
3923 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3930 ;; ??? This should be a define expand.
3932 (define_insn "lshrdi3_k"
3933 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3934 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3936 (clobber (reg:SI T_REG))]
3938 "shlr %S0\;rotcr %R0"
3939 [(set_attr "length" "4")
3940 (set_attr "type" "arith")])
3942 (define_insn "lshrdi3_media"
3943 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3944 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3945 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3947 && (arith_reg_dest (operands[0], DImode)
3948 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3952 [(set_attr "type" "arith_media")])
3954 (define_insn "*lshrdisi3_media"
3955 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3956 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3957 (match_operand:DI 2 "const_int_operand" "n")))]
3958 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3959 "shlri.l %1, %2, %0"
3960 [(set_attr "type" "arith_media")
3961 (set_attr "highpart" "ignore")])
3963 (define_expand "lshrdi3"
3964 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3965 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3966 (match_operand:DI 2 "immediate_operand" "")))
3967 (clobber (reg:SI T_REG))])]
3973 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3976 if (!CONST_INT_P (operands[2])
3977 || INTVAL (operands[2]) != 1)
3981 ;; ??? This should be a define expand.
3983 (define_insn "ashrdi3_k"
3984 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3985 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3987 (clobber (reg:SI T_REG))]
3989 "shar %S0\;rotcr %R0"
3990 [(set_attr "length" "4")
3991 (set_attr "type" "arith")])
3993 (define_insn "ashrdi3_media"
3994 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3995 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3996 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3998 && (arith_reg_dest (operands[0], DImode)
3999 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4003 [(set_attr "type" "arith_media")])
4005 (define_insn "*ashrdisi3_media"
4006 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4007 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4008 (match_operand:DI 2 "const_int_operand" "n")))]
4009 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4010 "shari.l %1, %2, %0"
4011 [(set_attr "type" "arith_media")
4012 (set_attr "highpart" "ignore")])
4014 (define_insn "ashrdisi3_media_high"
4015 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4017 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4018 (match_operand:DI 2 "const_int_operand" "n"))))]
4019 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4021 [(set_attr "type" "arith_media")])
4023 (define_insn "ashrdisi3_media_opaque"
4024 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4025 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4026 (match_operand:DI 2 "const_int_operand" "n")]
4030 [(set_attr "type" "arith_media")])
4032 (define_expand "ashrdi3"
4033 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4034 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4035 (match_operand:DI 2 "immediate_operand" "")))
4036 (clobber (reg:SI T_REG))])]
4042 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4045 if (!CONST_INT_P (operands[2])
4046 || INTVAL (operands[2]) != 1)
4050 ;; combined left/right shift
4053 [(set (match_operand:SI 0 "register_operand" "")
4054 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4055 (match_operand:SI 2 "const_int_operand" ""))
4056 (match_operand:SI 3 "const_int_operand" "")))]
4057 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4058 [(use (reg:SI R0_REG))]
4059 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4063 [(set (match_operand:SI 0 "register_operand" "")
4064 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4065 (match_operand:SI 2 "const_int_operand" ""))
4066 (match_operand:SI 3 "const_int_operand" "")))
4067 (clobber (reg:SI T_REG))]
4068 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4069 [(use (reg:SI R0_REG))]
4070 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4074 [(set (match_operand:SI 0 "register_operand" "=r")
4075 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4076 (match_operand:SI 2 "const_int_operand" "n"))
4077 (match_operand:SI 3 "const_int_operand" "n")))
4078 (clobber (reg:SI T_REG))]
4079 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4081 [(set (attr "length")
4082 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4084 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4086 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4088 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4090 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4092 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4094 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4095 (const_string "16")]
4096 (const_string "18")))
4097 (set_attr "type" "arith")])
4100 [(set (match_operand:SI 0 "register_operand" "=z")
4101 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4102 (match_operand:SI 2 "const_int_operand" "n"))
4103 (match_operand:SI 3 "const_int_operand" "n")))
4104 (clobber (reg:SI T_REG))]
4105 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4107 [(set (attr "length")
4108 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4110 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4112 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4114 (const_string "10")))
4115 (set_attr "type" "arith")])
4117 ;; shift left / and combination with a scratch register: The combine pass
4118 ;; does not accept the individual instructions, even though they are
4119 ;; cheap. But it needs a precise description so that it is usable after
4121 (define_insn "and_shl_scratch"
4122 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4126 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4127 (match_operand:SI 2 "const_int_operand" "N,n"))
4128 (match_operand:SI 3 "" "0,r"))
4129 (match_operand:SI 4 "const_int_operand" "n,n"))
4130 (match_operand:SI 5 "const_int_operand" "n,n")))
4131 (clobber (reg:SI T_REG))]
4134 [(set (attr "length")
4135 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4137 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4139 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4141 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4142 (const_string "10")]
4143 (const_string "12")))
4144 (set_attr "type" "arith")])
4147 [(set (match_operand:SI 0 "register_operand" "")
4151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4152 (match_operand:SI 2 "const_int_operand" ""))
4153 (match_operand:SI 3 "register_operand" ""))
4154 (match_operand:SI 4 "const_int_operand" ""))
4155 (match_operand:SI 5 "const_int_operand" "")))
4156 (clobber (reg:SI T_REG))]
4158 [(use (reg:SI R0_REG))]
4161 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4163 if (INTVAL (operands[2]))
4165 gen_shifty_op (LSHIFTRT, operands);
4167 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4168 operands[2] = operands[4];
4169 gen_shifty_op (ASHIFT, operands);
4170 if (INTVAL (operands[5]))
4172 operands[2] = operands[5];
4173 gen_shifty_op (LSHIFTRT, operands);
4178 ;; signed left/right shift combination.
4180 [(set (match_operand:SI 0 "register_operand" "")
4182 (ashift:SI (match_operand:SI 1 "register_operand" "")
4183 (match_operand:SI 2 "const_int_operand" ""))
4184 (match_operand:SI 3 "const_int_operand" "")
4186 (clobber (reg:SI T_REG))]
4188 [(use (reg:SI R0_REG))]
4189 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4192 (define_insn "shl_sext_ext"
4193 [(set (match_operand:SI 0 "register_operand" "=r")
4195 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4196 (match_operand:SI 2 "const_int_operand" "n"))
4197 (match_operand:SI 3 "const_int_operand" "n")
4199 (clobber (reg:SI T_REG))]
4200 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4202 [(set (attr "length")
4203 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4205 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4207 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4209 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4211 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4213 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4215 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4217 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4218 (const_string "16")]
4219 (const_string "18")))
4220 (set_attr "type" "arith")])
4222 (define_insn "shl_sext_sub"
4223 [(set (match_operand:SI 0 "register_operand" "=z")
4225 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4226 (match_operand:SI 2 "const_int_operand" "n"))
4227 (match_operand:SI 3 "const_int_operand" "n")
4229 (clobber (reg:SI T_REG))]
4230 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4232 [(set (attr "length")
4233 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4235 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4237 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4239 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4240 (const_string "12")]
4241 (const_string "14")))
4242 (set_attr "type" "arith")])
4244 ;; These patterns are found in expansions of DImode shifts by 16, and
4245 ;; allow the xtrct instruction to be generated from C source.
4247 (define_insn "xtrct_left"
4248 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4249 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4251 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4255 [(set_attr "type" "arith")])
4257 (define_insn "xtrct_right"
4258 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4259 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4261 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4265 [(set_attr "type" "arith")])
4267 ;; -------------------------------------------------------------------------
4269 ;; -------------------------------------------------------------------------
4272 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4273 (neg:SI (plus:SI (reg:SI T_REG)
4274 (match_operand:SI 1 "arith_reg_operand" "r"))))
4276 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4280 [(set_attr "type" "arith")])
4282 (define_insn "*negdi_media"
4283 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4284 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4287 [(set_attr "type" "arith_media")])
4289 (define_expand "negdi2"
4290 [(set (match_operand:DI 0 "arith_reg_operand" "")
4291 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4297 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4298 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4300 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4301 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4303 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4304 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4306 emit_insn (gen_clrt ());
4307 emit_insn (gen_negc (low_dst, low_src));
4308 emit_insn (gen_negc (high_dst, high_src));
4313 (define_insn "negsi2"
4314 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4315 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4318 [(set_attr "type" "arith")])
4320 (define_insn "one_cmplsi2"
4321 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4322 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4325 [(set_attr "type" "arith")])
4327 (define_expand "one_cmpldi2"
4328 [(set (match_operand:DI 0 "arith_reg_dest" "")
4329 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4331 "TARGET_SHMEDIA" "")
4333 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4334 This can be used as some kind of conditional execution, which is useful
4337 [(set (match_operand:SI 0 "arith_reg_dest" "")
4338 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4339 (match_operand:SI 1 "arith_reg_operand" ""))
4343 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4344 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4348 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4349 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4350 (match_operand:SI 1 "arith_reg_operand" "0")
4351 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4353 "bf 0f\;neg %2,%0\\n0:"
4354 [(set_attr "type" "arith") ;; poor approximation
4355 (set_attr "length" "4")])
4358 ;; -------------------------------------------------------------------------
4359 ;; Zero extension instructions
4360 ;; -------------------------------------------------------------------------
4362 (define_insn "zero_extendsidi2"
4363 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4364 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4366 "addz.l %1, r63, %0"
4367 [(set_attr "type" "arith_media")
4368 (set_attr "highpart" "extend")])
4370 (define_insn "zero_extendhidi2"
4371 [(set (match_operand:DI 0 "register_operand" "=r,r")
4372 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4377 [(set_attr "type" "*,load_media")
4378 (set (attr "highpart")
4379 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4380 (const_string "user")]
4381 (const_string "ignore")))])
4384 [(set (match_operand:DI 0 "register_operand" "")
4385 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4386 "TARGET_SHMEDIA && reload_completed"
4387 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4388 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4391 if (GET_CODE (operands[1]) == TRUNCATE)
4392 operands[1] = XEXP (operands[1], 0);
4395 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4396 ;; reload the entire truncate expression.
4397 (define_insn_and_split "*loaddi_trunc"
4398 [(set (match_operand 0 "any_register_operand" "=r")
4399 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4400 "TARGET_SHMEDIA && reload_completed"
4402 "TARGET_SHMEDIA && reload_completed"
4403 [(set (match_dup 0) (match_dup 1))]
4404 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4406 (define_insn "zero_extendqidi2"
4407 [(set (match_operand:DI 0 "register_operand" "=r,r")
4408 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4413 [(set_attr "type" "arith_media,load_media")
4414 (set (attr "highpart")
4415 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4416 (const_string "user")]
4417 (const_string "ignore")))])
4419 (define_expand "zero_extendhisi2"
4420 [(set (match_operand:SI 0 "arith_reg_operand" "")
4421 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4425 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4426 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4429 (define_insn "*zero_extendhisi2_compact"
4430 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4431 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4434 [(set_attr "type" "arith")])
4436 (define_insn "*zero_extendhisi2_media"
4437 [(set (match_operand:SI 0 "register_operand" "=r,r")
4438 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4443 [(set_attr "type" "arith_media,load_media")
4444 (set (attr "highpart")
4445 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446 (const_string "user")]
4447 (const_string "ignore")))])
4450 [(set (match_operand:SI 0 "register_operand" "")
4451 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4452 "TARGET_SHMEDIA && reload_completed"
4453 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4454 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4457 rtx op1 = operands[1];
4459 if (GET_CODE (op1) == TRUNCATE)
4460 op1 = XEXP (op1, 0);
4462 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4463 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4466 (define_expand "zero_extendqisi2"
4467 [(set (match_operand:SI 0 "arith_reg_operand" "")
4468 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4472 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4473 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4476 (define_insn "*zero_extendqisi2_compact"
4477 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4478 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4481 [(set_attr "type" "arith")])
4483 (define_insn "*zero_extendqisi2_media"
4484 [(set (match_operand:SI 0 "register_operand" "=r,r")
4485 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4490 [(set_attr "type" "arith_media,load_media")
4491 (set (attr "highpart")
4492 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4493 (const_string "user")]
4494 (const_string "ignore")))])
4496 (define_insn "zero_extendqihi2"
4497 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4498 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4501 [(set_attr "type" "arith")])
4503 ;; -------------------------------------------------------------------------
4504 ;; Sign extension instructions
4505 ;; -------------------------------------------------------------------------
4507 ;; ??? This should be a define expand.
4508 ;; ??? Or perhaps it should be dropped?
4510 ;; convert_move generates good code for SH[1-4].
4511 (define_insn "extendsidi2"
4512 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4513 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4519 [(set_attr "type" "arith_media,load_media,fpconv_media")
4520 (set (attr "highpart")
4521 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4522 (const_string "user")]
4523 (const_string "extend")))])
4525 (define_insn "extendhidi2"
4526 [(set (match_operand:DI 0 "register_operand" "=r,r")
4527 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4532 [(set_attr "type" "*,load_media")
4533 (set (attr "highpart")
4534 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4535 (const_string "user")]
4536 (const_string "ignore")))])
4539 [(set (match_operand:DI 0 "register_operand" "")
4540 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4541 "TARGET_SHMEDIA && reload_completed"
4542 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4543 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4546 if (GET_CODE (operands[1]) == TRUNCATE)
4547 operands[1] = XEXP (operands[1], 0);
4550 (define_insn "extendqidi2"
4551 [(set (match_operand:DI 0 "register_operand" "=r,r")
4552 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4557 [(set_attr "type" "*,load_media")
4558 (set (attr "highpart")
4559 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4560 (const_string "user")]
4561 (const_string "ignore")))])
4564 [(set (match_operand:DI 0 "register_operand" "")
4565 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4566 "TARGET_SHMEDIA && reload_completed"
4567 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4568 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4571 if (GET_CODE (operands[1]) == TRUNCATE)
4572 operands[1] = XEXP (operands[1], 0);
4575 (define_expand "extendhisi2"
4576 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4577 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4581 (define_insn "*extendhisi2_compact"
4582 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4583 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4588 [(set_attr "type" "arith,load")])
4590 (define_insn "*extendhisi2_media"
4591 [(set (match_operand:SI 0 "register_operand" "=r,r")
4592 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4597 [(set_attr "type" "arith_media,load_media")
4598 (set (attr "highpart")
4599 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600 (const_string "user")]
4601 (const_string "ignore")))])
4604 [(set (match_operand:SI 0 "register_operand" "")
4605 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4606 "TARGET_SHMEDIA && reload_completed"
4607 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4608 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4611 rtx op1 = operands[1];
4612 if (GET_CODE (op1) == TRUNCATE)
4613 op1 = XEXP (op1, 0);
4615 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4616 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4619 (define_expand "extendqisi2"
4620 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4621 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4625 (define_insn "*extendqisi2_compact"
4626 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4627 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4632 [(set_attr "type" "arith,load")
4633 (set_attr_alternative "length"
4636 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4637 (const_int 4) (const_int 2))])])
4639 (define_insn "*extendqisi2_media"
4640 [(set (match_operand:SI 0 "register_operand" "=r,r")
4641 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4646 [(set_attr "type" "arith_media,load_media")
4647 (set (attr "highpart")
4648 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4649 (const_string "user")]
4650 (const_string "ignore")))])
4653 [(set (match_operand:SI 0 "register_operand" "")
4654 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4655 "TARGET_SHMEDIA && reload_completed"
4656 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4657 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4660 rtx op1 = operands[1];
4661 if (GET_CODE (op1) == TRUNCATE)
4662 op1 = XEXP (op1, 0);
4664 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4665 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4668 (define_insn "extendqihi2"
4669 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4670 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4675 [(set_attr "type" "arith,load")
4676 (set_attr_alternative "length"
4679 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4680 (const_int 4) (const_int 2))])])
4682 /* It would seem useful to combine the truncXi patterns into the movXi
4683 patterns, but unary operators are ignored when matching constraints,
4684 so we need separate patterns. */
4685 (define_insn "truncdisi2"
4686 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4687 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4696 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4697 (set (attr "highpart")
4698 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4699 (const_string "user")]
4700 (const_string "extend")))])
4702 (define_insn "truncdihi2"
4703 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4704 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4707 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4709 [(set_attr "type" "arith_media,store_media")
4710 (set_attr "length" "8,4")
4711 (set (attr "highpart")
4712 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4713 (const_string "user")]
4714 (const_string "extend")))])
4716 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4717 ; Because we use zero extension, we can't provide signed QImode compares
4718 ; using a simple compare or conditional branch insn.
4719 (define_insn "truncdiqi2"
4720 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4721 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4726 [(set_attr "type" "arith_media,store")
4727 (set (attr "highpart")
4728 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4729 (const_string "user")]
4730 (const_string "extend")))])
4731 ;; -------------------------------------------------------------------------
4732 ;; Move instructions
4733 ;; -------------------------------------------------------------------------
4735 ;; define push and pop so it is easy for sh.c
4736 ;; We can't use push and pop on SHcompact because the stack must always
4737 ;; be 8-byte aligned.
4739 (define_expand "push"
4740 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4741 (match_operand:SI 0 "register_operand" "r,l,x"))]
4742 "TARGET_SH1 && ! TARGET_SH5"
4745 (define_expand "pop"
4746 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4747 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4748 "TARGET_SH1 && ! TARGET_SH5"
4751 (define_expand "push_e"
4752 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4753 (match_operand:SF 0 "" ""))
4754 (use (reg:PSI FPSCR_REG))
4755 (clobber (scratch:SI))])]
4756 "TARGET_SH1 && ! TARGET_SH5"
4759 (define_insn "push_fpul"
4760 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4761 "TARGET_SH2E && ! TARGET_SH5"
4763 [(set_attr "type" "fstore")
4764 (set_attr "late_fp_use" "yes")
4765 (set_attr "hit_stack" "yes")])
4767 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4769 (define_expand "push_4"
4770 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4771 (match_operand:DF 0 "" ""))
4772 (use (reg:PSI FPSCR_REG))
4773 (clobber (scratch:SI))])]
4774 "TARGET_SH1 && ! TARGET_SH5"
4777 (define_expand "pop_e"
4778 [(parallel [(set (match_operand:SF 0 "" "")
4779 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4780 (use (reg:PSI FPSCR_REG))
4781 (clobber (scratch:SI))])]
4782 "TARGET_SH1 && ! TARGET_SH5"
4785 (define_insn "pop_fpul"
4786 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4787 "TARGET_SH2E && ! TARGET_SH5"
4789 [(set_attr "type" "load")
4790 (set_attr "hit_stack" "yes")])
4792 (define_expand "pop_4"
4793 [(parallel [(set (match_operand:DF 0 "" "")
4794 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4795 (use (reg:PSI FPSCR_REG))
4796 (clobber (scratch:SI))])]
4797 "TARGET_SH1 && ! TARGET_SH5"
4800 (define_expand "push_fpscr"
4805 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4806 gen_rtx_PRE_DEC (Pmode,
4807 stack_pointer_rtx)),
4809 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4813 (define_expand "pop_fpscr"
4818 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4819 gen_frame_mem (PSImode,
4820 gen_rtx_POST_INC (Pmode,
4821 stack_pointer_rtx))));
4822 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4826 ;; These two patterns can happen as the result of optimization, when
4827 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4828 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4831 [(set (reg:SI T_REG) (const_int 0))]
4836 [(set (reg:SI T_REG) (const_int 1))]
4840 ;; Define additional pop for SH1 and SH2 so it does not get
4841 ;; placed in the delay slot.
4842 (define_insn "*movsi_pop"
4843 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
4844 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
4845 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
4851 [(set_attr "type" "load_si,mem_mac,pload")
4852 (set_attr "length" "2,2,2")
4853 (set_attr "in_delay_slot" "no,no,no")])
4855 ;; t/r must come after r/r, lest reload will try to reload stuff like
4856 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4857 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4858 (define_insn "movsi_i"
4859 [(set (match_operand:SI 0 "general_movdst_operand"
4860 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4861 (match_operand:SI 1 "general_movsrc_operand"
4862 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4866 && (register_operand (operands[0], SImode)
4867 || register_operand (operands[1], SImode))"
4885 [(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")
4886 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4888 ;; t/r must come after r/r, lest reload will try to reload stuff like
4889 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4890 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4891 ;; will require a reload.
4892 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4893 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4894 (define_insn "movsi_ie"
4895 [(set (match_operand:SI 0 "general_movdst_operand"
4896 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4897 (match_operand:SI 1 "general_movsrc_operand"
4898 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4899 "(TARGET_SH2E || TARGET_SH2A)
4900 && (register_operand (operands[0], SImode)
4901 || register_operand (operands[1], SImode))"
4928 ! move optimized away"
4929 [(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")
4930 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4931 (set_attr_alternative "length"
4939 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4940 (const_int 4) (const_int 2))
4945 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4946 (const_int 4) (const_int 2))
4963 (define_insn "movsi_i_lowpart"
4964 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4965 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4967 && (register_operand (operands[0], SImode)
4968 || register_operand (operands[1], SImode))"
4979 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4981 (define_insn_and_split "load_ra"
4982 [(set (match_operand:SI 0 "general_movdst_operand" "")
4983 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4986 "&& ! currently_expanding_to_rtl"
4987 [(set (match_dup 0) (match_dup 1))]
4990 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4991 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4994 ;; The '?'s in the following constraints may not reflect the time taken
4995 ;; to perform the move. They are there to discourage the use of floating-
4996 ;; point registers for storing integer values.
4997 (define_insn "*movsi_media"
4998 [(set (match_operand:SI 0 "general_movdst_operand"
4999 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5000 (match_operand:SI 1 "general_movsrc_operand"
5001 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5003 && (register_operand (operands[0], SImode)
5004 || sh_register_operand (operands[1], SImode)
5005 || GET_CODE (operands[1]) == TRUNCATE)"
5020 [(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")
5021 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5022 (set (attr "highpart")
5023 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5024 (const_string "user")]
5025 (const_string "ignore")))])
5027 (define_insn "*movsi_media_nofpu"
5028 [(set (match_operand:SI 0 "general_movdst_operand"
5029 "=r,r,r,r,m,*b,r,*b")
5030 (match_operand:SI 1 "general_movsrc_operand"
5031 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5033 && (register_operand (operands[0], SImode)
5034 || sh_register_operand (operands[1], SImode)
5035 || GET_CODE (operands[1]) == TRUNCATE)"
5045 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5046 (set_attr "length" "4,4,8,4,4,4,4,12")
5047 (set (attr "highpart")
5048 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5049 (const_string "user")]
5050 (const_string "ignore")))])
5052 (define_expand "movsi_const"
5053 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5054 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5055 (const_int 16)] UNSPEC_EXTRACT_S16)))
5057 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5058 (const:SI (unspec:SI [(match_dup 1)
5059 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5060 "TARGET_SHMEDIA && reload_completed
5061 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5064 if (GET_CODE (operands[1]) == LABEL_REF
5065 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5066 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5067 else if (GOTOFF_P (operands[1]))
5069 rtx unspec = XEXP (operands[1], 0);
5071 if (! UNSPEC_GOTOFF_P (unspec))
5073 unspec = XEXP (unspec, 0);
5074 if (! UNSPEC_GOTOFF_P (unspec))
5077 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5078 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5079 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5083 (define_expand "movsi_const_16bit"
5084 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5085 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5086 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5087 "TARGET_SHMEDIA && flag_pic && reload_completed
5088 && GET_CODE (operands[1]) == SYMBOL_REF"
5092 [(set (match_operand:SI 0 "arith_reg_dest" "")
5093 (match_operand:SI 1 "immediate_operand" ""))]
5094 "TARGET_SHMEDIA && reload_completed
5095 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5099 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5101 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5107 [(set (match_operand:SI 0 "register_operand" "")
5108 (match_operand:SI 1 "immediate_operand" ""))]
5109 "TARGET_SHMEDIA && reload_completed
5110 && ((CONST_INT_P (operands[1])
5111 && ! satisfies_constraint_I16 (operands[1]))
5112 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5113 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5115 (define_expand "movsi"
5116 [(set (match_operand:SI 0 "general_movdst_operand" "")
5117 (match_operand:SI 1 "general_movsrc_operand" ""))]
5119 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5121 (define_expand "ic_invalidate_line"
5122 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5123 (match_dup 1)] UNSPEC_ICACHE)
5124 (clobber (scratch:SI))])]
5125 "TARGET_HARD_SH4 || TARGET_SH5"
5130 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5133 else if (TARGET_SHCOMPACT)
5135 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5136 operands[1] = force_reg (Pmode, operands[1]);
5137 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5140 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5142 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5145 operands[0] = force_reg (Pmode, operands[0]);
5146 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5150 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5151 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5152 ;; the requirement *1*00 for associative address writes. The alignment of
5153 ;; %0 implies that its least significant bit is cleared,
5154 ;; thus we clear the V bit of a matching entry if there is one.
5155 (define_insn "ic_invalidate_line_i"
5156 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5157 (match_operand:SI 1 "register_operand" "r")]
5159 (clobber (match_scratch:SI 2 "=&r"))]
5161 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5162 [(set_attr "length" "8")
5163 (set_attr "type" "cwb")])
5165 (define_insn "ic_invalidate_line_sh4a"
5166 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5168 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5169 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5170 [(set_attr "length" "16")
5171 (set_attr "type" "cwb")])
5173 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5174 ;; an add in the code that calculates the address.
5175 (define_insn "ic_invalidate_line_media"
5176 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5179 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5180 [(set_attr "length" "16")
5181 (set_attr "type" "invalidate_line_media")])
5183 (define_insn "ic_invalidate_line_compact"
5184 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5185 (match_operand:SI 1 "register_operand" "r")]
5187 (clobber (reg:SI PR_REG))]
5190 [(set_attr "type" "sfunc")
5191 (set_attr "needs_delay_slot" "yes")])
5193 (define_expand "initialize_trampoline"
5194 [(match_operand:SI 0 "" "")
5195 (match_operand:SI 1 "" "")
5196 (match_operand:SI 2 "" "")]
5202 tramp = force_reg (Pmode, operands[0]);
5203 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5205 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5206 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5208 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5212 (define_insn "initialize_trampoline_compact"
5213 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5214 (match_operand:SI 1 "register_operand" "r")
5215 (reg:SI R2_REG) (reg:SI R3_REG)]
5218 (clobber (reg:SI PR_REG))]
5221 [(set_attr "type" "sfunc")
5222 (set_attr "needs_delay_slot" "yes")])
5224 (define_insn "movqi_i"
5225 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5226 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5228 && (arith_reg_operand (operands[0], QImode)
5229 || arith_reg_operand (operands[1], QImode))"
5238 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5239 (set_attr_alternative "length"
5243 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5244 (const_int 4) (const_int 2))
5246 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5247 (const_int 4) (const_int 2))
5252 (define_insn "*movqi_media"
5253 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5254 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5256 && (arith_reg_operand (operands[0], QImode)
5257 || extend_reg_or_0_operand (operands[1], QImode))"
5263 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5264 (set (attr "highpart")
5265 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5266 (const_string "user")]
5267 (const_string "ignore")))])
5269 (define_expand "movqi"
5270 [(set (match_operand:QI 0 "general_operand" "")
5271 (match_operand:QI 1 "general_operand" ""))]
5273 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5275 (define_expand "reload_inqi"
5276 [(set (match_operand:SI 2 "" "=&r")
5277 (match_operand:QI 1 "inqhi_operand" ""))
5278 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5279 (truncate:QI (match_dup 3)))]
5283 rtx inner = XEXP (operands[1], 0);
5284 int regno = REGNO (inner);
5286 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5287 operands[1] = gen_rtx_REG (SImode, regno);
5288 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5291 /* When storing r0, we have to avoid reg+reg addressing. */
5292 (define_insn "movhi_i"
5293 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5294 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5296 && (arith_reg_operand (operands[0], HImode)
5297 || arith_reg_operand (operands[1], HImode))
5298 && (!MEM_P (operands[0])
5299 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5300 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5301 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5311 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5313 (define_insn "*movhi_media"
5314 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5315 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5317 && (arith_reg_operand (operands[0], HImode)
5318 || arith_reg_or_0_operand (operands[1], HImode))"
5325 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5326 (set (attr "highpart")
5327 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5328 (const_string "user")]
5329 (const_string "ignore")))])
5332 [(set (match_operand:HI 0 "register_operand" "")
5333 (match_operand:HI 1 "immediate_operand" ""))]
5334 "TARGET_SHMEDIA && reload_completed
5335 && ! satisfies_constraint_I16 (operands[1])"
5336 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5338 (define_expand "movhi"
5339 [(set (match_operand:HI 0 "general_movdst_operand" "")
5340 (match_operand:HI 1 "general_movsrc_operand" ""))]
5342 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5344 (define_expand "reload_inhi"
5345 [(set (match_operand:SI 2 "" "=&r")
5346 (match_operand:HI 1 "inqhi_operand" ""))
5347 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5348 (truncate:HI (match_dup 3)))]
5352 rtx inner = XEXP (operands[1], 0);
5353 int regno = REGNO (inner);
5355 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5356 operands[1] = gen_rtx_REG (SImode, regno);
5357 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5360 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5361 ;; compiled with -m2 -ml -O3 -funroll-loops
5362 (define_insn "*movdi_i"
5363 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5364 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5366 && (arith_reg_operand (operands[0], DImode)
5367 || arith_reg_operand (operands[1], DImode))"
5368 "* return output_movedouble (insn, operands, DImode);"
5369 [(set_attr "length" "4")
5370 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5372 ;; If the output is a register and the input is memory or a register, we have
5373 ;; to be careful and see which word needs to be loaded first.
5376 [(set (match_operand:DI 0 "general_movdst_operand" "")
5377 (match_operand:DI 1 "general_movsrc_operand" ""))]
5378 "TARGET_SH1 && reload_completed"
5379 [(set (match_dup 2) (match_dup 3))
5380 (set (match_dup 4) (match_dup 5))]
5385 if ((MEM_P (operands[0])
5386 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5387 || (MEM_P (operands[1])
5388 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5391 switch (GET_CODE (operands[0]))
5394 regno = REGNO (operands[0]);
5397 regno = subreg_regno (operands[0]);
5407 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5409 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5410 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5411 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5412 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5416 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5417 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5418 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5419 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5422 if (operands[2] == 0 || operands[3] == 0
5423 || operands[4] == 0 || operands[5] == 0)
5427 ;; The '?'s in the following constraints may not reflect the time taken
5428 ;; to perform the move. They are there to discourage the use of floating-
5429 ;; point registers for storing integer values.
5430 (define_insn "*movdi_media"
5431 [(set (match_operand:DI 0 "general_movdst_operand"
5432 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5433 (match_operand:DI 1 "general_movsrc_operand"
5434 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5436 && (register_operand (operands[0], DImode)
5437 || sh_register_operand (operands[1], DImode))"
5452 [(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")
5453 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5455 (define_insn "*movdi_media_nofpu"
5456 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5457 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5459 && (register_operand (operands[0], DImode)
5460 || sh_register_operand (operands[1], DImode))"
5470 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5471 (set_attr "length" "4,4,16,4,4,4,4,*")])
5473 (define_insn "*movdi_media_I16"
5474 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5475 (match_operand:DI 1 "const_int_operand" "I16"))]
5476 "TARGET_SHMEDIA && reload_completed"
5478 [(set_attr "type" "arith_media")
5479 (set_attr "length" "4")])
5482 [(set (match_operand:DI 0 "arith_reg_dest" "")
5483 (match_operand:DI 1 "immediate_operand" ""))]
5484 "TARGET_SHMEDIA && reload_completed
5485 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5486 [(set (match_dup 0) (match_dup 1))]
5491 if (TARGET_SHMEDIA64)
5492 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5494 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5496 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5501 (define_expand "movdi_const"
5502 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5503 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5504 (const_int 48)] UNSPEC_EXTRACT_S16)))
5506 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5507 (const:DI (unspec:DI [(match_dup 1)
5508 (const_int 32)] 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 16)] UNSPEC_EXTRACT_U16))))
5514 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5515 (const:DI (unspec:DI [(match_dup 1)
5516 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5517 "TARGET_SHMEDIA64 && reload_completed
5518 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5521 sh_mark_label (operands[1], 4);
5524 (define_expand "movdi_const_32bit"
5525 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5526 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5527 (const_int 16)] UNSPEC_EXTRACT_S16)))
5529 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5530 (const:DI (unspec:DI [(match_dup 1)
5531 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5532 "TARGET_SHMEDIA32 && reload_completed
5533 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5536 sh_mark_label (operands[1], 2);
5539 (define_expand "movdi_const_16bit"
5540 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5541 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5542 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5543 "TARGET_SHMEDIA && flag_pic && reload_completed
5544 && GET_CODE (operands[1]) == SYMBOL_REF"
5548 [(set (match_operand:DI 0 "ext_dest_operand" "")
5549 (match_operand:DI 1 "immediate_operand" ""))]
5550 "TARGET_SHMEDIA && reload_completed
5551 && CONST_INT_P (operands[1])
5552 && ! satisfies_constraint_I16 (operands[1])"
5553 [(set (match_dup 0) (match_dup 2))
5557 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5558 unsigned HOST_WIDE_INT low = val;
5559 unsigned HOST_WIDE_INT high = val;
5560 unsigned HOST_WIDE_INT sign;
5561 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5563 /* Zero-extend the 16 least-significant bits. */
5566 /* Arithmetic shift right the word by 16 bits. */
5568 if (GET_CODE (operands[0]) == SUBREG
5569 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5578 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5584 /* If we can't generate the constant with a two-insn movi / shori
5585 sequence, try some other strategies. */
5586 if (! CONST_OK_FOR_I16 (high))
5588 /* Try constant load / left shift. We know VAL != 0. */
5589 val2 = val ^ (val-1);
5592 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5594 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5595 || (! CONST_OK_FOR_I16 (high >> 16)
5596 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5598 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5599 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5600 GEN_INT (trailing_zeroes));
5604 /* Try constant load / right shift. */
5605 val2 = (val >> 15) + 1;
5606 if (val2 == (val2 & -val2))
5608 int shift = 49 - exact_log2 (val2);
5610 val2 = trunc_int_for_mode (val << shift, DImode);
5611 if (CONST_OK_FOR_I16 (val2))
5613 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5619 val2 = val & 0xffff;
5620 if ((val >> 16 & 0xffff) == val2
5621 && (val >> 32 & 0xffff) == val2
5622 && (val >> 48 & 0xffff) == val2)
5624 val2 = (HOST_WIDE_INT) val >> 48;
5625 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5626 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5629 /* Try movi / mshflo.l */
5630 val2 = (HOST_WIDE_INT) val >> 32;
5631 if (val2 == ((unsigned HOST_WIDE_INT)
5632 trunc_int_for_mode (val, SImode)))
5634 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5638 /* Try movi / mshflo.l w/ r63. */
5639 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5640 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5642 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5648 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5651 operands[2] = GEN_INT (val2);
5655 [(set (match_operand:DI 0 "ext_dest_operand" "")
5656 (match_operand:DI 1 "immediate_operand" ""))]
5657 "TARGET_SHMEDIA && reload_completed
5658 && GET_CODE (operands[1]) == CONST_DOUBLE"
5659 [(set (match_dup 0) (match_dup 2))
5661 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5664 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5665 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5666 unsigned HOST_WIDE_INT val = low;
5667 unsigned HOST_WIDE_INT sign;
5669 /* Zero-extend the 16 least-significant bits. */
5671 operands[1] = GEN_INT (val);
5673 /* Arithmetic shift right the double-word by 16 bits. */
5675 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5678 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5682 /* This will only be true if high is a sign-extension of low, i.e.,
5683 it must be either 0 or (unsigned)-1, and be zero iff the
5684 most-significant bit of low is set. */
5685 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5686 operands[2] = GEN_INT (low);
5688 operands[2] = immed_double_const (low, high, DImode);
5691 (define_insn "shori_media"
5692 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5693 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5695 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5696 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5700 [(set_attr "type" "arith_media,*")])
5702 (define_insn "*shori_media_si"
5703 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5704 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5706 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5710 (define_expand "movdi"
5711 [(set (match_operand:DI 0 "general_movdst_operand" "")
5712 (match_operand:DI 1 "general_movsrc_operand" ""))]
5714 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5716 (define_insn "movdf_media"
5717 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5718 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5720 && (register_operand (operands[0], DFmode)
5721 || sh_register_operand (operands[1], DFmode))"
5732 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5734 (define_insn "movdf_media_nofpu"
5735 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5736 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5738 && (register_operand (operands[0], DFmode)
5739 || sh_register_operand (operands[1], DFmode))"
5745 [(set_attr "type" "arith_media,*,load_media,store_media")])
5748 [(set (match_operand:DF 0 "arith_reg_dest" "")
5749 (match_operand:DF 1 "immediate_operand" ""))]
5750 "TARGET_SHMEDIA && reload_completed"
5751 [(set (match_dup 3) (match_dup 2))]
5754 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5756 REAL_VALUE_TYPE value;
5758 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5759 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5761 if (HOST_BITS_PER_WIDE_INT >= 64)
5762 operands[2] = immed_double_const ((unsigned long) values[endian]
5763 | ((HOST_WIDE_INT) values[1 - endian]
5767 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5768 operands[2] = immed_double_const (values[endian], values[1 - endian],
5772 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5775 ;; ??? This should be a define expand.
5777 (define_insn "movdf_k"
5778 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5779 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5781 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5782 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5783 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5784 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5785 && (arith_reg_operand (operands[0], DFmode)
5786 || arith_reg_operand (operands[1], DFmode))"
5787 "* return output_movedouble (insn, operands, DFmode);"
5788 [(set_attr "length" "4")
5789 (set_attr "type" "move,pcload,load,store")])
5791 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5792 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5793 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5794 ;; the d/m/c/X alternative, which is split later into single-precision
5795 ;; instructions. And when not optimizing, no splits are done before fixing
5796 ;; up pcloads, so we need usable length information for that.
5797 (define_insn "movdf_i4"
5798 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5799 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5800 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5801 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5802 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5803 && (arith_reg_operand (operands[0], DFmode)
5804 || arith_reg_operand (operands[1], DFmode))"
5806 switch (which_alternative)
5810 return "fmov %1,%0";
5811 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5812 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5814 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5817 return "fmov.d %1,%0";
5822 [(set_attr_alternative "length"
5823 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5825 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5826 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5827 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5829 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5830 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5831 ;; increment or decrement r15 explicitly.
5833 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5834 (const_int 10) (const_int 8))
5836 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5837 (const_int 10) (const_int 8))])
5838 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5839 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5840 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5841 (const_string "double")
5842 (const_string "none")))])
5844 ;; Moving DFmode between fp/general registers through memory
5845 ;; (the top of the stack) is faster than moving through fpul even for
5846 ;; little endian. Because the type of an instruction is important for its
5847 ;; scheduling, it is beneficial to split these operations, rather than
5848 ;; emitting them in one single chunk, even if this will expose a stack
5849 ;; use that will prevent scheduling of other stack accesses beyond this
5852 [(set (match_operand:DF 0 "register_operand" "")
5853 (match_operand:DF 1 "register_operand" ""))
5854 (use (match_operand:PSI 2 "fpscr_operand" ""))
5855 (clobber (match_scratch:SI 3 "=X"))]
5856 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5857 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5863 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5865 emit_move_insn (stack_pointer_rtx,
5866 plus_constant (stack_pointer_rtx, -8));
5867 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5870 tos = gen_tmp_stack_mem (DFmode,
5871 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5872 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5873 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5874 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5875 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5876 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5878 tos = gen_tmp_stack_mem (DFmode,
5879 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5880 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5881 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5882 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5884 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5888 ;; local-alloc sometimes allocates scratch registers even when not required,
5889 ;; so we must be prepared to handle these.
5891 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5893 [(set (match_operand:DF 0 "general_movdst_operand" "")
5894 (match_operand:DF 1 "general_movsrc_operand" ""))
5895 (use (match_operand:PSI 2 "fpscr_operand" ""))
5896 (clobber (match_scratch:SI 3 ""))]
5897 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5899 && true_regnum (operands[0]) < 16
5900 && true_regnum (operands[1]) < 16"
5901 [(set (match_dup 0) (match_dup 1))]
5904 /* If this was a reg <-> mem operation with base + index reg addressing,
5905 we have to handle this in a special way. */
5906 rtx mem = operands[0];
5908 if (! memory_operand (mem, DFmode))
5913 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5914 mem = SUBREG_REG (mem);
5917 rtx addr = XEXP (mem, 0);
5918 if (GET_CODE (addr) == PLUS
5919 && REG_P (XEXP (addr, 0))
5920 && REG_P (XEXP (addr, 1)))
5923 rtx reg0 = gen_rtx_REG (Pmode, 0);
5924 rtx regop = operands[store_p], word0 ,word1;
5926 if (GET_CODE (regop) == SUBREG)
5927 alter_subreg (®op);
5928 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5932 mem = copy_rtx (mem);
5933 PUT_MODE (mem, SImode);
5934 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5935 alter_subreg (&word0);
5936 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5937 alter_subreg (&word1);
5938 if (store_p || ! refers_to_regno_p (REGNO (word0),
5939 REGNO (word0) + 1, addr, 0))
5942 ? gen_movsi_ie (mem, word0)
5943 : gen_movsi_ie (word0, mem));
5944 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5945 mem = copy_rtx (mem);
5947 ? gen_movsi_ie (mem, word1)
5948 : gen_movsi_ie (word1, mem));
5949 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5953 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5954 emit_insn (gen_movsi_ie (word1, mem));
5955 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5956 mem = copy_rtx (mem);
5957 emit_insn (gen_movsi_ie (word0, mem));
5964 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5966 [(set (match_operand:DF 0 "register_operand" "")
5967 (match_operand:DF 1 "memory_operand" ""))
5968 (use (match_operand:PSI 2 "fpscr_operand" ""))
5969 (clobber (reg:SI R0_REG))]
5970 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5971 [(parallel [(set (match_dup 0) (match_dup 1))
5973 (clobber (scratch:SI))])]
5976 (define_expand "reload_indf__frn"
5977 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5978 (match_operand:DF 1 "immediate_operand" "FQ"))
5979 (use (reg:PSI FPSCR_REG))
5980 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5984 (define_expand "reload_outdf__RnFRm"
5985 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5986 (match_operand:DF 1 "register_operand" "af,r"))
5987 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5991 ;; Simplify no-op moves.
5993 [(set (match_operand:SF 0 "register_operand" "")
5994 (match_operand:SF 1 "register_operand" ""))
5995 (use (match_operand:PSI 2 "fpscr_operand" ""))
5996 (clobber (match_scratch:SI 3 ""))]
5997 "TARGET_SH2E && reload_completed
5998 && true_regnum (operands[0]) == true_regnum (operands[1])"
5999 [(set (match_dup 0) (match_dup 0))]
6002 ;; fmovd substitute post-reload splits
6004 [(set (match_operand:DF 0 "register_operand" "")
6005 (match_operand:DF 1 "register_operand" ""))
6006 (use (match_operand:PSI 2 "fpscr_operand" ""))
6007 (clobber (match_scratch:SI 3 ""))]
6008 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6009 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6010 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6014 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6015 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6016 gen_rtx_REG (SFmode, src), operands[2]));
6017 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6018 gen_rtx_REG (SFmode, src + 1), operands[2]));
6023 [(set (match_operand:DF 0 "register_operand" "")
6024 (mem:DF (match_operand:SI 1 "register_operand" "")))
6025 (use (match_operand:PSI 2 "fpscr_operand" ""))
6026 (clobber (match_scratch:SI 3 ""))]
6027 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6028 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6029 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6033 int regno = true_regnum (operands[0]);
6035 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6037 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6038 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6039 regno + !! TARGET_LITTLE_ENDIAN),
6040 mem2, operands[2]));
6041 add_reg_note (insn, REG_INC, operands[1]);
6042 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6043 regno + ! TARGET_LITTLE_ENDIAN),
6044 change_address (mem, SFmode, NULL_RTX),
6050 [(set (match_operand:DF 0 "register_operand" "")
6051 (match_operand:DF 1 "memory_operand" ""))
6052 (use (match_operand:PSI 2 "fpscr_operand" ""))
6053 (clobber (match_scratch:SI 3 ""))]
6054 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6055 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6058 int regno = true_regnum (operands[0]);
6060 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6061 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6062 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6064 operands[1] = copy_rtx (mem2);
6065 addr = XEXP (mem2, 0);
6067 switch (GET_CODE (addr))
6070 /* This is complicated. If the register is an arithmetic register
6071 we can just fall through to the REG+DISP case below. Otherwise
6072 we have to use a combination of POST_INC and REG addressing... */
6073 if (! arith_reg_operand (operands[1], SFmode))
6075 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6076 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6077 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6079 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6081 /* If we have modified the stack pointer, the value that we have
6082 read with post-increment might be modified by an interrupt,
6083 so write it back. */
6084 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6085 emit_insn (gen_push_e (reg0));
6087 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6093 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6094 operands[1] = copy_rtx (operands[1]);
6095 XEXP (operands[1], 0) = plus_constant (addr, 4);
6096 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6100 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6101 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6103 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6104 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6116 [(set (match_operand:DF 0 "memory_operand" "")
6117 (match_operand:DF 1 "register_operand" ""))
6118 (use (match_operand:PSI 2 "fpscr_operand" ""))
6119 (clobber (match_scratch:SI 3 ""))]
6120 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6121 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6124 int regno = true_regnum (operands[1]);
6126 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6127 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6129 operands[0] = copy_rtx (operands[0]);
6130 PUT_MODE (operands[0], SFmode);
6131 addr = XEXP (operands[0], 0);
6133 switch (GET_CODE (addr))
6136 /* This is complicated. If the register is an arithmetic register
6137 we can just fall through to the REG+DISP case below. Otherwise
6138 we have to use a combination of REG and PRE_DEC addressing... */
6139 if (! arith_reg_operand (operands[0], SFmode))
6141 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6142 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6144 operands[0] = copy_rtx (operands[0]);
6145 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6147 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6148 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6154 /* Since REG+DISP addressing has already been decided upon by gcc
6155 we can rely upon it having chosen an arithmetic register as the
6156 register component of the address. Just emit the lower numbered
6157 register first, to the lower address, then the higher numbered
6158 register to the higher address. */
6159 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6161 operands[0] = copy_rtx (operands[0]);
6162 XEXP (operands[0], 0) = plus_constant (addr, 4);
6164 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6168 /* This is easy. Output the word to go to the higher address
6169 first (ie the word in the higher numbered register) then the
6170 word to go to the lower address. */
6172 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6173 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6175 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6176 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6188 ;; If the output is a register and the input is memory or a register, we have
6189 ;; to be careful and see which word needs to be loaded first.
6192 [(set (match_operand:DF 0 "general_movdst_operand" "")
6193 (match_operand:DF 1 "general_movsrc_operand" ""))]
6194 "TARGET_SH1 && reload_completed"
6195 [(set (match_dup 2) (match_dup 3))
6196 (set (match_dup 4) (match_dup 5))]
6201 if ((MEM_P (operands[0])
6202 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6203 || (MEM_P (operands[1])
6204 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6207 switch (GET_CODE (operands[0]))
6210 regno = REGNO (operands[0]);
6213 regno = subreg_regno (operands[0]);
6223 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6225 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6226 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6227 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6228 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6232 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6233 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6234 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6235 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6238 if (operands[2] == 0 || operands[3] == 0
6239 || operands[4] == 0 || operands[5] == 0)
6243 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6244 ;; used only once, let combine add in the index again.
6247 [(set (match_operand:SI 0 "register_operand" "")
6248 (match_operand:SI 1 "" ""))
6249 (clobber (match_operand 2 "register_operand" ""))]
6250 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6251 && ALLOW_INDEXED_ADDRESS"
6252 [(use (reg:SI R0_REG))]
6255 rtx addr, reg, const_int;
6257 if (!MEM_P (operands[1]))
6259 addr = XEXP (operands[1], 0);
6260 if (GET_CODE (addr) != PLUS)
6262 reg = XEXP (addr, 0);
6263 const_int = XEXP (addr, 1);
6264 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6265 && CONST_INT_P (const_int)))
6267 emit_move_insn (operands[2], const_int);
6268 emit_move_insn (operands[0],
6269 change_address (operands[1], VOIDmode,
6270 gen_rtx_PLUS (SImode, reg, operands[2])));
6275 [(set (match_operand:SI 1 "" "")
6276 (match_operand:SI 0 "register_operand" ""))
6277 (clobber (match_operand 2 "register_operand" ""))]
6278 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6279 && ALLOW_INDEXED_ADDRESS"
6280 [(use (reg:SI R0_REG))]
6283 rtx addr, reg, const_int;
6285 if (!MEM_P (operands[1]))
6287 addr = XEXP (operands[1], 0);
6288 if (GET_CODE (addr) != PLUS)
6290 reg = XEXP (addr, 0);
6291 const_int = XEXP (addr, 1);
6292 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6293 && CONST_INT_P (const_int)))
6295 emit_move_insn (operands[2], const_int);
6296 emit_move_insn (change_address (operands[1], VOIDmode,
6297 gen_rtx_PLUS (SImode, reg, operands[2])),
6302 (define_expand "movdf"
6303 [(set (match_operand:DF 0 "general_movdst_operand" "")
6304 (match_operand:DF 1 "general_movsrc_operand" ""))]
6308 if (prepare_move_operands (operands, DFmode)) DONE;
6311 if (TARGET_SHMEDIA_FPU)
6312 emit_insn (gen_movdf_media (operands[0], operands[1]));
6314 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6317 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6319 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6324 ;;This is incompatible with the way gcc uses subregs.
6325 ;;(define_insn "movv2sf_i"
6326 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6327 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6328 ;; "TARGET_SHMEDIA_FPU
6329 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6330 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6334 ;; fst%M0.p %m0, %1"
6335 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6337 (define_insn_and_split "movv2sf_i"
6338 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6339 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6340 "TARGET_SHMEDIA_FPU"
6342 "TARGET_SHMEDIA_FPU && reload_completed"
6343 [(set (match_dup 0) (match_dup 1))]
6346 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6347 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6350 (define_expand "movv2sf"
6351 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6352 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6353 "TARGET_SHMEDIA_FPU"
6356 if (prepare_move_operands (operands, V2SFmode))
6360 (define_expand "addv2sf3"
6361 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6362 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6363 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6364 "TARGET_SHMEDIA_FPU"
6367 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6371 (define_expand "subv2sf3"
6372 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6373 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6374 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6375 "TARGET_SHMEDIA_FPU"
6378 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6382 (define_expand "mulv2sf3"
6383 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6384 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6385 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6386 "TARGET_SHMEDIA_FPU"
6389 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6393 (define_expand "divv2sf3"
6394 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6395 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6396 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6397 "TARGET_SHMEDIA_FPU"
6400 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6404 (define_insn_and_split "*movv4sf_i"
6405 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6406 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6407 "TARGET_SHMEDIA_FPU"
6409 "&& reload_completed"
6415 for (i = 0; i < 4/2; i++)
6419 if (MEM_P (operands[0]))
6420 x = adjust_address (operands[0], V2SFmode,
6421 i * GET_MODE_SIZE (V2SFmode));
6423 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6425 if (MEM_P (operands[1]))
6426 y = adjust_address (operands[1], V2SFmode,
6427 i * GET_MODE_SIZE (V2SFmode));
6429 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6431 emit_insn (gen_movv2sf_i (x, y));
6436 [(set_attr "length" "8")])
6438 (define_expand "movv4sf"
6439 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6440 (match_operand:V4SF 1 "general_operand" ""))]
6441 "TARGET_SHMEDIA_FPU"
6444 if (prepare_move_operands (operands, V4SFmode))
6448 (define_insn_and_split "*movv16sf_i"
6449 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6450 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6451 "TARGET_SHMEDIA_FPU"
6453 "&& reload_completed"
6459 for (i = 0; i < 16/2; i++)
6463 if (MEM_P (operands[0]))
6464 x = adjust_address (operands[0], V2SFmode,
6465 i * GET_MODE_SIZE (V2SFmode));
6468 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6472 if (MEM_P (operands[1]))
6473 y = adjust_address (operands[1], V2SFmode,
6474 i * GET_MODE_SIZE (V2SFmode));
6477 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6481 emit_insn (gen_movv2sf_i (x, y));
6486 [(set_attr "length" "32")])
6488 (define_expand "movv16sf"
6489 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6490 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6491 "TARGET_SHMEDIA_FPU"
6494 if (prepare_move_operands (operands, V16SFmode))
6498 (define_insn "movsf_media"
6499 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6500 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6502 && (register_operand (operands[0], SFmode)
6503 || sh_register_operand (operands[1], SFmode))"
6514 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6515 (set (attr "highpart")
6516 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6517 (const_string "user")]
6518 (const_string "ignore")))])
6520 (define_insn "movsf_media_nofpu"
6521 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6522 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6524 && (register_operand (operands[0], SFmode)
6525 || sh_register_operand (operands[1], SFmode))"
6531 [(set_attr "type" "arith_media,*,load_media,store_media")
6532 (set (attr "highpart")
6533 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6534 (const_string "user")]
6535 (const_string "ignore")))])
6538 [(set (match_operand:SF 0 "arith_reg_dest" "")
6539 (match_operand:SF 1 "immediate_operand" ""))]
6540 "TARGET_SHMEDIA && reload_completed
6541 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6542 [(set (match_dup 3) (match_dup 2))]
6546 REAL_VALUE_TYPE value;
6548 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6549 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6550 operands[2] = GEN_INT (values);
6552 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6555 (define_insn "movsf_i"
6556 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6557 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6560 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6561 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6562 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6563 && (arith_reg_operand (operands[0], SFmode)
6564 || arith_reg_operand (operands[1], SFmode))"
6573 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6575 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6576 ;; update_flow_info would not know where to put REG_EQUAL notes
6577 ;; when the destination changes mode.
6578 (define_insn "movsf_ie"
6579 [(set (match_operand:SF 0 "general_movdst_operand"
6580 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6581 (match_operand:SF 1 "general_movsrc_operand"
6582 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6583 (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"))
6584 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6587 && (arith_reg_operand (operands[0], SFmode)
6588 || arith_reg_operand (operands[1], SFmode)
6589 || arith_reg_operand (operands[3], SImode)
6590 || (fpul_operand (operands[0], SFmode)
6591 && memory_operand (operands[1], SFmode)
6592 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6593 || (fpul_operand (operands[1], SFmode)
6594 && memory_operand (operands[0], SFmode)
6595 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6615 ! move optimized away"
6616 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6617 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6618 (set_attr_alternative "length"
6625 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6626 (const_int 4) (const_int 2))
6628 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6629 (const_int 4) (const_int 2))
6632 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6633 (const_int 4) (const_int 2))
6635 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6636 (const_int 4) (const_int 2))
6646 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6647 (const_string "single")
6648 (const_string "single")))])
6651 [(set (match_operand:SF 0 "register_operand" "")
6652 (match_operand:SF 1 "register_operand" ""))
6653 (use (match_operand:PSI 2 "fpscr_operand" ""))
6654 (clobber (reg:SI FPUL_REG))]
6656 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6658 (clobber (scratch:SI))])
6659 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6661 (clobber (scratch:SI))])]
6664 (define_expand "movsf"
6665 [(set (match_operand:SF 0 "general_movdst_operand" "")
6666 (match_operand:SF 1 "general_movsrc_operand" ""))]
6670 if (prepare_move_operands (operands, SFmode))
6674 if (TARGET_SHMEDIA_FPU)
6675 emit_insn (gen_movsf_media (operands[0], operands[1]));
6677 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6682 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6687 (define_insn "mov_nop"
6688 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6691 [(set_attr "length" "0")
6692 (set_attr "type" "nil")])
6694 (define_expand "reload_insf__frn"
6695 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6696 (match_operand:SF 1 "immediate_operand" "FQ"))
6697 (use (reg:PSI FPSCR_REG))
6698 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6702 (define_expand "reload_insi__i_fpul"
6703 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6704 (match_operand:SI 1 "immediate_operand" "i"))
6705 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6709 (define_expand "ptabs"
6710 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6714 if (!TARGET_PT_FIXED)
6716 rtx eq = operands[1];
6718 /* ??? For canonical RTL we really should remove any CONST from EQ
6719 before wrapping it in the AND, and finally wrap the EQ into a
6720 const if is constant. However, for reload we must expose the
6721 input register or symbolic constant, and we can't have
6722 different insn structures outside of the operands for different
6723 alternatives of the same pattern. */
6724 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6727 = (gen_rtx_IF_THEN_ELSE
6730 gen_rtx_MEM (PDImode, operands[1]),
6731 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6732 PDImode, operands[1])));
6736 ;; expanded by ptabs expander.
6737 (define_insn "*extendsipdi_media"
6738 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6739 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6743 (mem:PDI (match_dup 1))
6744 (sign_extend:PDI (match_dup 1))))]
6745 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6749 [(set_attr "type" "ptabs_media,pt_media")
6750 (set_attr "length" "4,*")])
6752 (define_insn "*truncdipdi_media"
6753 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6754 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6758 (mem:PDI (match_dup 1))
6759 (truncate:PDI (match_dup 1))))]
6760 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6764 [(set_attr "type" "ptabs_media,pt_media")
6765 (set_attr "length" "4,*")])
6767 (define_insn "*movsi_y"
6768 [(set (match_operand:SI 0 "register_operand" "=y,y")
6769 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6770 (clobber (match_scratch:SI 2 "=&z,r"))]
6772 && (reload_in_progress || reload_completed)"
6774 [(set_attr "length" "4")
6775 (set_attr "type" "pcload,move")])
6778 [(set (match_operand:SI 0 "register_operand" "")
6779 (match_operand:SI 1 "immediate_operand" ""))
6780 (clobber (match_operand:SI 2 "register_operand" ""))]
6782 [(set (match_dup 2) (match_dup 1))
6783 (set (match_dup 0) (match_dup 2))]
6787 [(set (match_operand:SI 0 "register_operand" "")
6788 (match_operand:SI 1 "memory_operand" ""))
6789 (clobber (reg:SI R0_REG))]
6791 [(set (match_dup 0) (match_dup 1))]
6794 ;; ------------------------------------------------------------------------
6795 ;; Define the real conditional branch instructions.
6796 ;; ------------------------------------------------------------------------
6798 (define_insn "branch_true"
6799 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6800 (label_ref (match_operand 0 "" ""))
6803 "* return output_branch (1, insn, operands);"
6804 [(set_attr "type" "cbranch")])
6806 (define_insn "branch_false"
6807 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6808 (label_ref (match_operand 0 "" ""))
6811 "* return output_branch (0, insn, operands);"
6812 [(set_attr "type" "cbranch")])
6814 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6815 ;; which destination is too far away.
6816 ;; The const_int_operand is distinct for each branch target; it avoids
6817 ;; unwanted matches with redundant_insn.
6818 (define_insn "block_branch_redirect"
6819 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6822 [(set_attr "length" "0")])
6824 ;; This one has the additional purpose to record a possible scratch register
6825 ;; for the following branch.
6826 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6827 ;; because the insn then might be deemed dead and deleted. And we can't
6828 ;; make the use in the jump insn explicit because that would disable
6829 ;; delay slot scheduling from the target.
6830 (define_insn "indirect_jump_scratch"
6831 [(set (match_operand:SI 0 "register_operand" "=r")
6832 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6833 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6836 [(set_attr "length" "0")])
6838 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6839 ;; being pulled into the delay slot of a condbranch that has been made to
6840 ;; jump around the unconditional jump because it was out of range.
6841 (define_insn "stuff_delay_slot"
6843 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6844 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6847 [(set_attr "length" "0")
6848 (set_attr "cond_delay_slot" "yes")])
6850 ;; Conditional branch insns
6852 (define_expand "cbranchint4_media"
6854 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6855 [(match_operand 1 "" "")
6856 (match_operand 2 "" "")])
6857 (match_operand 3 "" "")
6862 enum machine_mode mode = GET_MODE (operands[1]);
6863 if (mode == VOIDmode)
6864 mode = GET_MODE (operands[2]);
6865 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6867 operands[1] = force_reg (mode, operands[1]);
6868 if (CONSTANT_P (operands[2])
6869 && (! satisfies_constraint_I06 (operands[2])))
6870 operands[2] = force_reg (mode, operands[2]);
6874 if (operands[1] != const0_rtx)
6875 operands[1] = force_reg (mode, operands[1]);
6876 if (operands[2] != const0_rtx)
6877 operands[2] = force_reg (mode, operands[2]);
6879 switch (GET_CODE (operands[0]))
6885 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6886 VOIDmode, operands[2], operands[1]);
6887 operands[1] = XEXP (operands[0], 0);
6888 operands[2] = XEXP (operands[0], 1);
6891 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6892 VOIDmode, operands[1], operands[2]);
6895 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6898 (define_expand "cbranchfp4_media"
6900 (if_then_else (match_operator 0 "sh_float_comparison_operator"
6901 [(match_operand 1 "" "")
6902 (match_operand 2 "" "")])
6903 (match_operand 3 "" "")
6908 rtx tmp = gen_reg_rtx (SImode);
6910 if (GET_CODE (operands[0]) == NE)
6911 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6913 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6914 operands[1], operands[2]);
6916 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6918 if (GET_CODE (cmp) == GET_CODE (operands[0]))
6919 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6921 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6923 operands[2] = const0_rtx;
6924 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6927 (define_insn "*beq_media_i"
6929 (if_then_else (match_operator 3 "equality_comparison_operator"
6930 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6931 (match_operand:DI 2 "arith_operand" "r,I06")])
6932 (match_operand 0 "target_operand" "b,b")
6937 b%o3i%' %1, %2, %0%>"
6938 [(set_attr "type" "cbranch_media")])
6940 (define_insn "*beq_media_i32"
6942 (if_then_else (match_operator 3 "equality_comparison_operator"
6943 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6944 (match_operand:SI 2 "arith_operand" "r,I06")])
6945 (match_operand 0 "target_operand" "b,b")
6950 b%o3i%' %1, %2, %0%>"
6951 [(set_attr "type" "cbranch_media")])
6953 (define_insn "*bgt_media_i"
6955 (if_then_else (match_operator 3 "greater_comparison_operator"
6956 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6957 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6958 (match_operand 0 "target_operand" "b")
6961 "b%o3%' %N1, %N2, %0%>"
6962 [(set_attr "type" "cbranch_media")])
6964 (define_insn "*bgt_media_i32"
6966 (if_then_else (match_operator 3 "greater_comparison_operator"
6967 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6968 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6969 (match_operand 0 "target_operand" "b")
6972 "b%o3%' %N1, %N2, %0%>"
6973 [(set_attr "type" "cbranch_media")])
6975 ;; These are only needed to make invert_jump() happy - otherwise, jump
6976 ;; optimization will be silently disabled.
6977 (define_insn "*blt_media_i"
6979 (if_then_else (match_operator 3 "less_comparison_operator"
6980 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6981 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6982 (match_operand 0 "target_operand" "b")
6985 "b%o3%' %N2, %N1, %0%>"
6986 [(set_attr "type" "cbranch_media")])
6988 (define_insn "*blt_media_i32"
6990 (if_then_else (match_operator 3 "less_comparison_operator"
6991 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6992 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6993 (match_operand 0 "target_operand" "b")
6996 "b%o3%' %N2, %N1, %0%>"
6997 [(set_attr "type" "cbranch_media")])
6999 ;; combiner splitter for test-and-branch on single bit in register. This
7000 ;; is endian dependent because the non-paradoxical subreg looks different
7005 (match_operator 3 "equality_comparison_operator"
7006 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7007 "extend_reg_operand" "")
7011 "const_int_operand" "")) 0)
7013 (match_operand 0 "target_operand" "")
7015 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7016 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7017 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7018 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7022 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7023 operands[6] = (GET_CODE (operands[3]) == EQ
7024 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7025 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7028 ; operand 0 is the loop count pseudo register
7029 ; operand 1 is the number of loop iterations or 0 if it is unknown
7030 ; operand 2 is the maximum number of loop iterations
7031 ; operand 3 is the number of levels of enclosed loops
7032 ; operand 4 is the label to jump to at the top of the loop
7034 (define_expand "doloop_end"
7035 [(parallel [(set (pc) (if_then_else
7036 (ne:SI (match_operand:SI 0 "" "")
7038 (label_ref (match_operand 4 "" ""))
7041 (plus:SI (match_dup 0) (const_int -1)))
7042 (clobber (reg:SI T_REG))])]
7046 if (GET_MODE (operands[0]) != SImode)
7051 (define_insn_and_split "doloop_end_split"
7053 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7055 (label_ref (match_operand 1 "" ""))
7058 (plus (match_dup 0) (const_int -1)))
7059 (clobber (reg:SI T_REG))]
7063 [(parallel [(set (reg:SI T_REG)
7064 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7066 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7067 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7068 (label_ref (match_operand 1 "" ""))
7071 [(set_attr "type" "cbranch")])
7074 ;; ------------------------------------------------------------------------
7075 ;; Jump and linkage insns
7076 ;; ------------------------------------------------------------------------
7078 (define_insn "jump_compact"
7080 (label_ref (match_operand 0 "" "")))]
7081 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7084 /* The length is 16 if the delay slot is unfilled. */
7085 if (get_attr_length(insn) > 4)
7086 return output_far_jump(insn, operands[0]);
7088 return \"bra %l0%#\";
7090 [(set_attr "type" "jump")
7091 (set_attr "needs_delay_slot" "yes")])
7093 ;; ??? It would be much saner to explicitly use the scratch register
7094 ;; in the jump insn, and have indirect_jump_scratch only set it,
7095 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7096 ;; from the target then, as it uses simplejump_p.
7097 ;;(define_insn "jump_compact_far"
7099 ;; (label_ref (match_operand 0 "" "")))
7100 ;; (use (match_operand 1 "register_operand" "r")]
7102 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7103 ;; [(set_attr "type" "jump")
7104 ;; (set_attr "needs_delay_slot" "yes")])
7106 (define_insn "jump_media"
7108 (match_operand 0 "target_operand" "b"))]
7111 [(set_attr "type" "jump_media")])
7113 (define_expand "jump"
7115 (label_ref (match_operand 0 "" "")))]
7120 emit_jump_insn (gen_jump_compact (operands[0]));
7121 else if (TARGET_SHMEDIA)
7123 if (reload_in_progress || reload_completed)
7125 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7131 (define_insn "force_mode_for_call"
7132 [(use (reg:PSI FPSCR_REG))]
7135 [(set_attr "length" "0")
7136 (set (attr "fp_mode")
7137 (if_then_else (eq_attr "fpu_single" "yes")
7138 (const_string "single") (const_string "double")))])
7140 (define_insn "calli"
7141 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7142 (match_operand 1 "" ""))
7143 (use (reg:PSI FPSCR_REG))
7144 (clobber (reg:SI PR_REG))]
7148 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7149 return \"jsr/n\\t@%0\";
7151 return \"jsr\\t@%0%#\";
7154 [(set_attr "type" "call")
7155 (set (attr "fp_mode")
7156 (if_then_else (eq_attr "fpu_single" "yes")
7157 (const_string "single") (const_string "double")))
7158 (set_attr "needs_delay_slot" "yes")
7159 (set_attr "fp_set" "unknown")])
7161 ;; This is TBR relative jump instruction for SH2A architecture.
7162 ;; Its use is enabled assigning an attribute "function_vector"
7163 ;; and the vector number to a function during its declaration.
7165 (define_insn "calli_tbr_rel"
7166 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7167 (match_operand 1 "" ""))
7168 (use (reg:PSI FPSCR_REG))
7169 (clobber (reg:SI PR_REG))]
7170 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7173 unsigned HOST_WIDE_INT vect_num;
7174 vect_num = sh2a_get_function_vector_number (operands[0]);
7175 operands[2] = GEN_INT (vect_num * 4);
7177 return \"jsr/n\\t@@(%O2,tbr)\";
7179 [(set_attr "type" "call")
7180 (set (attr "fp_mode")
7181 (if_then_else (eq_attr "fpu_single" "yes")
7182 (const_string "single") (const_string "double")))
7183 (set_attr "needs_delay_slot" "no")
7184 (set_attr "fp_set" "unknown")])
7186 ;; This is a pc-rel call, using bsrf, for use with PIC.
7188 (define_insn "calli_pcrel"
7189 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7190 (match_operand 1 "" ""))
7191 (use (reg:PSI FPSCR_REG))
7192 (use (reg:SI PIC_REG))
7193 (use (match_operand 2 "" ""))
7194 (clobber (reg:SI PR_REG))]
7197 [(set_attr "type" "call")
7198 (set (attr "fp_mode")
7199 (if_then_else (eq_attr "fpu_single" "yes")
7200 (const_string "single") (const_string "double")))
7201 (set_attr "needs_delay_slot" "yes")
7202 (set_attr "fp_set" "unknown")])
7204 (define_insn_and_split "call_pcrel"
7205 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7206 (match_operand 1 "" ""))
7207 (use (reg:PSI FPSCR_REG))
7208 (use (reg:SI PIC_REG))
7209 (clobber (reg:SI PR_REG))
7210 (clobber (match_scratch:SI 2 "=r"))]
7217 rtx lab = PATTERN (gen_call_site ());
7219 if (SYMBOL_REF_LOCAL_P (operands[0]))
7220 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7222 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7223 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7226 [(set_attr "type" "call")
7227 (set (attr "fp_mode")
7228 (if_then_else (eq_attr "fpu_single" "yes")
7229 (const_string "single") (const_string "double")))
7230 (set_attr "needs_delay_slot" "yes")
7231 (set_attr "fp_set" "unknown")])
7233 (define_insn "call_compact"
7234 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7235 (match_operand 1 "" ""))
7236 (match_operand 2 "immediate_operand" "n")
7237 (use (reg:SI R0_REG))
7238 (use (reg:SI R1_REG))
7239 (use (reg:PSI FPSCR_REG))
7240 (clobber (reg:SI PR_REG))]
7241 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7243 [(set_attr "type" "call")
7244 (set (attr "fp_mode")
7245 (if_then_else (eq_attr "fpu_single" "yes")
7246 (const_string "single") (const_string "double")))
7247 (set_attr "needs_delay_slot" "yes")])
7249 (define_insn "call_compact_rettramp"
7250 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7251 (match_operand 1 "" ""))
7252 (match_operand 2 "immediate_operand" "n")
7253 (use (reg:SI R0_REG))
7254 (use (reg:SI R1_REG))
7255 (use (reg:PSI FPSCR_REG))
7256 (clobber (reg:SI R10_REG))
7257 (clobber (reg:SI PR_REG))]
7258 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7260 [(set_attr "type" "call")
7261 (set (attr "fp_mode")
7262 (if_then_else (eq_attr "fpu_single" "yes")
7263 (const_string "single") (const_string "double")))
7264 (set_attr "needs_delay_slot" "yes")])
7266 (define_insn "call_media"
7267 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7268 (match_operand 1 "" ""))
7269 (clobber (reg:DI PR_MEDIA_REG))]
7272 [(set_attr "type" "jump_media")])
7274 (define_insn "call_valuei"
7275 [(set (match_operand 0 "" "=rf")
7276 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7277 (match_operand 2 "" "")))
7278 (use (reg:PSI FPSCR_REG))
7279 (clobber (reg:SI PR_REG))]
7283 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7284 return \"jsr/n\\t@%1\";
7286 return \"jsr\\t@%1%#\";
7288 [(set_attr "type" "call")
7289 (set (attr "fp_mode")
7290 (if_then_else (eq_attr "fpu_single" "yes")
7291 (const_string "single") (const_string "double")))
7292 (set_attr "needs_delay_slot" "yes")
7293 (set_attr "fp_set" "unknown")])
7295 ;; This is TBR relative jump instruction for SH2A architecture.
7296 ;; Its use is enabled assigning an attribute "function_vector"
7297 ;; and the vector number to a function during its declaration.
7299 (define_insn "call_valuei_tbr_rel"
7300 [(set (match_operand 0 "" "=rf")
7301 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7302 (match_operand 2 "" "")))
7303 (use (reg:PSI FPSCR_REG))
7304 (clobber (reg:SI PR_REG))]
7305 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7308 unsigned HOST_WIDE_INT vect_num;
7309 vect_num = sh2a_get_function_vector_number (operands[1]);
7310 operands[3] = GEN_INT (vect_num * 4);
7312 return \"jsr/n\\t@@(%O3,tbr)\";
7314 [(set_attr "type" "call")
7315 (set (attr "fp_mode")
7316 (if_then_else (eq_attr "fpu_single" "yes")
7317 (const_string "single") (const_string "double")))
7318 (set_attr "needs_delay_slot" "no")
7319 (set_attr "fp_set" "unknown")])
7321 (define_insn "call_valuei_pcrel"
7322 [(set (match_operand 0 "" "=rf")
7323 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7324 (match_operand 2 "" "")))
7325 (use (reg:PSI FPSCR_REG))
7326 (use (reg:SI PIC_REG))
7327 (use (match_operand 3 "" ""))
7328 (clobber (reg:SI PR_REG))]
7331 [(set_attr "type" "call")
7332 (set (attr "fp_mode")
7333 (if_then_else (eq_attr "fpu_single" "yes")
7334 (const_string "single") (const_string "double")))
7335 (set_attr "needs_delay_slot" "yes")
7336 (set_attr "fp_set" "unknown")])
7338 (define_insn_and_split "call_value_pcrel"
7339 [(set (match_operand 0 "" "=rf")
7340 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7341 (match_operand 2 "" "")))
7342 (use (reg:PSI FPSCR_REG))
7343 (use (reg:SI PIC_REG))
7344 (clobber (reg:SI PR_REG))
7345 (clobber (match_scratch:SI 3 "=r"))]
7352 rtx lab = PATTERN (gen_call_site ());
7354 if (SYMBOL_REF_LOCAL_P (operands[1]))
7355 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7357 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7358 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7359 operands[2], copy_rtx (lab)));
7362 [(set_attr "type" "call")
7363 (set (attr "fp_mode")
7364 (if_then_else (eq_attr "fpu_single" "yes")
7365 (const_string "single") (const_string "double")))
7366 (set_attr "needs_delay_slot" "yes")
7367 (set_attr "fp_set" "unknown")])
7369 (define_insn "call_value_compact"
7370 [(set (match_operand 0 "" "=rf")
7371 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7372 (match_operand 2 "" "")))
7373 (match_operand 3 "immediate_operand" "n")
7374 (use (reg:SI R0_REG))
7375 (use (reg:SI R1_REG))
7376 (use (reg:PSI FPSCR_REG))
7377 (clobber (reg:SI PR_REG))]
7378 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7380 [(set_attr "type" "call")
7381 (set (attr "fp_mode")
7382 (if_then_else (eq_attr "fpu_single" "yes")
7383 (const_string "single") (const_string "double")))
7384 (set_attr "needs_delay_slot" "yes")])
7386 (define_insn "call_value_compact_rettramp"
7387 [(set (match_operand 0 "" "=rf")
7388 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7389 (match_operand 2 "" "")))
7390 (match_operand 3 "immediate_operand" "n")
7391 (use (reg:SI R0_REG))
7392 (use (reg:SI R1_REG))
7393 (use (reg:PSI FPSCR_REG))
7394 (clobber (reg:SI R10_REG))
7395 (clobber (reg:SI PR_REG))]
7396 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7398 [(set_attr "type" "call")
7399 (set (attr "fp_mode")
7400 (if_then_else (eq_attr "fpu_single" "yes")
7401 (const_string "single") (const_string "double")))
7402 (set_attr "needs_delay_slot" "yes")])
7404 (define_insn "call_value_media"
7405 [(set (match_operand 0 "" "=rf")
7406 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7407 (match_operand 2 "" "")))
7408 (clobber (reg:DI PR_MEDIA_REG))]
7411 [(set_attr "type" "jump_media")])
7413 (define_expand "call"
7414 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7415 (match_operand 1 "" ""))
7416 (match_operand 2 "" "")
7417 (use (reg:PSI FPSCR_REG))
7418 (clobber (reg:SI PR_REG))])]
7424 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7425 emit_call_insn (gen_call_media (operands[0], operands[1]));
7428 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7430 rtx cookie_rtx = operands[2];
7431 long cookie = INTVAL (cookie_rtx);
7432 rtx func = XEXP (operands[0], 0);
7437 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7439 rtx reg = gen_reg_rtx (Pmode);
7441 emit_insn (gen_symGOTPLT2reg (reg, func));
7445 func = legitimize_pic_address (func, Pmode, 0);
7448 r0 = gen_rtx_REG (SImode, R0_REG);
7449 r1 = gen_rtx_REG (SImode, R1_REG);
7451 /* Since such a call function may use all call-clobbered
7452 registers, we force a mode switch earlier, so that we don't
7453 run out of registers when adjusting fpscr for the call. */
7454 emit_insn (gen_force_mode_for_call ());
7457 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7459 operands[0] = force_reg (SImode, operands[0]);
7461 emit_move_insn (r0, func);
7462 emit_move_insn (r1, cookie_rtx);
7464 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7465 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7468 emit_call_insn (gen_call_compact (operands[0], operands[1],
7473 else if (TARGET_SHCOMPACT && flag_pic
7474 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7475 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7477 rtx reg = gen_reg_rtx (Pmode);
7479 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7480 XEXP (operands[0], 0) = reg;
7482 if (!flag_pic && TARGET_SH2A
7483 && MEM_P (operands[0])
7484 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7486 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7488 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7493 if (flag_pic && TARGET_SH2
7494 && MEM_P (operands[0])
7495 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7497 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7502 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7503 operands[1] = operands[2];
7506 emit_call_insn (gen_calli (operands[0], operands[1]));
7510 (define_insn "call_pop_compact"
7511 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7512 (match_operand 1 "" ""))
7513 (match_operand 2 "immediate_operand" "n")
7514 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7515 (match_operand 3 "immediate_operand" "n")))
7516 (use (reg:SI R0_REG))
7517 (use (reg:SI R1_REG))
7518 (use (reg:PSI FPSCR_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7528 (define_insn "call_pop_compact_rettramp"
7529 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7530 (match_operand 1 "" ""))
7531 (match_operand 2 "immediate_operand" "n")
7532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533 (match_operand 3 "immediate_operand" "n")))
7534 (use (reg:SI R0_REG))
7535 (use (reg:SI R1_REG))
7536 (use (reg:PSI FPSCR_REG))
7537 (clobber (reg:SI R10_REG))
7538 (clobber (reg:SI PR_REG))]
7539 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7541 [(set_attr "type" "call")
7542 (set (attr "fp_mode")
7543 (if_then_else (eq_attr "fpu_single" "yes")
7544 (const_string "single") (const_string "double")))
7545 (set_attr "needs_delay_slot" "yes")])
7547 (define_expand "call_pop"
7548 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7549 (match_operand 1 "" ""))
7550 (match_operand 2 "" "")
7551 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7552 (match_operand 3 "" "")))])]
7561 gcc_assert (operands[2] && INTVAL (operands[2]));
7562 cookie_rtx = operands[2];
7563 cookie = INTVAL (cookie_rtx);
7564 func = XEXP (operands[0], 0);
7568 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7570 rtx reg = gen_reg_rtx (Pmode);
7571 emit_insn (gen_symGOTPLT2reg (reg, func));
7575 func = legitimize_pic_address (func, Pmode, 0);
7578 r0 = gen_rtx_REG (SImode, R0_REG);
7579 r1 = gen_rtx_REG (SImode, R1_REG);
7581 /* Since such a call function may use all call-clobbered
7582 registers, we force a mode switch earlier, so that we don't
7583 run out of registers when adjusting fpscr for the call. */
7584 emit_insn (gen_force_mode_for_call ());
7586 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7588 operands[0] = force_reg (SImode, operands[0]);
7590 emit_move_insn (r0, func);
7591 emit_move_insn (r1, cookie_rtx);
7593 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7594 emit_call_insn (gen_call_pop_compact_rettramp
7595 (operands[0], operands[1], operands[2], operands[3]));
7597 emit_call_insn (gen_call_pop_compact
7598 (operands[0], operands[1], operands[2], operands[3]));
7603 (define_expand "call_value"
7604 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7605 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7606 (match_operand 2 "" "")))
7607 (match_operand 3 "" "")
7608 (use (reg:PSI FPSCR_REG))
7609 (clobber (reg:SI PR_REG))])]
7615 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7616 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7620 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7622 rtx cookie_rtx = operands[3];
7623 long cookie = INTVAL (cookie_rtx);
7624 rtx func = XEXP (operands[1], 0);
7629 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7631 rtx reg = gen_reg_rtx (Pmode);
7633 emit_insn (gen_symGOTPLT2reg (reg, func));
7637 func = legitimize_pic_address (func, Pmode, 0);
7640 r0 = gen_rtx_REG (SImode, R0_REG);
7641 r1 = gen_rtx_REG (SImode, R1_REG);
7643 /* Since such a call function may use all call-clobbered
7644 registers, we force a mode switch earlier, so that we don't
7645 run out of registers when adjusting fpscr for the call. */
7646 emit_insn (gen_force_mode_for_call ());
7649 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7651 operands[1] = force_reg (SImode, operands[1]);
7653 emit_move_insn (r0, func);
7654 emit_move_insn (r1, cookie_rtx);
7656 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7657 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7662 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7663 operands[2], operands[3]));
7667 else if (TARGET_SHCOMPACT && flag_pic
7668 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7669 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7671 rtx reg = gen_reg_rtx (Pmode);
7673 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7674 XEXP (operands[1], 0) = reg;
7676 if (!flag_pic && TARGET_SH2A
7677 && MEM_P (operands[1])
7678 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7680 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7682 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7683 XEXP (operands[1], 0), operands[2]));
7687 if (flag_pic && TARGET_SH2
7688 && MEM_P (operands[1])
7689 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7691 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7696 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7698 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7702 (define_insn "sibcalli"
7703 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7704 (match_operand 1 "" ""))
7705 (use (reg:PSI FPSCR_REG))
7709 [(set_attr "needs_delay_slot" "yes")
7710 (set (attr "fp_mode")
7711 (if_then_else (eq_attr "fpu_single" "yes")
7712 (const_string "single") (const_string "double")))
7713 (set_attr "type" "jump_ind")])
7715 (define_insn "sibcalli_pcrel"
7716 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7717 (match_operand 1 "" ""))
7718 (use (match_operand 2 "" ""))
7719 (use (reg:PSI FPSCR_REG))
7723 [(set_attr "needs_delay_slot" "yes")
7724 (set (attr "fp_mode")
7725 (if_then_else (eq_attr "fpu_single" "yes")
7726 (const_string "single") (const_string "double")))
7727 (set_attr "type" "jump_ind")])
7729 ;; This uses an unspec to describe that the symbol_ref is very close.
7730 (define_insn "sibcalli_thunk"
7731 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7733 (match_operand 1 "" ""))
7734 (use (reg:PSI FPSCR_REG))
7738 [(set_attr "needs_delay_slot" "yes")
7739 (set (attr "fp_mode")
7740 (if_then_else (eq_attr "fpu_single" "yes")
7741 (const_string "single") (const_string "double")))
7742 (set_attr "type" "jump")
7743 (set_attr "length" "2")])
7745 (define_insn_and_split "sibcall_pcrel"
7746 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7747 (match_operand 1 "" ""))
7748 (use (reg:PSI FPSCR_REG))
7749 (clobber (match_scratch:SI 2 "=k"))
7757 rtx lab = PATTERN (gen_call_site ());
7760 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7761 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7763 SIBLING_CALL_P (call_insn) = 1;
7766 [(set_attr "needs_delay_slot" "yes")
7767 (set (attr "fp_mode")
7768 (if_then_else (eq_attr "fpu_single" "yes")
7769 (const_string "single") (const_string "double")))
7770 (set_attr "type" "jump_ind")])
7772 (define_insn "sibcall_compact"
7773 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7774 (match_operand 1 "" ""))
7776 (use (match_operand:SI 2 "register_operand" "z,x"))
7777 (use (reg:SI R1_REG))
7778 (use (reg:PSI FPSCR_REG))
7779 ;; We want to make sure the `x' above will only match MACH_REG
7780 ;; because sibcall_epilogue may clobber MACL_REG.
7781 (clobber (reg:SI MACL_REG))]
7785 jmp @%0\\n sts %2, r0"
7786 [(set_attr "needs_delay_slot" "yes,no")
7787 (set_attr "length" "2,4")
7788 (set (attr "fp_mode") (const_string "single"))
7789 (set_attr "type" "jump_ind")])
7791 (define_insn "sibcall_media"
7792 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7793 (match_operand 1 "" ""))
7794 (use (reg:SI PR_MEDIA_REG))
7798 [(set_attr "type" "jump_media")])
7800 (define_expand "sibcall"
7802 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7803 (match_operand 1 "" ""))
7804 (match_operand 2 "" "")
7805 (use (reg:PSI FPSCR_REG))
7812 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7813 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7816 else if (TARGET_SHCOMPACT && operands[2]
7817 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7819 rtx cookie_rtx = operands[2];
7820 long cookie = INTVAL (cookie_rtx);
7821 rtx func = XEXP (operands[0], 0);
7826 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7828 rtx reg = gen_reg_rtx (Pmode);
7830 emit_insn (gen_symGOT2reg (reg, func));
7834 func = legitimize_pic_address (func, Pmode, 0);
7837 /* FIXME: if we could tell whether all argument registers are
7838 already taken, we could decide whether to force the use of
7839 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7840 simple way to tell. We could use the CALL_COOKIE, but we
7841 can't currently tell a register used for regular argument
7842 passing from one that is unused. If we leave it up to reload
7843 to decide which register to use, it seems to always choose
7844 R0_REG, which leaves no available registers in SIBCALL_REGS
7845 to hold the address of the trampoline. */
7846 mach = gen_rtx_REG (SImode, MACH_REG);
7847 r1 = gen_rtx_REG (SImode, R1_REG);
7849 /* Since such a call function may use all call-clobbered
7850 registers, we force a mode switch earlier, so that we don't
7851 run out of registers when adjusting fpscr for the call. */
7852 emit_insn (gen_force_mode_for_call ());
7855 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7857 operands[0] = force_reg (SImode, operands[0]);
7859 /* We don't need a return trampoline, since the callee will
7860 return directly to the upper caller. */
7861 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7863 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7864 cookie_rtx = GEN_INT (cookie);
7867 emit_move_insn (mach, func);
7868 emit_move_insn (r1, cookie_rtx);
7870 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7873 else if (TARGET_SHCOMPACT && flag_pic
7874 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7875 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7877 rtx reg = gen_reg_rtx (Pmode);
7879 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7880 XEXP (operands[0], 0) = reg;
7882 if (flag_pic && TARGET_SH2
7883 && MEM_P (operands[0])
7884 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7885 /* The PLT needs the PIC register, but the epilogue would have
7886 to restore it, so we can only use PC-relative PIC calls for
7887 static functions. */
7888 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7890 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7894 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7896 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7900 (define_insn "sibcall_valuei"
7901 [(set (match_operand 0 "" "=rf")
7902 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7903 (match_operand 2 "" "")))
7904 (use (reg:PSI FPSCR_REG))
7908 [(set_attr "needs_delay_slot" "yes")
7909 (set (attr "fp_mode")
7910 (if_then_else (eq_attr "fpu_single" "yes")
7911 (const_string "single") (const_string "double")))
7912 (set_attr "type" "jump_ind")])
7914 (define_insn "sibcall_valuei_pcrel"
7915 [(set (match_operand 0 "" "=rf")
7916 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7917 (match_operand 2 "" "")))
7918 (use (match_operand 3 "" ""))
7919 (use (reg:PSI FPSCR_REG))
7923 [(set_attr "needs_delay_slot" "yes")
7924 (set (attr "fp_mode")
7925 (if_then_else (eq_attr "fpu_single" "yes")
7926 (const_string "single") (const_string "double")))
7927 (set_attr "type" "jump_ind")])
7929 (define_insn_and_split "sibcall_value_pcrel"
7930 [(set (match_operand 0 "" "=rf")
7931 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7932 (match_operand 2 "" "")))
7933 (use (reg:PSI FPSCR_REG))
7934 (clobber (match_scratch:SI 3 "=k"))
7942 rtx lab = PATTERN (gen_call_site ());
7945 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7946 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7950 SIBLING_CALL_P (call_insn) = 1;
7953 [(set_attr "needs_delay_slot" "yes")
7954 (set (attr "fp_mode")
7955 (if_then_else (eq_attr "fpu_single" "yes")
7956 (const_string "single") (const_string "double")))
7957 (set_attr "type" "jump_ind")])
7959 (define_insn "sibcall_value_compact"
7960 [(set (match_operand 0 "" "=rf,rf")
7961 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7962 (match_operand 2 "" "")))
7964 (use (match_operand:SI 3 "register_operand" "z,x"))
7965 (use (reg:SI R1_REG))
7966 (use (reg:PSI FPSCR_REG))
7967 ;; We want to make sure the `x' above will only match MACH_REG
7968 ;; because sibcall_epilogue may clobber MACL_REG.
7969 (clobber (reg:SI MACL_REG))]
7973 jmp @%1\\n sts %3, r0"
7974 [(set_attr "needs_delay_slot" "yes,no")
7975 (set_attr "length" "2,4")
7976 (set (attr "fp_mode") (const_string "single"))
7977 (set_attr "type" "jump_ind")])
7979 (define_insn "sibcall_value_media"
7980 [(set (match_operand 0 "" "=rf")
7981 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7982 (match_operand 2 "" "")))
7983 (use (reg:SI PR_MEDIA_REG))
7987 [(set_attr "type" "jump_media")])
7989 (define_expand "sibcall_value"
7991 [(set (match_operand 0 "arith_reg_operand" "")
7992 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7993 (match_operand 2 "" "")))
7994 (match_operand 3 "" "")
7995 (use (reg:PSI FPSCR_REG))
8002 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8003 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8007 else if (TARGET_SHCOMPACT && operands[3]
8008 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8010 rtx cookie_rtx = operands[3];
8011 long cookie = INTVAL (cookie_rtx);
8012 rtx func = XEXP (operands[1], 0);
8017 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8019 rtx reg = gen_reg_rtx (Pmode);
8021 emit_insn (gen_symGOT2reg (reg, func));
8025 func = legitimize_pic_address (func, Pmode, 0);
8028 /* FIXME: if we could tell whether all argument registers are
8029 already taken, we could decide whether to force the use of
8030 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8031 simple way to tell. We could use the CALL_COOKIE, but we
8032 can't currently tell a register used for regular argument
8033 passing from one that is unused. If we leave it up to reload
8034 to decide which register to use, it seems to always choose
8035 R0_REG, which leaves no available registers in SIBCALL_REGS
8036 to hold the address of the trampoline. */
8037 mach = gen_rtx_REG (SImode, MACH_REG);
8038 r1 = gen_rtx_REG (SImode, R1_REG);
8040 /* Since such a call function may use all call-clobbered
8041 registers, we force a mode switch earlier, so that we don't
8042 run out of registers when adjusting fpscr for the call. */
8043 emit_insn (gen_force_mode_for_call ());
8046 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8048 operands[1] = force_reg (SImode, operands[1]);
8050 /* We don't need a return trampoline, since the callee will
8051 return directly to the upper caller. */
8052 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8054 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8055 cookie_rtx = GEN_INT (cookie);
8058 emit_move_insn (mach, func);
8059 emit_move_insn (r1, cookie_rtx);
8061 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8062 operands[2], mach));
8065 else if (TARGET_SHCOMPACT && flag_pic
8066 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8067 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8069 rtx reg = gen_reg_rtx (Pmode);
8071 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8072 XEXP (operands[1], 0) = reg;
8074 if (flag_pic && TARGET_SH2
8075 && MEM_P (operands[1])
8076 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8077 /* The PLT needs the PIC register, but the epilogue would have
8078 to restore it, so we can only use PC-relative PIC calls for
8079 static functions. */
8080 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8082 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8083 XEXP (operands[1], 0),
8088 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8090 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8094 (define_insn "call_value_pop_compact"
8095 [(set (match_operand 0 "" "=rf")
8096 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8097 (match_operand 2 "" "")))
8098 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8099 (match_operand 4 "immediate_operand" "n")))
8100 (match_operand 3 "immediate_operand" "n")
8101 (use (reg:SI R0_REG))
8102 (use (reg:SI R1_REG))
8103 (use (reg:PSI FPSCR_REG))
8104 (clobber (reg:SI PR_REG))]
8105 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8107 [(set_attr "type" "call")
8108 (set (attr "fp_mode")
8109 (if_then_else (eq_attr "fpu_single" "yes")
8110 (const_string "single") (const_string "double")))
8111 (set_attr "needs_delay_slot" "yes")])
8113 (define_insn "call_value_pop_compact_rettramp"
8114 [(set (match_operand 0 "" "=rf")
8115 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8116 (match_operand 2 "" "")))
8117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8118 (match_operand 4 "immediate_operand" "n")))
8119 (match_operand 3 "immediate_operand" "n")
8120 (use (reg:SI R0_REG))
8121 (use (reg:SI R1_REG))
8122 (use (reg:PSI FPSCR_REG))
8123 (clobber (reg:SI R10_REG))
8124 (clobber (reg:SI PR_REG))]
8125 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8127 [(set_attr "type" "call")
8128 (set (attr "fp_mode")
8129 (if_then_else (eq_attr "fpu_single" "yes")
8130 (const_string "single") (const_string "double")))
8131 (set_attr "needs_delay_slot" "yes")])
8133 (define_expand "call_value_pop"
8134 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8135 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8136 (match_operand 2 "" "")))
8137 (match_operand 3 "" "")
8138 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8139 (match_operand 4 "" "")))])]
8148 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8149 cookie_rtx = operands[3];
8150 cookie = INTVAL (cookie_rtx);
8151 func = XEXP (operands[1], 0);
8155 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8157 rtx reg = gen_reg_rtx (Pmode);
8159 emit_insn (gen_symGOTPLT2reg (reg, func));
8163 func = legitimize_pic_address (func, Pmode, 0);
8166 r0 = gen_rtx_REG (SImode, R0_REG);
8167 r1 = gen_rtx_REG (SImode, R1_REG);
8169 /* Since such a call function may use all call-clobbered
8170 registers, we force a mode switch earlier, so that we don't
8171 run out of registers when adjusting fpscr for the call. */
8172 emit_insn (gen_force_mode_for_call ());
8174 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8176 operands[1] = force_reg (SImode, operands[1]);
8178 emit_move_insn (r0, func);
8179 emit_move_insn (r1, cookie_rtx);
8181 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8182 emit_call_insn (gen_call_value_pop_compact_rettramp
8183 (operands[0], operands[1], operands[2],
8184 operands[3], operands[4]));
8186 emit_call_insn (gen_call_value_pop_compact
8187 (operands[0], operands[1], operands[2],
8188 operands[3], operands[4]));
8193 (define_expand "sibcall_epilogue"
8198 sh_expand_epilogue (1);
8199 if (TARGET_SHCOMPACT)
8203 /* If epilogue clobbers r0, preserve it in macl. */
8204 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8205 if ((set = single_set (insn))
8206 && REG_P (SET_DEST (set))
8207 && REGNO (SET_DEST (set)) == R0_REG)
8209 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8210 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8212 /* We can't tell at this point whether the sibcall is a
8213 sibcall_compact and, if it is, whether it uses r0 or
8214 mach as operand 2, so let the instructions that
8215 preserve r0 be optimized away if r0 turns out to be
8217 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8218 emit_move_insn (r0, tmp);
8225 (define_insn "indirect_jump_compact"
8227 (match_operand:SI 0 "arith_reg_operand" "r"))]
8230 [(set_attr "needs_delay_slot" "yes")
8231 (set_attr "type" "jump_ind")])
8233 (define_expand "indirect_jump"
8235 (match_operand 0 "register_operand" ""))]
8239 if (GET_MODE (operands[0]) != Pmode)
8240 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8243 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8244 ;; which can be present in structured code from indirect jumps which can not
8245 ;; be present in structured code. This allows -fprofile-arcs to work.
8247 ;; For SH1 processors.
8248 (define_insn "casesi_jump_1"
8250 (match_operand:SI 0 "register_operand" "r"))
8251 (use (label_ref (match_operand 1 "" "")))]
8254 [(set_attr "needs_delay_slot" "yes")
8255 (set_attr "type" "jump_ind")])
8257 ;; For all later processors.
8258 (define_insn "casesi_jump_2"
8259 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8260 (label_ref (match_operand 1 "" ""))))
8261 (use (label_ref (match_operand 2 "" "")))]
8263 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8265 [(set_attr "needs_delay_slot" "yes")
8266 (set_attr "type" "jump_ind")])
8268 (define_insn "casesi_jump_media"
8269 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8270 (use (label_ref (match_operand 1 "" "")))]
8273 [(set_attr "type" "jump_media")])
8275 ;; Call subroutine returning any type.
8276 ;; ??? This probably doesn't work.
8278 (define_expand "untyped_call"
8279 [(parallel [(call (match_operand 0 "" "")
8281 (match_operand 1 "" "")
8282 (match_operand 2 "" "")])]
8283 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8288 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8290 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8292 rtx set = XVECEXP (operands[2], 0, i);
8293 emit_move_insn (SET_DEST (set), SET_SRC (set));
8296 /* The optimizer does not know that the call sets the function value
8297 registers we stored in the result block. We avoid problems by
8298 claiming that all hard registers are used and clobbered at this
8300 emit_insn (gen_blockage ());
8305 ;; ------------------------------------------------------------------------
8307 ;; ------------------------------------------------------------------------
8310 [(set (reg:SI T_REG)
8311 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8312 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8315 [(set_attr "type" "arith")])
8322 ;; Load address of a label. This is only generated by the casesi expand,
8323 ;; and by machine_dependent_reorg (fixing up fp moves).
8324 ;; This must use unspec, because this only works for labels that are
8328 [(set (reg:SI R0_REG)
8329 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8332 [(set_attr "in_delay_slot" "no")
8333 (set_attr "type" "arith")])
8335 ;; machine_dependent_reorg will make this a `mova'.
8336 (define_insn "mova_const"
8337 [(set (reg:SI R0_REG)
8338 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8341 [(set_attr "in_delay_slot" "no")
8342 (set_attr "type" "arith")])
8344 (define_expand "GOTaddr2picreg"
8345 [(set (reg:SI R0_REG)
8346 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8348 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8349 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8352 if (TARGET_VXWORKS_RTP)
8354 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8355 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8356 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8360 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8361 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8365 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8366 rtx pic = operands[0];
8367 rtx lab = PATTERN (gen_call_site ());
8370 equiv = operands[1];
8371 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8372 UNSPEC_PCREL_SYMOFF);
8373 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8375 if (Pmode == SImode)
8377 emit_insn (gen_movsi_const (pic, operands[1]));
8378 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8382 emit_insn (gen_movdi_const (pic, operands[1]));
8383 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8386 insn = emit_move_insn (operands[0], tr);
8388 set_unique_reg_note (insn, REG_EQUAL, equiv);
8395 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8398 (define_expand "vxworks_picreg"
8399 [(set (reg:SI PIC_REG)
8400 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8401 (set (reg:SI R0_REG)
8402 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8403 (set (reg:SI PIC_REG)
8404 (mem:SI (reg:SI PIC_REG)))
8405 (set (reg:SI PIC_REG)
8406 (mem:SI (plus:SI (reg:SI PIC_REG)
8408 "TARGET_VXWORKS_RTP")
8411 [(set (match_operand 0 "target_reg_operand" "=b")
8412 (const (unspec [(match_operand 1 "" "Csy")]
8413 UNSPEC_DATALABEL)))]
8414 "TARGET_SHMEDIA && flag_pic
8415 && satisfies_constraint_Csy (operands[1])"
8416 "ptb/u datalabel %1, %0"
8417 [(set_attr "type" "ptabs_media")
8418 (set_attr "length" "*")])
8420 (define_insn "ptrel_si"
8421 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8422 (plus:SI (match_operand:SI 1 "register_operand" "r")
8424 (match_operand:SI 2 "" "")]
8426 "%O2: ptrel/u %1, %0"
8427 [(set_attr "type" "ptabs_media")])
8429 (define_insn "ptrel_di"
8430 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8431 (plus:DI (match_operand:DI 1 "register_operand" "r")
8433 (match_operand:DI 2 "" "")]
8435 "%O2: ptrel/u %1, %0"
8436 [(set_attr "type" "ptabs_media")])
8438 (define_expand "builtin_setjmp_receiver"
8439 [(match_operand 0 "" "")]
8443 emit_insn (gen_GOTaddr2picreg ());
8447 (define_expand "call_site"
8448 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8452 static HOST_WIDE_INT i = 0;
8453 operands[0] = GEN_INT (i);
8457 (define_expand "sym_label2reg"
8458 [(set (match_operand:SI 0 "" "")
8459 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8460 (const (plus:SI (match_operand:SI 2 "" "")
8465 (define_expand "symGOT_load"
8466 [(set (match_dup 2) (match_operand 1 "" ""))
8467 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8468 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8474 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8475 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8479 rtx reg = operands[2];
8481 if (Pmode == DImode)
8484 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8486 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8491 emit_insn (gen_movsi_const (reg, operands[1]));
8493 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8497 emit_move_insn (operands[2], operands[1]);
8499 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8501 gen_rtx_REG (Pmode, PIC_REG)));
8503 /* When stack protector inserts codes after the result is set to
8504 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8505 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8506 when rX is a GOT address for the guard symbol. Ugly but doesn't
8507 matter because this is a rare situation. */
8509 && flag_stack_protect
8510 && GET_CODE (operands[1]) == CONST
8511 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8512 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8513 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8514 \"__stack_chk_guard\") == 0)
8515 emit_insn (gen_blockage ());
8517 /* N.B. This is not constant for a GOTPLT relocation. */
8518 mem = gen_rtx_MEM (Pmode, operands[3]);
8519 MEM_NOTRAP_P (mem) = 1;
8520 /* ??? Should we have a special alias set for the GOT? */
8521 insn = emit_move_insn (operands[0], mem);
8526 (define_expand "sym2GOT"
8527 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8531 (define_expand "symGOT2reg"
8532 [(match_operand 0 "" "") (match_operand 1 "" "")]
8538 gotsym = gen_sym2GOT (operands[1]);
8539 PUT_MODE (gotsym, Pmode);
8540 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8542 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8547 (define_expand "symGOTPLT2reg"
8548 [(match_operand 0 "" "") (match_operand 1 "" "")]
8552 rtx pltsym = gen_rtx_CONST (Pmode,
8553 gen_rtx_UNSPEC (Pmode,
8554 gen_rtvec (1, operands[1]),
8556 emit_insn (gen_symGOT_load (operands[0], pltsym));
8560 (define_expand "sym2GOTOFF"
8561 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8565 (define_expand "symGOTOFF2reg"
8566 [(match_operand 0 "" "") (match_operand 1 "" "")]
8570 rtx gotoffsym, insn;
8571 rtx t = (!can_create_pseudo_p ()
8573 : gen_reg_rtx (GET_MODE (operands[0])));
8575 gotoffsym = gen_sym2GOTOFF (operands[1]);
8576 PUT_MODE (gotoffsym, Pmode);
8577 emit_move_insn (t, gotoffsym);
8578 insn = emit_move_insn (operands[0],
8579 gen_rtx_PLUS (Pmode, t,
8580 gen_rtx_REG (Pmode, PIC_REG)));
8582 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8587 (define_expand "symPLT_label2reg"
8588 [(set (match_operand:SI 0 "" "")
8591 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8592 (const:SI (plus:SI (match_operand:SI 2 "" "")
8593 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8594 ;; Even though the PIC register is not really used by the call
8595 ;; sequence in which this is expanded, the PLT code assumes the PIC
8596 ;; register is set, so we must not skip its initialization. Since
8597 ;; we only use this expand as part of calling sequences, and never
8598 ;; to take the address of a function, this is the best point to
8599 ;; insert the (use). Using the PLT to take the address of a
8600 ;; function would be wrong, not only because the PLT entry could
8601 ;; then be called from a function that doesn't initialize the PIC
8602 ;; register to the proper GOT, but also because pointers to the
8603 ;; same function might not compare equal, should they be set by
8604 ;; different shared libraries.
8605 (use (reg:SI PIC_REG))]
8609 (define_expand "sym2PIC"
8610 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8614 ;; TLS code generation.
8615 ;; ??? this should be a define_insn_and_split
8616 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8617 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8620 (define_insn "tls_global_dynamic"
8621 [(set (match_operand:SI 0 "register_operand" "=&z")
8622 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8625 (use (reg:PSI FPSCR_REG))
8626 (use (reg:SI PIC_REG))
8627 (clobber (reg:SI PR_REG))
8628 (clobber (scratch:SI))]
8634 \\tmova\\t2f,r0\\n\\
8635 \\tmov.l\\t2f,r1\\n\\
8638 \\tadd\\tr12,r4\\n\\
8642 1:\\t.long\\t%a1@TLSGD\\n\\
8643 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8646 [(set_attr "type" "tls_load")
8647 (set_attr "length" "26")])
8649 (define_insn "tls_local_dynamic"
8650 [(set (match_operand:SI 0 "register_operand" "=&z")
8651 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8654 (use (reg:PSI FPSCR_REG))
8655 (use (reg:SI PIC_REG))
8656 (clobber (reg:SI PR_REG))
8657 (clobber (scratch:SI))]
8663 \\tmova\\t2f,r0\\n\\
8664 \\tmov.l\\t2f,r1\\n\\
8667 \\tadd\\tr12,r4\\n\\
8671 1:\\t.long\\t%a1@TLSLDM\\n\\
8672 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8675 [(set_attr "type" "tls_load")
8676 (set_attr "length" "26")])
8678 (define_expand "sym2DTPOFF"
8679 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8683 (define_expand "symDTPOFF2reg"
8684 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8688 rtx dtpoffsym, insn;
8689 rtx t = (!can_create_pseudo_p ()
8691 : gen_reg_rtx (GET_MODE (operands[0])));
8693 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8694 PUT_MODE (dtpoffsym, Pmode);
8695 emit_move_insn (t, dtpoffsym);
8696 insn = emit_move_insn (operands[0],
8697 gen_rtx_PLUS (Pmode, t, operands[2]));
8701 (define_expand "sym2GOTTPOFF"
8702 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8706 (define_insn "tls_initial_exec"
8707 [(set (match_operand:SI 0 "register_operand" "=&r")
8708 (unspec:SI [(match_operand:SI 1 "" "")]
8710 (use (reg:SI GBR_REG))
8711 (use (reg:SI PIC_REG))
8712 (clobber (reg:SI R0_REG))]
8718 \\tstc\\tgbr,%0\\n\\
8719 \\tmov.l\\t@(r0,r12),r0\\n\\
8723 1:\\t.long\\t%a1\\n\\
8726 [(set_attr "type" "tls_load")
8727 (set_attr "length" "16")])
8729 (define_expand "sym2TPOFF"
8730 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8734 (define_expand "symTPOFF2reg"
8735 [(match_operand 0 "" "") (match_operand 1 "" "")]
8741 tpoffsym = gen_sym2TPOFF (operands[1]);
8742 PUT_MODE (tpoffsym, Pmode);
8743 insn = emit_move_insn (operands[0], tpoffsym);
8747 (define_insn "load_gbr"
8748 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8749 (use (reg:SI GBR_REG))]
8752 [(set_attr "type" "tls_load")])
8754 ;; case instruction for switch statements.
8756 ;; Operand 0 is index
8757 ;; operand 1 is the minimum bound
8758 ;; operand 2 is the maximum bound - minimum bound + 1
8759 ;; operand 3 is CODE_LABEL for the table;
8760 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8762 (define_expand "casesi"
8763 [(match_operand:SI 0 "arith_reg_operand" "")
8764 (match_operand:SI 1 "arith_reg_operand" "")
8765 (match_operand:SI 2 "arith_reg_operand" "")
8766 (match_operand 3 "" "") (match_operand 4 "" "")]
8770 rtx reg = gen_reg_rtx (SImode);
8771 rtx reg2 = gen_reg_rtx (SImode);
8774 rtx reg = gen_reg_rtx (DImode);
8775 rtx reg2 = gen_reg_rtx (DImode);
8776 rtx reg3 = gen_reg_rtx (Pmode);
8777 rtx reg4 = gen_reg_rtx (Pmode);
8778 rtx reg5 = gen_reg_rtx (Pmode);
8781 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8782 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8783 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8785 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8786 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8787 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8788 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8789 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8790 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8791 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8792 (Pmode, operands[3])));
8793 /* Messy: can we subreg to clean this up? */
8794 if (Pmode == DImode)
8795 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8797 load = gen_casesi_load_media (reg4,
8798 gen_rtx_SUBREG (DImode, reg3, 0),
8800 PUT_MODE (SET_SRC (load), Pmode);
8802 /* ??? The following add could be eliminated if we used ptrel. */
8803 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8804 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8808 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8809 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8810 /* If optimizing, casesi_worker depends on the mode of the instruction
8811 before label it 'uses' - operands[3]. */
8812 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8814 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8816 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8818 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8819 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8820 operands[3], but to lab. We will fix this up in
8821 machine_dependent_reorg. */
8826 (define_expand "casesi_0"
8827 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8828 (set (match_dup 4) (minus:SI (match_dup 4)
8829 (match_operand:SI 1 "arith_operand" "")))
8831 (gtu:SI (match_dup 4)
8832 (match_operand:SI 2 "arith_reg_operand" "")))
8834 (if_then_else (ne (reg:SI T_REG)
8836 (label_ref (match_operand 3 "" ""))
8841 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8842 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8843 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8845 (define_insn "casesi_worker_0"
8846 [(set (match_operand:SI 0 "register_operand" "=r,r")
8847 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8848 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8849 (clobber (match_scratch:SI 3 "=X,1"))
8850 (clobber (match_scratch:SI 4 "=&z,z"))]
8855 [(set (match_operand:SI 0 "register_operand" "")
8856 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8857 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8858 (clobber (match_scratch:SI 3 ""))
8859 (clobber (match_scratch:SI 4 ""))]
8860 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8861 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8862 (parallel [(set (match_dup 0)
8863 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8864 (label_ref (match_dup 2))] UNSPEC_CASESI))
8865 (clobber (match_dup 3))])
8866 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8867 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8870 [(set (match_operand:SI 0 "register_operand" "")
8871 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8872 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8873 (clobber (match_scratch:SI 3 ""))
8874 (clobber (match_scratch:SI 4 ""))]
8875 "TARGET_SH2 && reload_completed"
8876 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8877 (parallel [(set (match_dup 0)
8878 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8879 (label_ref (match_dup 2))] UNSPEC_CASESI))
8880 (clobber (match_dup 3))])]
8881 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8883 (define_insn "casesi_worker_1"
8884 [(set (match_operand:SI 0 "register_operand" "=r,r")
8885 (unspec:SI [(reg:SI R0_REG)
8886 (match_operand:SI 1 "register_operand" "0,r")
8887 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8888 (clobber (match_scratch:SI 3 "=X,1"))]
8892 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8894 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8896 switch (GET_MODE (diff_vec))
8899 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8901 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8903 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8904 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8905 return \"mov.b @(r0,%1),%0\";
8910 [(set_attr "length" "4")])
8912 (define_insn "casesi_worker_2"
8913 [(set (match_operand:SI 0 "register_operand" "=r,r")
8914 (unspec:SI [(reg:SI R0_REG)
8915 (match_operand:SI 1 "register_operand" "0,r")
8916 (label_ref (match_operand 2 "" ""))
8917 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8918 (clobber (match_operand:SI 4 "" "=X,1"))]
8919 "TARGET_SH2 && reload_completed && flag_pic"
8922 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8925 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8927 switch (GET_MODE (diff_vec))
8930 output_asm_insn (\"shll2 %1\", operands);
8931 load = \"mov.l @(r0,%1),%0\"; break;
8933 output_asm_insn (\"add %1,%1\", operands);
8934 load = \"mov.w @(r0,%1),%0\"; break;
8936 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8937 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8939 load = \"mov.b @(r0,%1),%0\";
8944 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8947 [(set_attr "length" "8")])
8949 (define_insn "casesi_shift_media"
8950 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8951 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8952 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8957 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8959 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8961 switch (GET_MODE (diff_vec))
8964 return \"shlli %1, 2, %0\";
8966 return \"shlli %1, 1, %0\";
8968 if (rtx_equal_p (operands[0], operands[1]))
8970 return \"add %1, r63, %0\";
8975 [(set_attr "type" "arith_media")])
8977 (define_insn "casesi_load_media"
8978 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8979 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8980 (match_operand:DI 2 "arith_reg_operand" "r")
8981 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8985 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8987 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8989 switch (GET_MODE (diff_vec))
8992 return \"ldx.l %1, %2, %0\";
8995 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8996 return \"ldx.uw %1, %2, %0\";
8998 return \"ldx.w %1, %2, %0\";
9000 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9001 return \"ldx.ub %1, %2, %0\";
9002 return \"ldx.b %1, %2, %0\";
9007 [(set_attr "type" "load_media")])
9009 (define_expand "return"
9011 "reload_completed && ! sh_need_epilogue ()"
9016 emit_jump_insn (gen_return_media ());
9020 if (TARGET_SHCOMPACT
9021 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9023 emit_jump_insn (gen_shcompact_return_tramp ());
9028 (define_insn "*return_i"
9030 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9031 && (crtl->args.info.call_cookie
9032 & CALL_COOKIE_RET_TRAMP (1)))
9034 && lookup_attribute (\"trap_exit\",
9035 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9038 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9039 && !current_function_interrupt)
9044 [(set_attr "type" "return")
9045 (set_attr "needs_delay_slot" "yes")])
9047 ;; trapa has no delay slot.
9048 (define_insn "*return_trapa"
9050 "TARGET_SH1 && !TARGET_SHCOMPACT
9051 && reload_completed"
9053 [(set_attr "type" "return")])
9055 (define_expand "shcompact_return_tramp"
9058 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9061 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9063 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9064 emit_jump_insn (gen_shcompact_return_tramp_i ());
9068 (define_insn "shcompact_return_tramp_i"
9069 [(parallel [(return) (use (reg:SI R0_REG))])]
9071 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9073 [(set_attr "type" "jump_ind")
9074 (set_attr "needs_delay_slot" "yes")])
9076 (define_insn "return_media_i"
9077 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9078 "TARGET_SHMEDIA && reload_completed"
9080 [(set_attr "type" "jump_media")])
9082 (define_insn "return_media_rte"
9084 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9086 [(set_attr "type" "jump_media")])
9088 (define_expand "return_media"
9090 "TARGET_SHMEDIA && reload_completed"
9093 int tr_regno = sh_media_register_for_return ();
9096 if (current_function_interrupt)
9098 emit_jump_insn (gen_return_media_rte ());
9103 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9105 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9107 tr = gen_rtx_REG (Pmode, tr_regno);
9108 emit_move_insn (tr, r18);
9111 tr = gen_rtx_REG (Pmode, tr_regno);
9113 emit_jump_insn (gen_return_media_i (tr));
9117 (define_insn "shcompact_preserve_incoming_args"
9118 [(set (match_operand:SI 0 "register_operand" "+r")
9119 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9122 [(set_attr "length" "0")])
9124 (define_insn "shcompact_incoming_args"
9125 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9126 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9127 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9128 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9129 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9130 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9131 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9132 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9133 (set (mem:BLK (reg:SI MACL_REG))
9134 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9135 (use (reg:SI R0_REG))
9136 (clobber (reg:SI R0_REG))
9137 (clobber (reg:SI MACL_REG))
9138 (clobber (reg:SI MACH_REG))
9139 (clobber (reg:SI PR_REG))]
9142 [(set_attr "needs_delay_slot" "yes")])
9144 (define_insn "shmedia_save_restore_regs_compact"
9145 [(set (reg:SI SP_REG)
9146 (plus:SI (reg:SI SP_REG)
9147 (match_operand:SI 0 "immediate_operand" "i")))
9148 (use (reg:SI R0_REG))
9149 (clobber (reg:SI PR_REG))]
9151 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9152 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9154 [(set_attr "needs_delay_slot" "yes")])
9156 (define_expand "prologue"
9159 "sh_expand_prologue (); DONE;")
9161 (define_expand "epilogue"
9166 sh_expand_epilogue (0);
9167 emit_jump_insn (gen_return ());
9171 (define_expand "eh_return"
9172 [(use (match_operand 0 "register_operand" ""))]
9175 rtx ra = operands[0];
9177 if (TARGET_SHMEDIA64)
9178 emit_insn (gen_eh_set_ra_di (ra));
9180 emit_insn (gen_eh_set_ra_si (ra));
9185 ;; Clobber the return address on the stack. We can't expand this
9186 ;; until we know where it will be put in the stack frame.
9188 (define_insn "eh_set_ra_si"
9189 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9191 (clobber (match_scratch:SI 1 "=&r"))]
9192 "! TARGET_SHMEDIA64"
9195 (define_insn "eh_set_ra_di"
9196 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9198 (clobber (match_scratch:DI 1 "=&r"))]
9203 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9205 (clobber (match_scratch 1 ""))]
9210 sh_set_return_address (operands[0], operands[1]);
9214 (define_insn "blockage"
9215 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9218 [(set_attr "length" "0")])
9220 ;; ------------------------------------------------------------------------
9222 ;; ------------------------------------------------------------------------
9225 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9226 (eq:SI (reg:SI T_REG) (const_int 1)))]
9229 [(set_attr "type" "arith")])
9231 (define_expand "cstore4_media"
9232 [(set (match_operand:SI 0 "register_operand" "=r")
9233 (match_operator:SI 1 "sh_float_comparison_operator"
9234 [(match_operand 2 "logical_operand" "")
9235 (match_operand 3 "cmp_operand" "")]))]
9239 enum machine_mode mode = GET_MODE (operands[2]);
9240 enum rtx_code code = GET_CODE (operands[1]);
9242 if (mode == VOIDmode)
9243 mode = GET_MODE (operands[3]);
9244 if (operands[2] == const0_rtx)
9246 if (code == EQ || code == NE)
9247 operands[2] = operands[3], operands[3] = const0_rtx;
9250 operands[2] = force_reg (mode, operands[2]);
9251 if (operands[3] != const0_rtx)
9252 operands[3] = force_reg (mode, operands[3]);
9258 swap = invert = !FLOAT_MODE_P (mode);
9263 swap = FLOAT_MODE_P (mode), invert = !swap;
9268 swap = true, invert = false;
9275 swap = invert = false;
9279 swap = invert = true;
9288 rtx tem = operands[2];
9289 operands[2] = operands[3];
9291 code = swap_condition (code);
9296 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9297 code = reverse_condition (code);
9298 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9299 emit_insn (gen_cstore4_media (tem, operands[1],
9300 operands[2], operands[3]));
9303 operands[3] = const0_rtx;
9306 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9309 (define_expand "cstoresi4"
9310 [(set (match_operand:SI 0 "register_operand" "=r")
9311 (match_operator:SI 1 "comparison_operator"
9312 [(match_operand:SI 2 "cmpsi_operand" "")
9313 (match_operand:SI 3 "arith_operand" "")]))]
9314 "TARGET_SH1 || TARGET_SHMEDIA"
9315 "if (TARGET_SHMEDIA)
9317 emit_insn (gen_cstore4_media (operands[0], operands[1],
9318 operands[2], operands[3]));
9322 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9323 && sh_expand_t_scc (operands))
9326 if (! currently_expanding_to_rtl)
9329 sh_emit_compare_and_set (operands, SImode);
9333 (define_expand "cstoredi4"
9334 [(set (match_operand:SI 0 "register_operand" "=r")
9335 (match_operator:SI 1 "comparison_operator"
9336 [(match_operand:DI 2 "arith_operand" "")
9337 (match_operand:DI 3 "arith_operand" "")]))]
9338 "TARGET_SH2 || TARGET_SHMEDIA"
9339 "if (TARGET_SHMEDIA)
9341 emit_insn (gen_cstore4_media (operands[0], operands[1],
9342 operands[2], operands[3]));
9346 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9347 && sh_expand_t_scc (operands))
9350 if (! currently_expanding_to_rtl)
9353 sh_emit_compare_and_set (operands, DImode);
9359 ;; sne moves the complement of the T reg to DEST like this:
9363 ;; This is better than xoring compare result with 1 because it does
9364 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9367 (define_expand "movnegt"
9368 [(set (match_dup 1) (const_int -1))
9369 (parallel [(set (match_operand:SI 0 "" "")
9370 (neg:SI (plus:SI (reg:SI T_REG)
9373 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9378 operands[1] = gen_reg_rtx (SImode);
9382 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9383 ;; This prevents a regression that occurred when we switched from xor to
9387 [(set (match_operand:SI 0 "arith_reg_dest" "")
9388 (plus:SI (reg:SI T_REG)
9391 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9392 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9395 (define_expand "cstoresf4"
9396 [(set (match_operand:SI 0 "register_operand" "=r")
9397 (match_operator:SI 1 "sh_float_comparison_operator"
9398 [(match_operand:SF 2 "arith_operand" "")
9399 (match_operand:SF 3 "arith_operand" "")]))]
9400 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9401 "if (TARGET_SHMEDIA)
9403 emit_insn (gen_cstore4_media (operands[0], operands[1],
9404 operands[2], operands[3]));
9408 if (! currently_expanding_to_rtl)
9411 sh_emit_compare_and_set (operands, SFmode);
9415 (define_expand "cstoredf4"
9416 [(set (match_operand:SI 0 "register_operand" "=r")
9417 (match_operator:SI 1 "sh_float_comparison_operator"
9418 [(match_operand:DF 2 "arith_operand" "")
9419 (match_operand:DF 3 "arith_operand" "")]))]
9420 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9421 "if (TARGET_SHMEDIA)
9423 emit_insn (gen_cstore4_media (operands[0], operands[1],
9424 operands[2], operands[3]));
9428 if (! currently_expanding_to_rtl)
9431 sh_emit_compare_and_set (operands, DFmode);
9436 ;; -------------------------------------------------------------------------
9437 ;; Instructions to cope with inline literal tables
9438 ;; -------------------------------------------------------------------------
9440 ; 2 byte integer in line
9442 (define_insn "consttable_2"
9443 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9444 (match_operand 1 "" "")]
9449 if (operands[1] != const0_rtx)
9450 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9453 [(set_attr "length" "2")
9454 (set_attr "in_delay_slot" "no")])
9456 ; 4 byte integer in line
9458 (define_insn "consttable_4"
9459 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9460 (match_operand 1 "" "")]
9465 if (operands[1] != const0_rtx)
9467 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9468 mark_symbol_refs_as_used (operands[0]);
9472 [(set_attr "length" "4")
9473 (set_attr "in_delay_slot" "no")])
9475 ; 8 byte integer in line
9477 (define_insn "consttable_8"
9478 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9479 (match_operand 1 "" "")]
9484 if (operands[1] != const0_rtx)
9485 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9488 [(set_attr "length" "8")
9489 (set_attr "in_delay_slot" "no")])
9491 ; 4 byte floating point
9493 (define_insn "consttable_sf"
9494 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9495 (match_operand 1 "" "")]
9500 if (operands[1] != const0_rtx)
9503 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9504 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9508 [(set_attr "length" "4")
9509 (set_attr "in_delay_slot" "no")])
9511 ; 8 byte floating point
9513 (define_insn "consttable_df"
9514 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9515 (match_operand 1 "" "")]
9520 if (operands[1] != const0_rtx)
9523 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9524 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9528 [(set_attr "length" "8")
9529 (set_attr "in_delay_slot" "no")])
9531 ;; Alignment is needed for some constant tables; it may also be added for
9532 ;; Instructions at the start of loops, or after unconditional branches.
9533 ;; ??? We would get more accurate lengths if we did instruction
9534 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9535 ;; here is too conservative.
9537 ; align to a two byte boundary
9539 (define_expand "align_2"
9540 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9544 ; align to a four byte boundary
9545 ;; align_4 and align_log are instructions for the starts of loops, or
9546 ;; after unconditional branches, which may take up extra room.
9548 (define_expand "align_4"
9549 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9553 ; align to a cache line boundary
9555 (define_insn "align_log"
9556 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9559 [(set_attr "length" "0")
9560 (set_attr "in_delay_slot" "no")])
9562 ; emitted at the end of the literal table, used to emit the
9563 ; 32bit branch labels if needed.
9565 (define_insn "consttable_end"
9566 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9568 "* return output_jump_label_table ();"
9569 [(set_attr "in_delay_slot" "no")])
9571 ; emitted at the end of the window in the literal table.
9573 (define_insn "consttable_window_end"
9574 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9577 [(set_attr "length" "0")
9578 (set_attr "in_delay_slot" "no")])
9580 ;; -------------------------------------------------------------------------
9582 ;; -------------------------------------------------------------------------
9584 ;; String/block move insn.
9586 (define_expand "movmemsi"
9587 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9588 (mem:BLK (match_operand:BLK 1 "" "")))
9589 (use (match_operand:SI 2 "nonmemory_operand" ""))
9590 (use (match_operand:SI 3 "immediate_operand" ""))
9591 (clobber (reg:SI PR_REG))
9592 (clobber (reg:SI R4_REG))
9593 (clobber (reg:SI R5_REG))
9594 (clobber (reg:SI R0_REG))])]
9595 "TARGET_SH1 && ! TARGET_SH5"
9598 if(expand_block_move (operands))
9603 (define_insn "block_move_real"
9604 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9605 (mem:BLK (reg:SI R5_REG)))
9606 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9607 (clobber (reg:SI PR_REG))
9608 (clobber (reg:SI R0_REG))])]
9609 "TARGET_SH1 && ! TARGET_HARD_SH4"
9611 [(set_attr "type" "sfunc")
9612 (set_attr "needs_delay_slot" "yes")])
9614 (define_insn "block_lump_real"
9615 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9616 (mem:BLK (reg:SI R5_REG)))
9617 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9618 (use (reg:SI R6_REG))
9619 (clobber (reg:SI PR_REG))
9620 (clobber (reg:SI T_REG))
9621 (clobber (reg:SI R4_REG))
9622 (clobber (reg:SI R5_REG))
9623 (clobber (reg:SI R6_REG))
9624 (clobber (reg:SI R0_REG))])]
9625 "TARGET_SH1 && ! TARGET_HARD_SH4"
9627 [(set_attr "type" "sfunc")
9628 (set_attr "needs_delay_slot" "yes")])
9630 (define_insn "block_move_real_i4"
9631 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9632 (mem:BLK (reg:SI R5_REG)))
9633 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9634 (clobber (reg:SI PR_REG))
9635 (clobber (reg:SI R0_REG))
9636 (clobber (reg:SI R1_REG))
9637 (clobber (reg:SI R2_REG))])]
9640 [(set_attr "type" "sfunc")
9641 (set_attr "needs_delay_slot" "yes")])
9643 (define_insn "block_lump_real_i4"
9644 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9645 (mem:BLK (reg:SI R5_REG)))
9646 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9647 (use (reg:SI R6_REG))
9648 (clobber (reg:SI PR_REG))
9649 (clobber (reg:SI T_REG))
9650 (clobber (reg:SI R4_REG))
9651 (clobber (reg:SI R5_REG))
9652 (clobber (reg:SI R6_REG))
9653 (clobber (reg:SI R0_REG))
9654 (clobber (reg:SI R1_REG))
9655 (clobber (reg:SI R2_REG))
9656 (clobber (reg:SI R3_REG))])]
9659 [(set_attr "type" "sfunc")
9660 (set_attr "needs_delay_slot" "yes")])
9662 ;; -------------------------------------------------------------------------
9663 ;; Floating point instructions.
9664 ;; -------------------------------------------------------------------------
9666 ;; ??? All patterns should have a type attribute.
9668 (define_expand "movpsi"
9669 [(set (match_operand:PSI 0 "register_operand" "")
9670 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9671 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9674 ;; The c / m alternative is a fake to guide reload to load directly into
9675 ;; fpscr, since reload doesn't know how to use post-increment.
9676 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9677 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9678 ;; predicate after reload.
9679 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9680 ;; like a mac -> gpr move.
9681 (define_insn "fpu_switch"
9682 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9683 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9685 && (! reload_completed
9686 || true_regnum (operands[0]) != FPSCR_REG
9687 || !MEM_P (operands[1])
9688 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9690 ! precision stays the same
9699 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9700 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9703 [(set (reg:PSI FPSCR_REG)
9704 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9705 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9708 rtx fpscr, mem, new_insn;
9710 fpscr = SET_DEST (PATTERN (curr_insn));
9711 mem = SET_SRC (PATTERN (curr_insn));
9712 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9714 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9715 add_reg_note (new_insn, REG_INC, operands[0]);
9720 [(set (reg:PSI FPSCR_REG)
9721 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9722 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9723 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9726 rtx fpscr, mem, new_insn;
9728 fpscr = SET_DEST (PATTERN (curr_insn));
9729 mem = SET_SRC (PATTERN (curr_insn));
9730 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9732 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9733 add_reg_note (new_insn, REG_INC, operands[0]);
9735 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9736 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9740 ;; ??? This uses the fp unit, but has no type indicating that.
9741 ;; If we did that, this would either give a bogus latency or introduce
9742 ;; a bogus FIFO constraint.
9743 ;; Since this insn is currently only used for prologues/epilogues,
9744 ;; it is probably best to claim no function unit, which matches the
9746 (define_insn "toggle_sz"
9747 [(set (reg:PSI FPSCR_REG)
9748 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9749 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9751 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9753 ;; There's no way we can use it today, since optimize mode switching
9754 ;; doesn't enable us to know from which mode we're switching to the
9755 ;; mode it requests, to tell whether we can use a relative mode switch
9756 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9758 (define_insn "toggle_pr"
9759 [(set (reg:PSI FPSCR_REG)
9760 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9761 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9763 [(set_attr "type" "fpscr_toggle")])
9765 (define_expand "addsf3"
9766 [(set (match_operand:SF 0 "arith_reg_operand" "")
9767 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9768 (match_operand:SF 2 "arith_reg_operand" "")))]
9769 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9774 expand_sf_binop (&gen_addsf3_i, operands);
9779 (define_insn "*addsf3_media"
9780 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9781 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9782 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9783 "TARGET_SHMEDIA_FPU"
9785 [(set_attr "type" "fparith_media")])
9787 (define_insn_and_split "unary_sf_op"
9788 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9793 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9794 (match_operator:SF 2 "unary_float_operator"
9795 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9796 (parallel [(match_operand 4
9797 "const_int_operand" "n")]))]))
9798 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9799 "TARGET_SHMEDIA_FPU"
9801 "TARGET_SHMEDIA_FPU && reload_completed"
9802 [(set (match_dup 5) (match_dup 6))]
9805 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9806 rtx op1 = gen_rtx_REG (SFmode,
9807 (true_regnum (operands[1])
9808 + (INTVAL (operands[4]) ^ endian)));
9810 operands[7] = gen_rtx_REG (SFmode,
9811 (true_regnum (operands[0])
9812 + (INTVAL (operands[3]) ^ endian)));
9813 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9815 [(set_attr "type" "fparith_media")])
9817 (define_insn_and_split "binary_sf_op0"
9818 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9820 (match_operator:SF 3 "binary_float_operator"
9821 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9822 (parallel [(const_int 0)]))
9823 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9824 (parallel [(const_int 0)]))])
9827 (parallel [(const_int 1)]))))]
9828 "TARGET_SHMEDIA_FPU"
9830 "&& reload_completed"
9831 [(set (match_dup 4) (match_dup 5))]
9834 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9835 rtx op1 = gen_rtx_REG (SFmode,
9836 true_regnum (operands[1]) + endian);
9837 rtx op2 = gen_rtx_REG (SFmode,
9838 true_regnum (operands[2]) + endian);
9840 operands[4] = gen_rtx_REG (SFmode,
9841 true_regnum (operands[0]) + endian);
9842 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9844 [(set_attr "type" "fparith_media")])
9846 (define_insn_and_split "binary_sf_op1"
9847 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9851 (parallel [(const_int 0)]))
9852 (match_operator:SF 3 "binary_float_operator"
9853 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9854 (parallel [(const_int 1)]))
9855 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9856 (parallel [(const_int 1)]))])))]
9857 "TARGET_SHMEDIA_FPU"
9859 "&& reload_completed"
9860 [(set (match_dup 4) (match_dup 5))]
9863 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9864 rtx op1 = gen_rtx_REG (SFmode,
9865 true_regnum (operands[1]) + (1 ^ endian));
9866 rtx op2 = gen_rtx_REG (SFmode,
9867 true_regnum (operands[2]) + (1 ^ endian));
9869 operands[4] = gen_rtx_REG (SFmode,
9870 true_regnum (operands[0]) + (1 ^ endian));
9871 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9873 [(set_attr "type" "fparith_media")])
9875 (define_insn "addsf3_i"
9876 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9877 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9878 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9879 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9882 [(set_attr "type" "fp")
9883 (set_attr "fp_mode" "single")])
9885 (define_expand "subsf3"
9886 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9887 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9888 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9889 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9894 expand_sf_binop (&gen_subsf3_i, operands);
9899 (define_insn "*subsf3_media"
9900 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9901 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9902 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9903 "TARGET_SHMEDIA_FPU"
9905 [(set_attr "type" "fparith_media")])
9907 (define_insn "subsf3_i"
9908 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9909 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9910 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9911 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9914 [(set_attr "type" "fp")
9915 (set_attr "fp_mode" "single")])
9917 (define_expand "mulsf3"
9918 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9919 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9920 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9921 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9924 (define_insn "*mulsf3_media"
9925 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9926 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9927 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9928 "TARGET_SHMEDIA_FPU"
9930 [(set_attr "type" "fparith_media")])
9932 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9933 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9934 ;; we start out with a mulsf pattern that does not depend on fpscr.
9935 ;; This is split after combine to introduce the dependency, in order to
9936 ;; get mode switching and scheduling right.
9937 (define_insn_and_split "mulsf3_ie"
9938 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9939 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9940 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9943 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9947 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9951 [(set_attr "type" "fp")])
9953 (define_insn "mulsf3_i4"
9954 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9955 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9956 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9957 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9960 [(set_attr "type" "fp")
9961 (set_attr "fp_mode" "single")])
9963 (define_insn "mac_media"
9964 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9965 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9966 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9967 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9968 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9970 [(set_attr "type" "fparith_media")])
9972 (define_insn "*macsf3"
9973 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9974 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9975 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9976 (match_operand:SF 3 "arith_reg_operand" "0")))
9977 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9978 "TARGET_SH2E && TARGET_FMAC"
9980 [(set_attr "type" "fp")
9981 (set_attr "fp_mode" "single")])
9983 (define_expand "divsf3"
9984 [(set (match_operand:SF 0 "arith_reg_operand" "")
9985 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9986 (match_operand:SF 2 "arith_reg_operand" "")))]
9987 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9992 expand_sf_binop (&gen_divsf3_i, operands);
9997 (define_insn "*divsf3_media"
9998 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9999 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10000 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10001 "TARGET_SHMEDIA_FPU"
10002 "fdiv.s %1, %2, %0"
10003 [(set_attr "type" "fdiv_media")])
10005 (define_insn "divsf3_i"
10006 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10007 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10008 (match_operand:SF 2 "arith_reg_operand" "f")))
10009 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10012 [(set_attr "type" "fdiv")
10013 (set_attr "fp_mode" "single")])
10015 (define_insn "floatdisf2"
10016 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10017 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10018 "TARGET_SHMEDIA_FPU"
10020 [(set_attr "type" "fpconv_media")])
10022 (define_expand "floatsisf2"
10023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10024 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10025 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10028 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10030 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10035 (define_insn "*floatsisf2_media"
10036 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10037 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10038 "TARGET_SHMEDIA_FPU"
10040 [(set_attr "type" "fpconv_media")])
10042 (define_insn "floatsisf2_i4"
10043 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10044 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10045 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10046 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10048 [(set_attr "type" "fp")
10049 (set_attr "fp_mode" "single")])
10051 (define_insn "*floatsisf2_ie"
10052 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10053 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10054 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10056 [(set_attr "type" "fp")])
10058 (define_insn "fix_truncsfdi2"
10059 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10060 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10061 "TARGET_SHMEDIA_FPU"
10063 [(set_attr "type" "fpconv_media")])
10065 (define_expand "fix_truncsfsi2"
10066 [(set (match_operand:SI 0 "fpul_operand" "=y")
10067 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10068 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10071 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10073 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10078 (define_insn "*fix_truncsfsi2_media"
10079 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10080 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10081 "TARGET_SHMEDIA_FPU"
10083 [(set_attr "type" "fpconv_media")])
10085 (define_insn "fix_truncsfsi2_i4"
10086 [(set (match_operand:SI 0 "fpul_operand" "=y")
10087 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10088 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10089 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10091 [(set_attr "type" "ftrc_s")
10092 (set_attr "fp_mode" "single")])
10094 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10095 ;; fix_truncsfsi2_i4.
10096 ;; (define_insn "fix_truncsfsi2_i4_2"
10097 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10098 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10099 ;; (use (reg:PSI FPSCR_REG))
10100 ;; (clobber (reg:SI FPUL_REG))]
10103 ;; [(set_attr "length" "4")
10104 ;; (set_attr "fp_mode" "single")])
10107 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10108 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10109 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10110 ;; (clobber (reg:SI FPUL_REG))]
10112 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10113 ;; (use (match_dup 2))])
10114 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10116 (define_insn "*fixsfsi"
10117 [(set (match_operand:SI 0 "fpul_operand" "=y")
10118 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10119 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10121 [(set_attr "type" "fp")])
10123 (define_insn "cmpgtsf_t"
10124 [(set (reg:SI T_REG)
10125 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10126 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10127 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10129 [(set_attr "type" "fp_cmp")
10130 (set_attr "fp_mode" "single")])
10132 (define_insn "cmpeqsf_t"
10133 [(set (reg:SI T_REG)
10134 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10135 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10136 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10138 [(set_attr "type" "fp_cmp")
10139 (set_attr "fp_mode" "single")])
10141 (define_insn "ieee_ccmpeqsf_t"
10142 [(set (reg:SI T_REG)
10143 (ior:SI (reg:SI T_REG)
10144 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10145 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10146 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10147 "* return output_ieee_ccmpeq (insn, operands);"
10148 [(set_attr "length" "4")])
10151 (define_insn "cmpgtsf_t_i4"
10152 [(set (reg:SI T_REG)
10153 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10154 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10155 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10156 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10158 [(set_attr "type" "fp_cmp")
10159 (set_attr "fp_mode" "single")])
10161 (define_insn "cmpeqsf_t_i4"
10162 [(set (reg:SI T_REG)
10163 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10164 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10165 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10166 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10168 [(set_attr "type" "fp_cmp")
10169 (set_attr "fp_mode" "single")])
10171 (define_insn "*ieee_ccmpeqsf_t_4"
10172 [(set (reg:SI T_REG)
10173 (ior:SI (reg:SI T_REG)
10174 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10175 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10176 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10177 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10178 "* return output_ieee_ccmpeq (insn, operands);"
10179 [(set_attr "length" "4")
10180 (set_attr "fp_mode" "single")])
10182 (define_insn "cmpeqsf_media"
10183 [(set (match_operand:SI 0 "register_operand" "=r")
10184 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10185 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10186 "TARGET_SHMEDIA_FPU"
10187 "fcmpeq.s %1, %2, %0"
10188 [(set_attr "type" "fcmp_media")])
10190 (define_insn "cmpgtsf_media"
10191 [(set (match_operand:SI 0 "register_operand" "=r")
10192 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10193 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10194 "TARGET_SHMEDIA_FPU"
10195 "fcmpgt.s %1, %2, %0"
10196 [(set_attr "type" "fcmp_media")])
10198 (define_insn "cmpgesf_media"
10199 [(set (match_operand:SI 0 "register_operand" "=r")
10200 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10201 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10202 "TARGET_SHMEDIA_FPU"
10203 "fcmpge.s %1, %2, %0"
10204 [(set_attr "type" "fcmp_media")])
10206 (define_insn "cmpunsf_media"
10207 [(set (match_operand:SI 0 "register_operand" "=r")
10208 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10209 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10210 "TARGET_SHMEDIA_FPU"
10211 "fcmpun.s %1, %2, %0"
10212 [(set_attr "type" "fcmp_media")])
10214 (define_expand "cbranchsf4"
10216 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10217 [(match_operand:SF 1 "arith_operand" "")
10218 (match_operand:SF 2 "arith_operand" "")])
10219 (match_operand 3 "" "")
10221 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10224 if (TARGET_SHMEDIA)
10225 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10228 sh_emit_compare_and_branch (operands, SFmode);
10232 (define_expand "negsf2"
10233 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10234 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10235 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10240 expand_sf_unop (&gen_negsf2_i, operands);
10245 (define_insn "*negsf2_media"
10246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10247 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10248 "TARGET_SHMEDIA_FPU"
10250 [(set_attr "type" "fmove_media")])
10252 (define_insn "negsf2_i"
10253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10254 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10255 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10258 [(set_attr "type" "fmove")
10259 (set_attr "fp_mode" "single")])
10261 (define_expand "sqrtsf2"
10262 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10263 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10264 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10269 expand_sf_unop (&gen_sqrtsf2_i, operands);
10274 (define_insn "*sqrtsf2_media"
10275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10276 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10277 "TARGET_SHMEDIA_FPU"
10279 [(set_attr "type" "fdiv_media")])
10281 (define_insn "sqrtsf2_i"
10282 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10283 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10284 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10287 [(set_attr "type" "fdiv")
10288 (set_attr "fp_mode" "single")])
10290 (define_insn "rsqrtsf2"
10291 [(set (match_operand:SF 0 "register_operand" "=f")
10292 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10293 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10294 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10295 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10296 && operands[1] == CONST1_RTX (SFmode)"
10298 [(set_attr "type" "fsrra")
10299 (set_attr "fp_mode" "single")])
10301 (define_insn "fsca"
10302 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10304 (unspec:SF [(mult:SF
10305 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10306 (match_operand:SF 2 "immediate_operand" "i"))
10308 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10310 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10311 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10312 && operands[2] == sh_fsca_int2sf ()"
10314 [(set_attr "type" "fsca")
10315 (set_attr "fp_mode" "single")])
10317 (define_expand "sinsf2"
10318 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10319 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10321 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10324 rtx scaled = gen_reg_rtx (SFmode);
10325 rtx truncated = gen_reg_rtx (SImode);
10326 rtx fsca = gen_reg_rtx (V2SFmode);
10327 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10329 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10330 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10331 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10332 get_fpscr_rtx ()));
10333 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10337 (define_expand "cossf2"
10338 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10339 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10341 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10344 rtx scaled = gen_reg_rtx (SFmode);
10345 rtx truncated = gen_reg_rtx (SImode);
10346 rtx fsca = gen_reg_rtx (V2SFmode);
10347 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10349 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10350 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10351 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10352 get_fpscr_rtx ()));
10353 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10357 (define_expand "sindf2"
10358 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10359 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10361 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10364 rtx scaled = gen_reg_rtx (DFmode);
10365 rtx truncated = gen_reg_rtx (SImode);
10366 rtx fsca = gen_reg_rtx (V2SFmode);
10367 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10368 rtx sfresult = gen_reg_rtx (SFmode);
10370 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10371 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10372 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10373 get_fpscr_rtx ()));
10374 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10375 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10379 (define_expand "cosdf2"
10380 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10381 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10383 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10386 rtx scaled = gen_reg_rtx (DFmode);
10387 rtx truncated = gen_reg_rtx (SImode);
10388 rtx fsca = gen_reg_rtx (V2SFmode);
10389 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10390 rtx sfresult = gen_reg_rtx (SFmode);
10392 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10393 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10394 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10395 get_fpscr_rtx ()));
10396 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10397 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10401 (define_expand "abssf2"
10402 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10403 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10404 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10409 expand_sf_unop (&gen_abssf2_i, operands);
10414 (define_insn "*abssf2_media"
10415 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10416 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10417 "TARGET_SHMEDIA_FPU"
10419 [(set_attr "type" "fmove_media")])
10421 (define_insn "abssf2_i"
10422 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10423 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10424 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10427 [(set_attr "type" "fmove")
10428 (set_attr "fp_mode" "single")])
10430 (define_expand "adddf3"
10431 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10432 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10433 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10434 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10437 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10439 expand_df_binop (&gen_adddf3_i, operands);
10444 (define_insn "*adddf3_media"
10445 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10446 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10447 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10448 "TARGET_SHMEDIA_FPU"
10449 "fadd.d %1, %2, %0"
10450 [(set_attr "type" "dfparith_media")])
10452 (define_insn "adddf3_i"
10453 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10454 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10455 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10456 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10457 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10459 [(set_attr "type" "dfp_arith")
10460 (set_attr "fp_mode" "double")])
10462 (define_expand "subdf3"
10463 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10464 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10465 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10466 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10469 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10471 expand_df_binop (&gen_subdf3_i, operands);
10476 (define_insn "*subdf3_media"
10477 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10478 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10479 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10480 "TARGET_SHMEDIA_FPU"
10481 "fsub.d %1, %2, %0"
10482 [(set_attr "type" "dfparith_media")])
10484 (define_insn "subdf3_i"
10485 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10486 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10487 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10488 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10489 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10491 [(set_attr "type" "dfp_arith")
10492 (set_attr "fp_mode" "double")])
10494 (define_expand "muldf3"
10495 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10496 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10497 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10498 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10501 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10503 expand_df_binop (&gen_muldf3_i, operands);
10508 (define_insn "*muldf3_media"
10509 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10510 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10511 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10512 "TARGET_SHMEDIA_FPU"
10513 "fmul.d %1, %2, %0"
10514 [(set_attr "type" "dfmul_media")])
10516 (define_insn "muldf3_i"
10517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10518 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10519 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10520 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10521 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10523 [(set_attr "type" "dfp_mul")
10524 (set_attr "fp_mode" "double")])
10526 (define_expand "divdf3"
10527 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10528 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10529 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10530 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10533 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10535 expand_df_binop (&gen_divdf3_i, operands);
10540 (define_insn "*divdf3_media"
10541 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10542 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10543 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10544 "TARGET_SHMEDIA_FPU"
10545 "fdiv.d %1, %2, %0"
10546 [(set_attr "type" "dfdiv_media")])
10548 (define_insn "divdf3_i"
10549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10551 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10552 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10553 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10555 [(set_attr "type" "dfdiv")
10556 (set_attr "fp_mode" "double")])
10558 (define_insn "floatdidf2"
10559 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10560 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10561 "TARGET_SHMEDIA_FPU"
10563 [(set_attr "type" "dfpconv_media")])
10565 (define_expand "floatsidf2"
10566 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10567 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10568 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10571 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10573 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10574 get_fpscr_rtx ()));
10579 (define_insn "*floatsidf2_media"
10580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10581 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10582 "TARGET_SHMEDIA_FPU"
10584 [(set_attr "type" "dfpconv_media")])
10586 (define_insn "floatsidf2_i"
10587 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10588 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10589 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10590 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10592 [(set_attr "type" "dfp_conv")
10593 (set_attr "fp_mode" "double")])
10595 (define_insn "fix_truncdfdi2"
10596 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10597 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10598 "TARGET_SHMEDIA_FPU"
10600 [(set_attr "type" "dfpconv_media")])
10602 (define_expand "fix_truncdfsi2"
10603 [(set (match_operand:SI 0 "fpul_operand" "")
10604 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10605 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10608 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10610 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10611 get_fpscr_rtx ()));
10616 (define_insn "*fix_truncdfsi2_media"
10617 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10618 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10619 "TARGET_SHMEDIA_FPU"
10621 [(set_attr "type" "dfpconv_media")])
10623 (define_insn "fix_truncdfsi2_i"
10624 [(set (match_operand:SI 0 "fpul_operand" "=y")
10625 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10626 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10627 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10629 [(set_attr "type" "dfp_conv")
10630 (set_attr "dfp_comp" "no")
10631 (set_attr "fp_mode" "double")])
10633 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10634 ;; fix_truncdfsi2_i.
10635 ;; (define_insn "fix_truncdfsi2_i4"
10636 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10637 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10638 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10639 ;; (clobber (reg:SI FPUL_REG))]
10642 ;; [(set_attr "length" "4")
10643 ;; (set_attr "fp_mode" "double")])
10646 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10647 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10648 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10649 ;; (clobber (reg:SI FPUL_REG))]
10651 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10652 ;; (use (match_dup 2))])
10653 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10655 (define_insn "cmpgtdf_t"
10656 [(set (reg:SI T_REG)
10657 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10658 (match_operand:DF 1 "arith_reg_operand" "f")))
10659 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10660 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10662 [(set_attr "type" "dfp_cmp")
10663 (set_attr "fp_mode" "double")])
10665 (define_insn "cmpeqdf_t"
10666 [(set (reg:SI T_REG)
10667 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10668 (match_operand:DF 1 "arith_reg_operand" "f")))
10669 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10670 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10672 [(set_attr "type" "dfp_cmp")
10673 (set_attr "fp_mode" "double")])
10675 (define_insn "*ieee_ccmpeqdf_t"
10676 [(set (reg:SI T_REG)
10677 (ior:SI (reg:SI T_REG)
10678 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10679 (match_operand:DF 1 "arith_reg_operand" "f"))))
10680 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10681 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10682 "* return output_ieee_ccmpeq (insn, operands);"
10683 [(set_attr "length" "4")
10684 (set_attr "fp_mode" "double")])
10686 (define_insn "cmpeqdf_media"
10687 [(set (match_operand:SI 0 "register_operand" "=r")
10688 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10689 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10690 "TARGET_SHMEDIA_FPU"
10691 "fcmpeq.d %1,%2,%0"
10692 [(set_attr "type" "fcmp_media")])
10694 (define_insn "cmpgtdf_media"
10695 [(set (match_operand:SI 0 "register_operand" "=r")
10696 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10697 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10698 "TARGET_SHMEDIA_FPU"
10699 "fcmpgt.d %1,%2,%0"
10700 [(set_attr "type" "fcmp_media")])
10702 (define_insn "cmpgedf_media"
10703 [(set (match_operand:SI 0 "register_operand" "=r")
10704 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10705 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10706 "TARGET_SHMEDIA_FPU"
10707 "fcmpge.d %1,%2,%0"
10708 [(set_attr "type" "fcmp_media")])
10710 (define_insn "cmpundf_media"
10711 [(set (match_operand:SI 0 "register_operand" "=r")
10712 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10713 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10714 "TARGET_SHMEDIA_FPU"
10715 "fcmpun.d %1,%2,%0"
10716 [(set_attr "type" "fcmp_media")])
10718 (define_expand "cbranchdf4"
10720 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10721 [(match_operand:DF 1 "arith_operand" "")
10722 (match_operand:DF 2 "arith_operand" "")])
10723 (match_operand 3 "" "")
10725 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10728 if (TARGET_SHMEDIA)
10729 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10732 sh_emit_compare_and_branch (operands, DFmode);
10737 (define_expand "negdf2"
10738 [(set (match_operand:DF 0 "arith_reg_operand" "")
10739 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10740 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10743 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10745 expand_df_unop (&gen_negdf2_i, operands);
10750 (define_insn "*negdf2_media"
10751 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10752 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10753 "TARGET_SHMEDIA_FPU"
10755 [(set_attr "type" "fmove_media")])
10757 (define_insn "negdf2_i"
10758 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10759 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10760 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10761 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10763 [(set_attr "type" "fmove")
10764 (set_attr "fp_mode" "double")])
10766 (define_expand "sqrtdf2"
10767 [(set (match_operand:DF 0 "arith_reg_operand" "")
10768 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10769 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10772 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10774 expand_df_unop (&gen_sqrtdf2_i, operands);
10779 (define_insn "*sqrtdf2_media"
10780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10781 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10782 "TARGET_SHMEDIA_FPU"
10784 [(set_attr "type" "dfdiv_media")])
10786 (define_insn "sqrtdf2_i"
10787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10788 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10789 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10790 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10792 [(set_attr "type" "dfdiv")
10793 (set_attr "fp_mode" "double")])
10795 (define_expand "absdf2"
10796 [(set (match_operand:DF 0 "arith_reg_operand" "")
10797 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10798 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10801 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10803 expand_df_unop (&gen_absdf2_i, operands);
10808 (define_insn "*absdf2_media"
10809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10810 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10811 "TARGET_SHMEDIA_FPU"
10813 [(set_attr "type" "fmove_media")])
10815 (define_insn "absdf2_i"
10816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10817 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10818 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10819 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10821 [(set_attr "type" "fmove")
10822 (set_attr "fp_mode" "double")])
10824 (define_expand "extendsfdf2"
10825 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10826 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10830 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10832 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10833 get_fpscr_rtx ()));
10838 (define_insn "*extendsfdf2_media"
10839 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10840 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10841 "TARGET_SHMEDIA_FPU"
10843 [(set_attr "type" "dfpconv_media")])
10845 (define_insn "extendsfdf2_i4"
10846 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10847 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10848 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10849 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10851 [(set_attr "type" "fp")
10852 (set_attr "fp_mode" "double")])
10854 (define_expand "truncdfsf2"
10855 [(set (match_operand:SF 0 "fpul_operand" "")
10856 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10857 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10860 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10862 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10863 get_fpscr_rtx ()));
10868 (define_insn "*truncdfsf2_media"
10869 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10870 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10871 "TARGET_SHMEDIA_FPU"
10873 [(set_attr "type" "dfpconv_media")])
10875 (define_insn "truncdfsf2_i4"
10876 [(set (match_operand:SF 0 "fpul_operand" "=y")
10877 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10878 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10879 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881 [(set_attr "type" "fp")
10882 (set_attr "fp_mode" "double")])
10884 ;; Bit field extract patterns. These give better code for packed bitfields,
10885 ;; because they allow auto-increment addresses to be generated.
10887 (define_expand "insv"
10888 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10889 (match_operand:SI 1 "immediate_operand" "")
10890 (match_operand:SI 2 "immediate_operand" ""))
10891 (match_operand:SI 3 "general_operand" ""))]
10892 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10895 rtx addr_target, orig_address, shift_reg, qi_val;
10896 HOST_WIDE_INT bitsize, size, v = 0;
10897 rtx x = operands[3];
10899 if (TARGET_SH2A && TARGET_BITOPS
10900 && (satisfies_constraint_Sbw (operands[0])
10901 || satisfies_constraint_Sbv (operands[0]))
10902 && satisfies_constraint_M (operands[1])
10903 && satisfies_constraint_K03 (operands[2]))
10905 if (satisfies_constraint_N (operands[3]))
10907 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10910 else if (satisfies_constraint_M (operands[3]))
10912 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10915 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10916 && satisfies_constraint_M (operands[1]))
10918 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10921 else if (REG_P (operands[3])
10922 && satisfies_constraint_M (operands[1]))
10924 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10925 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10929 /* ??? expmed doesn't care for non-register predicates. */
10930 if (! memory_operand (operands[0], VOIDmode)
10931 || ! immediate_operand (operands[1], VOIDmode)
10932 || ! immediate_operand (operands[2], VOIDmode)
10933 || ! general_operand (x, VOIDmode))
10935 /* If this isn't a 16 / 24 / 32 bit field, or if
10936 it doesn't start on a byte boundary, then fail. */
10937 bitsize = INTVAL (operands[1]);
10938 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10939 || (INTVAL (operands[2]) % 8) != 0)
10942 size = bitsize / 8;
10943 orig_address = XEXP (operands[0], 0);
10944 shift_reg = gen_reg_rtx (SImode);
10945 if (CONST_INT_P (x))
10948 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10952 emit_insn (gen_movsi (shift_reg, operands[3]));
10953 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10955 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10957 operands[0] = replace_equiv_address (operands[0], addr_target);
10958 emit_insn (gen_movqi (operands[0], qi_val));
10962 if (CONST_INT_P (x))
10964 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10967 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10968 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10970 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10971 emit_insn (gen_movqi (operands[0], qi_val));
10977 (define_insn "movua"
10978 [(set (match_operand:SI 0 "register_operand" "=z")
10979 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10983 [(set_attr "type" "movua")])
10985 ;; We shouldn't need this, but cse replaces increments with references
10986 ;; to other regs before flow has a chance to create post_inc
10987 ;; addressing modes, and only postreload's cse_move2add brings the
10988 ;; increments back to a usable form.
10990 [(set (match_operand:SI 0 "register_operand" "")
10991 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10992 (const_int 32) (const_int 0)))
10993 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10994 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10995 [(set (match_operand:SI 0 "register_operand" "")
10996 (sign_extract:SI (mem:SI (post_inc:SI
10997 (match_operand:SI 1 "register_operand" "")))
10998 (const_int 32) (const_int 0)))]
11001 (define_expand "extv"
11002 [(set (match_operand:SI 0 "register_operand" "")
11003 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11004 (match_operand 2 "const_int_operand" "")
11005 (match_operand 3 "const_int_operand" "")))]
11006 "TARGET_SH4A_ARCH || TARGET_SH2A"
11008 if (TARGET_SH2A && TARGET_BITOPS
11009 && (satisfies_constraint_Sbw (operands[1])
11010 || satisfies_constraint_Sbv (operands[1]))
11011 && satisfies_constraint_M (operands[2])
11012 && satisfies_constraint_K03 (operands[3]))
11014 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11015 if (REGNO (operands[0]) != T_REG)
11016 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11019 if (TARGET_SH4A_ARCH
11020 && INTVAL (operands[2]) == 32
11021 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11022 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11024 rtx src = adjust_address (operands[1], BLKmode, 0);
11025 set_mem_size (src, GEN_INT (4));
11026 emit_insn (gen_movua (operands[0], src));
11033 (define_expand "extzv"
11034 [(set (match_operand:SI 0 "register_operand" "")
11035 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11036 (match_operand 2 "const_int_operand" "")
11037 (match_operand 3 "const_int_operand" "")))]
11038 "TARGET_SH4A_ARCH || TARGET_SH2A"
11040 if (TARGET_SH2A && TARGET_BITOPS
11041 && (satisfies_constraint_Sbw (operands[1])
11042 || satisfies_constraint_Sbv (operands[1]))
11043 && satisfies_constraint_M (operands[2])
11044 && satisfies_constraint_K03 (operands[3]))
11046 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11047 if (REGNO (operands[0]) != T_REG)
11048 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11051 if (TARGET_SH4A_ARCH
11052 && INTVAL (operands[2]) == 32
11053 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11054 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11056 rtx src = adjust_address (operands[1], BLKmode, 0);
11057 set_mem_size (src, GEN_INT (4));
11058 emit_insn (gen_movua (operands[0], src));
11065 ;; SH2A instructions for bitwise operations.
11067 ;; Clear a bit in a memory location.
11068 (define_insn "bclr_m2a"
11069 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11071 (not:QI (ashift:QI (const_int 1)
11072 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11074 "TARGET_SH2A && TARGET_BITOPS"
11077 bclr.b\\t%1,@(0,%t0)"
11078 [(set_attr "length" "4,4")])
11080 (define_insn "bclrmem_m2a"
11081 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11082 (and:QI (match_dup 0)
11083 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11084 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11087 bclr.b\\t%W1,@(0,%t0)"
11088 [(set_attr "length" "4,4")])
11090 ;; Set a bit in a memory location.
11091 (define_insn "bset_m2a"
11092 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11094 (ashift:QI (const_int 1)
11095 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11097 "TARGET_SH2A && TARGET_BITOPS"
11100 bset.b\\t%1,@(0,%t0)"
11101 [(set_attr "length" "4,4")])
11103 (define_insn "bsetmem_m2a"
11104 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11105 (ior:QI (match_dup 0)
11106 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11107 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11110 bset.b\\t%V1,@(0,%t0)"
11111 [(set_attr "length" "4,4")])
11113 ;;; Transfer the contents of the T bit to a specified bit of memory.
11114 (define_insn "bst_m2a"
11115 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11116 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11118 (not:QI (ashift:QI (const_int 1)
11119 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11122 (ashift:QI (const_int 1) (match_dup 1))
11124 "TARGET_SH2A && TARGET_BITOPS"
11127 bst.b\\t%1,@(0,%t0)"
11128 [(set_attr "length" "4")])
11130 ;; Store a specified bit of memory in the T bit.
11131 (define_insn "bld_m2a"
11132 [(set (reg:SI T_REG)
11134 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11136 (match_operand 1 "const_int_operand" "K03,K03")))]
11137 "TARGET_SH2A && TARGET_BITOPS"
11140 bld.b\\t%1,@(0,%t0)"
11141 [(set_attr "length" "4,4")])
11143 ;; Store a specified bit of memory in the T bit.
11144 (define_insn "bldsign_m2a"
11145 [(set (reg:SI T_REG)
11147 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11149 (match_operand 1 "const_int_operand" "K03,K03")))]
11150 "TARGET_SH2A && TARGET_BITOPS"
11153 bld.b\\t%1,@(0,%t0)"
11154 [(set_attr "length" "4,4")])
11156 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11157 (define_insn "bld_reg"
11158 [(set (reg:SI T_REG)
11159 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11161 (match_operand 1 "const_int_operand" "K03")))]
11165 (define_insn "*bld_regqi"
11166 [(set (reg:SI T_REG)
11167 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11169 (match_operand 1 "const_int_operand" "K03")))]
11173 ;; Take logical and of a specified bit of memory with the T bit and
11174 ;; store its result in the T bit.
11175 (define_insn "band_m2a"
11176 [(set (reg:SI T_REG)
11177 (and:SI (reg:SI T_REG)
11179 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11181 (match_operand 1 "const_int_operand" "K03,K03"))))]
11182 "TARGET_SH2A && TARGET_BITOPS"
11185 band.b\\t%1,@(0,%t0)"
11186 [(set_attr "length" "4,4")])
11188 (define_insn "bandreg_m2a"
11189 [(set (match_operand:SI 0 "register_operand" "=r,r")
11190 (and:SI (zero_extract:SI
11191 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11193 (match_operand 2 "const_int_operand" "K03,K03"))
11194 (match_operand:SI 3 "register_operand" "r,r")))]
11195 "TARGET_SH2A && TARGET_BITOPS"
11197 band.b\\t%2,%1\;movt\\t%0
11198 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11199 [(set_attr "length" "6,6")])
11201 ;; Take logical or of a specified bit of memory with the T bit and
11202 ;; store its result in the T bit.
11203 (define_insn "bor_m2a"
11204 [(set (reg:SI T_REG)
11205 (ior:SI (reg:SI T_REG)
11207 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11209 (match_operand 1 "const_int_operand" "K03,K03"))))]
11210 "TARGET_SH2A && TARGET_BITOPS"
11213 bor.b\\t%1,@(0,%t0)"
11214 [(set_attr "length" "4,4")])
11216 (define_insn "borreg_m2a"
11217 [(set (match_operand:SI 0 "register_operand" "=r,r")
11218 (ior:SI (zero_extract:SI
11219 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11221 (match_operand 2 "const_int_operand" "K03,K03"))
11222 (match_operand:SI 3 "register_operand" "=r,r")))]
11223 "TARGET_SH2A && TARGET_BITOPS"
11225 bor.b\\t%2,%1\;movt\\t%0
11226 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11227 [(set_attr "length" "6,6")])
11229 ;; Take exclusive or of a specified bit of memory with the T bit and
11230 ;; store its result in the T bit.
11231 (define_insn "bxor_m2a"
11232 [(set (reg:SI T_REG)
11233 (xor:SI (reg:SI T_REG)
11235 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11237 (match_operand 1 "const_int_operand" "K03,K03"))))]
11238 "TARGET_SH2A && TARGET_BITOPS"
11241 bxor.b\\t%1,@(0,%t0)"
11242 [(set_attr "length" "4,4")])
11244 (define_insn "bxorreg_m2a"
11245 [(set (match_operand:SI 0 "register_operand" "=r,r")
11246 (xor:SI (zero_extract:SI
11247 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11249 (match_operand 2 "const_int_operand" "K03,K03"))
11250 (match_operand:SI 3 "register_operand" "=r,r")))]
11251 "TARGET_SH2A && TARGET_BITOPS"
11253 bxor.b\\t%2,%1\;movt\\t%0
11254 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11255 [(set_attr "length" "6,6")])
11258 ;; -------------------------------------------------------------------------
11260 ;; -------------------------------------------------------------------------
11261 ;; This matches cases where the bit in a memory location is set.
11263 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11264 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11266 (ior:SI (match_dup 0)
11267 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11269 (match_operand 3 "arith_reg_operand" "r,r"))]
11270 "TARGET_SH2A && TARGET_BITOPS
11271 && satisfies_constraint_Pso (operands[2])
11272 && REGNO (operands[0]) == REGNO (operands[3])"
11273 [(set (match_dup 1)
11274 (ior:QI (match_dup 1)
11278 ;; This matches cases where the bit in a memory location is cleared.
11280 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11281 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11283 (and:SI (match_dup 0)
11284 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11286 (match_operand 3 "arith_reg_operand" "r,r"))]
11287 "TARGET_SH2A && TARGET_BITOPS
11288 && satisfies_constraint_Psz (operands[2])
11289 && REGNO (operands[0]) == REGNO (operands[3])"
11290 [(set (match_dup 1)
11291 (and:QI (match_dup 1)
11295 ;; This matches cases where a stack pointer increment at the start of the
11296 ;; epilogue combines with a stack slot read loading the return value.
11299 [(set (match_operand:SI 0 "arith_reg_operand" "")
11300 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11301 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11302 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11305 ;; See the comment on the dt combiner pattern above.
11308 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11309 (plus:SI (match_dup 0)
11311 (set (reg:SI T_REG)
11312 (eq:SI (match_dup 0)
11317 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11318 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11319 ;; reload when the constant is too large for a reg+offset address.
11321 ;; ??? We would get much better code if this was done in reload. This would
11322 ;; require modifying find_reloads_address to recognize that if the constant
11323 ;; is out-of-range for an immediate add, then we get better code by reloading
11324 ;; the constant into a register than by reloading the sum into a register,
11325 ;; since the former is one instruction shorter if the address does not need
11326 ;; to be offsettable. Unfortunately this does not work, because there is
11327 ;; only one register, r0, that can be used as an index register. This register
11328 ;; is also the function return value register. So, if we try to force reload
11329 ;; to use double-reg addresses, then we end up with some instructions that
11330 ;; need to use r0 twice. The only way to fix this is to change the calling
11331 ;; convention so that r0 is not used to return values.
11334 [(set (match_operand:SI 0 "register_operand" "=r")
11335 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11336 (set (mem:SI (match_dup 0))
11337 (match_operand:SI 2 "general_movsrc_operand" ""))]
11338 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11339 "mov.l %2,@(%0,%1)")
11342 [(set (match_operand:SI 0 "register_operand" "=r")
11343 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344 (set (match_operand:SI 2 "general_movdst_operand" "")
11345 (mem:SI (match_dup 0)))]
11346 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11347 "mov.l @(%0,%1),%2")
11350 [(set (match_operand:SI 0 "register_operand" "=r")
11351 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11352 (set (mem:HI (match_dup 0))
11353 (match_operand:HI 2 "general_movsrc_operand" ""))]
11354 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11355 "mov.w %2,@(%0,%1)")
11358 [(set (match_operand:SI 0 "register_operand" "=r")
11359 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11360 (set (match_operand:HI 2 "general_movdst_operand" "")
11361 (mem:HI (match_dup 0)))]
11362 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11363 "mov.w @(%0,%1),%2")
11366 [(set (match_operand:SI 0 "register_operand" "=r")
11367 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11368 (set (mem:QI (match_dup 0))
11369 (match_operand:QI 2 "general_movsrc_operand" ""))]
11370 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11371 "mov.b %2,@(%0,%1)")
11374 [(set (match_operand:SI 0 "register_operand" "=r")
11375 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11376 (set (match_operand:QI 2 "general_movdst_operand" "")
11377 (mem:QI (match_dup 0)))]
11378 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11379 "mov.b @(%0,%1),%2")
11382 [(set (match_operand:SI 0 "register_operand" "=r")
11383 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11384 (set (mem:SF (match_dup 0))
11385 (match_operand:SF 2 "general_movsrc_operand" ""))]
11386 "TARGET_SH1 && REGNO (operands[0]) == 0
11387 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11388 || (GET_CODE (operands[2]) == SUBREG
11389 && REGNO (SUBREG_REG (operands[2])) < 16))
11390 && reg_unused_after (operands[0], insn)"
11391 "mov.l %2,@(%0,%1)")
11394 [(set (match_operand:SI 0 "register_operand" "=r")
11395 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11396 (set (match_operand:SF 2 "general_movdst_operand" "")
11398 (mem:SF (match_dup 0)))]
11399 "TARGET_SH1 && REGNO (operands[0]) == 0
11400 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11401 || (GET_CODE (operands[2]) == SUBREG
11402 && REGNO (SUBREG_REG (operands[2])) < 16))
11403 && reg_unused_after (operands[0], insn)"
11404 "mov.l @(%0,%1),%2")
11407 [(set (match_operand:SI 0 "register_operand" "=r")
11408 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11409 (set (mem:SF (match_dup 0))
11410 (match_operand:SF 2 "general_movsrc_operand" ""))]
11411 "TARGET_SH2E && REGNO (operands[0]) == 0
11412 && ((REG_P (operands[2])
11413 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11414 || (GET_CODE (operands[2]) == SUBREG
11415 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11416 && reg_unused_after (operands[0], insn)"
11417 "fmov{.s|} %2,@(%0,%1)")
11420 [(set (match_operand:SI 0 "register_operand" "=r")
11421 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11422 (set (match_operand:SF 2 "general_movdst_operand" "")
11424 (mem:SF (match_dup 0)))]
11425 "TARGET_SH2E && REGNO (operands[0]) == 0
11426 && ((REG_P (operands[2])
11427 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11428 || (GET_CODE (operands[2]) == SUBREG
11429 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11430 && reg_unused_after (operands[0], insn)"
11431 "fmov{.s|} @(%0,%1),%2")
11433 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11434 (define_insn "sp_switch_1"
11435 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11439 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11440 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11441 return \"mov r0,r15\";
11443 [(set_attr "length" "10")])
11445 ;; Switch back to the original stack for interrupt functions with the
11446 ;; sp_switch attribute. */
11447 (define_insn "sp_switch_2"
11450 "mov.l @r15+,r15\;mov.l @r15+,r0"
11451 [(set_attr "length" "4")])
11453 ;; Integer vector moves
11455 (define_expand "movv8qi"
11456 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11457 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11459 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11461 (define_insn "movv8qi_i"
11462 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11463 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11465 && (register_operand (operands[0], V8QImode)
11466 || sh_register_operand (operands[1], V8QImode))"
11473 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11474 (set_attr "length" "4,4,16,4,4")])
11477 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11478 (subreg:V8QI (const_int 0) 0))]
11480 [(set (match_dup 0)
11481 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11482 (const_int 0) (const_int 0) (const_int 0)
11483 (const_int 0) (const_int 0)]))])
11486 [(set (match_operand 0 "arith_reg_dest" "")
11487 (match_operand 1 "sh_rep_vec" ""))]
11488 "TARGET_SHMEDIA && reload_completed
11489 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11490 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11491 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11492 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11493 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11494 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11495 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11496 [(set (match_dup 0) (match_dup 1))
11500 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11501 rtx elt1 = XVECEXP (operands[1], 0, 1);
11504 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11508 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11509 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11511 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11512 operands[1] = XVECEXP (operands[1], 0, 0);
11515 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11517 = GEN_INT (TARGET_LITTLE_ENDIAN
11518 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11519 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11522 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11524 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11530 [(set (match_operand 0 "arith_reg_dest" "")
11531 (match_operand 1 "sh_const_vec" ""))]
11532 "TARGET_SHMEDIA && reload_completed
11533 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11534 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11535 [(set (match_dup 0) (match_dup 1))]
11538 rtx v = operands[1];
11539 enum machine_mode new_mode
11540 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11542 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11544 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11547 (define_expand "movv2hi"
11548 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11549 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11551 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11553 (define_insn "movv2hi_i"
11554 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11555 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11557 && (register_operand (operands[0], V2HImode)
11558 || sh_register_operand (operands[1], V2HImode))"
11565 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11566 (set_attr "length" "4,4,16,4,4")
11567 (set (attr "highpart")
11568 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11569 (const_string "user")]
11570 (const_string "ignore")))])
11572 (define_expand "movv4hi"
11573 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11574 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11576 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11578 (define_insn "movv4hi_i"
11579 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11580 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11582 && (register_operand (operands[0], V4HImode)
11583 || sh_register_operand (operands[1], V4HImode))"
11590 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11591 (set_attr "length" "4,4,16,4,4")
11592 (set_attr "highpart" "depend")])
11594 (define_expand "movv2si"
11595 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11596 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11598 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11600 (define_insn "movv2si_i"
11601 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11602 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11604 && (register_operand (operands[0], V2SImode)
11605 || sh_register_operand (operands[1], V2SImode))"
11612 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11613 (set_attr "length" "4,4,16,4,4")
11614 (set_attr "highpart" "depend")])
11616 ;; Multimedia Intrinsics
11618 (define_insn "absv2si2"
11619 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11620 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11623 [(set_attr "type" "mcmp_media")
11624 (set_attr "highpart" "depend")])
11626 (define_insn "absv4hi2"
11627 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11628 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11631 [(set_attr "type" "mcmp_media")
11632 (set_attr "highpart" "depend")])
11634 (define_insn "addv2si3"
11635 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11636 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11637 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11639 "madd.l %1, %2, %0"
11640 [(set_attr "type" "arith_media")
11641 (set_attr "highpart" "depend")])
11643 (define_insn "addv4hi3"
11644 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11645 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11646 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11648 "madd.w %1, %2, %0"
11649 [(set_attr "type" "arith_media")
11650 (set_attr "highpart" "depend")])
11652 (define_insn_and_split "addv2hi3"
11653 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11654 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11655 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11662 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11663 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11664 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11665 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11666 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11668 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11669 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11672 [(set_attr "highpart" "must_split")])
11674 (define_insn "ssaddv2si3"
11675 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11676 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11677 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11679 "madds.l %1, %2, %0"
11680 [(set_attr "type" "mcmp_media")
11681 (set_attr "highpart" "depend")])
11683 (define_insn "usaddv8qi3"
11684 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11685 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11686 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11688 "madds.ub %1, %2, %0"
11689 [(set_attr "type" "mcmp_media")
11690 (set_attr "highpart" "depend")])
11692 (define_insn "ssaddv4hi3"
11693 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11694 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11695 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11697 "madds.w %1, %2, %0"
11698 [(set_attr "type" "mcmp_media")
11699 (set_attr "highpart" "depend")])
11701 (define_insn "negcmpeqv8qi"
11702 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11703 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11704 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11706 "mcmpeq.b %N1, %N2, %0"
11707 [(set_attr "type" "mcmp_media")
11708 (set_attr "highpart" "depend")])
11710 (define_insn "negcmpeqv2si"
11711 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11712 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11713 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11715 "mcmpeq.l %N1, %N2, %0"
11716 [(set_attr "type" "mcmp_media")
11717 (set_attr "highpart" "depend")])
11719 (define_insn "negcmpeqv4hi"
11720 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11721 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11722 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11724 "mcmpeq.w %N1, %N2, %0"
11725 [(set_attr "type" "mcmp_media")
11726 (set_attr "highpart" "depend")])
11728 (define_insn "negcmpgtuv8qi"
11729 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11730 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11731 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11733 "mcmpgt.ub %N1, %N2, %0"
11734 [(set_attr "type" "mcmp_media")
11735 (set_attr "highpart" "depend")])
11737 (define_insn "negcmpgtv2si"
11738 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11739 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11740 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11742 "mcmpgt.l %N1, %N2, %0"
11743 [(set_attr "type" "mcmp_media")
11744 (set_attr "highpart" "depend")])
11746 (define_insn "negcmpgtv4hi"
11747 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11748 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11749 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11751 "mcmpgt.w %N1, %N2, %0"
11752 [(set_attr "type" "mcmp_media")
11753 (set_attr "highpart" "depend")])
11755 (define_insn "mcmv"
11756 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11757 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11758 (match_operand:DI 2 "arith_reg_operand" "r"))
11759 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11760 (not:DI (match_dup 2)))))]
11763 [(set_attr "type" "arith_media")
11764 (set_attr "highpart" "depend")])
11766 (define_insn "mcnvs_lw"
11767 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11769 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11770 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11772 "mcnvs.lw %N1, %N2, %0"
11773 [(set_attr "type" "mcmp_media")])
11775 (define_insn "mcnvs_wb"
11776 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11778 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11779 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11781 "mcnvs.wb %N1, %N2, %0"
11782 [(set_attr "type" "mcmp_media")])
11784 (define_insn "mcnvs_wub"
11785 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11787 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11788 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11790 "mcnvs.wub %N1, %N2, %0"
11791 [(set_attr "type" "mcmp_media")])
11793 (define_insn "mextr_rl"
11794 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11795 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11796 (match_operand:HI 3 "mextr_bit_offset" "i"))
11797 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11798 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11799 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11802 static char templ[21];
11804 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11805 (int) INTVAL (operands[3]) >> 3);
11808 [(set_attr "type" "arith_media")])
11810 (define_insn "*mextr_lr"
11811 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11812 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11813 (match_operand:HI 3 "mextr_bit_offset" "i"))
11814 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11815 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11816 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11819 static char templ[21];
11821 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11822 (int) INTVAL (operands[4]) >> 3);
11825 [(set_attr "type" "arith_media")])
11827 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11828 ; vector then varies depending on endianness.
11829 (define_expand "mextr1"
11830 [(match_operand:DI 0 "arith_reg_dest" "")
11831 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11832 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11836 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11837 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11841 (define_expand "mextr2"
11842 [(match_operand:DI 0 "arith_reg_dest" "")
11843 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11844 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11848 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11849 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11853 (define_expand "mextr3"
11854 [(match_operand:DI 0 "arith_reg_dest" "")
11855 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11856 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11860 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11861 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11865 (define_expand "mextr4"
11866 [(match_operand:DI 0 "arith_reg_dest" "")
11867 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11868 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11872 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11873 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11877 (define_expand "mextr5"
11878 [(match_operand:DI 0 "arith_reg_dest" "")
11879 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11880 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11884 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11885 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11889 (define_expand "mextr6"
11890 [(match_operand:DI 0 "arith_reg_dest" "")
11891 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11892 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11896 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11897 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11901 (define_expand "mextr7"
11902 [(match_operand:DI 0 "arith_reg_dest" "")
11903 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11904 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11908 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11909 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11913 (define_expand "mmacfx_wl"
11914 [(match_operand:V2SI 0 "arith_reg_dest" "")
11915 (match_operand:V2HI 1 "extend_reg_operand" "")
11916 (match_operand:V2HI 2 "extend_reg_operand" "")
11917 (match_operand:V2SI 3 "arith_reg_operand" "")]
11921 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11922 operands[1], operands[2]));
11926 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11928 (define_insn "mmacfx_wl_i"
11929 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11931 (match_operand:V2SI 1 "arith_reg_operand" "0")
11936 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11937 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11940 "mmacfx.wl %2, %3, %0"
11941 [(set_attr "type" "mac_media")
11942 (set_attr "highpart" "depend")])
11944 (define_expand "mmacnfx_wl"
11945 [(match_operand:V2SI 0 "arith_reg_dest" "")
11946 (match_operand:V2HI 1 "extend_reg_operand" "")
11947 (match_operand:V2HI 2 "extend_reg_operand" "")
11948 (match_operand:V2SI 3 "arith_reg_operand" "")]
11952 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11953 operands[1], operands[2]));
11957 (define_insn "mmacnfx_wl_i"
11958 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11960 (match_operand:V2SI 1 "arith_reg_operand" "0")
11965 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11966 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11969 "mmacnfx.wl %2, %3, %0"
11970 [(set_attr "type" "mac_media")
11971 (set_attr "highpart" "depend")])
11973 (define_insn "mulv2si3"
11974 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11975 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11976 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11978 "mmul.l %1, %2, %0"
11979 [(set_attr "type" "d2mpy_media")
11980 (set_attr "highpart" "depend")])
11982 (define_insn "mulv4hi3"
11983 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11984 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11985 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11987 "mmul.w %1, %2, %0"
11988 [(set_attr "type" "dmpy_media")
11989 (set_attr "highpart" "depend")])
11991 (define_insn "mmulfx_l"
11992 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11996 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11997 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12000 "mmulfx.l %1, %2, %0"
12001 [(set_attr "type" "d2mpy_media")
12002 (set_attr "highpart" "depend")])
12004 (define_insn "mmulfx_w"
12005 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12009 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12010 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12013 "mmulfx.w %1, %2, %0"
12014 [(set_attr "type" "dmpy_media")
12015 (set_attr "highpart" "depend")])
12017 (define_insn "mmulfxrp_w"
12018 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12023 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12024 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12028 "mmulfxrp.w %1, %2, %0"
12029 [(set_attr "type" "dmpy_media")
12030 (set_attr "highpart" "depend")])
12033 (define_expand "mmulhi_wl"
12034 [(match_operand:V2SI 0 "arith_reg_dest" "")
12035 (match_operand:V4HI 1 "arith_reg_operand" "")
12036 (match_operand:V4HI 2 "arith_reg_operand" "")]
12040 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12041 (operands[0], operands[1], operands[2]));
12045 (define_expand "mmullo_wl"
12046 [(match_operand:V2SI 0 "arith_reg_dest" "")
12047 (match_operand:V4HI 1 "arith_reg_operand" "")
12048 (match_operand:V4HI 2 "arith_reg_operand" "")]
12052 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12053 (operands[0], operands[1], operands[2]));
12057 (define_insn "mmul23_wl"
12058 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12061 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12062 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12063 (parallel [(const_int 2) (const_int 3)])))]
12065 "* return (TARGET_LITTLE_ENDIAN
12066 ? \"mmulhi.wl %1, %2, %0\"
12067 : \"mmullo.wl %1, %2, %0\");"
12068 [(set_attr "type" "dmpy_media")
12069 (set (attr "highpart")
12070 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12071 (const_string "user")))])
12073 (define_insn "mmul01_wl"
12074 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12077 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12078 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12079 (parallel [(const_int 0) (const_int 1)])))]
12081 "* return (TARGET_LITTLE_ENDIAN
12082 ? \"mmullo.wl %1, %2, %0\"
12083 : \"mmulhi.wl %1, %2, %0\");"
12084 [(set_attr "type" "dmpy_media")
12085 (set (attr "highpart")
12086 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12087 (const_string "user")))])
12090 (define_expand "mmulsum_wq"
12091 [(match_operand:DI 0 "arith_reg_dest" "")
12092 (match_operand:V4HI 1 "arith_reg_operand" "")
12093 (match_operand:V4HI 2 "arith_reg_operand" "")
12094 (match_operand:DI 3 "arith_reg_operand" "")]
12098 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12099 operands[1], operands[2]));
12103 (define_insn "mmulsum_wq_i"
12104 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12105 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12110 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12111 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12112 (parallel [(const_int 0)]))
12113 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12114 (sign_extend:V4DI (match_dup 3)))
12115 (parallel [(const_int 1)])))
12117 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12118 (sign_extend:V4DI (match_dup 3)))
12119 (parallel [(const_int 2)]))
12120 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12121 (sign_extend:V4DI (match_dup 3)))
12122 (parallel [(const_int 3)]))))))]
12124 "mmulsum.wq %2, %3, %0"
12125 [(set_attr "type" "mac_media")])
12127 (define_expand "mperm_w"
12128 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12129 (match_operand:V4HI 1 "arith_reg_operand" "r")
12130 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12134 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12135 (operands[0], operands[1], operands[2]));
12139 ; This use of vec_select isn't exactly correct according to rtl.texi
12140 ; (because not constant), but it seems a straightforward extension.
12141 (define_insn "mperm_w_little"
12142 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12144 (match_operand:V4HI 1 "arith_reg_operand" "r")
12146 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12147 (const_int 2) (const_int 0))
12148 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12149 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12150 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12151 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12152 "mperm.w %1, %N2, %0"
12153 [(set_attr "type" "arith_media")])
12155 (define_insn "mperm_w_big"
12156 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12158 (match_operand:V4HI 1 "arith_reg_operand" "r")
12160 [(zero_extract:QI (not:QI (match_operand:QI 2
12161 "extend_reg_or_0_operand" "rZ"))
12162 (const_int 2) (const_int 0))
12163 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12164 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12165 (zero_extract:QI (not:QI (match_dup 2))
12166 (const_int 2) (const_int 6))])))]
12167 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12168 "mperm.w %1, %N2, %0"
12169 [(set_attr "type" "arith_media")])
12171 (define_insn "mperm_w0"
12172 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12173 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12174 "trunc_hi_operand" "r"))))]
12176 "mperm.w %1, r63, %0"
12177 [(set_attr "type" "arith_media")
12178 (set_attr "highpart" "ignore")])
12180 (define_expand "msad_ubq"
12181 [(match_operand:DI 0 "arith_reg_dest" "")
12182 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12183 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12184 (match_operand:DI 3 "arith_reg_operand" "")]
12188 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12189 operands[1], operands[2]));
12193 (define_insn "msad_ubq_i"
12194 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12199 (match_operand:DI 1 "arith_reg_operand" "0")
12200 (abs:DI (vec_select:DI
12203 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12205 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12206 (parallel [(const_int 0)]))))
12207 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12208 (zero_extend:V8DI (match_dup 3)))
12209 (parallel [(const_int 1)]))))
12211 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12212 (zero_extend:V8DI (match_dup 3)))
12213 (parallel [(const_int 2)])))
12214 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12215 (zero_extend:V8DI (match_dup 3)))
12216 (parallel [(const_int 3)])))))
12219 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12220 (zero_extend:V8DI (match_dup 3)))
12221 (parallel [(const_int 4)])))
12222 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12223 (zero_extend:V8DI (match_dup 3)))
12224 (parallel [(const_int 5)]))))
12226 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12227 (zero_extend:V8DI (match_dup 3)))
12228 (parallel [(const_int 6)])))
12229 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12230 (zero_extend:V8DI (match_dup 3)))
12231 (parallel [(const_int 7)])))))))]
12233 "msad.ubq %N2, %N3, %0"
12234 [(set_attr "type" "mac_media")])
12236 (define_insn "mshalds_l"
12237 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12240 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12241 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12242 (const_int 31)))))]
12244 "mshalds.l %1, %2, %0"
12245 [(set_attr "type" "mcmp_media")
12246 (set_attr "highpart" "depend")])
12248 (define_insn "mshalds_w"
12249 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12252 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12253 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12254 (const_int 15)))))]
12256 "mshalds.w %1, %2, %0"
12257 [(set_attr "type" "mcmp_media")
12258 (set_attr "highpart" "depend")])
12260 (define_insn "ashrv2si3"
12261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12262 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12263 (match_operand:DI 2 "arith_reg_operand" "r")))]
12265 "mshard.l %1, %2, %0"
12266 [(set_attr "type" "arith_media")
12267 (set_attr "highpart" "depend")])
12269 (define_insn "ashrv4hi3"
12270 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12271 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12272 (match_operand:DI 2 "arith_reg_operand" "r")))]
12274 "mshard.w %1, %2, %0"
12275 [(set_attr "type" "arith_media")
12276 (set_attr "highpart" "depend")])
12278 (define_insn "mshards_q"
12279 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12281 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12282 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12284 "mshards.q %1, %N2, %0"
12285 [(set_attr "type" "mcmp_media")])
12287 (define_expand "mshfhi_b"
12288 [(match_operand:V8QI 0 "arith_reg_dest" "")
12289 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12290 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12294 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12295 (operands[0], operands[1], operands[2]));
12299 (define_expand "mshflo_b"
12300 [(match_operand:V8QI 0 "arith_reg_dest" "")
12301 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12302 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12306 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12307 (operands[0], operands[1], operands[2]));
12311 (define_insn "mshf4_b"
12313 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12315 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12316 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12317 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12318 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12320 "* return (TARGET_LITTLE_ENDIAN
12321 ? \"mshfhi.b %N1, %N2, %0\"
12322 : \"mshflo.b %N1, %N2, %0\");"
12323 [(set_attr "type" "arith_media")
12324 (set (attr "highpart")
12325 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12326 (const_string "user")))])
12328 (define_insn "mshf0_b"
12330 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12332 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12333 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12334 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12335 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12337 "* return (TARGET_LITTLE_ENDIAN
12338 ? \"mshflo.b %N1, %N2, %0\"
12339 : \"mshfhi.b %N1, %N2, %0\");"
12340 [(set_attr "type" "arith_media")
12341 (set (attr "highpart")
12342 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12343 (const_string "user")))])
12345 (define_expand "mshfhi_l"
12346 [(match_operand:V2SI 0 "arith_reg_dest" "")
12347 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12348 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12352 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12353 (operands[0], operands[1], operands[2]));
12357 (define_expand "mshflo_l"
12358 [(match_operand:V2SI 0 "arith_reg_dest" "")
12359 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12360 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12364 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12365 (operands[0], operands[1], operands[2]));
12369 (define_insn "mshf4_l"
12370 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12372 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12373 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12374 (parallel [(const_int 1) (const_int 3)])))]
12376 "* return (TARGET_LITTLE_ENDIAN
12377 ? \"mshfhi.l %N1, %N2, %0\"
12378 : \"mshflo.l %N1, %N2, %0\");"
12379 [(set_attr "type" "arith_media")
12380 (set (attr "highpart")
12381 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12382 (const_string "user")))])
12384 (define_insn "mshf0_l"
12385 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12387 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12388 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12389 (parallel [(const_int 0) (const_int 2)])))]
12391 "* return (TARGET_LITTLE_ENDIAN
12392 ? \"mshflo.l %N1, %N2, %0\"
12393 : \"mshfhi.l %N1, %N2, %0\");"
12394 [(set_attr "type" "arith_media")
12395 (set (attr "highpart")
12396 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12397 (const_string "user")))])
12399 (define_expand "mshfhi_w"
12400 [(match_operand:V4HI 0 "arith_reg_dest" "")
12401 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12402 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12406 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12407 (operands[0], operands[1], operands[2]));
12411 (define_expand "mshflo_w"
12412 [(match_operand:V4HI 0 "arith_reg_dest" "")
12413 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12414 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12418 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12419 (operands[0], operands[1], operands[2]));
12423 (define_insn "mshf4_w"
12424 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12426 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12427 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12428 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12430 "* return (TARGET_LITTLE_ENDIAN
12431 ? \"mshfhi.w %N1, %N2, %0\"
12432 : \"mshflo.w %N1, %N2, %0\");"
12433 [(set_attr "type" "arith_media")
12434 (set (attr "highpart")
12435 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12436 (const_string "user")))])
12438 (define_insn "mshf0_w"
12439 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12441 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12442 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12443 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12445 "* return (TARGET_LITTLE_ENDIAN
12446 ? \"mshflo.w %N1, %N2, %0\"
12447 : \"mshfhi.w %N1, %N2, %0\");"
12448 [(set_attr "type" "arith_media")
12449 (set (attr "highpart")
12450 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12451 (const_string "user")))])
12453 (define_insn "mshflo_w_x"
12454 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12456 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12457 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12458 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12460 "mshflo.w %N1, %N2, %0"
12461 [(set_attr "type" "arith_media")
12462 (set_attr "highpart" "ignore")])
12464 /* These are useful to expand ANDs and as combiner patterns. */
12465 (define_insn_and_split "mshfhi_l_di"
12466 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12467 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12469 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12470 (const_int -4294967296))))]
12473 mshfhi.l %N1, %N2, %0
12475 "TARGET_SHMEDIA && reload_completed
12476 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12477 [(set (match_dup 3) (match_dup 4))
12478 (set (match_dup 5) (match_dup 6))]
12481 operands[3] = gen_lowpart (SImode, operands[0]);
12482 operands[4] = gen_highpart (SImode, operands[1]);
12483 operands[5] = gen_highpart (SImode, operands[0]);
12484 operands[6] = gen_highpart (SImode, operands[2]);
12486 [(set_attr "type" "arith_media")])
12488 (define_insn "*mshfhi_l_di_rev"
12489 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12490 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12491 (const_int -4294967296))
12492 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12495 "mshfhi.l %N2, %N1, %0"
12496 [(set_attr "type" "arith_media")])
12499 [(set (match_operand:DI 0 "arith_reg_dest" "")
12500 (ior:DI (zero_extend:DI (match_operand:SI 1
12501 "extend_reg_or_0_operand" ""))
12502 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12503 (const_int -4294967296))))
12504 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12509 emit_insn (gen_ashldi3_media (operands[3],
12510 simplify_gen_subreg (DImode, operands[1],
12513 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12517 (define_insn "mshflo_l_di"
12518 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12519 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12520 (const_int 4294967295))
12521 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12525 "mshflo.l %N1, %N2, %0"
12526 [(set_attr "type" "arith_media")
12527 (set_attr "highpart" "ignore")])
12529 (define_insn "*mshflo_l_di_rev"
12530 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12531 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12533 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12534 (const_int 4294967295))))]
12537 "mshflo.l %N2, %N1, %0"
12538 [(set_attr "type" "arith_media")
12539 (set_attr "highpart" "ignore")])
12541 ;; Combiner pattern for trampoline initialization.
12542 (define_insn_and_split "*double_shori"
12543 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12544 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12546 (match_operand:DI 2 "const_int_operand" "n")))]
12548 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12550 "rtx_equal_p (operands[0], operands[1])"
12554 HOST_WIDE_INT v = INTVAL (operands[2]);
12556 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12557 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12560 [(set_attr "highpart" "ignore")])
12563 (define_insn "*mshflo_l_di_x"
12564 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12565 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12567 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12571 "mshflo.l %N1, %N2, %0"
12572 [(set_attr "type" "arith_media")
12573 (set_attr "highpart" "ignore")])
12575 (define_insn_and_split "concat_v2sf"
12576 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12577 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12578 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12579 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12583 mshflo.l %N1, %N2, %0
12586 "TARGET_SHMEDIA && reload_completed
12587 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12588 [(set (match_dup 3) (match_dup 1))
12589 (set (match_dup 4) (match_dup 2))]
12592 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12593 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12595 [(set_attr "type" "arith_media")
12596 (set_attr "highpart" "ignore")])
12598 (define_insn "*mshflo_l_di_x_rev"
12599 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12600 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12602 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12605 "mshflo.l %N2, %N1, %0"
12606 [(set_attr "type" "arith_media")
12607 (set_attr "highpart" "ignore")])
12609 (define_insn "ashlv2si3"
12610 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12611 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12612 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12614 "mshlld.l %1, %2, %0"
12615 [(set_attr "type" "arith_media")
12616 (set_attr "highpart" "depend")])
12619 [(set (match_operand 0 "any_register_operand" "")
12620 (match_operator 3 "shift_operator"
12621 [(match_operand 1 "any_register_operand" "")
12622 (match_operand 2 "shift_count_reg_operand" "")]))]
12623 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12624 [(set (match_dup 0) (match_dup 3))]
12627 rtx count = operands[2];
12628 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12630 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12631 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12632 || GET_CODE (count) == TRUNCATE)
12633 count = XEXP (count, 0);
12634 inner_mode = GET_MODE (count);
12635 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12636 subreg_lowpart_offset (outer_mode, inner_mode));
12637 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12638 operands[1], count);
12641 (define_insn "ashlv4hi3"
12642 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12643 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12644 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12646 "mshlld.w %1, %2, %0"
12647 [(set_attr "type" "arith_media")
12648 (set_attr "highpart" "depend")])
12650 (define_insn "lshrv2si3"
12651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12652 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12653 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12655 "mshlrd.l %1, %2, %0"
12656 [(set_attr "type" "arith_media")
12657 (set_attr "highpart" "depend")])
12659 (define_insn "lshrv4hi3"
12660 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12661 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12662 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12664 "mshlrd.w %1, %2, %0"
12665 [(set_attr "type" "arith_media")
12666 (set_attr "highpart" "depend")])
12668 (define_insn "subv2si3"
12669 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12670 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12671 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12673 "msub.l %N1, %2, %0"
12674 [(set_attr "type" "arith_media")
12675 (set_attr "highpart" "depend")])
12677 (define_insn "subv4hi3"
12678 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12679 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12680 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12682 "msub.w %N1, %2, %0"
12683 [(set_attr "type" "arith_media")
12684 (set_attr "highpart" "depend")])
12686 (define_insn_and_split "subv2hi3"
12687 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12688 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12689 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12696 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12697 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12698 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12699 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12700 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12702 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12703 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12706 [(set_attr "highpart" "must_split")])
12708 (define_insn "sssubv2si3"
12709 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12710 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12711 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12713 "msubs.l %N1, %2, %0"
12714 [(set_attr "type" "mcmp_media")
12715 (set_attr "highpart" "depend")])
12717 (define_insn "ussubv8qi3"
12718 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12719 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12720 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12722 "msubs.ub %N1, %2, %0"
12723 [(set_attr "type" "mcmp_media")
12724 (set_attr "highpart" "depend")])
12726 (define_insn "sssubv4hi3"
12727 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12728 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12729 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12731 "msubs.w %N1, %2, %0"
12732 [(set_attr "type" "mcmp_media")
12733 (set_attr "highpart" "depend")])
12735 ;; Floating Point Intrinsics
12737 (define_insn "fcosa_s"
12738 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12739 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12743 [(set_attr "type" "atrans_media")])
12745 (define_insn "fsina_s"
12746 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12747 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12751 [(set_attr "type" "atrans_media")])
12753 (define_insn "fipr"
12754 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12755 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12756 "fp_arith_reg_operand" "f")
12757 (match_operand:V4SF 2
12758 "fp_arith_reg_operand" "f"))
12759 (parallel [(const_int 0)]))
12760 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12761 (parallel [(const_int 1)])))
12762 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12763 (parallel [(const_int 2)]))
12764 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12765 (parallel [(const_int 3)])))))]
12767 "fipr.s %1, %2, %0"
12768 [(set_attr "type" "fparith_media")])
12770 (define_insn "fsrra_s"
12771 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12772 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12776 [(set_attr "type" "atrans_media")])
12778 (define_insn "ftrv"
12779 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12783 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12784 (parallel [(const_int 0) (const_int 5)
12785 (const_int 10) (const_int 15)]))
12786 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12788 (vec_select:V4SF (match_dup 1)
12789 (parallel [(const_int 4) (const_int 9)
12790 (const_int 14) (const_int 3)]))
12791 (vec_select:V4SF (match_dup 2)
12792 (parallel [(const_int 1) (const_int 2)
12793 (const_int 3) (const_int 0)]))))
12796 (vec_select:V4SF (match_dup 1)
12797 (parallel [(const_int 8) (const_int 13)
12798 (const_int 2) (const_int 7)]))
12799 (vec_select:V4SF (match_dup 2)
12800 (parallel [(const_int 2) (const_int 3)
12801 (const_int 0) (const_int 1)])))
12803 (vec_select:V4SF (match_dup 1)
12804 (parallel [(const_int 12) (const_int 1)
12805 (const_int 6) (const_int 11)]))
12806 (vec_select:V4SF (match_dup 2)
12807 (parallel [(const_int 3) (const_int 0)
12808 (const_int 1) (const_int 2)]))))))]
12810 "ftrv.s %1, %2, %0"
12811 [(set_attr "type" "fparith_media")])
12813 (define_insn "ldhi_l"
12814 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12816 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12819 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12823 [(set_attr "type" "load_media")])
12825 (define_insn "ldhi_q"
12826 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12828 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12831 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12835 [(set_attr "type" "load_media")])
12837 (define_insn_and_split "*ldhi_q_comb0"
12838 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12840 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12841 "register_operand" "r")
12842 (match_operand:SI 2
12843 "ua_offset" "I06"))
12846 (plus:SI (and:SI (match_dup 1) (const_int 7))
12849 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12853 "emit_insn (gen_ldhi_q (operands[0],
12854 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12858 (define_insn_and_split "*ldhi_q_comb1"
12859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12861 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12862 "register_operand" "r")
12863 (match_operand:SI 2
12864 "ua_offset" "I06"))
12867 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12868 "ua_offset" "I06"))
12872 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12873 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12877 "emit_insn (gen_ldhi_q (operands[0],
12878 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12882 (define_insn "ldlo_l"
12883 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12885 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12887 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12888 (and:SI (match_dup 1) (const_int 3))))]
12891 [(set_attr "type" "load_media")])
12893 (define_insn "ldlo_q"
12894 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12896 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12898 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12899 (and:SI (match_dup 1) (const_int 7))))]
12902 [(set_attr "type" "load_media")])
12904 (define_insn_and_split "*ldlo_q_comb0"
12905 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12907 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12908 (match_operand:SI 2 "ua_offset" "I06"))
12910 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12911 (and:SI (match_dup 1) (const_int 7))))]
12912 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12916 "emit_insn (gen_ldlo_q (operands[0],
12917 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12920 (define_insn_and_split "*ldlo_q_comb1"
12921 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12923 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12924 (match_operand:SI 2 "ua_offset" "I06"))
12926 (minus:SI (const_int 8)
12927 (and:SI (plus:SI (match_dup 1)
12928 (match_operand:SI 3 "ua_offset" "I06"))
12930 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12931 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12932 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12936 "emit_insn (gen_ldlo_q (operands[0],
12937 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12940 (define_insn "sthi_l"
12941 [(set (zero_extract:SI
12942 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12945 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12947 (match_operand:SI 1 "arith_reg_operand" "r"))]
12950 [(set_attr "type" "ustore_media")])
12952 ;; All unaligned stores are considered to be 'narrow' because they typically
12953 ;; operate on less that a quadword, and when they operate on a full quadword,
12954 ;; the vanilla store high / store low sequence will cause a stall if not
12955 ;; scheduled apart.
12956 (define_insn "sthi_q"
12957 [(set (zero_extract:DI
12958 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12961 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12963 (match_operand:DI 1 "arith_reg_operand" "r"))]
12966 [(set_attr "type" "ustore_media")])
12968 (define_insn_and_split "*sthi_q_comb0"
12969 [(set (zero_extract:DI
12970 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12971 "register_operand" "r")
12972 (match_operand:SI 1 "ua_offset"
12976 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12978 (match_operand:DI 2 "arith_reg_operand" "r"))]
12979 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12983 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12987 (define_insn_and_split "*sthi_q_comb1"
12988 [(set (zero_extract:DI
12989 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12990 "register_operand" "r")
12991 (match_operand:SI 1 "ua_offset"
12995 (plus:SI (and:SI (plus:SI (match_dup 0)
12996 (match_operand:SI 2 "ua_offset" "I06"))
13000 (match_operand:DI 3 "arith_reg_operand" "r"))]
13001 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13002 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13006 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13010 ;; This is highpart user because the address is used as full 64 bit.
13011 (define_insn "stlo_l"
13012 [(set (zero_extract:SI
13013 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13015 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13016 (and:SI (match_dup 0) (const_int 3)))
13017 (match_operand:SI 1 "arith_reg_operand" "r"))]
13020 [(set_attr "type" "ustore_media")])
13022 (define_insn "stlo_q"
13023 [(set (zero_extract:DI
13024 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13026 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13027 (and:SI (match_dup 0) (const_int 7)))
13028 (match_operand:DI 1 "arith_reg_operand" "r"))]
13031 [(set_attr "type" "ustore_media")])
13033 (define_insn_and_split "*stlo_q_comb0"
13034 [(set (zero_extract:DI
13035 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13036 (match_operand:SI 1 "ua_offset" "I06"))
13038 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13039 (and:SI (match_dup 0) (const_int 7)))
13040 (match_operand:DI 2 "arith_reg_operand" "r"))]
13041 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13045 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13049 (define_insn_and_split "*stlo_q_comb1"
13050 [(set (zero_extract:DI
13051 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13052 (match_operand:SI 1 "ua_offset" "I06"))
13054 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13055 (match_operand:SI 2
13056 "ua_offset" "I06"))
13058 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13059 (match_operand:DI 3 "arith_reg_operand" "r"))]
13060 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13064 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13068 (define_insn "ldhi_l64"
13069 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13071 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13074 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13078 [(set_attr "type" "load_media")])
13080 (define_insn "ldhi_q64"
13081 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13083 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13086 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13090 [(set_attr "type" "load_media")])
13092 (define_insn "ldlo_l64"
13093 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13095 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13097 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13098 (and:DI (match_dup 1) (const_int 3))))]
13101 [(set_attr "type" "load_media")])
13103 (define_insn "ldlo_q64"
13104 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13106 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13108 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13109 (and:DI (match_dup 1) (const_int 7))))]
13112 [(set_attr "type" "load_media")])
13114 (define_insn "sthi_l64"
13115 [(set (zero_extract:SI
13116 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13119 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13121 (match_operand:SI 1 "arith_reg_operand" "r"))]
13124 [(set_attr "type" "ustore_media")])
13126 (define_insn "sthi_q64"
13127 [(set (zero_extract:DI
13128 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13131 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13133 (match_operand:DI 1 "arith_reg_operand" "r"))]
13136 [(set_attr "type" "ustore_media")])
13138 (define_insn "stlo_l64"
13139 [(set (zero_extract:SI
13140 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13142 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13143 (and:DI (match_dup 0) (const_int 3)))
13144 (match_operand:SI 1 "arith_reg_operand" "r"))]
13147 [(set_attr "type" "ustore_media")])
13149 (define_insn "stlo_q64"
13150 [(set (zero_extract:DI
13151 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13153 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13154 (and:DI (match_dup 0) (const_int 7)))
13155 (match_operand:DI 1 "arith_reg_operand" "r"))]
13158 [(set_attr "type" "ustore_media")])
13161 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13162 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13166 [(set_attr "type" "arith_media")])
13168 (define_insn "nsbsi"
13169 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13171 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13175 [(set_attr "type" "arith_media")])
13177 (define_insn "nsbdi"
13178 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13180 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13184 [(set_attr "type" "arith_media")])
13186 (define_expand "ffsdi2"
13187 [(set (match_operand:DI 0 "arith_reg_dest" "")
13188 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13192 rtx scratch = gen_reg_rtx (DImode);
13195 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13196 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13197 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13198 emit_insn (gen_nsbdi (scratch, scratch));
13199 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13200 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13201 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13202 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13207 (define_expand "ffssi2"
13208 [(set (match_operand:SI 0 "arith_reg_dest" "")
13209 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13213 rtx scratch = gen_reg_rtx (SImode);
13214 rtx discratch = gen_reg_rtx (DImode);
13217 emit_insn (gen_adddi3 (discratch,
13218 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13220 emit_insn (gen_andcdi3 (discratch,
13221 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13223 emit_insn (gen_nsbsi (scratch, discratch));
13224 last = emit_insn (gen_subsi3 (operands[0],
13225 force_reg (SImode, GEN_INT (63)), scratch));
13226 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13231 (define_insn "byterev"
13232 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13233 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13234 (parallel [(const_int 7) (const_int 6) (const_int 5)
13235 (const_int 4) (const_int 3) (const_int 2)
13236 (const_int 1) (const_int 0)])))]
13239 [(set_attr "type" "arith_media")])
13241 (define_insn "*prefetch_media"
13242 [(prefetch (match_operand:QI 0 "address_operand" "p")
13243 (match_operand:SI 1 "const_int_operand" "n")
13244 (match_operand:SI 2 "const_int_operand" "n"))]
13248 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13249 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13252 [(set_attr "type" "other")])
13254 (define_insn "*prefetch_i4"
13255 [(prefetch (match_operand:SI 0 "register_operand" "r")
13256 (match_operand:SI 1 "const_int_operand" "n")
13257 (match_operand:SI 2 "const_int_operand" "n"))]
13258 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13261 return \"pref @%0\";
13263 [(set_attr "type" "other")])
13265 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13266 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13267 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13268 (define_expand "prefetch"
13269 [(prefetch (match_operand 0 "address_operand" "p")
13270 (match_operand:SI 1 "const_int_operand" "n")
13271 (match_operand:SI 2 "const_int_operand" "n"))]
13272 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13273 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13276 if (GET_MODE (operands[0]) != Pmode
13277 || !CONST_INT_P (operands[1])
13278 || !CONST_INT_P (operands[2]))
13280 if (! TARGET_SHMEDIA)
13281 operands[0] = force_reg (Pmode, operands[0]);
13284 (define_insn "prefetch_m2a"
13285 [(prefetch (match_operand:SI 0 "register_operand" "r")
13286 (match_operand:SI 1 "const_int_operand" "n")
13287 (match_operand:SI 2 "const_int_operand" "n"))]
13290 [(set_attr "type" "other")])
13292 (define_insn "alloco_i"
13293 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13294 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13300 if (GET_CODE (operands[0]) == PLUS)
13302 xops[0] = XEXP (operands[0], 0);
13303 xops[1] = XEXP (operands[0], 1);
13307 xops[0] = operands[0];
13308 xops[1] = const0_rtx;
13310 output_asm_insn (\"alloco %0, %1\", xops);
13313 [(set_attr "type" "other")])
13316 [(set (match_operand 0 "any_register_operand" "")
13317 (match_operand 1 "" ""))]
13318 "TARGET_SHMEDIA && reload_completed"
13319 [(set (match_dup 0) (match_dup 1))]
13324 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13329 ; Stack Protector Patterns
13331 (define_expand "stack_protect_set"
13332 [(set (match_operand 0 "memory_operand" "")
13333 (match_operand 1 "memory_operand" ""))]
13336 if (TARGET_SHMEDIA)
13338 if (TARGET_SHMEDIA64)
13339 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13341 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13344 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13349 (define_insn "stack_protect_set_si"
13350 [(set (match_operand:SI 0 "memory_operand" "=m")
13351 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13352 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13354 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13355 [(set_attr "type" "other")
13356 (set_attr "length" "6")])
13358 (define_insn "stack_protect_set_si_media"
13359 [(set (match_operand:SI 0 "memory_operand" "=m")
13360 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13361 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13363 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13364 [(set_attr "type" "other")
13365 (set_attr "length" "12")])
13367 (define_insn "stack_protect_set_di_media"
13368 [(set (match_operand:DI 0 "memory_operand" "=m")
13369 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13370 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13372 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13373 [(set_attr "type" "other")
13374 (set_attr "length" "12")])
13376 (define_expand "stack_protect_test"
13377 [(match_operand 0 "memory_operand" "")
13378 (match_operand 1 "memory_operand" "")
13379 (match_operand 2 "" "")]
13382 if (TARGET_SHMEDIA)
13384 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13387 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13388 if (TARGET_SHMEDIA64)
13390 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13392 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13396 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13398 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13403 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13404 emit_jump_insn (gen_branch_true (operands[2]));
13410 (define_insn "stack_protect_test_si"
13411 [(set (reg:SI T_REG)
13412 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13413 (match_operand:SI 1 "memory_operand" "m")]
13415 (set (match_scratch:SI 2 "=&r") (const_int 0))
13416 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13418 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13419 [(set_attr "type" "other")
13420 (set_attr "length" "10")])
13422 (define_insn "stack_protect_test_si_media"
13423 [(set (match_operand:SI 0 "register_operand" "=&r")
13424 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13425 (match_operand:SI 2 "memory_operand" "m")]
13427 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13429 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13430 [(set_attr "type" "other")
13431 (set_attr "length" "16")])
13433 (define_insn "stack_protect_test_di_media"
13434 [(set (match_operand:DI 0 "register_operand" "=&r")
13435 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13436 (match_operand:DI 2 "memory_operand" "m")]
13438 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13440 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13441 [(set_attr "type" "other")
13442 (set_attr "length" "16")])