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 2 "arith_reg_dest" "0")
7055 (label_ref (match_operand 1 "" ""))
7057 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7058 (plus (match_dup 2) (const_int -1)))
7059 (clobber (reg:SI T_REG))]
7063 [(parallel [(set (reg:SI T_REG)
7064 (eq:SI (match_dup 2) (const_int 1)))
7065 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7066 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7067 (label_ref (match_dup 1))
7070 [(set_attr "type" "cbranch")])
7073 ;; ------------------------------------------------------------------------
7074 ;; Jump and linkage insns
7075 ;; ------------------------------------------------------------------------
7077 (define_insn "jump_compact"
7079 (label_ref (match_operand 0 "" "")))]
7080 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7083 /* The length is 16 if the delay slot is unfilled. */
7084 if (get_attr_length(insn) > 4)
7085 return output_far_jump(insn, operands[0]);
7087 return \"bra %l0%#\";
7089 [(set_attr "type" "jump")
7090 (set_attr "needs_delay_slot" "yes")])
7092 ;; ??? It would be much saner to explicitly use the scratch register
7093 ;; in the jump insn, and have indirect_jump_scratch only set it,
7094 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7095 ;; from the target then, as it uses simplejump_p.
7096 ;;(define_insn "jump_compact_far"
7098 ;; (label_ref (match_operand 0 "" "")))
7099 ;; (use (match_operand 1 "register_operand" "r")]
7101 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7102 ;; [(set_attr "type" "jump")
7103 ;; (set_attr "needs_delay_slot" "yes")])
7105 (define_insn "jump_media"
7107 (match_operand 0 "target_operand" "b"))]
7110 [(set_attr "type" "jump_media")])
7112 (define_expand "jump"
7114 (label_ref (match_operand 0 "" "")))]
7119 emit_jump_insn (gen_jump_compact (operands[0]));
7120 else if (TARGET_SHMEDIA)
7122 if (reload_in_progress || reload_completed)
7124 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7130 (define_insn "force_mode_for_call"
7131 [(use (reg:PSI FPSCR_REG))]
7134 [(set_attr "length" "0")
7135 (set (attr "fp_mode")
7136 (if_then_else (eq_attr "fpu_single" "yes")
7137 (const_string "single") (const_string "double")))])
7139 (define_insn "calli"
7140 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7141 (match_operand 1 "" ""))
7142 (use (reg:PSI FPSCR_REG))
7143 (clobber (reg:SI PR_REG))]
7147 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7148 return \"jsr/n\\t@%0\";
7150 return \"jsr\\t@%0%#\";
7153 [(set_attr "type" "call")
7154 (set (attr "fp_mode")
7155 (if_then_else (eq_attr "fpu_single" "yes")
7156 (const_string "single") (const_string "double")))
7157 (set_attr "needs_delay_slot" "yes")
7158 (set_attr "fp_set" "unknown")])
7160 ;; This is TBR relative jump instruction for SH2A architecture.
7161 ;; Its use is enabled assigning an attribute "function_vector"
7162 ;; and the vector number to a function during its declaration.
7164 (define_insn "calli_tbr_rel"
7165 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7166 (match_operand 1 "" ""))
7167 (use (reg:PSI FPSCR_REG))
7168 (clobber (reg:SI PR_REG))]
7169 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7172 unsigned HOST_WIDE_INT vect_num;
7173 vect_num = sh2a_get_function_vector_number (operands[0]);
7174 operands[2] = GEN_INT (vect_num * 4);
7176 return \"jsr/n\\t@@(%O2,tbr)\";
7178 [(set_attr "type" "call")
7179 (set (attr "fp_mode")
7180 (if_then_else (eq_attr "fpu_single" "yes")
7181 (const_string "single") (const_string "double")))
7182 (set_attr "needs_delay_slot" "no")
7183 (set_attr "fp_set" "unknown")])
7185 ;; This is a pc-rel call, using bsrf, for use with PIC.
7187 (define_insn "calli_pcrel"
7188 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7189 (match_operand 1 "" ""))
7190 (use (reg:PSI FPSCR_REG))
7191 (use (reg:SI PIC_REG))
7192 (use (match_operand 2 "" ""))
7193 (clobber (reg:SI PR_REG))]
7196 [(set_attr "type" "call")
7197 (set (attr "fp_mode")
7198 (if_then_else (eq_attr "fpu_single" "yes")
7199 (const_string "single") (const_string "double")))
7200 (set_attr "needs_delay_slot" "yes")
7201 (set_attr "fp_set" "unknown")])
7203 (define_insn_and_split "call_pcrel"
7204 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7205 (match_operand 1 "" ""))
7206 (use (reg:PSI FPSCR_REG))
7207 (use (reg:SI PIC_REG))
7208 (clobber (reg:SI PR_REG))
7209 (clobber (match_scratch:SI 2 "=r"))]
7216 rtx lab = PATTERN (gen_call_site ());
7218 if (SYMBOL_REF_LOCAL_P (operands[0]))
7219 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7221 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7222 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7225 [(set_attr "type" "call")
7226 (set (attr "fp_mode")
7227 (if_then_else (eq_attr "fpu_single" "yes")
7228 (const_string "single") (const_string "double")))
7229 (set_attr "needs_delay_slot" "yes")
7230 (set_attr "fp_set" "unknown")])
7232 (define_insn "call_compact"
7233 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7234 (match_operand 1 "" ""))
7235 (match_operand 2 "immediate_operand" "n")
7236 (use (reg:SI R0_REG))
7237 (use (reg:SI R1_REG))
7238 (use (reg:PSI FPSCR_REG))
7239 (clobber (reg:SI PR_REG))]
7240 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7242 [(set_attr "type" "call")
7243 (set (attr "fp_mode")
7244 (if_then_else (eq_attr "fpu_single" "yes")
7245 (const_string "single") (const_string "double")))
7246 (set_attr "needs_delay_slot" "yes")])
7248 (define_insn "call_compact_rettramp"
7249 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7250 (match_operand 1 "" ""))
7251 (match_operand 2 "immediate_operand" "n")
7252 (use (reg:SI R0_REG))
7253 (use (reg:SI R1_REG))
7254 (use (reg:PSI FPSCR_REG))
7255 (clobber (reg:SI R10_REG))
7256 (clobber (reg:SI PR_REG))]
7257 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7259 [(set_attr "type" "call")
7260 (set (attr "fp_mode")
7261 (if_then_else (eq_attr "fpu_single" "yes")
7262 (const_string "single") (const_string "double")))
7263 (set_attr "needs_delay_slot" "yes")])
7265 (define_insn "call_media"
7266 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7267 (match_operand 1 "" ""))
7268 (clobber (reg:DI PR_MEDIA_REG))]
7271 [(set_attr "type" "jump_media")])
7273 (define_insn "call_valuei"
7274 [(set (match_operand 0 "" "=rf")
7275 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7276 (match_operand 2 "" "")))
7277 (use (reg:PSI FPSCR_REG))
7278 (clobber (reg:SI PR_REG))]
7282 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7283 return \"jsr/n\\t@%1\";
7285 return \"jsr\\t@%1%#\";
7287 [(set_attr "type" "call")
7288 (set (attr "fp_mode")
7289 (if_then_else (eq_attr "fpu_single" "yes")
7290 (const_string "single") (const_string "double")))
7291 (set_attr "needs_delay_slot" "yes")
7292 (set_attr "fp_set" "unknown")])
7294 ;; This is TBR relative jump instruction for SH2A architecture.
7295 ;; Its use is enabled assigning an attribute "function_vector"
7296 ;; and the vector number to a function during its declaration.
7298 (define_insn "call_valuei_tbr_rel"
7299 [(set (match_operand 0 "" "=rf")
7300 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7301 (match_operand 2 "" "")))
7302 (use (reg:PSI FPSCR_REG))
7303 (clobber (reg:SI PR_REG))]
7304 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7307 unsigned HOST_WIDE_INT vect_num;
7308 vect_num = sh2a_get_function_vector_number (operands[1]);
7309 operands[3] = GEN_INT (vect_num * 4);
7311 return \"jsr/n\\t@@(%O3,tbr)\";
7313 [(set_attr "type" "call")
7314 (set (attr "fp_mode")
7315 (if_then_else (eq_attr "fpu_single" "yes")
7316 (const_string "single") (const_string "double")))
7317 (set_attr "needs_delay_slot" "no")
7318 (set_attr "fp_set" "unknown")])
7320 (define_insn "call_valuei_pcrel"
7321 [(set (match_operand 0 "" "=rf")
7322 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7323 (match_operand 2 "" "")))
7324 (use (reg:PSI FPSCR_REG))
7325 (use (reg:SI PIC_REG))
7326 (use (match_operand 3 "" ""))
7327 (clobber (reg:SI PR_REG))]
7330 [(set_attr "type" "call")
7331 (set (attr "fp_mode")
7332 (if_then_else (eq_attr "fpu_single" "yes")
7333 (const_string "single") (const_string "double")))
7334 (set_attr "needs_delay_slot" "yes")
7335 (set_attr "fp_set" "unknown")])
7337 (define_insn_and_split "call_value_pcrel"
7338 [(set (match_operand 0 "" "=rf")
7339 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7340 (match_operand 2 "" "")))
7341 (use (reg:PSI FPSCR_REG))
7342 (use (reg:SI PIC_REG))
7343 (clobber (reg:SI PR_REG))
7344 (clobber (match_scratch:SI 3 "=r"))]
7351 rtx lab = PATTERN (gen_call_site ());
7353 if (SYMBOL_REF_LOCAL_P (operands[1]))
7354 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7356 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7357 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7358 operands[2], copy_rtx (lab)));
7361 [(set_attr "type" "call")
7362 (set (attr "fp_mode")
7363 (if_then_else (eq_attr "fpu_single" "yes")
7364 (const_string "single") (const_string "double")))
7365 (set_attr "needs_delay_slot" "yes")
7366 (set_attr "fp_set" "unknown")])
7368 (define_insn "call_value_compact"
7369 [(set (match_operand 0 "" "=rf")
7370 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7371 (match_operand 2 "" "")))
7372 (match_operand 3 "immediate_operand" "n")
7373 (use (reg:SI R0_REG))
7374 (use (reg:SI R1_REG))
7375 (use (reg:PSI FPSCR_REG))
7376 (clobber (reg:SI PR_REG))]
7377 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7379 [(set_attr "type" "call")
7380 (set (attr "fp_mode")
7381 (if_then_else (eq_attr "fpu_single" "yes")
7382 (const_string "single") (const_string "double")))
7383 (set_attr "needs_delay_slot" "yes")])
7385 (define_insn "call_value_compact_rettramp"
7386 [(set (match_operand 0 "" "=rf")
7387 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7388 (match_operand 2 "" "")))
7389 (match_operand 3 "immediate_operand" "n")
7390 (use (reg:SI R0_REG))
7391 (use (reg:SI R1_REG))
7392 (use (reg:PSI FPSCR_REG))
7393 (clobber (reg:SI R10_REG))
7394 (clobber (reg:SI PR_REG))]
7395 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7397 [(set_attr "type" "call")
7398 (set (attr "fp_mode")
7399 (if_then_else (eq_attr "fpu_single" "yes")
7400 (const_string "single") (const_string "double")))
7401 (set_attr "needs_delay_slot" "yes")])
7403 (define_insn "call_value_media"
7404 [(set (match_operand 0 "" "=rf")
7405 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7406 (match_operand 2 "" "")))
7407 (clobber (reg:DI PR_MEDIA_REG))]
7410 [(set_attr "type" "jump_media")])
7412 (define_expand "call"
7413 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7414 (match_operand 1 "" ""))
7415 (match_operand 2 "" "")
7416 (use (reg:PSI FPSCR_REG))
7417 (clobber (reg:SI PR_REG))])]
7423 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7424 emit_call_insn (gen_call_media (operands[0], operands[1]));
7427 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7429 rtx cookie_rtx = operands[2];
7430 long cookie = INTVAL (cookie_rtx);
7431 rtx func = XEXP (operands[0], 0);
7436 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7438 rtx reg = gen_reg_rtx (Pmode);
7440 emit_insn (gen_symGOTPLT2reg (reg, func));
7444 func = legitimize_pic_address (func, Pmode, 0);
7447 r0 = gen_rtx_REG (SImode, R0_REG);
7448 r1 = gen_rtx_REG (SImode, R1_REG);
7450 /* Since such a call function may use all call-clobbered
7451 registers, we force a mode switch earlier, so that we don't
7452 run out of registers when adjusting fpscr for the call. */
7453 emit_insn (gen_force_mode_for_call ());
7456 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7458 operands[0] = force_reg (SImode, operands[0]);
7460 emit_move_insn (r0, func);
7461 emit_move_insn (r1, cookie_rtx);
7463 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7464 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7467 emit_call_insn (gen_call_compact (operands[0], operands[1],
7472 else if (TARGET_SHCOMPACT && flag_pic
7473 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7474 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7476 rtx reg = gen_reg_rtx (Pmode);
7478 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7479 XEXP (operands[0], 0) = reg;
7481 if (!flag_pic && TARGET_SH2A
7482 && MEM_P (operands[0])
7483 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7485 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7487 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7492 if (flag_pic && TARGET_SH2
7493 && MEM_P (operands[0])
7494 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7496 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7501 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7502 operands[1] = operands[2];
7505 emit_call_insn (gen_calli (operands[0], operands[1]));
7509 (define_insn "call_pop_compact"
7510 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511 (match_operand 1 "" ""))
7512 (match_operand 2 "immediate_operand" "n")
7513 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514 (match_operand 3 "immediate_operand" "n")))
7515 (use (reg:SI R0_REG))
7516 (use (reg:SI R1_REG))
7517 (use (reg:PSI FPSCR_REG))
7518 (clobber (reg:SI PR_REG))]
7519 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521 [(set_attr "type" "call")
7522 (set (attr "fp_mode")
7523 (if_then_else (eq_attr "fpu_single" "yes")
7524 (const_string "single") (const_string "double")))
7525 (set_attr "needs_delay_slot" "yes")])
7527 (define_insn "call_pop_compact_rettramp"
7528 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7529 (match_operand 1 "" ""))
7530 (match_operand 2 "immediate_operand" "n")
7531 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7532 (match_operand 3 "immediate_operand" "n")))
7533 (use (reg:SI R0_REG))
7534 (use (reg:SI R1_REG))
7535 (use (reg:PSI FPSCR_REG))
7536 (clobber (reg:SI R10_REG))
7537 (clobber (reg:SI PR_REG))]
7538 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7540 [(set_attr "type" "call")
7541 (set (attr "fp_mode")
7542 (if_then_else (eq_attr "fpu_single" "yes")
7543 (const_string "single") (const_string "double")))
7544 (set_attr "needs_delay_slot" "yes")])
7546 (define_expand "call_pop"
7547 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7548 (match_operand 1 "" ""))
7549 (match_operand 2 "" "")
7550 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7551 (match_operand 3 "" "")))])]
7560 gcc_assert (operands[2] && INTVAL (operands[2]));
7561 cookie_rtx = operands[2];
7562 cookie = INTVAL (cookie_rtx);
7563 func = XEXP (operands[0], 0);
7567 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7569 rtx reg = gen_reg_rtx (Pmode);
7570 emit_insn (gen_symGOTPLT2reg (reg, func));
7574 func = legitimize_pic_address (func, Pmode, 0);
7577 r0 = gen_rtx_REG (SImode, R0_REG);
7578 r1 = gen_rtx_REG (SImode, R1_REG);
7580 /* Since such a call function may use all call-clobbered
7581 registers, we force a mode switch earlier, so that we don't
7582 run out of registers when adjusting fpscr for the call. */
7583 emit_insn (gen_force_mode_for_call ());
7585 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7587 operands[0] = force_reg (SImode, operands[0]);
7589 emit_move_insn (r0, func);
7590 emit_move_insn (r1, cookie_rtx);
7592 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7593 emit_call_insn (gen_call_pop_compact_rettramp
7594 (operands[0], operands[1], operands[2], operands[3]));
7596 emit_call_insn (gen_call_pop_compact
7597 (operands[0], operands[1], operands[2], operands[3]));
7602 (define_expand "call_value"
7603 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7604 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7605 (match_operand 2 "" "")))
7606 (match_operand 3 "" "")
7607 (use (reg:PSI FPSCR_REG))
7608 (clobber (reg:SI PR_REG))])]
7614 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7615 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7619 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7621 rtx cookie_rtx = operands[3];
7622 long cookie = INTVAL (cookie_rtx);
7623 rtx func = XEXP (operands[1], 0);
7628 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7630 rtx reg = gen_reg_rtx (Pmode);
7632 emit_insn (gen_symGOTPLT2reg (reg, func));
7636 func = legitimize_pic_address (func, Pmode, 0);
7639 r0 = gen_rtx_REG (SImode, R0_REG);
7640 r1 = gen_rtx_REG (SImode, R1_REG);
7642 /* Since such a call function may use all call-clobbered
7643 registers, we force a mode switch earlier, so that we don't
7644 run out of registers when adjusting fpscr for the call. */
7645 emit_insn (gen_force_mode_for_call ());
7648 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7650 operands[1] = force_reg (SImode, operands[1]);
7652 emit_move_insn (r0, func);
7653 emit_move_insn (r1, cookie_rtx);
7655 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7656 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7661 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7662 operands[2], operands[3]));
7666 else if (TARGET_SHCOMPACT && flag_pic
7667 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7668 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7670 rtx reg = gen_reg_rtx (Pmode);
7672 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7673 XEXP (operands[1], 0) = reg;
7675 if (!flag_pic && TARGET_SH2A
7676 && MEM_P (operands[1])
7677 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7679 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7681 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7682 XEXP (operands[1], 0), operands[2]));
7686 if (flag_pic && TARGET_SH2
7687 && MEM_P (operands[1])
7688 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7690 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7695 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7697 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7701 (define_insn "sibcalli"
7702 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7703 (match_operand 1 "" ""))
7704 (use (reg:PSI FPSCR_REG))
7708 [(set_attr "needs_delay_slot" "yes")
7709 (set (attr "fp_mode")
7710 (if_then_else (eq_attr "fpu_single" "yes")
7711 (const_string "single") (const_string "double")))
7712 (set_attr "type" "jump_ind")])
7714 (define_insn "sibcalli_pcrel"
7715 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7716 (match_operand 1 "" ""))
7717 (use (match_operand 2 "" ""))
7718 (use (reg:PSI FPSCR_REG))
7722 [(set_attr "needs_delay_slot" "yes")
7723 (set (attr "fp_mode")
7724 (if_then_else (eq_attr "fpu_single" "yes")
7725 (const_string "single") (const_string "double")))
7726 (set_attr "type" "jump_ind")])
7728 ;; This uses an unspec to describe that the symbol_ref is very close.
7729 (define_insn "sibcalli_thunk"
7730 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7732 (match_operand 1 "" ""))
7733 (use (reg:PSI FPSCR_REG))
7737 [(set_attr "needs_delay_slot" "yes")
7738 (set (attr "fp_mode")
7739 (if_then_else (eq_attr "fpu_single" "yes")
7740 (const_string "single") (const_string "double")))
7741 (set_attr "type" "jump")
7742 (set_attr "length" "2")])
7744 (define_insn_and_split "sibcall_pcrel"
7745 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7746 (match_operand 1 "" ""))
7747 (use (reg:PSI FPSCR_REG))
7748 (clobber (match_scratch:SI 2 "=k"))
7756 rtx lab = PATTERN (gen_call_site ());
7759 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7760 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7762 SIBLING_CALL_P (call_insn) = 1;
7765 [(set_attr "needs_delay_slot" "yes")
7766 (set (attr "fp_mode")
7767 (if_then_else (eq_attr "fpu_single" "yes")
7768 (const_string "single") (const_string "double")))
7769 (set_attr "type" "jump_ind")])
7771 (define_insn "sibcall_compact"
7772 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7773 (match_operand 1 "" ""))
7775 (use (match_operand:SI 2 "register_operand" "z,x"))
7776 (use (reg:SI R1_REG))
7777 (use (reg:PSI FPSCR_REG))
7778 ;; We want to make sure the `x' above will only match MACH_REG
7779 ;; because sibcall_epilogue may clobber MACL_REG.
7780 (clobber (reg:SI MACL_REG))]
7784 jmp @%0\\n sts %2, r0"
7785 [(set_attr "needs_delay_slot" "yes,no")
7786 (set_attr "length" "2,4")
7787 (set (attr "fp_mode") (const_string "single"))
7788 (set_attr "type" "jump_ind")])
7790 (define_insn "sibcall_media"
7791 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7792 (match_operand 1 "" ""))
7793 (use (reg:SI PR_MEDIA_REG))
7797 [(set_attr "type" "jump_media")])
7799 (define_expand "sibcall"
7801 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7802 (match_operand 1 "" ""))
7803 (match_operand 2 "" "")
7804 (use (reg:PSI FPSCR_REG))
7811 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7812 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7815 else if (TARGET_SHCOMPACT && operands[2]
7816 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7818 rtx cookie_rtx = operands[2];
7819 long cookie = INTVAL (cookie_rtx);
7820 rtx func = XEXP (operands[0], 0);
7825 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7827 rtx reg = gen_reg_rtx (Pmode);
7829 emit_insn (gen_symGOT2reg (reg, func));
7833 func = legitimize_pic_address (func, Pmode, 0);
7836 /* FIXME: if we could tell whether all argument registers are
7837 already taken, we could decide whether to force the use of
7838 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7839 simple way to tell. We could use the CALL_COOKIE, but we
7840 can't currently tell a register used for regular argument
7841 passing from one that is unused. If we leave it up to reload
7842 to decide which register to use, it seems to always choose
7843 R0_REG, which leaves no available registers in SIBCALL_REGS
7844 to hold the address of the trampoline. */
7845 mach = gen_rtx_REG (SImode, MACH_REG);
7846 r1 = gen_rtx_REG (SImode, R1_REG);
7848 /* Since such a call function may use all call-clobbered
7849 registers, we force a mode switch earlier, so that we don't
7850 run out of registers when adjusting fpscr for the call. */
7851 emit_insn (gen_force_mode_for_call ());
7854 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7856 operands[0] = force_reg (SImode, operands[0]);
7858 /* We don't need a return trampoline, since the callee will
7859 return directly to the upper caller. */
7860 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7862 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7863 cookie_rtx = GEN_INT (cookie);
7866 emit_move_insn (mach, func);
7867 emit_move_insn (r1, cookie_rtx);
7869 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7872 else if (TARGET_SHCOMPACT && flag_pic
7873 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7874 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7876 rtx reg = gen_reg_rtx (Pmode);
7878 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7879 XEXP (operands[0], 0) = reg;
7881 if (flag_pic && TARGET_SH2
7882 && MEM_P (operands[0])
7883 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7884 /* The PLT needs the PIC register, but the epilogue would have
7885 to restore it, so we can only use PC-relative PIC calls for
7886 static functions. */
7887 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7889 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7893 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7895 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7899 (define_insn "sibcall_valuei"
7900 [(set (match_operand 0 "" "=rf")
7901 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7902 (match_operand 2 "" "")))
7903 (use (reg:PSI FPSCR_REG))
7907 [(set_attr "needs_delay_slot" "yes")
7908 (set (attr "fp_mode")
7909 (if_then_else (eq_attr "fpu_single" "yes")
7910 (const_string "single") (const_string "double")))
7911 (set_attr "type" "jump_ind")])
7913 (define_insn "sibcall_valuei_pcrel"
7914 [(set (match_operand 0 "" "=rf")
7915 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7916 (match_operand 2 "" "")))
7917 (use (match_operand 3 "" ""))
7918 (use (reg:PSI FPSCR_REG))
7922 [(set_attr "needs_delay_slot" "yes")
7923 (set (attr "fp_mode")
7924 (if_then_else (eq_attr "fpu_single" "yes")
7925 (const_string "single") (const_string "double")))
7926 (set_attr "type" "jump_ind")])
7928 (define_insn_and_split "sibcall_value_pcrel"
7929 [(set (match_operand 0 "" "=rf")
7930 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7931 (match_operand 2 "" "")))
7932 (use (reg:PSI FPSCR_REG))
7933 (clobber (match_scratch:SI 3 "=k"))
7941 rtx lab = PATTERN (gen_call_site ());
7944 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7945 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7949 SIBLING_CALL_P (call_insn) = 1;
7952 [(set_attr "needs_delay_slot" "yes")
7953 (set (attr "fp_mode")
7954 (if_then_else (eq_attr "fpu_single" "yes")
7955 (const_string "single") (const_string "double")))
7956 (set_attr "type" "jump_ind")])
7958 (define_insn "sibcall_value_compact"
7959 [(set (match_operand 0 "" "=rf,rf")
7960 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7961 (match_operand 2 "" "")))
7963 (use (match_operand:SI 3 "register_operand" "z,x"))
7964 (use (reg:SI R1_REG))
7965 (use (reg:PSI FPSCR_REG))
7966 ;; We want to make sure the `x' above will only match MACH_REG
7967 ;; because sibcall_epilogue may clobber MACL_REG.
7968 (clobber (reg:SI MACL_REG))]
7972 jmp @%1\\n sts %3, r0"
7973 [(set_attr "needs_delay_slot" "yes,no")
7974 (set_attr "length" "2,4")
7975 (set (attr "fp_mode") (const_string "single"))
7976 (set_attr "type" "jump_ind")])
7978 (define_insn "sibcall_value_media"
7979 [(set (match_operand 0 "" "=rf")
7980 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7981 (match_operand 2 "" "")))
7982 (use (reg:SI PR_MEDIA_REG))
7986 [(set_attr "type" "jump_media")])
7988 (define_expand "sibcall_value"
7990 [(set (match_operand 0 "arith_reg_operand" "")
7991 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7992 (match_operand 2 "" "")))
7993 (match_operand 3 "" "")
7994 (use (reg:PSI FPSCR_REG))
8001 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8002 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8006 else if (TARGET_SHCOMPACT && operands[3]
8007 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8009 rtx cookie_rtx = operands[3];
8010 long cookie = INTVAL (cookie_rtx);
8011 rtx func = XEXP (operands[1], 0);
8016 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8018 rtx reg = gen_reg_rtx (Pmode);
8020 emit_insn (gen_symGOT2reg (reg, func));
8024 func = legitimize_pic_address (func, Pmode, 0);
8027 /* FIXME: if we could tell whether all argument registers are
8028 already taken, we could decide whether to force the use of
8029 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8030 simple way to tell. We could use the CALL_COOKIE, but we
8031 can't currently tell a register used for regular argument
8032 passing from one that is unused. If we leave it up to reload
8033 to decide which register to use, it seems to always choose
8034 R0_REG, which leaves no available registers in SIBCALL_REGS
8035 to hold the address of the trampoline. */
8036 mach = gen_rtx_REG (SImode, MACH_REG);
8037 r1 = gen_rtx_REG (SImode, R1_REG);
8039 /* Since such a call function may use all call-clobbered
8040 registers, we force a mode switch earlier, so that we don't
8041 run out of registers when adjusting fpscr for the call. */
8042 emit_insn (gen_force_mode_for_call ());
8045 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8047 operands[1] = force_reg (SImode, operands[1]);
8049 /* We don't need a return trampoline, since the callee will
8050 return directly to the upper caller. */
8051 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8053 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8054 cookie_rtx = GEN_INT (cookie);
8057 emit_move_insn (mach, func);
8058 emit_move_insn (r1, cookie_rtx);
8060 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8061 operands[2], mach));
8064 else if (TARGET_SHCOMPACT && flag_pic
8065 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8066 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8068 rtx reg = gen_reg_rtx (Pmode);
8070 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8071 XEXP (operands[1], 0) = reg;
8073 if (flag_pic && TARGET_SH2
8074 && MEM_P (operands[1])
8075 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8076 /* The PLT needs the PIC register, but the epilogue would have
8077 to restore it, so we can only use PC-relative PIC calls for
8078 static functions. */
8079 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8081 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8082 XEXP (operands[1], 0),
8087 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8089 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8093 (define_insn "call_value_pop_compact"
8094 [(set (match_operand 0 "" "=rf")
8095 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8096 (match_operand 2 "" "")))
8097 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8098 (match_operand 4 "immediate_operand" "n")))
8099 (match_operand 3 "immediate_operand" "n")
8100 (use (reg:SI R0_REG))
8101 (use (reg:SI R1_REG))
8102 (use (reg:PSI FPSCR_REG))
8103 (clobber (reg:SI PR_REG))]
8104 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8106 [(set_attr "type" "call")
8107 (set (attr "fp_mode")
8108 (if_then_else (eq_attr "fpu_single" "yes")
8109 (const_string "single") (const_string "double")))
8110 (set_attr "needs_delay_slot" "yes")])
8112 (define_insn "call_value_pop_compact_rettramp"
8113 [(set (match_operand 0 "" "=rf")
8114 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8115 (match_operand 2 "" "")))
8116 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8117 (match_operand 4 "immediate_operand" "n")))
8118 (match_operand 3 "immediate_operand" "n")
8119 (use (reg:SI R0_REG))
8120 (use (reg:SI R1_REG))
8121 (use (reg:PSI FPSCR_REG))
8122 (clobber (reg:SI R10_REG))
8123 (clobber (reg:SI PR_REG))]
8124 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8126 [(set_attr "type" "call")
8127 (set (attr "fp_mode")
8128 (if_then_else (eq_attr "fpu_single" "yes")
8129 (const_string "single") (const_string "double")))
8130 (set_attr "needs_delay_slot" "yes")])
8132 (define_expand "call_value_pop"
8133 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8134 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8135 (match_operand 2 "" "")))
8136 (match_operand 3 "" "")
8137 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8138 (match_operand 4 "" "")))])]
8147 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8148 cookie_rtx = operands[3];
8149 cookie = INTVAL (cookie_rtx);
8150 func = XEXP (operands[1], 0);
8154 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8156 rtx reg = gen_reg_rtx (Pmode);
8158 emit_insn (gen_symGOTPLT2reg (reg, func));
8162 func = legitimize_pic_address (func, Pmode, 0);
8165 r0 = gen_rtx_REG (SImode, R0_REG);
8166 r1 = gen_rtx_REG (SImode, R1_REG);
8168 /* Since such a call function may use all call-clobbered
8169 registers, we force a mode switch earlier, so that we don't
8170 run out of registers when adjusting fpscr for the call. */
8171 emit_insn (gen_force_mode_for_call ());
8173 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8175 operands[1] = force_reg (SImode, operands[1]);
8177 emit_move_insn (r0, func);
8178 emit_move_insn (r1, cookie_rtx);
8180 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8181 emit_call_insn (gen_call_value_pop_compact_rettramp
8182 (operands[0], operands[1], operands[2],
8183 operands[3], operands[4]));
8185 emit_call_insn (gen_call_value_pop_compact
8186 (operands[0], operands[1], operands[2],
8187 operands[3], operands[4]));
8192 (define_expand "sibcall_epilogue"
8197 sh_expand_epilogue (1);
8198 if (TARGET_SHCOMPACT)
8202 /* If epilogue clobbers r0, preserve it in macl. */
8203 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8204 if ((set = single_set (insn))
8205 && REG_P (SET_DEST (set))
8206 && REGNO (SET_DEST (set)) == R0_REG)
8208 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8209 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8211 /* We can't tell at this point whether the sibcall is a
8212 sibcall_compact and, if it is, whether it uses r0 or
8213 mach as operand 2, so let the instructions that
8214 preserve r0 be optimized away if r0 turns out to be
8216 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8217 emit_move_insn (r0, tmp);
8224 (define_insn "indirect_jump_compact"
8226 (match_operand:SI 0 "arith_reg_operand" "r"))]
8229 [(set_attr "needs_delay_slot" "yes")
8230 (set_attr "type" "jump_ind")])
8232 (define_expand "indirect_jump"
8234 (match_operand 0 "register_operand" ""))]
8238 if (GET_MODE (operands[0]) != Pmode)
8239 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8242 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8243 ;; which can be present in structured code from indirect jumps which can not
8244 ;; be present in structured code. This allows -fprofile-arcs to work.
8246 ;; For SH1 processors.
8247 (define_insn "casesi_jump_1"
8249 (match_operand:SI 0 "register_operand" "r"))
8250 (use (label_ref (match_operand 1 "" "")))]
8253 [(set_attr "needs_delay_slot" "yes")
8254 (set_attr "type" "jump_ind")])
8256 ;; For all later processors.
8257 (define_insn "casesi_jump_2"
8258 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8259 (label_ref (match_operand 1 "" ""))))
8260 (use (label_ref (match_operand 2 "" "")))]
8262 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8264 [(set_attr "needs_delay_slot" "yes")
8265 (set_attr "type" "jump_ind")])
8267 (define_insn "casesi_jump_media"
8268 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8269 (use (label_ref (match_operand 1 "" "")))]
8272 [(set_attr "type" "jump_media")])
8274 ;; Call subroutine returning any type.
8275 ;; ??? This probably doesn't work.
8277 (define_expand "untyped_call"
8278 [(parallel [(call (match_operand 0 "" "")
8280 (match_operand 1 "" "")
8281 (match_operand 2 "" "")])]
8282 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8287 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8289 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8291 rtx set = XVECEXP (operands[2], 0, i);
8292 emit_move_insn (SET_DEST (set), SET_SRC (set));
8295 /* The optimizer does not know that the call sets the function value
8296 registers we stored in the result block. We avoid problems by
8297 claiming that all hard registers are used and clobbered at this
8299 emit_insn (gen_blockage ());
8304 ;; ------------------------------------------------------------------------
8306 ;; ------------------------------------------------------------------------
8309 [(set (reg:SI T_REG)
8310 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8311 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8312 (plus:SI (match_dup 1) (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 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 "" "")]
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 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8700 (define_expand "sym2GOTTPOFF"
8701 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8705 (define_insn "tls_initial_exec"
8706 [(set (match_operand:SI 0 "register_operand" "=&r")
8707 (unspec:SI [(match_operand:SI 1 "" "")]
8709 (use (reg:SI GBR_REG))
8710 (use (reg:SI PIC_REG))
8711 (clobber (reg:SI R0_REG))]
8717 \\tstc\\tgbr,%0\\n\\
8718 \\tmov.l\\t@(r0,r12),r0\\n\\
8722 1:\\t.long\\t%a1\\n\\
8725 [(set_attr "type" "tls_load")
8726 (set_attr "length" "16")])
8728 (define_expand "sym2TPOFF"
8729 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8733 (define_expand "symTPOFF2reg"
8734 [(match_operand 0 "" "") (match_operand 1 "" "")]
8740 tpoffsym = gen_sym2TPOFF (operands[1]);
8741 PUT_MODE (tpoffsym, Pmode);
8742 emit_move_insn (operands[0], tpoffsym);
8746 (define_insn "load_gbr"
8747 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8748 (use (reg:SI GBR_REG))]
8751 [(set_attr "type" "tls_load")])
8753 ;; case instruction for switch statements.
8755 ;; Operand 0 is index
8756 ;; operand 1 is the minimum bound
8757 ;; operand 2 is the maximum bound - minimum bound + 1
8758 ;; operand 3 is CODE_LABEL for the table;
8759 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8761 (define_expand "casesi"
8762 [(match_operand:SI 0 "arith_reg_operand" "")
8763 (match_operand:SI 1 "arith_reg_operand" "")
8764 (match_operand:SI 2 "arith_reg_operand" "")
8765 (match_operand 3 "" "") (match_operand 4 "" "")]
8769 rtx reg = gen_reg_rtx (SImode);
8770 rtx reg2 = gen_reg_rtx (SImode);
8773 rtx reg = gen_reg_rtx (DImode);
8774 rtx reg2 = gen_reg_rtx (DImode);
8775 rtx reg3 = gen_reg_rtx (Pmode);
8776 rtx reg4 = gen_reg_rtx (Pmode);
8777 rtx reg5 = gen_reg_rtx (Pmode);
8780 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8781 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8782 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8784 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8785 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8786 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8787 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8788 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8789 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8790 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8791 (Pmode, operands[3])));
8792 /* Messy: can we subreg to clean this up? */
8793 if (Pmode == DImode)
8794 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8796 load = gen_casesi_load_media (reg4,
8797 gen_rtx_SUBREG (DImode, reg3, 0),
8799 PUT_MODE (SET_SRC (load), Pmode);
8801 /* ??? The following add could be eliminated if we used ptrel. */
8802 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8803 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8807 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8808 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8809 /* If optimizing, casesi_worker depends on the mode of the instruction
8810 before label it 'uses' - operands[3]. */
8811 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8813 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8815 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8817 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8818 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8819 operands[3], but to lab. We will fix this up in
8820 machine_dependent_reorg. */
8825 (define_expand "casesi_0"
8826 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8827 (set (match_dup 4) (minus:SI (match_dup 4)
8828 (match_operand:SI 1 "arith_operand" "")))
8830 (gtu:SI (match_dup 4)
8831 (match_operand:SI 2 "arith_reg_operand" "")))
8833 (if_then_else (ne (reg:SI T_REG)
8835 (label_ref (match_operand 3 "" ""))
8840 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8841 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8842 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8844 (define_insn "casesi_worker_0"
8845 [(set (match_operand:SI 0 "register_operand" "=r,r")
8846 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8847 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8848 (clobber (match_scratch:SI 3 "=X,1"))
8849 (clobber (match_scratch:SI 4 "=&z,z"))]
8854 [(set (match_operand:SI 0 "register_operand" "")
8855 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8856 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8857 (clobber (match_scratch:SI 3 ""))
8858 (clobber (match_scratch:SI 4 ""))]
8859 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8860 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8861 (parallel [(set (match_dup 0)
8862 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8863 (label_ref (match_dup 2))] UNSPEC_CASESI))
8864 (clobber (match_dup 3))])
8865 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8866 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8869 [(set (match_operand:SI 0 "register_operand" "")
8870 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8871 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8872 (clobber (match_scratch:SI 3 ""))
8873 (clobber (match_scratch:SI 4 ""))]
8874 "TARGET_SH2 && reload_completed"
8875 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8876 (parallel [(set (match_dup 0)
8877 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8878 (label_ref (match_dup 2))] UNSPEC_CASESI))
8879 (clobber (match_dup 3))])]
8880 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8882 (define_insn "casesi_worker_1"
8883 [(set (match_operand:SI 0 "register_operand" "=r,r")
8884 (unspec:SI [(reg:SI R0_REG)
8885 (match_operand:SI 1 "register_operand" "0,r")
8886 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8887 (clobber (match_scratch:SI 3 "=X,1"))]
8891 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8893 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8895 switch (GET_MODE (diff_vec))
8898 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8900 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8902 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8903 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8904 return \"mov.b @(r0,%1),%0\";
8909 [(set_attr "length" "4")])
8911 (define_insn "casesi_worker_2"
8912 [(set (match_operand:SI 0 "register_operand" "=r,r")
8913 (unspec:SI [(reg:SI R0_REG)
8914 (match_operand:SI 1 "register_operand" "0,r")
8915 (label_ref (match_operand 2 "" ""))
8916 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8917 (clobber (match_operand:SI 4 "" "=X,1"))]
8918 "TARGET_SH2 && reload_completed && flag_pic"
8921 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8924 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8926 switch (GET_MODE (diff_vec))
8929 output_asm_insn (\"shll2 %1\", operands);
8930 load = \"mov.l @(r0,%1),%0\"; break;
8932 output_asm_insn (\"add %1,%1\", operands);
8933 load = \"mov.w @(r0,%1),%0\"; break;
8935 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8936 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8938 load = \"mov.b @(r0,%1),%0\";
8943 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8946 [(set_attr "length" "8")])
8948 (define_insn "casesi_shift_media"
8949 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8950 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8951 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8956 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8958 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8960 switch (GET_MODE (diff_vec))
8963 return \"shlli %1, 2, %0\";
8965 return \"shlli %1, 1, %0\";
8967 if (rtx_equal_p (operands[0], operands[1]))
8969 return \"add %1, r63, %0\";
8974 [(set_attr "type" "arith_media")])
8976 (define_insn "casesi_load_media"
8977 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8978 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8979 (match_operand:DI 2 "arith_reg_operand" "r")
8980 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8984 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8986 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8988 switch (GET_MODE (diff_vec))
8991 return \"ldx.l %1, %2, %0\";
8994 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8995 return \"ldx.uw %1, %2, %0\";
8997 return \"ldx.w %1, %2, %0\";
8999 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9000 return \"ldx.ub %1, %2, %0\";
9001 return \"ldx.b %1, %2, %0\";
9006 [(set_attr "type" "load_media")])
9008 (define_expand "return"
9010 "reload_completed && ! sh_need_epilogue ()"
9015 emit_jump_insn (gen_return_media ());
9019 if (TARGET_SHCOMPACT
9020 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9022 emit_jump_insn (gen_shcompact_return_tramp ());
9027 (define_insn "*return_i"
9029 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9030 && (crtl->args.info.call_cookie
9031 & CALL_COOKIE_RET_TRAMP (1)))
9033 && lookup_attribute (\"trap_exit\",
9034 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9037 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9038 && !current_function_interrupt)
9043 [(set_attr "type" "return")
9044 (set_attr "needs_delay_slot" "yes")])
9046 ;; trapa has no delay slot.
9047 (define_insn "*return_trapa"
9049 "TARGET_SH1 && !TARGET_SHCOMPACT
9050 && reload_completed"
9052 [(set_attr "type" "return")])
9054 (define_expand "shcompact_return_tramp"
9057 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9060 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9062 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9063 emit_jump_insn (gen_shcompact_return_tramp_i ());
9067 (define_insn "shcompact_return_tramp_i"
9068 [(parallel [(return) (use (reg:SI R0_REG))])]
9070 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9072 [(set_attr "type" "jump_ind")
9073 (set_attr "needs_delay_slot" "yes")])
9075 (define_insn "return_media_i"
9076 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9077 "TARGET_SHMEDIA && reload_completed"
9079 [(set_attr "type" "jump_media")])
9081 (define_insn "return_media_rte"
9083 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9085 [(set_attr "type" "jump_media")])
9087 (define_expand "return_media"
9089 "TARGET_SHMEDIA && reload_completed"
9092 int tr_regno = sh_media_register_for_return ();
9095 if (current_function_interrupt)
9097 emit_jump_insn (gen_return_media_rte ());
9102 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9104 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9106 tr = gen_rtx_REG (Pmode, tr_regno);
9107 emit_move_insn (tr, r18);
9110 tr = gen_rtx_REG (Pmode, tr_regno);
9112 emit_jump_insn (gen_return_media_i (tr));
9116 (define_insn "shcompact_preserve_incoming_args"
9117 [(set (match_operand:SI 0 "register_operand" "+r")
9118 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9121 [(set_attr "length" "0")])
9123 (define_insn "shcompact_incoming_args"
9124 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9125 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9126 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9127 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9128 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9129 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9130 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9131 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9132 (set (mem:BLK (reg:SI MACL_REG))
9133 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9134 (use (reg:SI R0_REG))
9135 (clobber (reg:SI R0_REG))
9136 (clobber (reg:SI MACL_REG))
9137 (clobber (reg:SI MACH_REG))
9138 (clobber (reg:SI PR_REG))]
9141 [(set_attr "needs_delay_slot" "yes")])
9143 (define_insn "shmedia_save_restore_regs_compact"
9144 [(set (reg:SI SP_REG)
9145 (plus:SI (reg:SI SP_REG)
9146 (match_operand:SI 0 "immediate_operand" "i")))
9147 (use (reg:SI R0_REG))
9148 (clobber (reg:SI PR_REG))]
9150 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9151 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9153 [(set_attr "needs_delay_slot" "yes")])
9155 (define_expand "prologue"
9158 "sh_expand_prologue (); DONE;")
9160 (define_expand "epilogue"
9165 sh_expand_epilogue (0);
9166 emit_jump_insn (gen_return ());
9170 (define_expand "eh_return"
9171 [(use (match_operand 0 "register_operand" ""))]
9174 rtx ra = operands[0];
9176 if (TARGET_SHMEDIA64)
9177 emit_insn (gen_eh_set_ra_di (ra));
9179 emit_insn (gen_eh_set_ra_si (ra));
9184 ;; Clobber the return address on the stack. We can't expand this
9185 ;; until we know where it will be put in the stack frame.
9187 (define_insn "eh_set_ra_si"
9188 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9190 (clobber (match_scratch:SI 1 "=&r"))]
9191 "! TARGET_SHMEDIA64"
9194 (define_insn "eh_set_ra_di"
9195 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9197 (clobber (match_scratch:DI 1 "=&r"))]
9202 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9204 (clobber (match_scratch 1 ""))]
9209 sh_set_return_address (operands[0], operands[1]);
9213 (define_insn "blockage"
9214 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9217 [(set_attr "length" "0")])
9219 ;; Define movml instructions for SH2A target. Currently they are
9220 ;; used to push and pop all banked registers only.
9222 (define_insn "movml_push_banked"
9223 [(set (match_operand:SI 0 "register_operand" "=r")
9224 (plus (match_dup 0) (const_int -32)))
9225 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9226 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9227 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9228 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9229 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9230 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9231 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9232 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9233 "TARGET_SH2A && REGNO (operands[0]) == 15"
9235 [(set_attr "in_delay_slot" "no")])
9237 (define_insn "movml_pop_banked"
9238 [(set (match_operand:SI 0 "register_operand" "=r")
9239 (plus (match_dup 0) (const_int 32)))
9240 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9241 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9242 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9243 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9244 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9245 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9246 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9247 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9248 "TARGET_SH2A && REGNO (operands[0]) == 15"
9250 [(set_attr "in_delay_slot" "no")])
9252 ;; ------------------------------------------------------------------------
9254 ;; ------------------------------------------------------------------------
9257 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9258 (eq:SI (reg:SI T_REG) (const_int 1)))]
9261 [(set_attr "type" "arith")])
9263 (define_expand "cstore4_media"
9264 [(set (match_operand:SI 0 "register_operand" "=r")
9265 (match_operator:SI 1 "sh_float_comparison_operator"
9266 [(match_operand 2 "logical_operand" "")
9267 (match_operand 3 "cmp_operand" "")]))]
9271 enum machine_mode mode = GET_MODE (operands[2]);
9272 enum rtx_code code = GET_CODE (operands[1]);
9274 if (mode == VOIDmode)
9275 mode = GET_MODE (operands[3]);
9276 if (operands[2] == const0_rtx)
9278 if (code == EQ || code == NE)
9279 operands[2] = operands[3], operands[3] = const0_rtx;
9282 operands[2] = force_reg (mode, operands[2]);
9283 if (operands[3] != const0_rtx)
9284 operands[3] = force_reg (mode, operands[3]);
9290 swap = invert = !FLOAT_MODE_P (mode);
9295 swap = FLOAT_MODE_P (mode), invert = !swap;
9300 swap = true, invert = false;
9307 swap = invert = false;
9311 swap = invert = true;
9320 rtx tem = operands[2];
9321 operands[2] = operands[3];
9323 code = swap_condition (code);
9328 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9329 code = reverse_condition (code);
9330 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9331 emit_insn (gen_cstore4_media (tem, operands[1],
9332 operands[2], operands[3]));
9335 operands[3] = const0_rtx;
9338 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9341 (define_expand "cstoresi4"
9342 [(set (match_operand:SI 0 "register_operand" "=r")
9343 (match_operator:SI 1 "comparison_operator"
9344 [(match_operand:SI 2 "cmpsi_operand" "")
9345 (match_operand:SI 3 "arith_operand" "")]))]
9346 "TARGET_SH1 || TARGET_SHMEDIA"
9347 "if (TARGET_SHMEDIA)
9349 emit_insn (gen_cstore4_media (operands[0], operands[1],
9350 operands[2], operands[3]));
9354 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9355 && sh_expand_t_scc (operands))
9358 if (! currently_expanding_to_rtl)
9361 sh_emit_compare_and_set (operands, SImode);
9365 (define_expand "cstoredi4"
9366 [(set (match_operand:SI 0 "register_operand" "=r")
9367 (match_operator:SI 1 "comparison_operator"
9368 [(match_operand:DI 2 "arith_operand" "")
9369 (match_operand:DI 3 "arith_operand" "")]))]
9370 "TARGET_SH2 || TARGET_SHMEDIA"
9371 "if (TARGET_SHMEDIA)
9373 emit_insn (gen_cstore4_media (operands[0], operands[1],
9374 operands[2], operands[3]));
9378 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9379 && sh_expand_t_scc (operands))
9382 if (! currently_expanding_to_rtl)
9385 sh_emit_compare_and_set (operands, DImode);
9391 ;; sne moves the complement of the T reg to DEST like this:
9395 ;; This is better than xoring compare result with 1 because it does
9396 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9399 (define_expand "movnegt"
9400 [(set (match_dup 1) (const_int -1))
9401 (parallel [(set (match_operand:SI 0 "" "")
9402 (neg:SI (plus:SI (reg:SI T_REG)
9405 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9410 operands[1] = gen_reg_rtx (SImode);
9414 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9415 ;; This prevents a regression that occurred when we switched from xor to
9419 [(set (match_operand:SI 0 "arith_reg_dest" "")
9420 (plus:SI (reg:SI T_REG)
9423 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9424 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9427 (define_expand "cstoresf4"
9428 [(set (match_operand:SI 0 "register_operand" "=r")
9429 (match_operator:SI 1 "sh_float_comparison_operator"
9430 [(match_operand:SF 2 "arith_operand" "")
9431 (match_operand:SF 3 "arith_operand" "")]))]
9432 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9433 "if (TARGET_SHMEDIA)
9435 emit_insn (gen_cstore4_media (operands[0], operands[1],
9436 operands[2], operands[3]));
9440 if (! currently_expanding_to_rtl)
9443 sh_emit_compare_and_set (operands, SFmode);
9447 (define_expand "cstoredf4"
9448 [(set (match_operand:SI 0 "register_operand" "=r")
9449 (match_operator:SI 1 "sh_float_comparison_operator"
9450 [(match_operand:DF 2 "arith_operand" "")
9451 (match_operand:DF 3 "arith_operand" "")]))]
9452 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9453 "if (TARGET_SHMEDIA)
9455 emit_insn (gen_cstore4_media (operands[0], operands[1],
9456 operands[2], operands[3]));
9460 if (! currently_expanding_to_rtl)
9463 sh_emit_compare_and_set (operands, DFmode);
9468 ;; -------------------------------------------------------------------------
9469 ;; Instructions to cope with inline literal tables
9470 ;; -------------------------------------------------------------------------
9472 ; 2 byte integer in line
9474 (define_insn "consttable_2"
9475 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9476 (match_operand 1 "" "")]
9481 if (operands[1] != const0_rtx)
9482 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9485 [(set_attr "length" "2")
9486 (set_attr "in_delay_slot" "no")])
9488 ; 4 byte integer in line
9490 (define_insn "consttable_4"
9491 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9492 (match_operand 1 "" "")]
9497 if (operands[1] != const0_rtx)
9499 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9500 mark_symbol_refs_as_used (operands[0]);
9504 [(set_attr "length" "4")
9505 (set_attr "in_delay_slot" "no")])
9507 ; 8 byte integer in line
9509 (define_insn "consttable_8"
9510 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9511 (match_operand 1 "" "")]
9516 if (operands[1] != const0_rtx)
9517 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9520 [(set_attr "length" "8")
9521 (set_attr "in_delay_slot" "no")])
9523 ; 4 byte floating point
9525 (define_insn "consttable_sf"
9526 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9527 (match_operand 1 "" "")]
9532 if (operands[1] != const0_rtx)
9535 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9536 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9540 [(set_attr "length" "4")
9541 (set_attr "in_delay_slot" "no")])
9543 ; 8 byte floating point
9545 (define_insn "consttable_df"
9546 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9547 (match_operand 1 "" "")]
9552 if (operands[1] != const0_rtx)
9555 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9556 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9560 [(set_attr "length" "8")
9561 (set_attr "in_delay_slot" "no")])
9563 ;; Alignment is needed for some constant tables; it may also be added for
9564 ;; Instructions at the start of loops, or after unconditional branches.
9565 ;; ??? We would get more accurate lengths if we did instruction
9566 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9567 ;; here is too conservative.
9569 ; align to a two byte boundary
9571 (define_expand "align_2"
9572 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9576 ; align to a four byte boundary
9577 ;; align_4 and align_log are instructions for the starts of loops, or
9578 ;; after unconditional branches, which may take up extra room.
9580 (define_expand "align_4"
9581 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9585 ; align to a cache line boundary
9587 (define_insn "align_log"
9588 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9591 [(set_attr "length" "0")
9592 (set_attr "in_delay_slot" "no")])
9594 ; emitted at the end of the literal table, used to emit the
9595 ; 32bit branch labels if needed.
9597 (define_insn "consttable_end"
9598 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9600 "* return output_jump_label_table ();"
9601 [(set_attr "in_delay_slot" "no")])
9603 ; emitted at the end of the window in the literal table.
9605 (define_insn "consttable_window_end"
9606 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9609 [(set_attr "length" "0")
9610 (set_attr "in_delay_slot" "no")])
9612 ;; -------------------------------------------------------------------------
9614 ;; -------------------------------------------------------------------------
9616 ;; String/block move insn.
9618 (define_expand "movmemsi"
9619 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9620 (mem:BLK (match_operand:BLK 1 "" "")))
9621 (use (match_operand:SI 2 "nonmemory_operand" ""))
9622 (use (match_operand:SI 3 "immediate_operand" ""))
9623 (clobber (reg:SI PR_REG))
9624 (clobber (reg:SI R4_REG))
9625 (clobber (reg:SI R5_REG))
9626 (clobber (reg:SI R0_REG))])]
9627 "TARGET_SH1 && ! TARGET_SH5"
9630 if(expand_block_move (operands))
9635 (define_insn "block_move_real"
9636 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9637 (mem:BLK (reg:SI R5_REG)))
9638 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9639 (clobber (reg:SI PR_REG))
9640 (clobber (reg:SI R0_REG))])]
9641 "TARGET_SH1 && ! TARGET_HARD_SH4"
9643 [(set_attr "type" "sfunc")
9644 (set_attr "needs_delay_slot" "yes")])
9646 (define_insn "block_lump_real"
9647 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9648 (mem:BLK (reg:SI R5_REG)))
9649 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9650 (use (reg:SI R6_REG))
9651 (clobber (reg:SI PR_REG))
9652 (clobber (reg:SI T_REG))
9653 (clobber (reg:SI R4_REG))
9654 (clobber (reg:SI R5_REG))
9655 (clobber (reg:SI R6_REG))
9656 (clobber (reg:SI R0_REG))])]
9657 "TARGET_SH1 && ! TARGET_HARD_SH4"
9659 [(set_attr "type" "sfunc")
9660 (set_attr "needs_delay_slot" "yes")])
9662 (define_insn "block_move_real_i4"
9663 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9664 (mem:BLK (reg:SI R5_REG)))
9665 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9666 (clobber (reg:SI PR_REG))
9667 (clobber (reg:SI R0_REG))
9668 (clobber (reg:SI R1_REG))
9669 (clobber (reg:SI R2_REG))])]
9672 [(set_attr "type" "sfunc")
9673 (set_attr "needs_delay_slot" "yes")])
9675 (define_insn "block_lump_real_i4"
9676 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9677 (mem:BLK (reg:SI R5_REG)))
9678 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9679 (use (reg:SI R6_REG))
9680 (clobber (reg:SI PR_REG))
9681 (clobber (reg:SI T_REG))
9682 (clobber (reg:SI R4_REG))
9683 (clobber (reg:SI R5_REG))
9684 (clobber (reg:SI R6_REG))
9685 (clobber (reg:SI R0_REG))
9686 (clobber (reg:SI R1_REG))
9687 (clobber (reg:SI R2_REG))
9688 (clobber (reg:SI R3_REG))])]
9691 [(set_attr "type" "sfunc")
9692 (set_attr "needs_delay_slot" "yes")])
9694 ;; -------------------------------------------------------------------------
9695 ;; Floating point instructions.
9696 ;; -------------------------------------------------------------------------
9698 ;; ??? All patterns should have a type attribute.
9700 (define_expand "movpsi"
9701 [(set (match_operand:PSI 0 "register_operand" "")
9702 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9703 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9706 ;; The c / m alternative is a fake to guide reload to load directly into
9707 ;; fpscr, since reload doesn't know how to use post-increment.
9708 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9709 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9710 ;; predicate after reload.
9711 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9712 ;; like a mac -> gpr move.
9713 (define_insn "fpu_switch"
9714 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9715 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9717 && (! reload_completed
9718 || true_regnum (operands[0]) != FPSCR_REG
9719 || !MEM_P (operands[1])
9720 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9722 ! precision stays the same
9731 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9732 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9735 [(set (reg:PSI FPSCR_REG)
9736 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9737 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9740 rtx fpscr, mem, new_insn;
9742 fpscr = SET_DEST (PATTERN (curr_insn));
9743 mem = SET_SRC (PATTERN (curr_insn));
9744 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9746 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9747 add_reg_note (new_insn, REG_INC, operands[0]);
9752 [(set (reg:PSI FPSCR_REG)
9753 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9754 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9755 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9758 rtx fpscr, mem, new_insn;
9760 fpscr = SET_DEST (PATTERN (curr_insn));
9761 mem = SET_SRC (PATTERN (curr_insn));
9762 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9764 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9765 add_reg_note (new_insn, REG_INC, operands[0]);
9767 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9768 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9772 ;; ??? This uses the fp unit, but has no type indicating that.
9773 ;; If we did that, this would either give a bogus latency or introduce
9774 ;; a bogus FIFO constraint.
9775 ;; Since this insn is currently only used for prologues/epilogues,
9776 ;; it is probably best to claim no function unit, which matches the
9778 (define_insn "toggle_sz"
9779 [(set (reg:PSI FPSCR_REG)
9780 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9781 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9783 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9785 ;; There's no way we can use it today, since optimize mode switching
9786 ;; doesn't enable us to know from which mode we're switching to the
9787 ;; mode it requests, to tell whether we can use a relative mode switch
9788 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9790 (define_insn "toggle_pr"
9791 [(set (reg:PSI FPSCR_REG)
9792 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9793 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9795 [(set_attr "type" "fpscr_toggle")])
9797 (define_expand "addsf3"
9798 [(set (match_operand:SF 0 "arith_reg_operand" "")
9799 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9800 (match_operand:SF 2 "arith_reg_operand" "")))]
9801 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9806 expand_sf_binop (&gen_addsf3_i, operands);
9811 (define_insn "*addsf3_media"
9812 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9813 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9814 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9815 "TARGET_SHMEDIA_FPU"
9817 [(set_attr "type" "fparith_media")])
9819 (define_insn_and_split "unary_sf_op"
9820 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9825 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9826 (match_operator:SF 2 "unary_float_operator"
9827 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9828 (parallel [(match_operand 4
9829 "const_int_operand" "n")]))]))
9830 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9831 "TARGET_SHMEDIA_FPU"
9833 "TARGET_SHMEDIA_FPU && reload_completed"
9834 [(set (match_dup 5) (match_dup 6))]
9837 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9838 rtx op1 = gen_rtx_REG (SFmode,
9839 (true_regnum (operands[1])
9840 + (INTVAL (operands[4]) ^ endian)));
9842 operands[7] = gen_rtx_REG (SFmode,
9843 (true_regnum (operands[0])
9844 + (INTVAL (operands[3]) ^ endian)));
9845 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9847 [(set_attr "type" "fparith_media")])
9849 (define_insn_and_split "binary_sf_op0"
9850 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
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 0)]))
9855 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9856 (parallel [(const_int 0)]))])
9859 (parallel [(const_int 1)]))))]
9860 "TARGET_SHMEDIA_FPU"
9862 "&& reload_completed"
9863 [(set (match_dup 4) (match_dup 5))]
9866 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9867 rtx op1 = gen_rtx_REG (SFmode,
9868 true_regnum (operands[1]) + endian);
9869 rtx op2 = gen_rtx_REG (SFmode,
9870 true_regnum (operands[2]) + endian);
9872 operands[4] = gen_rtx_REG (SFmode,
9873 true_regnum (operands[0]) + endian);
9874 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9876 [(set_attr "type" "fparith_media")])
9878 (define_insn_and_split "binary_sf_op1"
9879 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9883 (parallel [(const_int 0)]))
9884 (match_operator:SF 3 "binary_float_operator"
9885 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9886 (parallel [(const_int 1)]))
9887 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9888 (parallel [(const_int 1)]))])))]
9889 "TARGET_SHMEDIA_FPU"
9891 "&& reload_completed"
9892 [(set (match_dup 4) (match_dup 5))]
9895 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9896 rtx op1 = gen_rtx_REG (SFmode,
9897 true_regnum (operands[1]) + (1 ^ endian));
9898 rtx op2 = gen_rtx_REG (SFmode,
9899 true_regnum (operands[2]) + (1 ^ endian));
9901 operands[4] = gen_rtx_REG (SFmode,
9902 true_regnum (operands[0]) + (1 ^ endian));
9903 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9905 [(set_attr "type" "fparith_media")])
9907 (define_insn "addsf3_i"
9908 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9909 (plus: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 "subsf3"
9918 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9919 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9920 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9921 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9926 expand_sf_binop (&gen_subsf3_i, operands);
9931 (define_insn "*subsf3_media"
9932 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9933 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9934 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9935 "TARGET_SHMEDIA_FPU"
9937 [(set_attr "type" "fparith_media")])
9939 (define_insn "subsf3_i"
9940 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9941 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9942 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9943 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9946 [(set_attr "type" "fp")
9947 (set_attr "fp_mode" "single")])
9949 (define_expand "mulsf3"
9950 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9951 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9952 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9953 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9956 (define_insn "*mulsf3_media"
9957 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9959 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9960 "TARGET_SHMEDIA_FPU"
9962 [(set_attr "type" "fparith_media")])
9964 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9965 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9966 ;; we start out with a mulsf pattern that does not depend on fpscr.
9967 ;; This is split after combine to introduce the dependency, in order to
9968 ;; get mode switching and scheduling right.
9969 (define_insn_and_split "mulsf3_ie"
9970 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9971 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9972 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9975 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9979 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9983 [(set_attr "type" "fp")])
9985 (define_insn "mulsf3_i4"
9986 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9987 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9988 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9989 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9992 [(set_attr "type" "fp")
9993 (set_attr "fp_mode" "single")])
9995 (define_insn "mac_media"
9996 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9997 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9998 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9999 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10000 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10001 "fmac.s %1, %2, %0"
10002 [(set_attr "type" "fparith_media")])
10004 (define_insn "*macsf3"
10005 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10006 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10007 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10008 (match_operand:SF 3 "arith_reg_operand" "0")))
10009 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10010 "TARGET_SH2E && TARGET_FMAC"
10012 [(set_attr "type" "fp")
10013 (set_attr "fp_mode" "single")])
10015 (define_expand "divsf3"
10016 [(set (match_operand:SF 0 "arith_reg_operand" "")
10017 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10018 (match_operand:SF 2 "arith_reg_operand" "")))]
10019 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10024 expand_sf_binop (&gen_divsf3_i, operands);
10029 (define_insn "*divsf3_media"
10030 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10031 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10032 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10033 "TARGET_SHMEDIA_FPU"
10034 "fdiv.s %1, %2, %0"
10035 [(set_attr "type" "fdiv_media")])
10037 (define_insn "divsf3_i"
10038 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10039 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10040 (match_operand:SF 2 "arith_reg_operand" "f")))
10041 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10044 [(set_attr "type" "fdiv")
10045 (set_attr "fp_mode" "single")])
10047 (define_insn "floatdisf2"
10048 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10049 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10050 "TARGET_SHMEDIA_FPU"
10052 [(set_attr "type" "fpconv_media")])
10054 (define_expand "floatsisf2"
10055 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10056 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10057 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10060 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10062 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10067 (define_insn "*floatsisf2_media"
10068 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10069 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10070 "TARGET_SHMEDIA_FPU"
10072 [(set_attr "type" "fpconv_media")])
10074 (define_insn "floatsisf2_i4"
10075 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10076 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10077 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10078 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10080 [(set_attr "type" "fp")
10081 (set_attr "fp_mode" "single")])
10083 (define_insn "*floatsisf2_ie"
10084 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10085 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10086 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10088 [(set_attr "type" "fp")])
10090 (define_insn "fix_truncsfdi2"
10091 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10092 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10093 "TARGET_SHMEDIA_FPU"
10095 [(set_attr "type" "fpconv_media")])
10097 (define_expand "fix_truncsfsi2"
10098 [(set (match_operand:SI 0 "fpul_operand" "=y")
10099 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10100 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10103 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10105 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10110 (define_insn "*fix_truncsfsi2_media"
10111 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10112 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10113 "TARGET_SHMEDIA_FPU"
10115 [(set_attr "type" "fpconv_media")])
10117 (define_insn "fix_truncsfsi2_i4"
10118 [(set (match_operand:SI 0 "fpul_operand" "=y")
10119 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10120 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10121 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10123 [(set_attr "type" "ftrc_s")
10124 (set_attr "fp_mode" "single")])
10126 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10127 ;; fix_truncsfsi2_i4.
10128 ;; (define_insn "fix_truncsfsi2_i4_2"
10129 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10130 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10131 ;; (use (reg:PSI FPSCR_REG))
10132 ;; (clobber (reg:SI FPUL_REG))]
10135 ;; [(set_attr "length" "4")
10136 ;; (set_attr "fp_mode" "single")])
10139 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10140 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10141 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10142 ;; (clobber (reg:SI FPUL_REG))]
10144 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10145 ;; (use (match_dup 2))])
10146 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10148 (define_insn "*fixsfsi"
10149 [(set (match_operand:SI 0 "fpul_operand" "=y")
10150 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10151 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10153 [(set_attr "type" "fp")])
10155 (define_insn "cmpgtsf_t"
10156 [(set (reg:SI T_REG)
10157 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10158 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10159 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10161 [(set_attr "type" "fp_cmp")
10162 (set_attr "fp_mode" "single")])
10164 (define_insn "cmpeqsf_t"
10165 [(set (reg:SI T_REG)
10166 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10167 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10168 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10170 [(set_attr "type" "fp_cmp")
10171 (set_attr "fp_mode" "single")])
10173 (define_insn "ieee_ccmpeqsf_t"
10174 [(set (reg:SI T_REG)
10175 (ior:SI (reg:SI T_REG)
10176 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10177 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10178 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10179 "* return output_ieee_ccmpeq (insn, operands);"
10180 [(set_attr "length" "4")])
10183 (define_insn "cmpgtsf_t_i4"
10184 [(set (reg:SI T_REG)
10185 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10186 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10187 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10188 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10190 [(set_attr "type" "fp_cmp")
10191 (set_attr "fp_mode" "single")])
10193 (define_insn "cmpeqsf_t_i4"
10194 [(set (reg:SI T_REG)
10195 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10196 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10197 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10198 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10200 [(set_attr "type" "fp_cmp")
10201 (set_attr "fp_mode" "single")])
10203 (define_insn "*ieee_ccmpeqsf_t_4"
10204 [(set (reg:SI T_REG)
10205 (ior:SI (reg:SI T_REG)
10206 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10207 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10208 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10209 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10210 "* return output_ieee_ccmpeq (insn, operands);"
10211 [(set_attr "length" "4")
10212 (set_attr "fp_mode" "single")])
10214 (define_insn "cmpeqsf_media"
10215 [(set (match_operand:SI 0 "register_operand" "=r")
10216 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10217 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10218 "TARGET_SHMEDIA_FPU"
10219 "fcmpeq.s %1, %2, %0"
10220 [(set_attr "type" "fcmp_media")])
10222 (define_insn "cmpgtsf_media"
10223 [(set (match_operand:SI 0 "register_operand" "=r")
10224 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10225 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10226 "TARGET_SHMEDIA_FPU"
10227 "fcmpgt.s %1, %2, %0"
10228 [(set_attr "type" "fcmp_media")])
10230 (define_insn "cmpgesf_media"
10231 [(set (match_operand:SI 0 "register_operand" "=r")
10232 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10233 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10234 "TARGET_SHMEDIA_FPU"
10235 "fcmpge.s %1, %2, %0"
10236 [(set_attr "type" "fcmp_media")])
10238 (define_insn "cmpunsf_media"
10239 [(set (match_operand:SI 0 "register_operand" "=r")
10240 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10241 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10242 "TARGET_SHMEDIA_FPU"
10243 "fcmpun.s %1, %2, %0"
10244 [(set_attr "type" "fcmp_media")])
10246 (define_expand "cbranchsf4"
10248 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10249 [(match_operand:SF 1 "arith_operand" "")
10250 (match_operand:SF 2 "arith_operand" "")])
10251 (match_operand 3 "" "")
10253 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10256 if (TARGET_SHMEDIA)
10257 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10260 sh_emit_compare_and_branch (operands, SFmode);
10264 (define_expand "negsf2"
10265 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10266 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10267 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10272 expand_sf_unop (&gen_negsf2_i, operands);
10277 (define_insn "*negsf2_media"
10278 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10279 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10280 "TARGET_SHMEDIA_FPU"
10282 [(set_attr "type" "fmove_media")])
10284 (define_insn "negsf2_i"
10285 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10286 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10287 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10290 [(set_attr "type" "fmove")
10291 (set_attr "fp_mode" "single")])
10293 (define_expand "sqrtsf2"
10294 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10295 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10296 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10301 expand_sf_unop (&gen_sqrtsf2_i, operands);
10306 (define_insn "*sqrtsf2_media"
10307 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10308 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10309 "TARGET_SHMEDIA_FPU"
10311 [(set_attr "type" "fdiv_media")])
10313 (define_insn "sqrtsf2_i"
10314 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10315 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10316 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10319 [(set_attr "type" "fdiv")
10320 (set_attr "fp_mode" "single")])
10322 (define_insn "rsqrtsf2"
10323 [(set (match_operand:SF 0 "register_operand" "=f")
10324 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10325 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10326 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10327 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10328 && operands[1] == CONST1_RTX (SFmode)"
10330 [(set_attr "type" "fsrra")
10331 (set_attr "fp_mode" "single")])
10333 (define_insn "fsca"
10334 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10336 (unspec:SF [(mult:SF
10337 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10338 (match_operand:SF 2 "immediate_operand" "i"))
10340 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10342 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10343 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10344 && operands[2] == sh_fsca_int2sf ()"
10346 [(set_attr "type" "fsca")
10347 (set_attr "fp_mode" "single")])
10349 (define_expand "sinsf2"
10350 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10351 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10353 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10356 rtx scaled = gen_reg_rtx (SFmode);
10357 rtx truncated = gen_reg_rtx (SImode);
10358 rtx fsca = gen_reg_rtx (V2SFmode);
10359 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10361 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10362 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10363 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10364 get_fpscr_rtx ()));
10365 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10369 (define_expand "cossf2"
10370 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10371 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10373 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10376 rtx scaled = gen_reg_rtx (SFmode);
10377 rtx truncated = gen_reg_rtx (SImode);
10378 rtx fsca = gen_reg_rtx (V2SFmode);
10379 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10381 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10382 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10383 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10384 get_fpscr_rtx ()));
10385 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10389 (define_expand "sindf2"
10390 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10391 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10393 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10396 rtx scaled = gen_reg_rtx (DFmode);
10397 rtx truncated = gen_reg_rtx (SImode);
10398 rtx fsca = gen_reg_rtx (V2SFmode);
10399 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10400 rtx sfresult = gen_reg_rtx (SFmode);
10402 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10403 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10404 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10405 get_fpscr_rtx ()));
10406 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10407 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10411 (define_expand "cosdf2"
10412 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10413 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10415 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10418 rtx scaled = gen_reg_rtx (DFmode);
10419 rtx truncated = gen_reg_rtx (SImode);
10420 rtx fsca = gen_reg_rtx (V2SFmode);
10421 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10422 rtx sfresult = gen_reg_rtx (SFmode);
10424 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10425 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10426 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10427 get_fpscr_rtx ()));
10428 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10429 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10433 (define_expand "abssf2"
10434 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10435 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10436 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10441 expand_sf_unop (&gen_abssf2_i, operands);
10446 (define_insn "*abssf2_media"
10447 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10448 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10449 "TARGET_SHMEDIA_FPU"
10451 [(set_attr "type" "fmove_media")])
10453 (define_insn "abssf2_i"
10454 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10455 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10456 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10459 [(set_attr "type" "fmove")
10460 (set_attr "fp_mode" "single")])
10462 (define_expand "adddf3"
10463 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10464 (plus: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_adddf3_i, operands);
10476 (define_insn "*adddf3_media"
10477 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10478 (plus: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 "fadd.d %1, %2, %0"
10482 [(set_attr "type" "dfparith_media")])
10484 (define_insn "adddf3_i"
10485 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10486 (plus: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 "subdf3"
10495 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10496 (minus: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_subdf3_i, operands);
10508 (define_insn "*subdf3_media"
10509 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10510 (minus: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 "fsub.d %1, %2, %0"
10514 [(set_attr "type" "dfparith_media")])
10516 (define_insn "subdf3_i"
10517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10518 (minus: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_arith")
10524 (set_attr "fp_mode" "double")])
10526 (define_expand "muldf3"
10527 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10528 (mult: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_muldf3_i, operands);
10540 (define_insn "*muldf3_media"
10541 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10542 (mult: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 "fmul.d %1, %2, %0"
10546 [(set_attr "type" "dfmul_media")])
10548 (define_insn "muldf3_i"
10549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550 (mult: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" "dfp_mul")
10556 (set_attr "fp_mode" "double")])
10558 (define_expand "divdf3"
10559 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10560 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10561 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10562 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10565 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10567 expand_df_binop (&gen_divdf3_i, operands);
10572 (define_insn "*divdf3_media"
10573 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10574 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10575 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10576 "TARGET_SHMEDIA_FPU"
10577 "fdiv.d %1, %2, %0"
10578 [(set_attr "type" "dfdiv_media")])
10580 (define_insn "divdf3_i"
10581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10582 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10583 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10584 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10585 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10587 [(set_attr "type" "dfdiv")
10588 (set_attr "fp_mode" "double")])
10590 (define_insn "floatdidf2"
10591 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10592 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10593 "TARGET_SHMEDIA_FPU"
10595 [(set_attr "type" "dfpconv_media")])
10597 (define_expand "floatsidf2"
10598 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10599 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10600 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10603 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10605 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10606 get_fpscr_rtx ()));
10611 (define_insn "*floatsidf2_media"
10612 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10613 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10614 "TARGET_SHMEDIA_FPU"
10616 [(set_attr "type" "dfpconv_media")])
10618 (define_insn "floatsidf2_i"
10619 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10620 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10621 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10622 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10624 [(set_attr "type" "dfp_conv")
10625 (set_attr "fp_mode" "double")])
10627 (define_insn "fix_truncdfdi2"
10628 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10629 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10630 "TARGET_SHMEDIA_FPU"
10632 [(set_attr "type" "dfpconv_media")])
10634 (define_expand "fix_truncdfsi2"
10635 [(set (match_operand:SI 0 "fpul_operand" "")
10636 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10637 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10640 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10642 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10643 get_fpscr_rtx ()));
10648 (define_insn "*fix_truncdfsi2_media"
10649 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10650 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10651 "TARGET_SHMEDIA_FPU"
10653 [(set_attr "type" "dfpconv_media")])
10655 (define_insn "fix_truncdfsi2_i"
10656 [(set (match_operand:SI 0 "fpul_operand" "=y")
10657 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10658 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10659 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10661 [(set_attr "type" "dfp_conv")
10662 (set_attr "dfp_comp" "no")
10663 (set_attr "fp_mode" "double")])
10665 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10666 ;; fix_truncdfsi2_i.
10667 ;; (define_insn "fix_truncdfsi2_i4"
10668 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10669 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10670 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10671 ;; (clobber (reg:SI FPUL_REG))]
10674 ;; [(set_attr "length" "4")
10675 ;; (set_attr "fp_mode" "double")])
10678 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10679 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10680 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10681 ;; (clobber (reg:SI FPUL_REG))]
10683 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10684 ;; (use (match_dup 2))])
10685 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10687 (define_insn "cmpgtdf_t"
10688 [(set (reg:SI T_REG)
10689 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10690 (match_operand:DF 1 "arith_reg_operand" "f")))
10691 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10692 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10694 [(set_attr "type" "dfp_cmp")
10695 (set_attr "fp_mode" "double")])
10697 (define_insn "cmpeqdf_t"
10698 [(set (reg:SI T_REG)
10699 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10700 (match_operand:DF 1 "arith_reg_operand" "f")))
10701 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10702 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10704 [(set_attr "type" "dfp_cmp")
10705 (set_attr "fp_mode" "double")])
10707 (define_insn "*ieee_ccmpeqdf_t"
10708 [(set (reg:SI T_REG)
10709 (ior:SI (reg:SI T_REG)
10710 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10711 (match_operand:DF 1 "arith_reg_operand" "f"))))
10712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10713 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10714 "* return output_ieee_ccmpeq (insn, operands);"
10715 [(set_attr "length" "4")
10716 (set_attr "fp_mode" "double")])
10718 (define_insn "cmpeqdf_media"
10719 [(set (match_operand:SI 0 "register_operand" "=r")
10720 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10721 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10722 "TARGET_SHMEDIA_FPU"
10723 "fcmpeq.d %1,%2,%0"
10724 [(set_attr "type" "fcmp_media")])
10726 (define_insn "cmpgtdf_media"
10727 [(set (match_operand:SI 0 "register_operand" "=r")
10728 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10729 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10730 "TARGET_SHMEDIA_FPU"
10731 "fcmpgt.d %1,%2,%0"
10732 [(set_attr "type" "fcmp_media")])
10734 (define_insn "cmpgedf_media"
10735 [(set (match_operand:SI 0 "register_operand" "=r")
10736 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10737 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10738 "TARGET_SHMEDIA_FPU"
10739 "fcmpge.d %1,%2,%0"
10740 [(set_attr "type" "fcmp_media")])
10742 (define_insn "cmpundf_media"
10743 [(set (match_operand:SI 0 "register_operand" "=r")
10744 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10745 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10746 "TARGET_SHMEDIA_FPU"
10747 "fcmpun.d %1,%2,%0"
10748 [(set_attr "type" "fcmp_media")])
10750 (define_expand "cbranchdf4"
10752 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10753 [(match_operand:DF 1 "arith_operand" "")
10754 (match_operand:DF 2 "arith_operand" "")])
10755 (match_operand 3 "" "")
10757 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10760 if (TARGET_SHMEDIA)
10761 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10764 sh_emit_compare_and_branch (operands, DFmode);
10769 (define_expand "negdf2"
10770 [(set (match_operand:DF 0 "arith_reg_operand" "")
10771 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10772 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10775 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10777 expand_df_unop (&gen_negdf2_i, operands);
10782 (define_insn "*negdf2_media"
10783 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10784 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10785 "TARGET_SHMEDIA_FPU"
10787 [(set_attr "type" "fmove_media")])
10789 (define_insn "negdf2_i"
10790 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10791 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10792 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10793 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10795 [(set_attr "type" "fmove")
10796 (set_attr "fp_mode" "double")])
10798 (define_expand "sqrtdf2"
10799 [(set (match_operand:DF 0 "arith_reg_operand" "")
10800 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10801 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10804 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10806 expand_df_unop (&gen_sqrtdf2_i, operands);
10811 (define_insn "*sqrtdf2_media"
10812 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10813 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10814 "TARGET_SHMEDIA_FPU"
10816 [(set_attr "type" "dfdiv_media")])
10818 (define_insn "sqrtdf2_i"
10819 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10820 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10821 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10822 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10824 [(set_attr "type" "dfdiv")
10825 (set_attr "fp_mode" "double")])
10827 (define_expand "absdf2"
10828 [(set (match_operand:DF 0 "arith_reg_operand" "")
10829 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10830 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10833 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10835 expand_df_unop (&gen_absdf2_i, operands);
10840 (define_insn "*absdf2_media"
10841 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10843 "TARGET_SHMEDIA_FPU"
10845 [(set_attr "type" "fmove_media")])
10847 (define_insn "absdf2_i"
10848 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10849 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10850 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10851 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10853 [(set_attr "type" "fmove")
10854 (set_attr "fp_mode" "double")])
10856 (define_expand "extendsfdf2"
10857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10858 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10859 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10862 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10864 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10865 get_fpscr_rtx ()));
10870 (define_insn "*extendsfdf2_media"
10871 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10872 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10873 "TARGET_SHMEDIA_FPU"
10875 [(set_attr "type" "dfpconv_media")])
10877 (define_insn "extendsfdf2_i4"
10878 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10879 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10880 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10881 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10883 [(set_attr "type" "fp")
10884 (set_attr "fp_mode" "double")])
10886 (define_expand "truncdfsf2"
10887 [(set (match_operand:SF 0 "fpul_operand" "")
10888 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10889 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10892 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10894 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10895 get_fpscr_rtx ()));
10900 (define_insn "*truncdfsf2_media"
10901 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10902 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10903 "TARGET_SHMEDIA_FPU"
10905 [(set_attr "type" "dfpconv_media")])
10907 (define_insn "truncdfsf2_i4"
10908 [(set (match_operand:SF 0 "fpul_operand" "=y")
10909 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10910 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10911 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10913 [(set_attr "type" "fp")
10914 (set_attr "fp_mode" "double")])
10916 ;; Bit field extract patterns. These give better code for packed bitfields,
10917 ;; because they allow auto-increment addresses to be generated.
10919 (define_expand "insv"
10920 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10921 (match_operand:SI 1 "immediate_operand" "")
10922 (match_operand:SI 2 "immediate_operand" ""))
10923 (match_operand:SI 3 "general_operand" ""))]
10924 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10927 rtx addr_target, orig_address, shift_reg, qi_val;
10928 HOST_WIDE_INT bitsize, size, v = 0;
10929 rtx x = operands[3];
10931 if (TARGET_SH2A && TARGET_BITOPS
10932 && (satisfies_constraint_Sbw (operands[0])
10933 || satisfies_constraint_Sbv (operands[0]))
10934 && satisfies_constraint_M (operands[1])
10935 && satisfies_constraint_K03 (operands[2]))
10937 if (satisfies_constraint_N (operands[3]))
10939 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10942 else if (satisfies_constraint_M (operands[3]))
10944 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10947 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10948 && satisfies_constraint_M (operands[1]))
10950 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10953 else if (REG_P (operands[3])
10954 && satisfies_constraint_M (operands[1]))
10956 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10957 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10961 /* ??? expmed doesn't care for non-register predicates. */
10962 if (! memory_operand (operands[0], VOIDmode)
10963 || ! immediate_operand (operands[1], VOIDmode)
10964 || ! immediate_operand (operands[2], VOIDmode)
10965 || ! general_operand (x, VOIDmode))
10967 /* If this isn't a 16 / 24 / 32 bit field, or if
10968 it doesn't start on a byte boundary, then fail. */
10969 bitsize = INTVAL (operands[1]);
10970 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10971 || (INTVAL (operands[2]) % 8) != 0)
10974 size = bitsize / 8;
10975 orig_address = XEXP (operands[0], 0);
10976 shift_reg = gen_reg_rtx (SImode);
10977 if (CONST_INT_P (x))
10980 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10984 emit_insn (gen_movsi (shift_reg, operands[3]));
10985 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10987 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10989 operands[0] = replace_equiv_address (operands[0], addr_target);
10990 emit_insn (gen_movqi (operands[0], qi_val));
10994 if (CONST_INT_P (x))
10996 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10999 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11000 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11002 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11003 emit_insn (gen_movqi (operands[0], qi_val));
11009 (define_insn "movua"
11010 [(set (match_operand:SI 0 "register_operand" "=z")
11011 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11015 [(set_attr "type" "movua")])
11017 ;; We shouldn't need this, but cse replaces increments with references
11018 ;; to other regs before flow has a chance to create post_inc
11019 ;; addressing modes, and only postreload's cse_move2add brings the
11020 ;; increments back to a usable form.
11022 [(set (match_operand:SI 0 "register_operand" "")
11023 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11024 (const_int 32) (const_int 0)))
11025 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11026 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11027 [(set (match_operand:SI 0 "register_operand" "")
11028 (sign_extract:SI (mem:SI (post_inc:SI
11029 (match_operand:SI 1 "register_operand" "")))
11030 (const_int 32) (const_int 0)))]
11033 (define_expand "extv"
11034 [(set (match_operand:SI 0 "register_operand" "")
11035 (sign_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_bldsign_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 (define_expand "extzv"
11066 [(set (match_operand:SI 0 "register_operand" "")
11067 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11068 (match_operand 2 "const_int_operand" "")
11069 (match_operand 3 "const_int_operand" "")))]
11070 "TARGET_SH4A_ARCH || TARGET_SH2A"
11072 if (TARGET_SH2A && TARGET_BITOPS
11073 && (satisfies_constraint_Sbw (operands[1])
11074 || satisfies_constraint_Sbv (operands[1]))
11075 && satisfies_constraint_M (operands[2])
11076 && satisfies_constraint_K03 (operands[3]))
11078 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11079 if (REGNO (operands[0]) != T_REG)
11080 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11083 if (TARGET_SH4A_ARCH
11084 && INTVAL (operands[2]) == 32
11085 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11086 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11088 rtx src = adjust_address (operands[1], BLKmode, 0);
11089 set_mem_size (src, GEN_INT (4));
11090 emit_insn (gen_movua (operands[0], src));
11097 ;; SH2A instructions for bitwise operations.
11099 ;; Clear a bit in a memory location.
11100 (define_insn "bclr_m2a"
11101 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11103 (not:QI (ashift:QI (const_int 1)
11104 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11106 "TARGET_SH2A && TARGET_BITOPS"
11109 bclr.b\\t%1,@(0,%t0)"
11110 [(set_attr "length" "4,4")])
11112 (define_insn "bclrmem_m2a"
11113 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11114 (and:QI (match_dup 0)
11115 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11116 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11119 bclr.b\\t%W1,@(0,%t0)"
11120 [(set_attr "length" "4,4")])
11122 ;; Set a bit in a memory location.
11123 (define_insn "bset_m2a"
11124 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11126 (ashift:QI (const_int 1)
11127 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11129 "TARGET_SH2A && TARGET_BITOPS"
11132 bset.b\\t%1,@(0,%t0)"
11133 [(set_attr "length" "4,4")])
11135 (define_insn "bsetmem_m2a"
11136 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11137 (ior:QI (match_dup 0)
11138 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11139 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11142 bset.b\\t%V1,@(0,%t0)"
11143 [(set_attr "length" "4,4")])
11145 ;;; Transfer the contents of the T bit to a specified bit of memory.
11146 (define_insn "bst_m2a"
11147 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11148 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11150 (not:QI (ashift:QI (const_int 1)
11151 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11154 (ashift:QI (const_int 1) (match_dup 1))
11156 "TARGET_SH2A && TARGET_BITOPS"
11159 bst.b\\t%1,@(0,%t0)"
11160 [(set_attr "length" "4")])
11162 ;; Store a specified bit of memory in the T bit.
11163 (define_insn "bld_m2a"
11164 [(set (reg:SI T_REG)
11166 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11168 (match_operand 1 "const_int_operand" "K03,K03")))]
11169 "TARGET_SH2A && TARGET_BITOPS"
11172 bld.b\\t%1,@(0,%t0)"
11173 [(set_attr "length" "4,4")])
11175 ;; Store a specified bit of memory in the T bit.
11176 (define_insn "bldsign_m2a"
11177 [(set (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 bld.b\\t%1,@(0,%t0)"
11186 [(set_attr "length" "4,4")])
11188 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11189 (define_insn "bld_reg"
11190 [(set (reg:SI T_REG)
11191 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11193 (match_operand 1 "const_int_operand" "K03")))]
11197 (define_insn "*bld_regqi"
11198 [(set (reg:SI T_REG)
11199 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11201 (match_operand 1 "const_int_operand" "K03")))]
11205 ;; Take logical and of a specified bit of memory with the T bit and
11206 ;; store its result in the T bit.
11207 (define_insn "band_m2a"
11208 [(set (reg:SI T_REG)
11209 (and:SI (reg:SI T_REG)
11211 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11213 (match_operand 1 "const_int_operand" "K03,K03"))))]
11214 "TARGET_SH2A && TARGET_BITOPS"
11217 band.b\\t%1,@(0,%t0)"
11218 [(set_attr "length" "4,4")])
11220 (define_insn "bandreg_m2a"
11221 [(set (match_operand:SI 0 "register_operand" "=r,r")
11222 (and:SI (zero_extract:SI
11223 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11225 (match_operand 2 "const_int_operand" "K03,K03"))
11226 (match_operand:SI 3 "register_operand" "r,r")))]
11227 "TARGET_SH2A && TARGET_BITOPS"
11229 band.b\\t%2,%1\;movt\\t%0
11230 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11231 [(set_attr "length" "6,6")])
11233 ;; Take logical or of a specified bit of memory with the T bit and
11234 ;; store its result in the T bit.
11235 (define_insn "bor_m2a"
11236 [(set (reg:SI T_REG)
11237 (ior:SI (reg:SI T_REG)
11239 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11241 (match_operand 1 "const_int_operand" "K03,K03"))))]
11242 "TARGET_SH2A && TARGET_BITOPS"
11245 bor.b\\t%1,@(0,%t0)"
11246 [(set_attr "length" "4,4")])
11248 (define_insn "borreg_m2a"
11249 [(set (match_operand:SI 0 "register_operand" "=r,r")
11250 (ior:SI (zero_extract:SI
11251 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11253 (match_operand 2 "const_int_operand" "K03,K03"))
11254 (match_operand:SI 3 "register_operand" "=r,r")))]
11255 "TARGET_SH2A && TARGET_BITOPS"
11257 bor.b\\t%2,%1\;movt\\t%0
11258 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11259 [(set_attr "length" "6,6")])
11261 ;; Take exclusive or of a specified bit of memory with the T bit and
11262 ;; store its result in the T bit.
11263 (define_insn "bxor_m2a"
11264 [(set (reg:SI T_REG)
11265 (xor:SI (reg:SI T_REG)
11267 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11269 (match_operand 1 "const_int_operand" "K03,K03"))))]
11270 "TARGET_SH2A && TARGET_BITOPS"
11273 bxor.b\\t%1,@(0,%t0)"
11274 [(set_attr "length" "4,4")])
11276 (define_insn "bxorreg_m2a"
11277 [(set (match_operand:SI 0 "register_operand" "=r,r")
11278 (xor:SI (zero_extract:SI
11279 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11281 (match_operand 2 "const_int_operand" "K03,K03"))
11282 (match_operand:SI 3 "register_operand" "=r,r")))]
11283 "TARGET_SH2A && TARGET_BITOPS"
11285 bxor.b\\t%2,%1\;movt\\t%0
11286 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11287 [(set_attr "length" "6,6")])
11290 ;; -------------------------------------------------------------------------
11292 ;; -------------------------------------------------------------------------
11293 ;; This matches cases where the bit in a memory location is set.
11295 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11296 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11298 (ior:SI (match_dup 0)
11299 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11301 (match_operand 3 "arith_reg_operand" "r,r"))]
11302 "TARGET_SH2A && TARGET_BITOPS
11303 && satisfies_constraint_Pso (operands[2])
11304 && REGNO (operands[0]) == REGNO (operands[3])"
11305 [(set (match_dup 1)
11306 (ior:QI (match_dup 1)
11310 ;; This matches cases where the bit in a memory location is cleared.
11312 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11313 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11315 (and:SI (match_dup 0)
11316 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11318 (match_operand 3 "arith_reg_operand" "r,r"))]
11319 "TARGET_SH2A && TARGET_BITOPS
11320 && satisfies_constraint_Psz (operands[2])
11321 && REGNO (operands[0]) == REGNO (operands[3])"
11322 [(set (match_dup 1)
11323 (and:QI (match_dup 1)
11327 ;; This matches cases where a stack pointer increment at the start of the
11328 ;; epilogue combines with a stack slot read loading the return value.
11331 [(set (match_operand:SI 0 "arith_reg_operand" "")
11332 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11333 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11334 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11337 ;; See the comment on the dt combiner pattern above.
11340 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11341 (plus:SI (match_dup 0)
11343 (set (reg:SI T_REG)
11344 (eq:SI (match_dup 0)
11349 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11350 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11351 ;; reload when the constant is too large for a reg+offset address.
11353 ;; ??? We would get much better code if this was done in reload. This would
11354 ;; require modifying find_reloads_address to recognize that if the constant
11355 ;; is out-of-range for an immediate add, then we get better code by reloading
11356 ;; the constant into a register than by reloading the sum into a register,
11357 ;; since the former is one instruction shorter if the address does not need
11358 ;; to be offsettable. Unfortunately this does not work, because there is
11359 ;; only one register, r0, that can be used as an index register. This register
11360 ;; is also the function return value register. So, if we try to force reload
11361 ;; to use double-reg addresses, then we end up with some instructions that
11362 ;; need to use r0 twice. The only way to fix this is to change the calling
11363 ;; convention so that r0 is not used to return values.
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:SI (match_dup 0))
11369 (match_operand:SI 2 "general_movsrc_operand" ""))]
11370 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11371 "mov.l %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:SI 2 "general_movdst_operand" "")
11377 (mem:SI (match_dup 0)))]
11378 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11379 "mov.l @(%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:HI (match_dup 0))
11385 (match_operand:HI 2 "general_movsrc_operand" ""))]
11386 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11387 "mov.w %2,@(%0,%1)")
11390 [(set (match_operand:SI 0 "register_operand" "=r")
11391 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11392 (set (match_operand:HI 2 "general_movdst_operand" "")
11393 (mem:HI (match_dup 0)))]
11394 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11395 "mov.w @(%0,%1),%2")
11398 [(set (match_operand:SI 0 "register_operand" "=r")
11399 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11400 (set (mem:QI (match_dup 0))
11401 (match_operand:QI 2 "general_movsrc_operand" ""))]
11402 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11403 "mov.b %2,@(%0,%1)")
11406 [(set (match_operand:SI 0 "register_operand" "=r")
11407 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11408 (set (match_operand:QI 2 "general_movdst_operand" "")
11409 (mem:QI (match_dup 0)))]
11410 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11411 "mov.b @(%0,%1),%2")
11414 [(set (match_operand:SI 0 "register_operand" "=r")
11415 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11416 (set (mem:SF (match_dup 0))
11417 (match_operand:SF 2 "general_movsrc_operand" ""))]
11418 "TARGET_SH1 && REGNO (operands[0]) == 0
11419 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11420 || (GET_CODE (operands[2]) == SUBREG
11421 && REGNO (SUBREG_REG (operands[2])) < 16))
11422 && reg_unused_after (operands[0], insn)"
11423 "mov.l %2,@(%0,%1)")
11426 [(set (match_operand:SI 0 "register_operand" "=r")
11427 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11428 (set (match_operand:SF 2 "general_movdst_operand" "")
11430 (mem:SF (match_dup 0)))]
11431 "TARGET_SH1 && REGNO (operands[0]) == 0
11432 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11433 || (GET_CODE (operands[2]) == SUBREG
11434 && REGNO (SUBREG_REG (operands[2])) < 16))
11435 && reg_unused_after (operands[0], insn)"
11436 "mov.l @(%0,%1),%2")
11439 [(set (match_operand:SI 0 "register_operand" "=r")
11440 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11441 (set (mem:SF (match_dup 0))
11442 (match_operand:SF 2 "general_movsrc_operand" ""))]
11443 "TARGET_SH2E && REGNO (operands[0]) == 0
11444 && ((REG_P (operands[2])
11445 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11446 || (GET_CODE (operands[2]) == SUBREG
11447 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11448 && reg_unused_after (operands[0], insn)"
11449 "fmov{.s|} %2,@(%0,%1)")
11452 [(set (match_operand:SI 0 "register_operand" "=r")
11453 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11454 (set (match_operand:SF 2 "general_movdst_operand" "")
11456 (mem:SF (match_dup 0)))]
11457 "TARGET_SH2E && REGNO (operands[0]) == 0
11458 && ((REG_P (operands[2])
11459 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11460 || (GET_CODE (operands[2]) == SUBREG
11461 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11462 && reg_unused_after (operands[0], insn)"
11463 "fmov{.s|} @(%0,%1),%2")
11465 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11466 (define_insn "sp_switch_1"
11467 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11471 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11472 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11473 return \"mov r0,r15\";
11475 [(set_attr "length" "10")])
11477 ;; Switch back to the original stack for interrupt functions with the
11478 ;; sp_switch attribute. */
11479 (define_insn "sp_switch_2"
11482 "mov.l @r15+,r15\;mov.l @r15+,r0"
11483 [(set_attr "length" "4")])
11485 ;; Integer vector moves
11487 (define_expand "movv8qi"
11488 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11489 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11491 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11493 (define_insn "movv8qi_i"
11494 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11495 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11497 && (register_operand (operands[0], V8QImode)
11498 || sh_register_operand (operands[1], V8QImode))"
11505 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11506 (set_attr "length" "4,4,16,4,4")])
11509 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11510 (subreg:V8QI (const_int 0) 0))]
11512 [(set (match_dup 0)
11513 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11514 (const_int 0) (const_int 0) (const_int 0)
11515 (const_int 0) (const_int 0)]))])
11518 [(set (match_operand 0 "arith_reg_dest" "")
11519 (match_operand 1 "sh_rep_vec" ""))]
11520 "TARGET_SHMEDIA && reload_completed
11521 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11522 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11523 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11524 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11525 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11526 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11527 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11528 [(set (match_dup 0) (match_dup 1))
11532 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11533 rtx elt1 = XVECEXP (operands[1], 0, 1);
11536 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11540 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11541 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11543 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11544 operands[1] = XVECEXP (operands[1], 0, 0);
11547 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11549 = GEN_INT (TARGET_LITTLE_ENDIAN
11550 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11551 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11554 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11556 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11562 [(set (match_operand 0 "arith_reg_dest" "")
11563 (match_operand 1 "sh_const_vec" ""))]
11564 "TARGET_SHMEDIA && reload_completed
11565 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11566 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11567 [(set (match_dup 0) (match_dup 1))]
11570 rtx v = operands[1];
11571 enum machine_mode new_mode
11572 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11574 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11576 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11579 (define_expand "movv2hi"
11580 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11581 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11583 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11585 (define_insn "movv2hi_i"
11586 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11587 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11589 && (register_operand (operands[0], V2HImode)
11590 || sh_register_operand (operands[1], V2HImode))"
11597 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11598 (set_attr "length" "4,4,16,4,4")
11599 (set (attr "highpart")
11600 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11601 (const_string "user")]
11602 (const_string "ignore")))])
11604 (define_expand "movv4hi"
11605 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11606 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11608 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11610 (define_insn "movv4hi_i"
11611 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11612 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11614 && (register_operand (operands[0], V4HImode)
11615 || sh_register_operand (operands[1], V4HImode))"
11622 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11623 (set_attr "length" "4,4,16,4,4")
11624 (set_attr "highpart" "depend")])
11626 (define_expand "movv2si"
11627 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11628 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11630 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11632 (define_insn "movv2si_i"
11633 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11634 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11636 && (register_operand (operands[0], V2SImode)
11637 || sh_register_operand (operands[1], V2SImode))"
11644 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11645 (set_attr "length" "4,4,16,4,4")
11646 (set_attr "highpart" "depend")])
11648 ;; Multimedia Intrinsics
11650 (define_insn "absv2si2"
11651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11652 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11655 [(set_attr "type" "mcmp_media")
11656 (set_attr "highpart" "depend")])
11658 (define_insn "absv4hi2"
11659 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11660 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11663 [(set_attr "type" "mcmp_media")
11664 (set_attr "highpart" "depend")])
11666 (define_insn "addv2si3"
11667 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11668 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11669 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11671 "madd.l %1, %2, %0"
11672 [(set_attr "type" "arith_media")
11673 (set_attr "highpart" "depend")])
11675 (define_insn "addv4hi3"
11676 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11677 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11678 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11680 "madd.w %1, %2, %0"
11681 [(set_attr "type" "arith_media")
11682 (set_attr "highpart" "depend")])
11684 (define_insn_and_split "addv2hi3"
11685 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11686 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11687 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11694 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11695 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11696 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11697 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11698 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11700 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11701 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11704 [(set_attr "highpart" "must_split")])
11706 (define_insn "ssaddv2si3"
11707 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11708 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11709 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11711 "madds.l %1, %2, %0"
11712 [(set_attr "type" "mcmp_media")
11713 (set_attr "highpart" "depend")])
11715 (define_insn "usaddv8qi3"
11716 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11717 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11718 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11720 "madds.ub %1, %2, %0"
11721 [(set_attr "type" "mcmp_media")
11722 (set_attr "highpart" "depend")])
11724 (define_insn "ssaddv4hi3"
11725 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11726 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11727 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11729 "madds.w %1, %2, %0"
11730 [(set_attr "type" "mcmp_media")
11731 (set_attr "highpart" "depend")])
11733 (define_insn "negcmpeqv8qi"
11734 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11735 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11736 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11738 "mcmpeq.b %N1, %N2, %0"
11739 [(set_attr "type" "mcmp_media")
11740 (set_attr "highpart" "depend")])
11742 (define_insn "negcmpeqv2si"
11743 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11744 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11745 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11747 "mcmpeq.l %N1, %N2, %0"
11748 [(set_attr "type" "mcmp_media")
11749 (set_attr "highpart" "depend")])
11751 (define_insn "negcmpeqv4hi"
11752 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11753 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11754 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11756 "mcmpeq.w %N1, %N2, %0"
11757 [(set_attr "type" "mcmp_media")
11758 (set_attr "highpart" "depend")])
11760 (define_insn "negcmpgtuv8qi"
11761 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11762 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11763 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11765 "mcmpgt.ub %N1, %N2, %0"
11766 [(set_attr "type" "mcmp_media")
11767 (set_attr "highpart" "depend")])
11769 (define_insn "negcmpgtv2si"
11770 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11771 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11772 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11774 "mcmpgt.l %N1, %N2, %0"
11775 [(set_attr "type" "mcmp_media")
11776 (set_attr "highpart" "depend")])
11778 (define_insn "negcmpgtv4hi"
11779 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11780 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11781 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11783 "mcmpgt.w %N1, %N2, %0"
11784 [(set_attr "type" "mcmp_media")
11785 (set_attr "highpart" "depend")])
11787 (define_insn "mcmv"
11788 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11789 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11790 (match_operand:DI 2 "arith_reg_operand" "r"))
11791 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11792 (not:DI (match_dup 2)))))]
11795 [(set_attr "type" "arith_media")
11796 (set_attr "highpart" "depend")])
11798 (define_insn "mcnvs_lw"
11799 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11801 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11802 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11804 "mcnvs.lw %N1, %N2, %0"
11805 [(set_attr "type" "mcmp_media")])
11807 (define_insn "mcnvs_wb"
11808 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11810 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11811 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11813 "mcnvs.wb %N1, %N2, %0"
11814 [(set_attr "type" "mcmp_media")])
11816 (define_insn "mcnvs_wub"
11817 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11819 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11820 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11822 "mcnvs.wub %N1, %N2, %0"
11823 [(set_attr "type" "mcmp_media")])
11825 (define_insn "mextr_rl"
11826 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11827 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11828 (match_operand:HI 3 "mextr_bit_offset" "i"))
11829 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11830 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11831 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11834 static char templ[21];
11836 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11837 (int) INTVAL (operands[3]) >> 3);
11840 [(set_attr "type" "arith_media")])
11842 (define_insn "*mextr_lr"
11843 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11844 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11845 (match_operand:HI 3 "mextr_bit_offset" "i"))
11846 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11847 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11848 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11851 static char templ[21];
11853 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11854 (int) INTVAL (operands[4]) >> 3);
11857 [(set_attr "type" "arith_media")])
11859 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11860 ; vector then varies depending on endianness.
11861 (define_expand "mextr1"
11862 [(match_operand:DI 0 "arith_reg_dest" "")
11863 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11864 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11868 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11869 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11873 (define_expand "mextr2"
11874 [(match_operand:DI 0 "arith_reg_dest" "")
11875 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11876 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11880 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11881 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11885 (define_expand "mextr3"
11886 [(match_operand:DI 0 "arith_reg_dest" "")
11887 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11888 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11892 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11893 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11897 (define_expand "mextr4"
11898 [(match_operand:DI 0 "arith_reg_dest" "")
11899 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11900 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11904 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11905 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11909 (define_expand "mextr5"
11910 [(match_operand:DI 0 "arith_reg_dest" "")
11911 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11912 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11916 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11917 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11921 (define_expand "mextr6"
11922 [(match_operand:DI 0 "arith_reg_dest" "")
11923 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11924 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11928 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11929 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11933 (define_expand "mextr7"
11934 [(match_operand:DI 0 "arith_reg_dest" "")
11935 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11936 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11940 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11941 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11945 (define_expand "mmacfx_wl"
11946 [(match_operand:V2SI 0 "arith_reg_dest" "")
11947 (match_operand:V2HI 1 "extend_reg_operand" "")
11948 (match_operand:V2HI 2 "extend_reg_operand" "")
11949 (match_operand:V2SI 3 "arith_reg_operand" "")]
11953 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11954 operands[1], operands[2]));
11958 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11960 (define_insn "mmacfx_wl_i"
11961 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11963 (match_operand:V2SI 1 "arith_reg_operand" "0")
11968 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11969 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11972 "mmacfx.wl %2, %3, %0"
11973 [(set_attr "type" "mac_media")
11974 (set_attr "highpart" "depend")])
11976 (define_expand "mmacnfx_wl"
11977 [(match_operand:V2SI 0 "arith_reg_dest" "")
11978 (match_operand:V2HI 1 "extend_reg_operand" "")
11979 (match_operand:V2HI 2 "extend_reg_operand" "")
11980 (match_operand:V2SI 3 "arith_reg_operand" "")]
11984 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11985 operands[1], operands[2]));
11989 (define_insn "mmacnfx_wl_i"
11990 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11992 (match_operand:V2SI 1 "arith_reg_operand" "0")
11997 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11998 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12001 "mmacnfx.wl %2, %3, %0"
12002 [(set_attr "type" "mac_media")
12003 (set_attr "highpart" "depend")])
12005 (define_insn "mulv2si3"
12006 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12007 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12008 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12010 "mmul.l %1, %2, %0"
12011 [(set_attr "type" "d2mpy_media")
12012 (set_attr "highpart" "depend")])
12014 (define_insn "mulv4hi3"
12015 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12016 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12017 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12019 "mmul.w %1, %2, %0"
12020 [(set_attr "type" "dmpy_media")
12021 (set_attr "highpart" "depend")])
12023 (define_insn "mmulfx_l"
12024 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12028 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12029 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12032 "mmulfx.l %1, %2, %0"
12033 [(set_attr "type" "d2mpy_media")
12034 (set_attr "highpart" "depend")])
12036 (define_insn "mmulfx_w"
12037 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12041 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12042 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12045 "mmulfx.w %1, %2, %0"
12046 [(set_attr "type" "dmpy_media")
12047 (set_attr "highpart" "depend")])
12049 (define_insn "mmulfxrp_w"
12050 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12055 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12056 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12060 "mmulfxrp.w %1, %2, %0"
12061 [(set_attr "type" "dmpy_media")
12062 (set_attr "highpart" "depend")])
12065 (define_expand "mmulhi_wl"
12066 [(match_operand:V2SI 0 "arith_reg_dest" "")
12067 (match_operand:V4HI 1 "arith_reg_operand" "")
12068 (match_operand:V4HI 2 "arith_reg_operand" "")]
12072 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12073 (operands[0], operands[1], operands[2]));
12077 (define_expand "mmullo_wl"
12078 [(match_operand:V2SI 0 "arith_reg_dest" "")
12079 (match_operand:V4HI 1 "arith_reg_operand" "")
12080 (match_operand:V4HI 2 "arith_reg_operand" "")]
12084 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12085 (operands[0], operands[1], operands[2]));
12089 (define_insn "mmul23_wl"
12090 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12093 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12094 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12095 (parallel [(const_int 2) (const_int 3)])))]
12097 "* return (TARGET_LITTLE_ENDIAN
12098 ? \"mmulhi.wl %1, %2, %0\"
12099 : \"mmullo.wl %1, %2, %0\");"
12100 [(set_attr "type" "dmpy_media")
12101 (set (attr "highpart")
12102 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12103 (const_string "user")))])
12105 (define_insn "mmul01_wl"
12106 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12109 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12110 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12111 (parallel [(const_int 0) (const_int 1)])))]
12113 "* return (TARGET_LITTLE_ENDIAN
12114 ? \"mmullo.wl %1, %2, %0\"
12115 : \"mmulhi.wl %1, %2, %0\");"
12116 [(set_attr "type" "dmpy_media")
12117 (set (attr "highpart")
12118 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12119 (const_string "user")))])
12122 (define_expand "mmulsum_wq"
12123 [(match_operand:DI 0 "arith_reg_dest" "")
12124 (match_operand:V4HI 1 "arith_reg_operand" "")
12125 (match_operand:V4HI 2 "arith_reg_operand" "")
12126 (match_operand:DI 3 "arith_reg_operand" "")]
12130 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12131 operands[1], operands[2]));
12135 (define_insn "mmulsum_wq_i"
12136 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12137 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12142 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12143 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12144 (parallel [(const_int 0)]))
12145 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12146 (sign_extend:V4DI (match_dup 3)))
12147 (parallel [(const_int 1)])))
12149 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12150 (sign_extend:V4DI (match_dup 3)))
12151 (parallel [(const_int 2)]))
12152 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12153 (sign_extend:V4DI (match_dup 3)))
12154 (parallel [(const_int 3)]))))))]
12156 "mmulsum.wq %2, %3, %0"
12157 [(set_attr "type" "mac_media")])
12159 (define_expand "mperm_w"
12160 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12161 (match_operand:V4HI 1 "arith_reg_operand" "r")
12162 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12166 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12167 (operands[0], operands[1], operands[2]));
12171 ; This use of vec_select isn't exactly correct according to rtl.texi
12172 ; (because not constant), but it seems a straightforward extension.
12173 (define_insn "mperm_w_little"
12174 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12176 (match_operand:V4HI 1 "arith_reg_operand" "r")
12178 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12179 (const_int 2) (const_int 0))
12180 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12181 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12182 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12183 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12184 "mperm.w %1, %N2, %0"
12185 [(set_attr "type" "arith_media")])
12187 (define_insn "mperm_w_big"
12188 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12190 (match_operand:V4HI 1 "arith_reg_operand" "r")
12192 [(zero_extract:QI (not:QI (match_operand:QI 2
12193 "extend_reg_or_0_operand" "rZ"))
12194 (const_int 2) (const_int 0))
12195 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12196 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12197 (zero_extract:QI (not:QI (match_dup 2))
12198 (const_int 2) (const_int 6))])))]
12199 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12200 "mperm.w %1, %N2, %0"
12201 [(set_attr "type" "arith_media")])
12203 (define_insn "mperm_w0"
12204 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12205 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12206 "trunc_hi_operand" "r"))))]
12208 "mperm.w %1, r63, %0"
12209 [(set_attr "type" "arith_media")
12210 (set_attr "highpart" "ignore")])
12212 (define_expand "msad_ubq"
12213 [(match_operand:DI 0 "arith_reg_dest" "")
12214 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12215 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12216 (match_operand:DI 3 "arith_reg_operand" "")]
12220 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12221 operands[1], operands[2]));
12225 (define_insn "msad_ubq_i"
12226 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12231 (match_operand:DI 1 "arith_reg_operand" "0")
12232 (abs:DI (vec_select:DI
12235 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12237 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12238 (parallel [(const_int 0)]))))
12239 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12240 (zero_extend:V8DI (match_dup 3)))
12241 (parallel [(const_int 1)]))))
12243 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12244 (zero_extend:V8DI (match_dup 3)))
12245 (parallel [(const_int 2)])))
12246 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12247 (zero_extend:V8DI (match_dup 3)))
12248 (parallel [(const_int 3)])))))
12251 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12252 (zero_extend:V8DI (match_dup 3)))
12253 (parallel [(const_int 4)])))
12254 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12255 (zero_extend:V8DI (match_dup 3)))
12256 (parallel [(const_int 5)]))))
12258 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12259 (zero_extend:V8DI (match_dup 3)))
12260 (parallel [(const_int 6)])))
12261 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12262 (zero_extend:V8DI (match_dup 3)))
12263 (parallel [(const_int 7)])))))))]
12265 "msad.ubq %N2, %N3, %0"
12266 [(set_attr "type" "mac_media")])
12268 (define_insn "mshalds_l"
12269 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12272 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12273 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12274 (const_int 31)))))]
12276 "mshalds.l %1, %2, %0"
12277 [(set_attr "type" "mcmp_media")
12278 (set_attr "highpart" "depend")])
12280 (define_insn "mshalds_w"
12281 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12284 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12285 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12286 (const_int 15)))))]
12288 "mshalds.w %1, %2, %0"
12289 [(set_attr "type" "mcmp_media")
12290 (set_attr "highpart" "depend")])
12292 (define_insn "ashrv2si3"
12293 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12294 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12295 (match_operand:DI 2 "arith_reg_operand" "r")))]
12297 "mshard.l %1, %2, %0"
12298 [(set_attr "type" "arith_media")
12299 (set_attr "highpart" "depend")])
12301 (define_insn "ashrv4hi3"
12302 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12303 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12304 (match_operand:DI 2 "arith_reg_operand" "r")))]
12306 "mshard.w %1, %2, %0"
12307 [(set_attr "type" "arith_media")
12308 (set_attr "highpart" "depend")])
12310 (define_insn "mshards_q"
12311 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12313 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12314 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12316 "mshards.q %1, %N2, %0"
12317 [(set_attr "type" "mcmp_media")])
12319 (define_expand "mshfhi_b"
12320 [(match_operand:V8QI 0 "arith_reg_dest" "")
12321 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12322 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12326 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12327 (operands[0], operands[1], operands[2]));
12331 (define_expand "mshflo_b"
12332 [(match_operand:V8QI 0 "arith_reg_dest" "")
12333 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12334 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12338 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12339 (operands[0], operands[1], operands[2]));
12343 (define_insn "mshf4_b"
12345 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12347 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12348 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12349 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12350 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12352 "* return (TARGET_LITTLE_ENDIAN
12353 ? \"mshfhi.b %N1, %N2, %0\"
12354 : \"mshflo.b %N1, %N2, %0\");"
12355 [(set_attr "type" "arith_media")
12356 (set (attr "highpart")
12357 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12358 (const_string "user")))])
12360 (define_insn "mshf0_b"
12362 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12364 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12365 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12366 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12367 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12369 "* return (TARGET_LITTLE_ENDIAN
12370 ? \"mshflo.b %N1, %N2, %0\"
12371 : \"mshfhi.b %N1, %N2, %0\");"
12372 [(set_attr "type" "arith_media")
12373 (set (attr "highpart")
12374 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12375 (const_string "user")))])
12377 (define_expand "mshfhi_l"
12378 [(match_operand:V2SI 0 "arith_reg_dest" "")
12379 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12380 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12384 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12385 (operands[0], operands[1], operands[2]));
12389 (define_expand "mshflo_l"
12390 [(match_operand:V2SI 0 "arith_reg_dest" "")
12391 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12392 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12396 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12397 (operands[0], operands[1], operands[2]));
12401 (define_insn "mshf4_l"
12402 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12404 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12405 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12406 (parallel [(const_int 1) (const_int 3)])))]
12408 "* return (TARGET_LITTLE_ENDIAN
12409 ? \"mshfhi.l %N1, %N2, %0\"
12410 : \"mshflo.l %N1, %N2, %0\");"
12411 [(set_attr "type" "arith_media")
12412 (set (attr "highpart")
12413 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12414 (const_string "user")))])
12416 (define_insn "mshf0_l"
12417 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12419 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12420 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12421 (parallel [(const_int 0) (const_int 2)])))]
12423 "* return (TARGET_LITTLE_ENDIAN
12424 ? \"mshflo.l %N1, %N2, %0\"
12425 : \"mshfhi.l %N1, %N2, %0\");"
12426 [(set_attr "type" "arith_media")
12427 (set (attr "highpart")
12428 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12429 (const_string "user")))])
12431 (define_expand "mshfhi_w"
12432 [(match_operand:V4HI 0 "arith_reg_dest" "")
12433 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12434 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12438 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12439 (operands[0], operands[1], operands[2]));
12443 (define_expand "mshflo_w"
12444 [(match_operand:V4HI 0 "arith_reg_dest" "")
12445 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12446 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12450 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12451 (operands[0], operands[1], operands[2]));
12455 (define_insn "mshf4_w"
12456 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12458 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12459 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12460 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12462 "* return (TARGET_LITTLE_ENDIAN
12463 ? \"mshfhi.w %N1, %N2, %0\"
12464 : \"mshflo.w %N1, %N2, %0\");"
12465 [(set_attr "type" "arith_media")
12466 (set (attr "highpart")
12467 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12468 (const_string "user")))])
12470 (define_insn "mshf0_w"
12471 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12473 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12474 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12475 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12477 "* return (TARGET_LITTLE_ENDIAN
12478 ? \"mshflo.w %N1, %N2, %0\"
12479 : \"mshfhi.w %N1, %N2, %0\");"
12480 [(set_attr "type" "arith_media")
12481 (set (attr "highpart")
12482 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12483 (const_string "user")))])
12485 (define_insn "mshflo_w_x"
12486 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12488 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12489 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12490 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12492 "mshflo.w %N1, %N2, %0"
12493 [(set_attr "type" "arith_media")
12494 (set_attr "highpart" "ignore")])
12496 /* These are useful to expand ANDs and as combiner patterns. */
12497 (define_insn_and_split "mshfhi_l_di"
12498 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12499 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12501 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12502 (const_int -4294967296))))]
12505 mshfhi.l %N1, %N2, %0
12507 "TARGET_SHMEDIA && reload_completed
12508 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12509 [(set (match_dup 3) (match_dup 4))
12510 (set (match_dup 5) (match_dup 6))]
12513 operands[3] = gen_lowpart (SImode, operands[0]);
12514 operands[4] = gen_highpart (SImode, operands[1]);
12515 operands[5] = gen_highpart (SImode, operands[0]);
12516 operands[6] = gen_highpart (SImode, operands[2]);
12518 [(set_attr "type" "arith_media")])
12520 (define_insn "*mshfhi_l_di_rev"
12521 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12522 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12523 (const_int -4294967296))
12524 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12527 "mshfhi.l %N2, %N1, %0"
12528 [(set_attr "type" "arith_media")])
12531 [(set (match_operand:DI 0 "arith_reg_dest" "")
12532 (ior:DI (zero_extend:DI (match_operand:SI 1
12533 "extend_reg_or_0_operand" ""))
12534 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12535 (const_int -4294967296))))
12536 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12541 emit_insn (gen_ashldi3_media (operands[3],
12542 simplify_gen_subreg (DImode, operands[1],
12545 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12549 (define_insn "mshflo_l_di"
12550 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12551 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12552 (const_int 4294967295))
12553 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12557 "mshflo.l %N1, %N2, %0"
12558 [(set_attr "type" "arith_media")
12559 (set_attr "highpart" "ignore")])
12561 (define_insn "*mshflo_l_di_rev"
12562 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12563 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12565 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12566 (const_int 4294967295))))]
12569 "mshflo.l %N2, %N1, %0"
12570 [(set_attr "type" "arith_media")
12571 (set_attr "highpart" "ignore")])
12573 ;; Combiner pattern for trampoline initialization.
12574 (define_insn_and_split "*double_shori"
12575 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12576 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12578 (match_operand:DI 2 "const_int_operand" "n")))]
12580 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12582 "rtx_equal_p (operands[0], operands[1])"
12586 HOST_WIDE_INT v = INTVAL (operands[2]);
12588 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12589 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12592 [(set_attr "highpart" "ignore")])
12595 (define_insn "*mshflo_l_di_x"
12596 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12597 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12599 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12603 "mshflo.l %N1, %N2, %0"
12604 [(set_attr "type" "arith_media")
12605 (set_attr "highpart" "ignore")])
12607 (define_insn_and_split "concat_v2sf"
12608 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12609 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12610 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12611 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12615 mshflo.l %N1, %N2, %0
12618 "TARGET_SHMEDIA && reload_completed
12619 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12620 [(set (match_dup 3) (match_dup 1))
12621 (set (match_dup 4) (match_dup 2))]
12624 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12625 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12627 [(set_attr "type" "arith_media")
12628 (set_attr "highpart" "ignore")])
12630 (define_insn "*mshflo_l_di_x_rev"
12631 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12632 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12634 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12637 "mshflo.l %N2, %N1, %0"
12638 [(set_attr "type" "arith_media")
12639 (set_attr "highpart" "ignore")])
12641 (define_insn "ashlv2si3"
12642 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12643 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12644 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12646 "mshlld.l %1, %2, %0"
12647 [(set_attr "type" "arith_media")
12648 (set_attr "highpart" "depend")])
12651 [(set (match_operand 0 "any_register_operand" "")
12652 (match_operator 3 "shift_operator"
12653 [(match_operand 1 "any_register_operand" "")
12654 (match_operand 2 "shift_count_reg_operand" "")]))]
12655 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12656 [(set (match_dup 0) (match_dup 3))]
12659 rtx count = operands[2];
12660 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12662 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12663 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12664 || GET_CODE (count) == TRUNCATE)
12665 count = XEXP (count, 0);
12666 inner_mode = GET_MODE (count);
12667 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12668 subreg_lowpart_offset (outer_mode, inner_mode));
12669 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12670 operands[1], count);
12673 (define_insn "ashlv4hi3"
12674 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12675 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12676 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12678 "mshlld.w %1, %2, %0"
12679 [(set_attr "type" "arith_media")
12680 (set_attr "highpart" "depend")])
12682 (define_insn "lshrv2si3"
12683 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12684 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12685 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12687 "mshlrd.l %1, %2, %0"
12688 [(set_attr "type" "arith_media")
12689 (set_attr "highpart" "depend")])
12691 (define_insn "lshrv4hi3"
12692 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12693 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12694 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12696 "mshlrd.w %1, %2, %0"
12697 [(set_attr "type" "arith_media")
12698 (set_attr "highpart" "depend")])
12700 (define_insn "subv2si3"
12701 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12702 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12703 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12705 "msub.l %N1, %2, %0"
12706 [(set_attr "type" "arith_media")
12707 (set_attr "highpart" "depend")])
12709 (define_insn "subv4hi3"
12710 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12711 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12712 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12714 "msub.w %N1, %2, %0"
12715 [(set_attr "type" "arith_media")
12716 (set_attr "highpart" "depend")])
12718 (define_insn_and_split "subv2hi3"
12719 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12720 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12721 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12728 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12729 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12730 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12731 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12732 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12734 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12735 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12738 [(set_attr "highpart" "must_split")])
12740 (define_insn "sssubv2si3"
12741 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12742 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12743 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12745 "msubs.l %N1, %2, %0"
12746 [(set_attr "type" "mcmp_media")
12747 (set_attr "highpart" "depend")])
12749 (define_insn "ussubv8qi3"
12750 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12751 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12752 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12754 "msubs.ub %N1, %2, %0"
12755 [(set_attr "type" "mcmp_media")
12756 (set_attr "highpart" "depend")])
12758 (define_insn "sssubv4hi3"
12759 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12760 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12761 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12763 "msubs.w %N1, %2, %0"
12764 [(set_attr "type" "mcmp_media")
12765 (set_attr "highpart" "depend")])
12767 ;; Floating Point Intrinsics
12769 (define_insn "fcosa_s"
12770 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12771 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12775 [(set_attr "type" "atrans_media")])
12777 (define_insn "fsina_s"
12778 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12779 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12783 [(set_attr "type" "atrans_media")])
12785 (define_insn "fipr"
12786 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12787 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12788 "fp_arith_reg_operand" "f")
12789 (match_operand:V4SF 2
12790 "fp_arith_reg_operand" "f"))
12791 (parallel [(const_int 0)]))
12792 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12793 (parallel [(const_int 1)])))
12794 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12795 (parallel [(const_int 2)]))
12796 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12797 (parallel [(const_int 3)])))))]
12799 "fipr.s %1, %2, %0"
12800 [(set_attr "type" "fparith_media")])
12802 (define_insn "fsrra_s"
12803 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12804 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12808 [(set_attr "type" "atrans_media")])
12810 (define_insn "ftrv"
12811 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12815 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12816 (parallel [(const_int 0) (const_int 5)
12817 (const_int 10) (const_int 15)]))
12818 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12820 (vec_select:V4SF (match_dup 1)
12821 (parallel [(const_int 4) (const_int 9)
12822 (const_int 14) (const_int 3)]))
12823 (vec_select:V4SF (match_dup 2)
12824 (parallel [(const_int 1) (const_int 2)
12825 (const_int 3) (const_int 0)]))))
12828 (vec_select:V4SF (match_dup 1)
12829 (parallel [(const_int 8) (const_int 13)
12830 (const_int 2) (const_int 7)]))
12831 (vec_select:V4SF (match_dup 2)
12832 (parallel [(const_int 2) (const_int 3)
12833 (const_int 0) (const_int 1)])))
12835 (vec_select:V4SF (match_dup 1)
12836 (parallel [(const_int 12) (const_int 1)
12837 (const_int 6) (const_int 11)]))
12838 (vec_select:V4SF (match_dup 2)
12839 (parallel [(const_int 3) (const_int 0)
12840 (const_int 1) (const_int 2)]))))))]
12842 "ftrv.s %1, %2, %0"
12843 [(set_attr "type" "fparith_media")])
12845 (define_insn "ldhi_l"
12846 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12848 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12851 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12855 [(set_attr "type" "load_media")])
12857 (define_insn "ldhi_q"
12858 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12860 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12863 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12867 [(set_attr "type" "load_media")])
12869 (define_insn_and_split "*ldhi_q_comb0"
12870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12872 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12873 "register_operand" "r")
12874 (match_operand:SI 2
12875 "ua_offset" "I06"))
12878 (plus:SI (and:SI (match_dup 1) (const_int 7))
12881 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12885 "emit_insn (gen_ldhi_q (operands[0],
12886 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12890 (define_insn_and_split "*ldhi_q_comb1"
12891 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12893 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12894 "register_operand" "r")
12895 (match_operand:SI 2
12896 "ua_offset" "I06"))
12899 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12900 "ua_offset" "I06"))
12904 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12905 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12909 "emit_insn (gen_ldhi_q (operands[0],
12910 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12914 (define_insn "ldlo_l"
12915 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12917 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12919 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12920 (and:SI (match_dup 1) (const_int 3))))]
12923 [(set_attr "type" "load_media")])
12925 (define_insn "ldlo_q"
12926 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12928 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12930 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12931 (and:SI (match_dup 1) (const_int 7))))]
12934 [(set_attr "type" "load_media")])
12936 (define_insn_and_split "*ldlo_q_comb0"
12937 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12939 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12940 (match_operand:SI 2 "ua_offset" "I06"))
12942 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12943 (and:SI (match_dup 1) (const_int 7))))]
12944 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12948 "emit_insn (gen_ldlo_q (operands[0],
12949 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12952 (define_insn_and_split "*ldlo_q_comb1"
12953 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12955 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12956 (match_operand:SI 2 "ua_offset" "I06"))
12958 (minus:SI (const_int 8)
12959 (and:SI (plus:SI (match_dup 1)
12960 (match_operand:SI 3 "ua_offset" "I06"))
12962 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12963 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12964 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12968 "emit_insn (gen_ldlo_q (operands[0],
12969 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12972 (define_insn "sthi_l"
12973 [(set (zero_extract:SI
12974 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12977 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12979 (match_operand:SI 1 "arith_reg_operand" "r"))]
12982 [(set_attr "type" "ustore_media")])
12984 ;; All unaligned stores are considered to be 'narrow' because they typically
12985 ;; operate on less that a quadword, and when they operate on a full quadword,
12986 ;; the vanilla store high / store low sequence will cause a stall if not
12987 ;; scheduled apart.
12988 (define_insn "sthi_q"
12989 [(set (zero_extract:DI
12990 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12993 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12995 (match_operand:DI 1 "arith_reg_operand" "r"))]
12998 [(set_attr "type" "ustore_media")])
13000 (define_insn_and_split "*sthi_q_comb0"
13001 [(set (zero_extract:DI
13002 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13003 "register_operand" "r")
13004 (match_operand:SI 1 "ua_offset"
13008 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13010 (match_operand:DI 2 "arith_reg_operand" "r"))]
13011 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13015 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13019 (define_insn_and_split "*sthi_q_comb1"
13020 [(set (zero_extract:DI
13021 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13022 "register_operand" "r")
13023 (match_operand:SI 1 "ua_offset"
13027 (plus:SI (and:SI (plus:SI (match_dup 0)
13028 (match_operand:SI 2 "ua_offset" "I06"))
13032 (match_operand:DI 3 "arith_reg_operand" "r"))]
13033 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13034 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13038 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13042 ;; This is highpart user because the address is used as full 64 bit.
13043 (define_insn "stlo_l"
13044 [(set (zero_extract:SI
13045 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13047 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13048 (and:SI (match_dup 0) (const_int 3)))
13049 (match_operand:SI 1 "arith_reg_operand" "r"))]
13052 [(set_attr "type" "ustore_media")])
13054 (define_insn "stlo_q"
13055 [(set (zero_extract:DI
13056 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13058 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13059 (and:SI (match_dup 0) (const_int 7)))
13060 (match_operand:DI 1 "arith_reg_operand" "r"))]
13063 [(set_attr "type" "ustore_media")])
13065 (define_insn_and_split "*stlo_q_comb0"
13066 [(set (zero_extract:DI
13067 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13068 (match_operand:SI 1 "ua_offset" "I06"))
13070 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13071 (and:SI (match_dup 0) (const_int 7)))
13072 (match_operand:DI 2 "arith_reg_operand" "r"))]
13073 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13077 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13081 (define_insn_and_split "*stlo_q_comb1"
13082 [(set (zero_extract:DI
13083 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13084 (match_operand:SI 1 "ua_offset" "I06"))
13086 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13087 (match_operand:SI 2
13088 "ua_offset" "I06"))
13090 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13091 (match_operand:DI 3 "arith_reg_operand" "r"))]
13092 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13096 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13100 (define_insn "ldhi_l64"
13101 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13103 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13106 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13110 [(set_attr "type" "load_media")])
13112 (define_insn "ldhi_q64"
13113 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13115 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13118 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13122 [(set_attr "type" "load_media")])
13124 (define_insn "ldlo_l64"
13125 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13127 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13129 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13130 (and:DI (match_dup 1) (const_int 3))))]
13133 [(set_attr "type" "load_media")])
13135 (define_insn "ldlo_q64"
13136 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13138 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13140 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13141 (and:DI (match_dup 1) (const_int 7))))]
13144 [(set_attr "type" "load_media")])
13146 (define_insn "sthi_l64"
13147 [(set (zero_extract:SI
13148 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13151 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13153 (match_operand:SI 1 "arith_reg_operand" "r"))]
13156 [(set_attr "type" "ustore_media")])
13158 (define_insn "sthi_q64"
13159 [(set (zero_extract:DI
13160 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13163 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13165 (match_operand:DI 1 "arith_reg_operand" "r"))]
13168 [(set_attr "type" "ustore_media")])
13170 (define_insn "stlo_l64"
13171 [(set (zero_extract:SI
13172 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13174 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13175 (and:DI (match_dup 0) (const_int 3)))
13176 (match_operand:SI 1 "arith_reg_operand" "r"))]
13179 [(set_attr "type" "ustore_media")])
13181 (define_insn "stlo_q64"
13182 [(set (zero_extract:DI
13183 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13185 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13186 (and:DI (match_dup 0) (const_int 7)))
13187 (match_operand:DI 1 "arith_reg_operand" "r"))]
13190 [(set_attr "type" "ustore_media")])
13193 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13194 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13198 [(set_attr "type" "arith_media")])
13200 (define_insn "nsbsi"
13201 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13203 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13207 [(set_attr "type" "arith_media")])
13209 (define_insn "nsbdi"
13210 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13212 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13216 [(set_attr "type" "arith_media")])
13218 (define_expand "ffsdi2"
13219 [(set (match_operand:DI 0 "arith_reg_dest" "")
13220 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13224 rtx scratch = gen_reg_rtx (DImode);
13227 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13228 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13229 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13230 emit_insn (gen_nsbdi (scratch, scratch));
13231 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13232 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13233 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13234 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13239 (define_expand "ffssi2"
13240 [(set (match_operand:SI 0 "arith_reg_dest" "")
13241 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13245 rtx scratch = gen_reg_rtx (SImode);
13246 rtx discratch = gen_reg_rtx (DImode);
13249 emit_insn (gen_adddi3 (discratch,
13250 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13252 emit_insn (gen_andcdi3 (discratch,
13253 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13255 emit_insn (gen_nsbsi (scratch, discratch));
13256 last = emit_insn (gen_subsi3 (operands[0],
13257 force_reg (SImode, GEN_INT (63)), scratch));
13258 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13263 (define_insn "byterev"
13264 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13265 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13266 (parallel [(const_int 7) (const_int 6) (const_int 5)
13267 (const_int 4) (const_int 3) (const_int 2)
13268 (const_int 1) (const_int 0)])))]
13271 [(set_attr "type" "arith_media")])
13273 (define_insn "*prefetch_media"
13274 [(prefetch (match_operand:QI 0 "address_operand" "p")
13275 (match_operand:SI 1 "const_int_operand" "n")
13276 (match_operand:SI 2 "const_int_operand" "n"))]
13280 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13281 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13284 [(set_attr "type" "other")])
13286 (define_insn "*prefetch_i4"
13287 [(prefetch (match_operand:SI 0 "register_operand" "r")
13288 (match_operand:SI 1 "const_int_operand" "n")
13289 (match_operand:SI 2 "const_int_operand" "n"))]
13290 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13293 return \"pref @%0\";
13295 [(set_attr "type" "other")])
13297 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13298 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13299 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13300 (define_expand "prefetch"
13301 [(prefetch (match_operand 0 "address_operand" "p")
13302 (match_operand:SI 1 "const_int_operand" "n")
13303 (match_operand:SI 2 "const_int_operand" "n"))]
13304 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13305 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13308 if (GET_MODE (operands[0]) != Pmode
13309 || !CONST_INT_P (operands[1])
13310 || !CONST_INT_P (operands[2]))
13312 if (! TARGET_SHMEDIA)
13313 operands[0] = force_reg (Pmode, operands[0]);
13316 (define_insn "prefetch_m2a"
13317 [(prefetch (match_operand:SI 0 "register_operand" "r")
13318 (match_operand:SI 1 "const_int_operand" "n")
13319 (match_operand:SI 2 "const_int_operand" "n"))]
13322 [(set_attr "type" "other")])
13324 (define_insn "alloco_i"
13325 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13326 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13332 if (GET_CODE (operands[0]) == PLUS)
13334 xops[0] = XEXP (operands[0], 0);
13335 xops[1] = XEXP (operands[0], 1);
13339 xops[0] = operands[0];
13340 xops[1] = const0_rtx;
13342 output_asm_insn (\"alloco %0, %1\", xops);
13345 [(set_attr "type" "other")])
13348 [(set (match_operand 0 "any_register_operand" "")
13349 (match_operand 1 "" ""))]
13350 "TARGET_SHMEDIA && reload_completed"
13351 [(set (match_dup 0) (match_dup 1))]
13356 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13361 ; Stack Protector Patterns
13363 (define_expand "stack_protect_set"
13364 [(set (match_operand 0 "memory_operand" "")
13365 (match_operand 1 "memory_operand" ""))]
13368 if (TARGET_SHMEDIA)
13370 if (TARGET_SHMEDIA64)
13371 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13373 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13376 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13381 (define_insn "stack_protect_set_si"
13382 [(set (match_operand:SI 0 "memory_operand" "=m")
13383 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13384 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13386 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13387 [(set_attr "type" "other")
13388 (set_attr "length" "6")])
13390 (define_insn "stack_protect_set_si_media"
13391 [(set (match_operand:SI 0 "memory_operand" "=m")
13392 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13393 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13395 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13396 [(set_attr "type" "other")
13397 (set_attr "length" "12")])
13399 (define_insn "stack_protect_set_di_media"
13400 [(set (match_operand:DI 0 "memory_operand" "=m")
13401 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13402 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13404 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13405 [(set_attr "type" "other")
13406 (set_attr "length" "12")])
13408 (define_expand "stack_protect_test"
13409 [(match_operand 0 "memory_operand" "")
13410 (match_operand 1 "memory_operand" "")
13411 (match_operand 2 "" "")]
13414 if (TARGET_SHMEDIA)
13416 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13419 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13420 if (TARGET_SHMEDIA64)
13422 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13424 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13428 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13430 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13435 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13436 emit_jump_insn (gen_branch_true (operands[2]));
13442 (define_insn "stack_protect_test_si"
13443 [(set (reg:SI T_REG)
13444 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13445 (match_operand:SI 1 "memory_operand" "m")]
13447 (set (match_scratch:SI 2 "=&r") (const_int 0))
13448 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13450 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13451 [(set_attr "type" "other")
13452 (set_attr "length" "10")])
13454 (define_insn "stack_protect_test_si_media"
13455 [(set (match_operand:SI 0 "register_operand" "=&r")
13456 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13457 (match_operand:SI 2 "memory_operand" "m")]
13459 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13461 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13462 [(set_attr "type" "other")
13463 (set_attr "length" "16")])
13465 (define_insn "stack_protect_test_di_media"
13466 [(set (match_operand:DI 0 "register_operand" "=&r")
13467 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13468 (match_operand:DI 2 "memory_operand" "m")]
13470 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13472 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13473 [(set_attr "type" "other")
13474 (set_attr "length" "16")])